summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXinchen Hui <laruence@gmail.com>2016-07-20 16:12:37 +0800
committerXinchen Hui <laruence@gmail.com>2016-07-20 16:12:37 +0800
commit3c3b8c8365dc9ac7d62034c9eecbabb4800b7353 (patch)
tree05947c35c279b214b103b811850a1beaa50409d7
parentdf5ee7bc2557fd87a7e296d399cd947d68c1a4d3 (diff)
downloadphp-git-3c3b8c8365dc9ac7d62034c9eecbabb4800b7353.tar.gz
Fixed bug #72622 (array_walk + array_replace_recursive create references from nothing)
-rw-r--r--NEWS2
-rw-r--r--ext/standard/array.c4
-rw-r--r--ext/standard/tests/array/bug72622.phpt34
3 files changed, 39 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index ce9fe677c9..6a42e1cf97 100644
--- 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
diff --git a/ext/standard/array.c b/ext/standard/array.c
index 6c58e3aa74..e5c38f2906 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -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
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"
+}