Skip to content

Commit 56dec3c

Browse files
committed
Fixed bug #79830 introduced by fixing bug #79821
This also fixes memory error in debug_zval_dump and var_export.
1 parent 150504e commit 56dec3c

File tree

2 files changed

+37
-25
lines changed

2 files changed

+37
-25
lines changed

ext/standard/tests/bug79821.phpt

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,18 @@ Bug #79821 (array grow during var_dump)
33
--FILE--
44
<?php
55

6-
$foo = $bar = [];
7-
for ($i = 0; $i < 3; $i++) {
8-
$foo = [$foo, [&$bar]];
6+
foreach (['var_dump', 'debug_zval_dump', 'var_export'] as $output) {
7+
$foo = $bar = [];
8+
for ($i = 0; $i < 3; $i++) {
9+
$foo = [$foo, [&$bar]];
10+
}
11+
ob_start(function (string $buffer) use (&$bar) {
12+
$bar[][] = null;
13+
return '';
14+
}, 64);
15+
$output($foo[0]);
16+
ob_end_clean();
917
}
10-
ob_start(function (string $buffer) use (&$bar) {
11-
$bar[][] = null;
12-
return '';
13-
}, 1);
14-
var_dump($foo[0]);
15-
ob_end_clean();
1618

1719
echo "OK\n";
1820

ext/standard/var.c

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -117,22 +117,26 @@ PHPAPI void php_var_dump(zval *struc, int level) /* {{{ */
117117
break;
118118
case IS_ARRAY:
119119
myht = Z_ARRVAL_P(struc);
120-
if (level > 1 && !(GC_FLAGS(myht) & GC_IMMUTABLE)) {
121-
if (GC_IS_RECURSIVE(myht)) {
122-
PUTS("*RECURSION*\n");
123-
return;
120+
if (!(GC_FLAGS(myht) & GC_IMMUTABLE)) {
121+
if (level > 1) {
122+
if (GC_IS_RECURSIVE(myht)) {
123+
PUTS("*RECURSION*\n");
124+
return;
125+
}
126+
GC_PROTECT_RECURSION(myht);
124127
}
125128
GC_ADDREF(myht);
126-
GC_PROTECT_RECURSION(myht);
127129
}
128130
count = zend_array_count(myht);
129131
php_printf("%sarray(%d) {\n", COMMON, count);
130-
131132
ZEND_HASH_FOREACH_KEY_VAL_IND(myht, num, key, val) {
132133
php_array_element_dump(val, num, key, level);
133134
} ZEND_HASH_FOREACH_END();
134-
if (level > 1 && !(GC_FLAGS(myht) & GC_IMMUTABLE)) {
135-
GC_UNPROTECT_RECURSION(myht);
135+
if (!(GC_FLAGS(myht) & GC_IMMUTABLE)) {
136+
if (level > 1) {
137+
GC_UNPROTECT_RECURSION(myht);
138+
}
139+
GC_DELREF(myht);
136140
}
137141
if (level > 1) {
138142
php_printf("%*c", level-1, ' ');
@@ -285,20 +289,26 @@ PHPAPI void php_debug_zval_dump(zval *struc, int level) /* {{{ */
285289
break;
286290
case IS_ARRAY:
287291
myht = Z_ARRVAL_P(struc);
288-
if (level > 1 && !(GC_FLAGS(myht) & GC_IMMUTABLE)) {
289-
if (GC_IS_RECURSIVE(myht)) {
290-
PUTS("*RECURSION*\n");
291-
return;
292+
if (!(GC_FLAGS(myht) & GC_IMMUTABLE)) {
293+
if (level > 1) {
294+
if (GC_IS_RECURSIVE(myht)) {
295+
PUTS("*RECURSION*\n");
296+
return;
297+
}
298+
GC_PROTECT_RECURSION(myht);
292299
}
293-
GC_PROTECT_RECURSION(myht);
300+
GC_ADDREF(myht);
294301
}
295302
count = zend_array_count(myht);
296303
php_printf("%sarray(%d) refcount(%u){\n", COMMON, count, Z_REFCOUNTED_P(struc) ? Z_REFCOUNT_P(struc) : 1);
297304
ZEND_HASH_FOREACH_KEY_VAL_IND(myht, index, key, val) {
298305
zval_array_element_dump(val, index, key, level);
299306
} ZEND_HASH_FOREACH_END();
300-
if (level > 1 && !(GC_FLAGS(myht) & GC_IMMUTABLE)) {
301-
GC_UNPROTECT_RECURSION(myht);
307+
if (!(GC_FLAGS(myht) & GC_IMMUTABLE)) {
308+
if (level > 1) {
309+
GC_UNPROTECT_RECURSION(myht);
310+
}
311+
GC_DELREF(myht);
302312
}
303313
if (is_temp) {
304314
zend_hash_destroy(myht);
@@ -497,6 +507,7 @@ PHPAPI void php_var_export_ex(zval *struc, int level, smart_str *buf) /* {{{ */
497507
zend_error(E_WARNING, "var_export does not handle circular references");
498508
return;
499509
}
510+
GC_ADDREF(myht);
500511
GC_PROTECT_RECURSION(myht);
501512
}
502513
if (level > 1) {
@@ -507,7 +518,6 @@ PHPAPI void php_var_export_ex(zval *struc, int level, smart_str *buf) /* {{{ */
507518
ZEND_HASH_FOREACH_KEY_VAL_IND(myht, index, key, val) {
508519
php_array_element_export(val, index, key, level, buf);
509520
} ZEND_HASH_FOREACH_END();
510-
511521
if (!(GC_FLAGS(myht) & GC_IMMUTABLE)) {
512522
GC_UNPROTECT_RECURSION(myht);
513523
GC_DELREF(myht);

0 commit comments

Comments
 (0)