Skip to content

Commit

Permalink
Fixed bug #79830 introduced by fixing bug #79821
Browse files Browse the repository at this point in the history
This also fixes memory error in debug_zval_dump and var_export.
  • Loading branch information
twose committed Jul 11, 2020
1 parent 150504e commit 56dec3c
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 25 deletions.
20 changes: 11 additions & 9 deletions ext/standard/tests/bug79821.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@ Bug #79821 (array grow during var_dump)
--FILE--
<?php

$foo = $bar = [];
for ($i = 0; $i < 3; $i++) {
$foo = [$foo, [&$bar]];
foreach (['var_dump', 'debug_zval_dump', 'var_export'] as $output) {
$foo = $bar = [];
for ($i = 0; $i < 3; $i++) {
$foo = [$foo, [&$bar]];
}
ob_start(function (string $buffer) use (&$bar) {
$bar[][] = null;
return '';
}, 64);
$output($foo[0]);
ob_end_clean();
}
ob_start(function (string $buffer) use (&$bar) {
$bar[][] = null;
return '';
}, 1);
var_dump($foo[0]);
ob_end_clean();

echo "OK\n";

Expand Down
42 changes: 26 additions & 16 deletions ext/standard/var.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,22 +117,26 @@ PHPAPI void php_var_dump(zval *struc, int level) /* {{{ */
break;
case IS_ARRAY:
myht = Z_ARRVAL_P(struc);
if (level > 1 && !(GC_FLAGS(myht) & GC_IMMUTABLE)) {
if (GC_IS_RECURSIVE(myht)) {
PUTS("*RECURSION*\n");
return;
if (!(GC_FLAGS(myht) & GC_IMMUTABLE)) {
if (level > 1) {
if (GC_IS_RECURSIVE(myht)) {
PUTS("*RECURSION*\n");
return;
}
GC_PROTECT_RECURSION(myht);
}
GC_ADDREF(myht);
GC_PROTECT_RECURSION(myht);
}
count = zend_array_count(myht);
php_printf("%sarray(%d) {\n", COMMON, count);

ZEND_HASH_FOREACH_KEY_VAL_IND(myht, num, key, val) {
php_array_element_dump(val, num, key, level);
} ZEND_HASH_FOREACH_END();
if (level > 1 && !(GC_FLAGS(myht) & GC_IMMUTABLE)) {
GC_UNPROTECT_RECURSION(myht);
if (!(GC_FLAGS(myht) & GC_IMMUTABLE)) {
if (level > 1) {
GC_UNPROTECT_RECURSION(myht);
}
GC_DELREF(myht);
}
if (level > 1) {
php_printf("%*c", level-1, ' ');
Expand Down Expand Up @@ -285,20 +289,26 @@ PHPAPI void php_debug_zval_dump(zval *struc, int level) /* {{{ */
break;
case IS_ARRAY:
myht = Z_ARRVAL_P(struc);
if (level > 1 && !(GC_FLAGS(myht) & GC_IMMUTABLE)) {
if (GC_IS_RECURSIVE(myht)) {
PUTS("*RECURSION*\n");
return;
if (!(GC_FLAGS(myht) & GC_IMMUTABLE)) {
if (level > 1) {
if (GC_IS_RECURSIVE(myht)) {
PUTS("*RECURSION*\n");
return;
}
GC_PROTECT_RECURSION(myht);
}
GC_PROTECT_RECURSION(myht);
GC_ADDREF(myht);
}
count = zend_array_count(myht);
php_printf("%sarray(%d) refcount(%u){\n", COMMON, count, Z_REFCOUNTED_P(struc) ? Z_REFCOUNT_P(struc) : 1);
ZEND_HASH_FOREACH_KEY_VAL_IND(myht, index, key, val) {
zval_array_element_dump(val, index, key, level);
} ZEND_HASH_FOREACH_END();
if (level > 1 && !(GC_FLAGS(myht) & GC_IMMUTABLE)) {
GC_UNPROTECT_RECURSION(myht);
if (!(GC_FLAGS(myht) & GC_IMMUTABLE)) {
if (level > 1) {
GC_UNPROTECT_RECURSION(myht);
}
GC_DELREF(myht);
}
if (is_temp) {
zend_hash_destroy(myht);
Expand Down Expand Up @@ -497,6 +507,7 @@ PHPAPI void php_var_export_ex(zval *struc, int level, smart_str *buf) /* {{{ */
zend_error(E_WARNING, "var_export does not handle circular references");
return;
}
GC_ADDREF(myht);
GC_PROTECT_RECURSION(myht);
}
if (level > 1) {
Expand All @@ -507,7 +518,6 @@ PHPAPI void php_var_export_ex(zval *struc, int level, smart_str *buf) /* {{{ */
ZEND_HASH_FOREACH_KEY_VAL_IND(myht, index, key, val) {
php_array_element_export(val, index, key, level, buf);
} ZEND_HASH_FOREACH_END();

if (!(GC_FLAGS(myht) & GC_IMMUTABLE)) {
GC_UNPROTECT_RECURSION(myht);
GC_DELREF(myht);
Expand Down

0 comments on commit 56dec3c

Please sign in to comment.