]> granicus.if.org Git - php/commitdiff
Fixed bug #71969 (str_replace returns an incorrect resulting array after a foreach...
authorXinchen Hui <laruence@gmail.com>
Wed, 6 Apr 2016 02:19:24 +0000 (10:19 +0800)
committerXinchen Hui <laruence@gmail.com>
Wed, 6 Apr 2016 02:19:24 +0000 (10:19 +0800)
NEWS
ext/standard/string.c
ext/standard/tests/strings/bug71969.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index aa6feda1ca1c5ebb83416b4834266c5751c7ff59..e468c8b4ec263b727e25ce665c41f37599f0d63f 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -69,6 +69,8 @@ PHP                                                                        NEWS
   . Fixed bug #71735 (Double-free in SplDoublyLinkedList::offsetSet). (Stas)
 
 - Standard:
+  . Fixed bug #71969 (str_replace returns an incorrect resulting array after
+    a foreach by reference). (Laruence)
   . Fixed bug #71827 (substr_replace bug, string length). (krakjoe)
   . Fixed bug #71891 (header_register_callback() and
     register_shutdown_function()). (Laruence)
index 24c3862bf55550925796cf96d30825e70bad1159..3f47e73c1d68cca0dce7d77bc215c8a727985677 100644 (file)
@@ -4151,6 +4151,7 @@ static void php_str_replace_common(INTERNAL_FUNCTION_PARAMETERS, int case_sensit
                /* For each subject entry, convert it to string, then perform replacement
                   and add the result to the return_value array. */
                ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(subject), num_key, string_key, subject_entry) {
+                       ZVAL_DEREF(subject_entry);
                        if (Z_TYPE_P(subject_entry) != IS_ARRAY && Z_TYPE_P(subject_entry) != IS_OBJECT) {
                                count += php_str_replace_in_subject(search, replace, subject_entry, &result, case_sensitivity);
                        } else {
diff --git a/ext/standard/tests/strings/bug71969.phpt b/ext/standard/tests/strings/bug71969.phpt
new file mode 100644 (file)
index 0000000..aafceb0
--- /dev/null
@@ -0,0 +1,28 @@
+--TEST--
+Bug #71969 (str_replace returns an incorrect resulting array after a foreach by reference)
+--FILE--
+<?php
+$a = array(
+       array("one" => array("a"=>"0000", "b"=>"1111")),
+);
+
+//foreach by reference, changing the array value
+foreach($a as &$record)
+{
+       $record["one"]["a"] = "2222";
+}
+var_dump(str_replace("2", "3", $a));
+?>
+--EXPECT--
+array(1) {
+  [0]=>
+  array(1) {
+    ["one"]=>
+    array(2) {
+      ["a"]=>
+      string(4) "2222"
+      ["b"]=>
+      string(4) "1111"
+    }
+  }
+}