summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/standard/tests/bug79821.phpt20
-rw-r--r--ext/standard/var.c42
2 files changed, 37 insertions, 25 deletions
diff --git a/ext/standard/tests/bug79821.phpt b/ext/standard/tests/bug79821.phpt
index cf1d27e128..53c28ccf0f 100644
--- a/ext/standard/tests/bug79821.phpt
+++ b/ext/standard/tests/bug79821.phpt
@@ -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";
diff --git a/ext/standard/var.c b/ext/standard/var.c
index 460674a8ed..79c3b323f6 100644
--- a/ext/standard/var.c
+++ b/ext/standard/var.c
@@ -127,22 +127,26 @@ again:
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, ' ');
@@ -312,20 +316,26 @@ again:
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 (level > 1) {
php_printf("%*c", level - 1, ' ');
@@ -529,6 +539,7 @@ again:
zend_error(E_WARNING, "var_export does not handle circular references");
return;
}
+ GC_ADDREF(myht);
GC_PROTECT_RECURSION(myht);
}
if (level > 1) {
@@ -539,7 +550,6 @@ again:
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);