summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortwosee <twose@qq.com>2020-07-11 06:14:22 +0800
committertwosee <twose@qq.com>2020-07-11 06:14:22 +0800
commit150504e6b1ea2b2eac3177c8cff2657a243da22c (patch)
tree23b9752dcd7b8e06b5874a11b5312634d958fc11
parenta72c53a0707db617ba0cf55d639bc188c3aa8ede (diff)
downloadphp-git-150504e6b1ea2b2eac3177c8cff2657a243da22c.tar.gz
Fixed bug #79821
HashTable was reallocated (zend_hash_packed_grow) during php_var_dump, so we should call GC_ADDREF to make SEPARATE_ARRAY work. Closes GH-5837.
-rw-r--r--ext/standard/tests/bug79821.phpt21
-rw-r--r--ext/standard/var.c3
2 files changed, 24 insertions, 0 deletions
diff --git a/ext/standard/tests/bug79821.phpt b/ext/standard/tests/bug79821.phpt
new file mode 100644
index 0000000000..cf1d27e128
--- /dev/null
+++ b/ext/standard/tests/bug79821.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Bug #79821 (array grow during var_dump)
+--FILE--
+<?php
+
+$foo = $bar = [];
+for ($i = 0; $i < 3; $i++) {
+ $foo = [$foo, [&$bar]];
+}
+ob_start(function (string $buffer) use (&$bar) {
+ $bar[][] = null;
+ return '';
+}, 1);
+var_dump($foo[0]);
+ob_end_clean();
+
+echo "OK\n";
+
+?>
+--EXPECT--
+OK
diff --git a/ext/standard/var.c b/ext/standard/var.c
index a008aab4cb..241880b903 100644
--- a/ext/standard/var.c
+++ b/ext/standard/var.c
@@ -122,6 +122,7 @@ again:
PUTS("*RECURSION*\n");
return;
}
+ GC_ADDREF(myht);
GC_PROTECT_RECURSION(myht);
}
count = zend_array_count(myht);
@@ -506,8 +507,10 @@ 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);
}
if (level > 1) {
buffer_append_spaces(buf, level - 1);