com php-src: Fixed bug #67633: NEWS Zend/tests/bug67633.phpt Zend/zend_compile.c
| From: | Nikita Popov | Date: | Sat, 20 Sep 2014 19:46:25 +0000 |
| Subject: | com php-src: Fixed bug #67633: NEWS Zend/tests/bug67633.phpt Zend/zend_compile.c | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-81815@lists.php.net to get a copy of this message | ||
Commit: 5e977e69e144ca92868ae73cd3563eb473b75937
Author: Nikita Popov <nikic@php.net> Sat, 20 Sep 2014 21:46:25 +0200
Parents: 5d9403f56c14fefafa558b7de45f132a4d3f5fde
Branches: master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=5e977e69e144ca92868ae73cd3563eb473b75937
Log:
Fixed bug #67633
Bugs:
https://bugs..php.net/67633
Changed paths:
M NEWS
A Zend/tests/bug67633.phpt
M Zend/zend_compile.c
Diff:
diff --git a/NEWS b/NEWS
index 3fc0f80..50d2707 100644
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,8 @@ PHP NEWS
unset). (Tjerk)
. Fixed bug #67739 (Windows 8.1/Server 2012 R2 OS build number reported
as 6.2 (instead of 6.3)). (Christian Wenz)
+ . Fixed bug #67633 (A foreach on an array returned from a function not doing
+ copy-on-write). (Nikita)
- FPM:
. Fixed bug #65641 (PHP-FPM incorrectly defines the SCRIPT_NAME variable
diff --git a/Zend/tests/bug67633.phpt b/Zend/tests/bug67633.phpt
new file mode 100644
index 0000000..a9e05d1
--- /dev/null
+++ b/Zend/tests/bug67633.phpt
@@ -0,0 +1,44 @@
+--TEST--
+Bug #67633: A foreach on an array returned from a function not doing copy-on-write
+--FILE--
+<?php
+
+function id($x) {
+ return $x;
+}
+
+function &ref_id(&$x) {
+ return $x;
+}
+
+$c = 'c';
+$array = ['a', 'b', $c];
+
+foreach(id($array) as &$v) {
+ $v .= 'q';
+}
+var_dump($array);
+
+foreach(ref_id($array) as &$v) {
+ $v .= 'q';
+}
+var_dump($array);
+
+?>
+--EXPECT--
+array(3) {
+ [0]=>
+ string(1) "a"
+ [1]=>
+ string(1) "b"
+ [2]=>
+ string(1) "c"
+}
+array(3) {
+ [0]=>
+ string(2) "aq"
+ [1]=>
+ string(2) "bq"
+ [2]=>
+ &string(2) "cq"
+}
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 0ac3bce..bd3e1dd 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -6231,6 +6231,15 @@ void zend_do_foreach_begin(znode *foreach_token, znode *open_brackets_token,
zno
/* save the location of FETCH_W instruction(s) */
open_brackets_token->u.op.opline_num = get_next_op_number(CG(active_op_array));
zend_do_end_variable_parse(array, BP_VAR_W, 0 TSRMLS_CC);
+
+ if (zend_is_function_or_method_call(array)) {
+ opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+ opline->opcode = ZEND_SEPARATE;
+ SET_NODE(opline->op1, array);
+ SET_UNUSED(opline->op2);
+ opline->result_type = IS_VAR;
+ opline->result.var = opline->op1.var;
+ }
} else {
is_variable = 0;
open_brackets_token->u.op.opline_num = get_next_op_number(CG(active_op_array));