com php-src: Fix ref handling in array_merge/replace_recurs ive(): ext/standard/array.c ext/standard/tests/arra
y/array_merge_replace_recursive_refs.phpt
| From: | Nikita Popov | Date: | Fri, 29 Jul 2016 17:07:04 +0000 |
| Subject: | com php-src: Fix ref handling in array_merge/replace_recurs ive(): ext/standard/array.c ext/standard/tests/arra y/array_merge_replace_recursive_refs.phpt |
||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-93480@lists.php.net to get a copy of this message | ||
Commit: 8a442a33c319a9663212e732dda4cd717d4efff6
Author: Nikita Popov <nikic@php.net> Fri, 29 Jul 2016 19:07:04 +0200
Parents: 1666e80cb90c3c88bfd00522999e862625222e9b
Branches: PHP-7.0 PHP-7.1 master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=8a442a33c319a9663212e732dda4cd717d4efff6
Log:
Fix ref handling in array_merge/replace_recursive()
As usual, if the reference has rc=1 it really isn't a reference.
Changed paths:
M ext/standard/array.c
A ext/standard/tests/array/array_merge_replace_recursive_refs.phpt
Diff:
diff --git a/ext/standard/array.c b/ext/standard/array.c
index e5c38f2..538460b 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -3075,16 +3075,12 @@ PHPAPI int php_array_merge_recursive(HashTable *dest, HashTable *src) /* {{{
*/
}
zval_ptr_dtor(&tmp);
} else {
- if (Z_REFCOUNTED_P(src_entry)) {
- Z_ADDREF_P(src_entry);
- }
- zend_hash_add_new(dest, string_key, src_entry);
+ zval *zv = zend_hash_add_new(dest, string_key, src_entry);
+ zval_add_ref(zv);
}
} else {
- if (Z_REFCOUNTED_P(src_entry)) {
- Z_ADDREF_P(src_entry);
- }
- zend_hash_next_index_insert_new(dest, src_entry);
+ zval *zv = zend_hash_next_index_insert_new(dest, src_entry);
+ zval_add_ref(zv);
}
} ZEND_HASH_FOREACH_END();
return 1;
@@ -3134,11 +3130,8 @@ PHPAPI int php_array_replace_recursive(HashTable *dest, HashTable *src) /*
{{{ *
(Z_TYPE_P(dest_entry) != IS_ARRAY &&
(!Z_ISREF_P(dest_entry) || Z_TYPE_P(Z_REFVAL_P(dest_entry)) != IS_ARRAY))) {
- if (Z_REFCOUNTED_P(src_entry)) {
- Z_ADDREF_P(src_entry);
- }
- zend_hash_update(dest, string_key, src_entry);
-
+ zval *zv = zend_hash_update(dest, string_key, src_entry);
+ zval_add_ref(zv);
continue;
}
} else {
@@ -3147,11 +3140,8 @@ PHPAPI int php_array_replace_recursive(HashTable *dest, HashTable *src) /*
{{{ *
(Z_TYPE_P(dest_entry) != IS_ARRAY &&
(!Z_ISREF_P(dest_entry) || Z_TYPE_P(Z_REFVAL_P(dest_entry)) != IS_ARRAY))) {
- if (Z_REFCOUNTED_P(src_entry)) {
- Z_ADDREF_P(src_entry);
- }
- zend_hash_index_update(dest, num_key, src_entry);
-
+ zval *zv = zend_hash_index_update(dest, num_key, src_entry);
+ zval_add_ref(zv);
continue;
}
}
diff --git a/ext/standard/tests/array/array_merge_replace_recursive_refs.phpt
b/ext/standard/tests/array/array_merge_replace_recursive_refs.phpt
new file mode 100644
index 0000000..ac8be2b
--- /dev/null
+++ b/ext/standard/tests/array/array_merge_replace_recursive_refs.phpt
@@ -0,0 +1,38 @@
+--TEST--
+array_merge/replace_recursive() should unwrap references with rc=1
+--FILE--
+<?php
+
+$x = 24;
+$arr1 = [[42]];
+$arr2 = [[&$x]];
+unset($x);
+$arr3 = array_replace_recursive($arr1, $arr2);
+$arr2[0][0] = 12;
+var_dump($arr3);
+
+unset($arr1, $arr2, $arr3);
+
+$x = 24;
+$arr1 = [42];
+$arr2 = [&$x];
+unset($x);
+$arr3 = array_merge_recursive($arr1, $arr2);
+$arr2[0] = 12;
+var_dump($arr3);
+
+?>
+--EXPECT--
+array(1) {
+ [0]=>
+ array(1) {
+ [0]=>
+ int(24)
+ }
+}
+array(2) {
+ [0]=>
+ int(42)
+ [1]=>
+ int(24)
+}