summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXinchen Hui <laruence@gmail.com>2016-07-20 16:12:49 +0800
committerXinchen Hui <laruence@gmail.com>2016-07-20 16:12:49 +0800
commitc35dab005c2c1048367b64acdd5e64420c34b091 (patch)
treea5e127bc3266fbedc477d0ded5b3650a7b1679d4
parentdda0ea9b3af0c392be8d850ccdbe8a1bfa2badb6 (diff)
parent3c3b8c8365dc9ac7d62034c9eecbabb4800b7353 (diff)
downloadphp-git-c35dab005c2c1048367b64acdd5e64420c34b091.tar.gz
Merge branch 'PHP-7.0'
* PHP-7.0: Fixed bug #72622 (array_walk + array_replace_recursive create references from nothing)
-rw-r--r--ext/standard/array.c4
-rw-r--r--ext/standard/tests/array/bug72622.phpt34
2 files changed, 37 insertions, 1 deletions
diff --git a/ext/standard/array.c b/ext/standard/array.c
index 359bd978d4..ccf3ceb0f2 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -1476,7 +1476,9 @@ static int php_array_walk(HashTable *target_hash, zval *userdata, int recursive)
if (!was_ref && Z_ISREF(args[0])) {
/* copy reference back */
zval garbage;
-
+ if (Z_REFCOUNT(args[0]) == 1) {
+ ZVAL_UNREF(&args[0]);
+ }
ZVAL_COPY_VALUE(&garbage, zv);
ZVAL_COPY_VALUE(zv, &args[0]);
zval_ptr_dtor(&garbage);
diff --git a/ext/standard/tests/array/bug72622.phpt b/ext/standard/tests/array/bug72622.phpt
new file mode 100644
index 0000000000..66e22f3bf9
--- /dev/null
+++ b/ext/standard/tests/array/bug72622.phpt
@@ -0,0 +1,34 @@
+--TEST--
+Bug #72622 (array_walk + array_replace_recursive create references from nothing)
+--FILE--
+<?php
+
+function walk (array $arr) {
+ array_walk($arr, function (&$val, $name) {
+
+ });
+
+ return $arr;
+}
+
+$arr3 = ['foo' => 'foo'];
+$arr4 = walk(['foo' => 'bar']);
+$arr5 = array_replace_recursive($arr3, $arr4);
+$arr5['foo'] = 'baz';
+
+var_dump($arr3, $arr4, $arr5);
+
+?>
+--EXPECT--
+array(1) {
+ ["foo"]=>
+ string(3) "foo"
+}
+array(1) {
+ ["foo"]=>
+ string(3) "bar"
+}
+array(1) {
+ ["foo"]=>
+ string(3) "baz"
+}