summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/standard/array.c2
-rw-r--r--ext/standard/tests/array/bug42850.phpt59
2 files changed, 60 insertions, 1 deletions
diff --git a/ext/standard/array.c b/ext/standard/array.c
index b2983090e0..c7f2c3a30a 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -1038,7 +1038,7 @@ static int php_array_walk(HashTable *target_hash, zval **userdata, int recursive
zend_fcall_info orig_array_walk_fci;
zend_fcall_info_cache orig_array_walk_fci_cache;
- SEPARATE_ZVAL_TO_MAKE_IS_REF(args[0]);
+ SEPARATE_ZVAL_IF_NOT_REF(args[0]);
thash = HASH_OF(*(args[0]));
if (thash->nApplyCount > 1) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion detected");
diff --git a/ext/standard/tests/array/bug42850.phpt b/ext/standard/tests/array/bug42850.phpt
new file mode 100644
index 0000000000..737cd170d8
--- /dev/null
+++ b/ext/standard/tests/array/bug42850.phpt
@@ -0,0 +1,59 @@
+--TEST--
+Bug #42850 array_walk_recursive() leaves references, #34982 array_walk_recursive() modifies elements outside function scope
+--FILE--
+<?php
+
+// Bug #42850
+$data = array ('key1' => 'val1', array('key2' => 'val2'));
+function apply_dumb($item, $key) {};
+var_dump($data);
+array_walk_recursive($data, 'apply_dumb');
+$data2 = $data;
+$data2[0] = 'altered';
+var_dump($data);
+var_dump($data2);
+
+// Bug #34982
+function myfunc($data) {
+ array_walk_recursive($data, 'apply_changed');
+}
+function apply_changed(&$input, $key) {
+ $input = 'changed';
+}
+myfunc($data);
+var_dump($data);
+
+--EXPECT--
+array(2) {
+ ["key1"]=>
+ string(4) "val1"
+ [0]=>
+ array(1) {
+ ["key2"]=>
+ string(4) "val2"
+ }
+}
+array(2) {
+ ["key1"]=>
+ string(4) "val1"
+ [0]=>
+ array(1) {
+ ["key2"]=>
+ string(4) "val2"
+ }
+}
+array(2) {
+ ["key1"]=>
+ string(4) "val1"
+ [0]=>
+ string(7) "altered"
+}
+array(2) {
+ ["key1"]=>
+ string(4) "val1"
+ [0]=>
+ array(1) {
+ ["key2"]=>
+ string(4) "val2"
+ }
+}