]> granicus.if.org Git - php/commitdiff
Fixed bug #40705 (Iterating within function moves original array pointer)
authorDmitry Stogov <dmitry@php.net>
Tue, 24 Jul 2007 19:24:40 +0000 (19:24 +0000)
committerDmitry Stogov <dmitry@php.net>
Tue, 24 Jul 2007 19:24:40 +0000 (19:24 +0000)
Fixed bug #40509 (key() function changed behaviour if global array is used within function)

NEWS
Zend/tests/bug40509.phpt [new file with mode: 0755]
Zend/tests/bug40705.phpt [new file with mode: 0755]
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/NEWS b/NEWS
index 31122b4e78d88f492e057752da95a6dccc37fb95..5b921263f1ee3c88a68f829aaf92fdf5892febe1 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -169,6 +169,10 @@ PHP                                                                        NEWS
 - Fixed bug #41127 (Memory leak in ldap_{first|next}_attribute functions).
   (Jani)
 - Fixed bug #40757 (get_object_vars get nothing in child class). (Dmitry)
+- Fixed bug #40705 (Iterating within function moves original array pointer).
+  (Dmitry)
+- Fixed bug #40509 (key() function changed behaviour if global array is used
+  within function). (Dmitry)
 - Fixed bug #40419 (Trailing slash in CGI request does not work). (Dmitry)
 - Fixed bug #39330 (apache2handler does not call shutdown actions before 
   apache child die). (isk at ecommerce dot com, Gopal, Tony)
diff --git a/Zend/tests/bug40509.phpt b/Zend/tests/bug40509.phpt
new file mode 100755 (executable)
index 0000000..453060d
--- /dev/null
@@ -0,0 +1,26 @@
+--TEST--
+Bug #40509 key() function changed behaviour if global array is used within function 
+--FILE--
+<?php
+function foo()
+{
+       global $arr;
+       
+       $c = $arr["v"];
+       foreach ($c as $v) {}
+}
+
+$arr["v"] = array("a");
+
+var_dump(key($arr["v"]));
+foo();
+var_dump(key($arr["v"]));
+foreach ($arr["v"] as $k => $v) {
+       var_dump($k);
+}
+var_dump(key($arr["v"]));
+--EXPECT--
+int(0)
+int(0)
+int(0)
+NULL
diff --git a/Zend/tests/bug40705.phpt b/Zend/tests/bug40705.phpt
new file mode 100755 (executable)
index 0000000..198f985
--- /dev/null
@@ -0,0 +1,26 @@
+--TEST--
+Bug #40705 Iterating within function moves original array pointer 
+--FILE--
+<?php
+function doForeach($array)
+{
+    foreach ($array as $k => $v) {
+        // do stuff
+    }
+}
+
+$foo = array('foo', 'bar', 'baz');
+var_dump(key($foo));
+doForeach($foo);
+var_dump(key($foo));
+foreach ($foo as $k => $v) {
+       var_dump($k);
+}
+var_dump(key($foo));
+--EXPECT--
+int(0)
+int(0)
+int(0)
+int(1)
+int(2)
+NULL
index 42c4d2dfe3d3ca1b0a3c90473614e6c21de6b5a8..e5fb3fb386b3496f0861443ea2d2e427125b7e68 100644 (file)
@@ -3127,11 +3127,9 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY)
                                array_ptr->refcount++;
                        }
                } else {
-                       if (OP1_TYPE == IS_VAR &&
-                               free_op1.var == NULL &&
+                       if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) &&
                            !array_ptr->is_ref &&
                            array_ptr->refcount > 1) {
-                               /* non-separated return value from function */
                                zval *tmp;
 
                                ALLOC_ZVAL(tmp);
index 9edc65b164a974632bf57dc575c2fa7c96755ab8..51e18469eaef5568db4da5a5ecf27d228530660b 100644 (file)
@@ -2122,7 +2122,7 @@ static int ZEND_UNSET_VAR_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 static int ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
-       zend_free_op free_op1;
+
        zval *array_ptr, **array_ptr_ptr;
        HashTable *fe_ht;
        zend_object_iterator *iter = NULL;
@@ -2169,11 +2169,9 @@ static int ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                                array_ptr->refcount++;
                        }
                } else {
-                       if (IS_CONST == IS_VAR &&
-                               free_op1.var == NULL &&
+                       if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) &&
                            !array_ptr->is_ref &&
                            array_ptr->refcount > 1) {
-                               /* non-separated return value from function */
                                zval *tmp;
 
                                ALLOC_ZVAL(tmp);
@@ -4737,11 +4735,9 @@ static int ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                                array_ptr->refcount++;
                        }
                } else {
-                       if (IS_TMP_VAR == IS_VAR &&
-                               free_op1.var == NULL &&
+                       if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) &&
                            !array_ptr->is_ref &&
                            array_ptr->refcount > 1) {
-                               /* non-separated return value from function */
                                zval *tmp;
 
                                ALLOC_ZVAL(tmp);
@@ -7877,11 +7873,9 @@ static int ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                                array_ptr->refcount++;
                        }
                } else {
-                       if (IS_VAR == IS_VAR &&
-                               free_op1.var == NULL &&
+                       if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) &&
                            !array_ptr->is_ref &&
                            array_ptr->refcount > 1) {
-                               /* non-separated return value from function */
                                zval *tmp;
 
                                ALLOC_ZVAL(tmp);
@@ -19895,7 +19889,7 @@ static int ZEND_UNSET_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 static int ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
-       zend_free_op free_op1;
+
        zval *array_ptr, **array_ptr_ptr;
        HashTable *fe_ht;
        zend_object_iterator *iter = NULL;
@@ -19942,11 +19936,9 @@ static int ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                                array_ptr->refcount++;
                        }
                } else {
-                       if (IS_CV == IS_VAR &&
-                               free_op1.var == NULL &&
+                       if ((IS_CV == IS_CV || IS_CV == IS_VAR) &&
                            !array_ptr->is_ref &&
                            array_ptr->refcount > 1) {
-                               /* non-separated return value from function */
                                zval *tmp;
 
                                ALLOC_ZVAL(tmp);