]> granicus.if.org Git - php/commitdiff
Fixed bug #35163 (Array elements can lose references)
authorDmitry Stogov <dmitry@php.net>
Tue, 23 Oct 2007 09:55:25 +0000 (09:55 +0000)
committerDmitry Stogov <dmitry@php.net>
Tue, 23 Oct 2007 09:55:25 +0000 (09:55 +0000)
Zend/tests/bug35163.phpt [new file with mode: 0755]
Zend/zend_compile.c
Zend/zend_language_parser.y
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/Zend/tests/bug35163.phpt b/Zend/tests/bug35163.phpt
new file mode 100755 (executable)
index 0000000..4501fa9
--- /dev/null
@@ -0,0 +1,38 @@
+--TEST--
+Bug #35163 (Array elements can lose references)
+--FILE--
+<?php
+$a = array(array(1));
+$a[0][] =& $a[0];
+$a[0][] =& $a[0];
+$a[0][0] = 2;
+var_dump($a);
+$a[0] = null;
+$a = null;
+?>
+--EXPECT--
+array(1) {
+  [0]=>
+  &array(3) {
+    [0]=>
+    int(2)
+    [1]=>
+    &array(3) {
+      [0]=>
+      int(2)
+      [1]=>
+      *RECURSION*
+      [2]=>
+      *RECURSION*
+    }
+    [2]=>
+    &array(3) {
+      [0]=>
+      int(2)
+      [1]=>
+      *RECURSION*
+      [2]=>
+      *RECURSION*
+    }
+  }
+}
index 7ea34c5d6c74618cb5a7ce6596b625a096f686d8..25ca7f95819160ddbb37b665d266537ee5e944b2 100644 (file)
@@ -988,6 +988,9 @@ void zend_do_end_variable_parse(int type, int arg_offset TSRMLS_DC) /* {{{ */
                        if (le == NULL) break;
                        opline_ptr = (zend_op *)le->data;
                }
+               if (opline->opcode == ZEND_FETCH_DIM_W) {
+                       opline->extended_value = arg_offset;
+               }
        }
        zend_llist_destroy(fetch_list_ptr);
        zend_stack_del_top(&CG(bp_stack));
index 0150d30e96ecd24bd3c5665005340278e2b038ea..a658e98ea359e5d5c6a386cdbf275d1fd2404475 100644 (file)
@@ -572,7 +572,7 @@ non_empty_for_expr:
 expr_without_variable:
                T_LIST '(' { zend_do_list_init(TSRMLS_C); } assignment_list ')' '=' expr { zend_do_list_end(&$$, &$7 TSRMLS_CC); }
        |       variable '=' expr               { zend_check_writable_variable(&$1); zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC); zend_do_assign(&$$, &$1, &$3 TSRMLS_CC); }
-       |       variable '=' '&' variable { zend_check_writable_variable(&$1); zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC); zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC); zend_do_assign_ref(&$$, &$1, &$4 TSRMLS_CC); }
+       |       variable '=' '&' variable { zend_check_writable_variable(&$1); zend_do_end_variable_parse(BP_VAR_W, 1 TSRMLS_CC); zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC); zend_do_assign_ref(&$$, &$1, &$4 TSRMLS_CC); }
        |       variable '=' '&' T_NEW class_name_reference { zend_error(E_STRICT, "Assigning the return value of new by reference is deprecated");  zend_check_writable_variable(&$1); zend_do_extended_fcall_begin(TSRMLS_C); zend_do_begin_new_object(&$4, &$5 TSRMLS_CC); } ctor_arguments { zend_do_end_new_object(&$3, &$4, &$7 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); zend_do_end_variable_parse(BP_VAR_W, 0 TSRMLS_CC); zend_do_assign_ref(&$$, &$1, &$3 TSRMLS_CC); }
        |       T_NEW class_name_reference { zend_do_extended_fcall_begin(TSRMLS_C); zend_do_begin_new_object(&$1, &$2 TSRMLS_CC); } ctor_arguments { zend_do_end_new_object(&$$, &$1, &$4 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); $$.u.EA.type = ZEND_PARSED_NEW; }
        |       T_CLONE expr { zend_do_clone(&$$, &$2 TSRMLS_CC); }
index d4c359f2b2cf85dca544c82c817228d678c0f367..3a94dbed791357065b92ed903aa0bf3809bc6588 100644 (file)
@@ -1102,6 +1102,14 @@ ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMP|VAR|UNUSED|CV)
                AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
        FREE_OP1_VAR_PTR();
+       
+       /* We are going to assign the result by reference */
+       if (opline->extended_value) {           
+               Z_DELREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+               SEPARATE_ZVAL_TO_MAKE_IS_REF(EX_T(opline->result.u.var).var.ptr_ptr);
+               Z_ADDREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+       }
+
        ZEND_VM_NEXT_OPCODE();
 }
 
index 83c14d28d5507f6005a4e9b05197261e4ab37a24..807253dc184f82b84eba86377b03e7bb34302096 100644 (file)
@@ -9652,6 +9652,14 @@ static int ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+
+       /* We are going to assign the result by reference */
+       if (opline->extended_value) {
+               Z_DELREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+               SEPARATE_ZVAL_TO_MAKE_IS_REF(EX_T(opline->result.u.var).var.ptr_ptr);
+               Z_ADDREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+       }
+
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -11380,6 +11388,14 @@ static int ZEND_FETCH_DIM_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+
+       /* We are going to assign the result by reference */
+       if (opline->extended_value) {
+               Z_DELREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+               SEPARATE_ZVAL_TO_MAKE_IS_REF(EX_T(opline->result.u.var).var.ptr_ptr);
+               Z_ADDREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+       }
+
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -13017,6 +13033,14 @@ static int ZEND_FETCH_DIM_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+
+       /* We are going to assign the result by reference */
+       if (opline->extended_value) {
+               Z_DELREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+               SEPARATE_ZVAL_TO_MAKE_IS_REF(EX_T(opline->result.u.var).var.ptr_ptr);
+               Z_ADDREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+       }
+
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -14254,6 +14278,14 @@ static int ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+
+       /* We are going to assign the result by reference */
+       if (opline->extended_value) {
+               Z_DELREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+               SEPARATE_ZVAL_TO_MAKE_IS_REF(EX_T(opline->result.u.var).var.ptr_ptr);
+               Z_ADDREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+       }
+
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -15217,6 +15249,14 @@ static int ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
        if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
+
+       /* We are going to assign the result by reference */
+       if (opline->extended_value) {
+               Z_DELREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+               SEPARATE_ZVAL_TO_MAKE_IS_REF(EX_T(opline->result.u.var).var.ptr_ptr);
+               Z_ADDREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+       }
+
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -22709,6 +22749,13 @@ static int ZEND_FETCH_DIM_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
 
+       /* We are going to assign the result by reference */
+       if (opline->extended_value) {
+               Z_DELREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+               SEPARATE_ZVAL_TO_MAKE_IS_REF(EX_T(opline->result.u.var).var.ptr_ptr);
+               Z_ADDREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+       }
+
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -24272,6 +24319,13 @@ static int ZEND_FETCH_DIM_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
 
+       /* We are going to assign the result by reference */
+       if (opline->extended_value) {
+               Z_DELREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+               SEPARATE_ZVAL_TO_MAKE_IS_REF(EX_T(opline->result.u.var).var.ptr_ptr);
+               Z_ADDREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+       }
+
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -25811,6 +25865,13 @@ static int ZEND_FETCH_DIM_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
 
+       /* We are going to assign the result by reference */
+       if (opline->extended_value) {
+               Z_DELREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+               SEPARATE_ZVAL_TO_MAKE_IS_REF(EX_T(opline->result.u.var).var.ptr_ptr);
+               Z_ADDREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+       }
+
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -26949,6 +27010,13 @@ static int ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
 
+       /* We are going to assign the result by reference */
+       if (opline->extended_value) {
+               Z_DELREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+               SEPARATE_ZVAL_TO_MAKE_IS_REF(EX_T(opline->result.u.var).var.ptr_ptr);
+               Z_ADDREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+       }
+
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -27821,6 +27889,13 @@ static int ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                AI_USE_PTR(EX_T(opline->result.u.var).var);
        }
 
+       /* We are going to assign the result by reference */
+       if (opline->extended_value) {
+               Z_DELREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+               SEPARATE_ZVAL_TO_MAKE_IS_REF(EX_T(opline->result.u.var).var.ptr_ptr);
+               Z_ADDREF_PP(EX_T(opline->result.u.var).var.ptr_ptr);
+       }
+
        ZEND_VM_NEXT_OPCODE();
 }