From d892fd3da4cfb8d7bda97b6ecef566948f1c355e Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 23 Oct 2007 09:55:25 +0000 Subject: [PATCH] Fixed bug #35163 (Array elements can lose references) --- Zend/tests/bug35163.phpt | 38 +++++++++++++++++++ Zend/zend_compile.c | 3 ++ Zend/zend_language_parser.y | 2 +- Zend/zend_vm_def.h | 8 ++++ Zend/zend_vm_execute.h | 75 +++++++++++++++++++++++++++++++++++++ 5 files changed, 125 insertions(+), 1 deletion(-) create mode 100755 Zend/tests/bug35163.phpt diff --git a/Zend/tests/bug35163.phpt b/Zend/tests/bug35163.phpt new file mode 100755 index 0000000000..4501fa9372 --- /dev/null +++ b/Zend/tests/bug35163.phpt @@ -0,0 +1,38 @@ +--TEST-- +Bug #35163 (Array elements can lose references) +--FILE-- + +--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* + } + } +} diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 7ea34c5d6c..25ca7f9581 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -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)); diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 0150d30e96..a658e98ea3 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -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); } diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index d4c359f2b2..3a94dbed79 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -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(); } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 83c14d28d5..807253dc18 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -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(); } -- 2.50.1