From: Dmitry Stogov Date: Tue, 23 Oct 2007 12:52:51 +0000 (+0000) Subject: Fixed variations of bug #35163 X-Git-Tag: RELEASE_2_0_0a1~1553 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a53eb396b3becce36e5662192df8233eac95da0d;p=php Fixed variations of bug #35163 --- diff --git a/Zend/tests/bug35163_2.phpt b/Zend/tests/bug35163_2.phpt new file mode 100755 index 0000000000..4adf7709ae --- /dev/null +++ b/Zend/tests/bug35163_2.phpt @@ -0,0 +1,65 @@ +--TEST-- +Bug #35163.2 (Array elements can lose references) +--FILE-- + +--EXPECT-- +array(3) { + [0]=> + int(2) + [1]=> + &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* + } + } + [2]=> + &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/tests/bug35163_3.phpt b/Zend/tests/bug35163_3.phpt new file mode 100755 index 0000000000..d34b94e9df --- /dev/null +++ b/Zend/tests/bug35163_3.phpt @@ -0,0 +1,65 @@ +--TEST-- +Bug #35163.3 (Array elements can lose references) +--FILE-- +b = array(1); +$a->b[] =& $a->b; +$a->b[] =& $a->b; +$a->b[0] = 2; +var_dump($a); +$a->b = null; +$a = null; +?> +--EXPECT-- +object(stdClass)#1 (1) { + ["b"]=> + &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* + } + } +} +--UEXPECT-- +object(stdClass)#1 (1) { + [u"b"]=> + &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 25ca7f9581..963f7c2d1e 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -988,8 +988,8 @@ 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; + if (type == BP_VAR_W && arg_offset) { + opline->extended_value = ZEND_FETCH_MAKE_REF; } } zend_llist_destroy(fetch_list_ptr); diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 8b86cd3e50..ec26c360a0 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -692,7 +692,8 @@ int zendlex(znode *zendlval TSRMLS_DC); #define ZEND_HANDLE_STREAM 5 #define ZEND_FETCH_STANDARD 0 -#define ZEND_FETCH_ADD_LOCK 1 +#define ZEND_FETCH_ADD_LOCK (1<<0) +#define ZEND_FETCH_MAKE_REF (1<<1) #define ZEND_FE_FETCH_BYREF 1 #define ZEND_FE_FETCH_WITH_KEY 2 diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 3a94dbed79..5956bf90ef 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1014,6 +1014,9 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMP|VAR|CV, ANY, int type zval_dtor(varname); } if (!RETURN_VALUE_UNUSED(&opline->result)) { + if (opline->extended_value & ZEND_FETCH_MAKE_REF) { + SEPARATE_ZVAL_TO_MAKE_IS_REF(retval); + } EX_T(opline->result.u.var).var.ptr_ptr = retval; PZVAL_LOCK(*retval); switch (type) { @@ -1104,7 +1107,7 @@ ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMP|VAR|UNUSED|CV) FREE_OP1_VAR_PTR(); /* We are going to assign the result by reference */ - if (opline->extended_value) { + 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); @@ -1275,7 +1278,7 @@ ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|CV, CONST|TMP|VAR|CV) zend_free_op free_op1, free_op2; zval *property = GET_OP2_ZVAL_PTR(BP_VAR_R); - if (opline->extended_value == ZEND_FETCH_ADD_LOCK && OP1_TYPE != IS_CV) { + if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && OP1_TYPE != IS_CV) { PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr); EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr; } @@ -1295,6 +1298,14 @@ ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|CV, CONST|TMP|VAR|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 & ZEND_FETCH_MAKE_REF) { + 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 807253dc18..5d1d7af5b7 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1353,6 +1353,9 @@ static int zend_fetch_var_address_helper_SPEC_CONST(int type, ZEND_OPCODE_HANDLE zval_dtor(varname); } if (!RETURN_VALUE_UNUSED(&opline->result)) { + if (opline->extended_value & ZEND_FETCH_MAKE_REF) { + SEPARATE_ZVAL_TO_MAKE_IS_REF(retval); + } EX_T(opline->result.u.var).var.ptr_ptr = retval; PZVAL_LOCK(*retval); switch (type) { @@ -4557,6 +4560,9 @@ static int zend_fetch_var_address_helper_SPEC_TMP(int type, ZEND_OPCODE_HANDLER_ zval_dtor(varname); } if (!RETURN_VALUE_UNUSED(&opline->result)) { + if (opline->extended_value & ZEND_FETCH_MAKE_REF) { + SEPARATE_ZVAL_TO_MAKE_IS_REF(retval); + } EX_T(opline->result.u.var).var.ptr_ptr = retval; PZVAL_LOCK(*retval); switch (type) { @@ -7751,6 +7757,9 @@ static int zend_fetch_var_address_helper_SPEC_VAR(int type, ZEND_OPCODE_HANDLER_ zval_dtor(varname); } if (!RETURN_VALUE_UNUSED(&opline->result)) { + if (opline->extended_value & ZEND_FETCH_MAKE_REF) { + SEPARATE_ZVAL_TO_MAKE_IS_REF(retval); + } EX_T(opline->result.u.var).var.ptr_ptr = retval; PZVAL_LOCK(*retval); switch (type) { @@ -9825,7 +9834,7 @@ static int ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_free_op free_op1; zval *property = &opline->op2.u.constant; - if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_VAR != IS_CV) { + if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_VAR != IS_CV) { PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr); EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr; } @@ -9845,6 +9854,14 @@ static int ZEND_FETCH_OBJ_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 & ZEND_FETCH_MAKE_REF) { + 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(); } @@ -11561,7 +11578,7 @@ static int ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_free_op free_op1, free_op2; zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); - if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_VAR != IS_CV) { + if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_VAR != IS_CV) { PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr); EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr; } @@ -11581,6 +11598,14 @@ static int ZEND_FETCH_OBJ_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 & ZEND_FETCH_MAKE_REF) { + 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(); } @@ -13206,7 +13231,7 @@ static int ZEND_FETCH_OBJ_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_free_op free_op1, free_op2; zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); - if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_VAR != IS_CV) { + if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_VAR != IS_CV) { PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr); EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr; } @@ -13226,6 +13251,14 @@ static int ZEND_FETCH_OBJ_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 & ZEND_FETCH_MAKE_REF) { + 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(); } @@ -15422,7 +15455,7 @@ static int ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_free_op free_op1; zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC); - if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_VAR != IS_CV) { + if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_VAR != IS_CV) { PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr); EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr; } @@ -15442,6 +15475,14 @@ static int ZEND_FETCH_OBJ_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 & ZEND_FETCH_MAKE_REF) { + 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(); } @@ -16808,7 +16849,7 @@ static int ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_free_op free_op1; zval *property = &opline->op2.u.constant; - if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_UNUSED != IS_CV) { + if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_UNUSED != IS_CV) { PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr); EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr; } @@ -16828,6 +16869,13 @@ static int ZEND_FETCH_OBJ_W_SPEC_UNUSED_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 & ZEND_FETCH_MAKE_REF) { + 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(); } @@ -17893,7 +17941,7 @@ static int ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_free_op free_op1, free_op2; zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); - if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_UNUSED != IS_CV) { + if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_UNUSED != IS_CV) { PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr); EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr; } @@ -17913,6 +17961,13 @@ static int ZEND_FETCH_OBJ_W_SPEC_UNUSED_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 & ZEND_FETCH_MAKE_REF) { + 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(); } @@ -18912,7 +18967,7 @@ static int ZEND_FETCH_OBJ_W_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_free_op free_op1, free_op2; zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); - if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_UNUSED != IS_CV) { + if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_UNUSED != IS_CV) { PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr); EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr; } @@ -18932,6 +18987,13 @@ static int ZEND_FETCH_OBJ_W_SPEC_UNUSED_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 & ZEND_FETCH_MAKE_REF) { + 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(); } @@ -20196,7 +20258,7 @@ static int ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_free_op free_op1; zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC); - if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_UNUSED != IS_CV) { + if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_UNUSED != IS_CV) { PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr); EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr; } @@ -20216,6 +20278,13 @@ static int ZEND_FETCH_OBJ_W_SPEC_UNUSED_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 & ZEND_FETCH_MAKE_REF) { + 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(); } @@ -21021,6 +21090,9 @@ static int zend_fetch_var_address_helper_SPEC_CV(int type, ZEND_OPCODE_HANDLER_A zval_dtor(varname); } if (!RETURN_VALUE_UNUSED(&opline->result)) { + if (opline->extended_value & ZEND_FETCH_MAKE_REF) { + SEPARATE_ZVAL_TO_MAKE_IS_REF(retval); + } EX_T(opline->result.u.var).var.ptr_ptr = retval; PZVAL_LOCK(*retval); switch (type) { @@ -22920,7 +22992,7 @@ static int ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_free_op free_op1; zval *property = &opline->op2.u.constant; - if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_CV != IS_CV) { + if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_CV != IS_CV) { PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr); EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr; } @@ -22940,6 +23012,13 @@ static int ZEND_FETCH_OBJ_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 & ZEND_FETCH_MAKE_REF) { + 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(); } @@ -24490,7 +24569,7 @@ static int ZEND_FETCH_OBJ_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_free_op free_op1, free_op2; zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); - if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_CV != IS_CV) { + if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_CV != IS_CV) { PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr); EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr; } @@ -24510,6 +24589,13 @@ static int ZEND_FETCH_OBJ_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 & ZEND_FETCH_MAKE_REF) { + 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(); } @@ -26036,7 +26122,7 @@ static int ZEND_FETCH_OBJ_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_free_op free_op1, free_op2; zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); - if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_CV != IS_CV) { + if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_CV != IS_CV) { PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr); EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr; } @@ -26056,6 +26142,13 @@ static int ZEND_FETCH_OBJ_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 & ZEND_FETCH_MAKE_REF) { + 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(); } @@ -28060,7 +28153,7 @@ static int ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_free_op free_op1; zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC); - if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_CV != IS_CV) { + if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_CV != IS_CV) { PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr); EX_T(opline->op1.u.var).var.ptr = *EX_T(opline->op1.u.var).var.ptr_ptr; } @@ -28080,6 +28173,13 @@ static int ZEND_FETCH_OBJ_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 & ZEND_FETCH_MAKE_REF) { + 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(); }