]> granicus.if.org Git - php/commitdiff
Fixed bug #72622 (array_walk + array_replace_recursive create references from nothing)
authorXinchen Hui <laruence@gmail.com>
Wed, 20 Jul 2016 08:12:37 +0000 (16:12 +0800)
committerXinchen Hui <laruence@gmail.com>
Wed, 20 Jul 2016 08:12:37 +0000 (16:12 +0800)
NEWS
ext/standard/array.c
ext/standard/tests/array/bug72622.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index ce9fe677c90845a3e59a777d115ef5134d43552f..6a42e1cf9768c49abbd62377ad2e578d279e1dbf 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -64,6 +64,8 @@ PHP                                                                        NEWS
   . Fixed bug #72571 (SQLite3::bindValue, SQLite3::bindParam crash). (Laruence)
 
 - Standard:
+  . Fixed bug #72622 (array_walk + array_replace_recursive create references
+    from nothing). (Laruence)
   . Fixed bug #72152 (base64_decode $strict fails to detect null byte).
     (Lauri Kenttä)
   . Fixed bug #72263 (base64_decode skips a character after padding in strict
index 6c58e3aa74735c80a89b36cb7d90cc0fd74c17d2..e5c38f2906523514f14248652ba4c00047b7087b 100644 (file)
@@ -1481,7 +1481,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 (file)
index 0000000..66e22f3
--- /dev/null
@@ -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"
+}