]> granicus.if.org Git - php/commitdiff
Fixed bug #34467 (foreach + __get + __set incosistency)
authorDmitry Stogov <dmitry@php.net>
Mon, 10 Oct 2005 09:50:05 +0000 (09:50 +0000)
committerDmitry Stogov <dmitry@php.net>
Mon, 10 Oct 2005 09:50:05 +0000 (09:50 +0000)
NEWS
Zend/tests/bug34467.phpt [new file with mode: 0755]
Zend/zend_compile.c

diff --git a/NEWS b/NEWS
index 2cc68dd59fefeb289a0ea35b131dc8742ac88888..37cfe1d1b6885eccf2ad3623fe6f2d40f3e46d5b 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -70,6 +70,7 @@ PHP                                                                        NEWS
 - Fixed bug #34505 (Possible memory corruption when unmangling properties 
   with empty names). (Tony)
 - Fixed bug #34478 (Incorrect parsing of url's fragment (#...)). (Dmitry)
+- Fixed bug #34467 (foreach + __get + __set incosistency). (Dmitry)
 - Fixed bug #34456 (Possible crash inside pspell extension). (Nuno)
 - Fixed bug #34453 (parsing http://www.w3.org/2001/xml.xsd exception). (Dmitry)
 - Fixed bug #34450 (Segfault when calling mysqli_close() in destructor). (Tony)
diff --git a/Zend/tests/bug34467.phpt b/Zend/tests/bug34467.phpt
new file mode 100755 (executable)
index 0000000..5f0ccaf
--- /dev/null
@@ -0,0 +1,27 @@
+--TEST--
+Bug #34467 (foreach + __get + __set incosistency)
+--FILE--
+<?php
+class abc {
+       private $arr;
+
+       function __set ($key, $value) {
+    $this->arr[$key] = $value;
+  }
+       
+       function __get ($key) {
+         return $this->arr[$key];
+       } 
+}
+$abc = new abc();
+foreach (array (1,2,3) as $abc->k => $abc->v) {
+       var_dump($abc->k,$abc->v);
+}
+?>
+--EXPECT--
+int(0)
+int(1)
+int(1)
+int(2)
+int(2)
+int(3)
index 4ea2d7c4bc3ea1f5e5d9f7c96a12236aba8813c0..4ce4f1fe9389c466736266166a245d629f8b11d8 100644 (file)
@@ -537,40 +537,53 @@ static zend_bool opline_is_fetch_this(zend_op *opline TSRMLS_DC)
 
 void zend_do_assign(znode *result, znode *variable, znode *value TSRMLS_DC)
 {
-       int last_op_number = get_next_op_number(CG(active_op_array));
        zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
 
-       if (last_op_number > 0) {
-               zend_op *last_op = &CG(active_op_array)->opcodes[last_op_number-1];
+       if (variable->op_type == IS_VAR) {
+               int last_op_number = get_next_op_number(CG(active_op_array));
+               int n = 0;
 
-               if (variable->op_type == IS_VAR &&
-                   last_op->opcode == ZEND_FETCH_OBJ_W &&
-                   last_op->result.op_type == IS_VAR &&
-                   last_op->result.u.var == variable->u.var) {
-                       last_op->opcode = ZEND_ASSIGN_OBJ;
-
-                       zend_do_op_data(opline, value TSRMLS_CC);
-                       SET_UNUSED(opline->result);
-                       *result = last_op->result;
-                       return;
-               } else if (variable->op_type == IS_VAR &&
-                          last_op->opcode == ZEND_FETCH_DIM_W &&
-                          last_op->result.op_type == IS_VAR &&
-                          last_op->result.u.var == variable->u.var) {
-                       last_op->opcode = ZEND_ASSIGN_DIM;
-
-                       zend_do_op_data(opline, value TSRMLS_CC);
-                       opline->op2.u.var = get_temporary_variable(CG(active_op_array));
-                       opline->op2.u.EA.type = 0;
-                       opline->op2.op_type = IS_VAR;
-                       SET_UNUSED(opline->result);
-                       *result = last_op->result;
-                       return;
-               } else {
-                       if (variable->op_type == IS_VAR &&
-                           opline_is_fetch_this(last_op TSRMLS_CC)) {
-                               zend_error(E_COMPILE_ERROR, "Cannot re-assign $this");
+               while (last_op_number - n > 0) {
+                       zend_op *last_op;
+               
+                       last_op = &CG(active_op_array)->opcodes[last_op_number-n-1];
+
+                       if (last_op->result.op_type == IS_VAR &&
+                           last_op->result.u.var == variable->u.var) {
+                               if (last_op->opcode == ZEND_FETCH_OBJ_W) {
+                                       if (n > 0) {
+                                               *opline = *last_op;
+                                               MAKE_NOP(last_op);
+                                               last_op = opline;
+                                               opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+                                       }
+                                       last_op->opcode = ZEND_ASSIGN_OBJ;
+                                       zend_do_op_data(opline, value TSRMLS_CC);
+                                       SET_UNUSED(opline->result);
+                                       *result = last_op->result;
+                                       return;
+                               } else if (last_op->opcode == ZEND_FETCH_DIM_W) {
+                                       if (n > 0) {
+                                               *opline = *last_op;
+                                               MAKE_NOP(last_op);
+                                               last_op = opline;
+                                               opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+                                       }
+                                       last_op->opcode = ZEND_ASSIGN_DIM;
+                                       zend_do_op_data(opline, value TSRMLS_CC);
+                                       opline->op2.u.var = get_temporary_variable(CG(active_op_array));
+                                       opline->op2.u.EA.type = 0;
+                                       opline->op2.op_type = IS_VAR;
+                                       SET_UNUSED(opline->result);
+                                       *result = last_op->result;
+                                       return;
+                               } else if (opline_is_fetch_this(last_op TSRMLS_CC)) {
+                                       zend_error(E_COMPILE_ERROR, "Cannot re-assign $this");
+                               } else {
+                                       break;
+                               }
                        }
+                       n++;
                }
        }