1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Fix GH-19801: address leak when calling var_dump() with recursion in __debugInfo() (#19837)

This commit is contained in:
Alexandre Daubois
2025-09-16 15:05:45 +02:00
committed by GitHub
parent f045716288
commit 75217c16c8
4 changed files with 66 additions and 2 deletions

2
NEWS
View File

@@ -29,6 +29,8 @@ PHP NEWS
. Fixed bug GH-12265 (Cloning an object breaks serialization recursion).
(nielsdos)
. Fixed bug GH-19701 (Serialize/deserialize loses some data). (nielsdos)
. Fixed bug GH-19801 (leaks in var_dump() and debug_zval_dump()).
(alexandre-daubois)
- Zip:
. Fixed bug GH-19688 (Remove pattern overflow in zip addGlob()). (nielsdos)

View File

@@ -0,0 +1,32 @@
--TEST--
GH-19801 (debug_zval_dump() leak with __debugInfo() that modifies circular references)
--FILE--
<?php
$a = [
new class {
function __debugInfo() {
global $b;
$b->a = null;
gc_collect_cycles();
return [];
}
},
];
$b = new stdClass;
$b->a = &$a;
debug_zval_dump($b);
?>
--EXPECTF--
object(stdClass)#2 (1) refcount(%d){
["a"]=>
reference refcount(%d) {
array(1) refcount(%d){
[0]=>
object(class@anonymous)#1 (0) refcount(%d){
}
}
}
}

View File

@@ -0,0 +1,30 @@
--TEST--
GH-19801 (var_dump() memory leak with __debugInfo() that modifies circular references)
--FILE--
<?php
$a = [
new class {
function __debugInfo() {
global $b;
$b->a = null;
gc_collect_cycles();
return [];
}
},
];
$b = new stdClass;
$b->a = &$a;
var_dump($b);
?>
--EXPECTF--
object(stdClass)#2 (1) {
["a"]=>
&array(1) {
[0]=>
object(class@anonymous)#1 (0) {
}
}
}

View File

@@ -139,7 +139,7 @@ again:
} ZEND_HASH_FOREACH_END();
if (!(GC_FLAGS(myht) & GC_IMMUTABLE)) {
GC_UNPROTECT_RECURSION(myht);
GC_DELREF(myht);
GC_DTOR_NO_REF(myht);
}
if (level > 1) {
php_printf("%*c", level-1, ' ');
@@ -336,7 +336,7 @@ PHPAPI void php_debug_zval_dump(zval *struc, int level) /* {{{ */
} ZEND_HASH_FOREACH_END();
if (!(GC_FLAGS(myht) & GC_IMMUTABLE)) {
GC_UNPROTECT_RECURSION(myht);
GC_DELREF(myht);
GC_DTOR_NO_REF(myht);
}
if (level > 1) {
php_printf("%*c", level - 1, ' ');