diff options
Diffstat (limited to 'Zend/zend_vm_execute.h')
| -rw-r--r-- | Zend/zend_vm_execute.h | 1772 |
1 files changed, 1281 insertions, 491 deletions
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index ff65eede84..865b2f34ac 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -652,13 +652,13 @@ static int ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) char *function_name_strval, *lcname; int function_name_strlen; - int ret; zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope)); if (IS_CONST == IS_CONST) { - function_name_strval = Z_STRVAL(opline->op2.u.constant); - ret = zend_hash_quick_find(EG(function_table), Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant)+1, opline->extended_value, (void **) &EX(fbc)); + if (zend_hash_quick_find(EG(function_table), Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant)+1, opline->extended_value, (void **) &EX(fbc)) == FAILURE) { + zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL(opline->op2.u.constant)); + } } else { function_name = &opline->op2.u.constant; @@ -675,15 +675,10 @@ static int ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } else { lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen); } - ret = zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &EX(fbc)); + if (zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &EX(fbc)) == FAILURE) { + zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); + } efree(lcname); - } - - if (ret == FAILURE) { - zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); - } - - if (IS_CONST != IS_CONST) { } @@ -817,13 +812,13 @@ static int ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) char *function_name_strval, *lcname; int function_name_strlen; zend_free_op free_op2; - int ret; zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope)); if (IS_TMP_VAR == IS_CONST) { - function_name_strval = Z_STRVAL(opline->op2.u.constant); - ret = zend_hash_quick_find(EG(function_table), Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant)+1, opline->extended_value, (void **) &EX(fbc)); + if (zend_hash_quick_find(EG(function_table), Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant)+1, opline->extended_value, (void **) &EX(fbc)) == FAILURE) { + zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL(opline->op2.u.constant)); + } } else { function_name = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); @@ -840,15 +835,10 @@ static int ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } else { lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen); } - ret = zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &EX(fbc)); + if (zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &EX(fbc)) == FAILURE) { + zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); + } efree(lcname); - } - - if (ret == FAILURE) { - zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); - } - - if (IS_TMP_VAR != IS_CONST) { zval_dtor(free_op2.var); } @@ -918,13 +908,13 @@ static int ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) char *function_name_strval, *lcname; int function_name_strlen; zend_free_op free_op2; - int ret; zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope)); if (IS_VAR == IS_CONST) { - function_name_strval = Z_STRVAL(opline->op2.u.constant); - ret = zend_hash_quick_find(EG(function_table), Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant)+1, opline->extended_value, (void **) &EX(fbc)); + if (zend_hash_quick_find(EG(function_table), Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant)+1, opline->extended_value, (void **) &EX(fbc)) == FAILURE) { + zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL(opline->op2.u.constant)); + } } else { function_name = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); @@ -941,15 +931,10 @@ static int ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } else { lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen); } - ret = zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &EX(fbc)); + if (zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &EX(fbc)) == FAILURE) { + zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); + } efree(lcname); - } - - if (ret == FAILURE) { - zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); - } - - if (IS_VAR != IS_CONST) { if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; } @@ -1047,13 +1032,13 @@ static int ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) char *function_name_strval, *lcname; int function_name_strlen; - int ret; zend_ptr_stack_3_push(&EG(arg_types_stack), EX(fbc), EX(object), EX(called_scope)); if (IS_CV == IS_CONST) { - function_name_strval = Z_STRVAL(opline->op2.u.constant); - ret = zend_hash_quick_find(EG(function_table), Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant)+1, opline->extended_value, (void **) &EX(fbc)); + if (zend_hash_quick_find(EG(function_table), Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant)+1, opline->extended_value, (void **) &EX(fbc)) == FAILURE) { + zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL(opline->op2.u.constant)); + } } else { function_name = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC); @@ -1070,15 +1055,10 @@ static int ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } else { lcname = zend_str_tolower_dup(function_name_strval, function_name_strlen); } - ret = zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &EX(fbc)); + if (zend_hash_find(EG(function_table), lcname, function_name_strlen+1, (void **) &EX(fbc)) == FAILURE) { + zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); + } efree(lcname); - } - - if (ret == FAILURE) { - zend_error_noreturn(E_ERROR, "Call to undefined function %s()", function_name_strval); - } - - if (IS_CV != IS_CONST) { } @@ -1170,7 +1150,7 @@ static int zend_fetch_var_address_helper_SPEC_CONST(int type, ZEND_OPCODE_HANDLE zval tmp_varname; HashTable *target_symbol_table; - if (Z_TYPE_P(varname) != IS_STRING) { + if (IS_CONST != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { tmp_varname = *varname; zval_copy_ctor(&tmp_varname); convert_to_string(&tmp_varname); @@ -1229,7 +1209,7 @@ static int zend_fetch_var_address_helper_SPEC_CONST(int type, ZEND_OPCODE_HANDLE } - if (varname == &tmp_varname) { + if (IS_CONST != IS_CONST && varname == &tmp_varname) { zval_dtor(varname); } if (!RETURN_VALUE_UNUSED(&opline->result)) { @@ -1330,16 +1310,20 @@ static int ZEND_JMPZNZ_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) int retval = i_zend_is_true(&opline->op1.u.constant); - if (retval) { + if (UNEXPECTED(EG(exception) != NULL)) { + ZEND_VM_CONTINUE(); + } else if (EXPECTED(retval != 0)) { #if DEBUG_ZEND>=2 printf("Conditional jmp on true to %d\n", opline->extended_value); #endif - ZEND_VM_JMP(&EX(op_array)->opcodes[opline->extended_value]); + ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->extended_value]); + ZEND_VM_CONTINUE(); /* CHECK_ME */ } else { #if DEBUG_ZEND>=2 printf("Conditional jmp on false to %d\n", opline->op2.u.opline_num); #endif - ZEND_VM_JMP(&EX(op_array)->opcodes[opline->op2.u.opline_num]); + ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.u.opline_num]); + ZEND_VM_CONTINUE(); /* CHECK_ME */ } } @@ -1410,7 +1394,7 @@ static int ZEND_RETURN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) retval_ptr_ptr = NULL; - if (!retval_ptr_ptr) { + if (IS_CONST == IS_VAR && !retval_ptr_ptr) { zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference"); } @@ -2234,9 +2218,10 @@ static int ZEND_IS_NOT_IDENTICAL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR zend_op *opline = EX(opline); - is_not_identical_function(&EX_T(opline->result.u.var).tmp_var, + is_identical_function(&EX_T(opline->result.u.var).tmp_var, &opline->op1.u.constant, &opline->op2.u.constant TSRMLS_CC); + Z_LVAL(EX_T(opline->result.u.var).tmp_var) = !Z_LVAL(EX_T(opline->result.u.var).tmp_var); ZEND_VM_NEXT_OPCODE(); @@ -2247,9 +2232,11 @@ static int ZEND_IS_EQUAL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); - is_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, &opline->op1.u.constant, &opline->op2.u.constant TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) == 0)); ZEND_VM_NEXT_OPCODE(); @@ -2260,9 +2247,11 @@ static int ZEND_IS_NOT_EQUAL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); - is_not_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, &opline->op1.u.constant, &opline->op2.u.constant TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) != 0)); ZEND_VM_NEXT_OPCODE(); @@ -2273,9 +2262,11 @@ static int ZEND_IS_SMALLER_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); - is_smaller_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, &opline->op1.u.constant, &opline->op2.u.constant TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) < 0)); ZEND_VM_NEXT_OPCODE(); @@ -2286,9 +2277,11 @@ static int ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER zend_op *opline = EX(opline); - is_smaller_or_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, &opline->op1.u.constant, &opline->op2.u.constant TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) <= 0)); ZEND_VM_NEXT_OPCODE(); @@ -2398,10 +2391,9 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HAN if(IS_CONST != IS_UNUSED) { char *function_name_strval; int function_name_strlen; - zend_bool is_const = (IS_CONST == IS_CONST); - if (is_const) { + if (IS_CONST == IS_CONST) { function_name_strval = Z_STRVAL(opline->op2.u.constant); function_name_strlen = Z_STRLEN(opline->op2.u.constant); } else { @@ -2420,7 +2412,7 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HAN EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC); } - if (!is_const) { + if (IS_CONST != IS_CONST) { efree(function_name_strval); } @@ -2809,9 +2801,10 @@ static int ZEND_IS_NOT_IDENTICAL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS zend_op *opline = EX(opline); zend_free_op free_op2; - is_not_identical_function(&EX_T(opline->result.u.var).tmp_var, + is_identical_function(&EX_T(opline->result.u.var).tmp_var, &opline->op1.u.constant, _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + Z_LVAL(EX_T(opline->result.u.var).tmp_var) = !Z_LVAL(EX_T(opline->result.u.var).tmp_var); zval_dtor(free_op2.var); ZEND_VM_NEXT_OPCODE(); @@ -2822,9 +2815,11 @@ static int ZEND_IS_EQUAL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op2; - is_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, &opline->op1.u.constant, _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) == 0)); zval_dtor(free_op2.var); ZEND_VM_NEXT_OPCODE(); @@ -2835,9 +2830,11 @@ static int ZEND_IS_NOT_EQUAL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op2; - is_not_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, &opline->op1.u.constant, _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) != 0)); zval_dtor(free_op2.var); ZEND_VM_NEXT_OPCODE(); @@ -2848,9 +2845,11 @@ static int ZEND_IS_SMALLER_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op2; - is_smaller_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, &opline->op1.u.constant, _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) < 0)); zval_dtor(free_op2.var); ZEND_VM_NEXT_OPCODE(); @@ -2861,9 +2860,11 @@ static int ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_A zend_op *opline = EX(opline); zend_free_op free_op2; - is_smaller_or_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, &opline->op1.u.constant, _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) <= 0)); zval_dtor(free_op2.var); ZEND_VM_NEXT_OPCODE(); @@ -2951,10 +2952,9 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDL if(IS_TMP_VAR != IS_UNUSED) { char *function_name_strval; int function_name_strlen; - zend_bool is_const = (IS_TMP_VAR == IS_CONST); zend_free_op free_op2; - if (is_const) { + if (IS_TMP_VAR == IS_CONST) { function_name_strval = Z_STRVAL(opline->op2.u.constant); function_name_strlen = Z_STRLEN(opline->op2.u.constant); } else { @@ -2973,7 +2973,7 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDL EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC); } - if (!is_const) { + if (IS_TMP_VAR != IS_CONST) { efree(function_name_strval); zval_dtor(free_op2.var); } @@ -3257,9 +3257,10 @@ static int ZEND_IS_NOT_IDENTICAL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS zend_op *opline = EX(opline); zend_free_op free_op2; - is_not_identical_function(&EX_T(opline->result.u.var).tmp_var, + is_identical_function(&EX_T(opline->result.u.var).tmp_var, &opline->op1.u.constant, _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + Z_LVAL(EX_T(opline->result.u.var).tmp_var) = !Z_LVAL(EX_T(opline->result.u.var).tmp_var); if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; ZEND_VM_NEXT_OPCODE(); @@ -3270,9 +3271,11 @@ static int ZEND_IS_EQUAL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op2; - is_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, &opline->op1.u.constant, _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) == 0)); if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; ZEND_VM_NEXT_OPCODE(); @@ -3283,9 +3286,11 @@ static int ZEND_IS_NOT_EQUAL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op2; - is_not_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, &opline->op1.u.constant, _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) != 0)); if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; ZEND_VM_NEXT_OPCODE(); @@ -3296,9 +3301,11 @@ static int ZEND_IS_SMALLER_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op2; - is_smaller_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, &opline->op1.u.constant, _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) < 0)); if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; ZEND_VM_NEXT_OPCODE(); @@ -3309,9 +3316,11 @@ static int ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_A zend_op *opline = EX(opline); zend_free_op free_op2; - is_smaller_or_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, &opline->op1.u.constant, _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) <= 0)); if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; ZEND_VM_NEXT_OPCODE(); @@ -3399,10 +3408,9 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDL if(IS_VAR != IS_UNUSED) { char *function_name_strval; int function_name_strlen; - zend_bool is_const = (IS_VAR == IS_CONST); zend_free_op free_op2; - if (is_const) { + if (IS_VAR == IS_CONST) { function_name_strval = Z_STRVAL(opline->op2.u.constant); function_name_strlen = Z_STRLEN(opline->op2.u.constant); } else { @@ -3421,7 +3429,7 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDL EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC); } - if (!is_const) { + if (IS_VAR != IS_CONST) { efree(function_name_strval); if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; } @@ -3613,10 +3621,9 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HA if(IS_UNUSED != IS_UNUSED) { char *function_name_strval; int function_name_strlen; - zend_bool is_const = (IS_UNUSED == IS_CONST); - if (is_const) { + if (IS_UNUSED == IS_CONST) { function_name_strval = Z_STRVAL(opline->op2.u.constant); function_name_strlen = Z_STRLEN(opline->op2.u.constant); } else { @@ -3635,7 +3642,7 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HA EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC); } - if (!is_const) { + if (IS_UNUSED != IS_CONST) { efree(function_name_strval); } @@ -3887,9 +3894,10 @@ static int ZEND_IS_NOT_IDENTICAL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); - is_not_identical_function(&EX_T(opline->result.u.var).tmp_var, + is_identical_function(&EX_T(opline->result.u.var).tmp_var, &opline->op1.u.constant, _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC); + Z_LVAL(EX_T(opline->result.u.var).tmp_var) = !Z_LVAL(EX_T(opline->result.u.var).tmp_var); ZEND_VM_NEXT_OPCODE(); @@ -3900,9 +3908,11 @@ static int ZEND_IS_EQUAL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); - is_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, &opline->op1.u.constant, _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) == 0)); ZEND_VM_NEXT_OPCODE(); @@ -3913,9 +3923,11 @@ static int ZEND_IS_NOT_EQUAL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); - is_not_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, &opline->op1.u.constant, _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) != 0)); ZEND_VM_NEXT_OPCODE(); @@ -3926,9 +3938,11 @@ static int ZEND_IS_SMALLER_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); - is_smaller_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, &opline->op1.u.constant, _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) < 0)); ZEND_VM_NEXT_OPCODE(); @@ -3939,9 +3953,11 @@ static int ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_AR zend_op *opline = EX(opline); - is_smaller_or_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, &opline->op1.u.constant, _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) <= 0)); ZEND_VM_NEXT_OPCODE(); @@ -4029,10 +4045,9 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLE if(IS_CV != IS_UNUSED) { char *function_name_strval; int function_name_strlen; - zend_bool is_const = (IS_CV == IS_CONST); - if (is_const) { + if (IS_CV == IS_CONST) { function_name_strval = Z_STRVAL(opline->op2.u.constant); function_name_strlen = Z_STRLEN(opline->op2.u.constant); } else { @@ -4051,7 +4066,7 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLE EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC); } - if (!is_const) { + if (IS_CV != IS_CONST) { efree(function_name_strval); } @@ -4272,7 +4287,7 @@ static int zend_fetch_var_address_helper_SPEC_TMP(int type, ZEND_OPCODE_HANDLER_ zval tmp_varname; HashTable *target_symbol_table; - if (Z_TYPE_P(varname) != IS_STRING) { + if (IS_TMP_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { tmp_varname = *varname; zval_copy_ctor(&tmp_varname); convert_to_string(&tmp_varname); @@ -4331,7 +4346,7 @@ static int zend_fetch_var_address_helper_SPEC_TMP(int type, ZEND_OPCODE_HANDLER_ } - if (varname == &tmp_varname) { + if (IS_TMP_VAR != IS_CONST && varname == &tmp_varname) { zval_dtor(varname); } if (!RETURN_VALUE_UNUSED(&opline->result)) { @@ -4435,16 +4450,21 @@ static int ZEND_JMPZNZ_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) int retval = i_zend_is_true(_get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC)); zval_dtor(free_op1.var); - if (retval) { + + if (UNEXPECTED(EG(exception) != NULL)) { + ZEND_VM_CONTINUE(); + } else if (EXPECTED(retval != 0)) { #if DEBUG_ZEND>=2 printf("Conditional jmp on true to %d\n", opline->extended_value); #endif - ZEND_VM_JMP(&EX(op_array)->opcodes[opline->extended_value]); + ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->extended_value]); + ZEND_VM_CONTINUE(); /* CHECK_ME */ } else { #if DEBUG_ZEND>=2 printf("Conditional jmp on false to %d\n", opline->op2.u.opline_num); #endif - ZEND_VM_JMP(&EX(op_array)->opcodes[opline->op2.u.opline_num]); + ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.u.opline_num]); + ZEND_VM_CONTINUE(); /* CHECK_ME */ } } @@ -4507,7 +4527,7 @@ static int ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) retval_ptr_ptr = NULL; - if (!retval_ptr_ptr) { + if (IS_TMP_VAR == IS_VAR && !retval_ptr_ptr) { zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference"); } @@ -5364,9 +5384,10 @@ static int ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS zend_op *opline = EX(opline); zend_free_op free_op1; - is_not_identical_function(&EX_T(opline->result.u.var).tmp_var, + is_identical_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), &opline->op2.u.constant TSRMLS_CC); + Z_LVAL(EX_T(opline->result.u.var).tmp_var) = !Z_LVAL(EX_T(opline->result.u.var).tmp_var); zval_dtor(free_op1.var); ZEND_VM_NEXT_OPCODE(); @@ -5377,9 +5398,11 @@ static int ZEND_IS_EQUAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; - is_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), &opline->op2.u.constant TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) == 0)); zval_dtor(free_op1.var); ZEND_VM_NEXT_OPCODE(); @@ -5390,9 +5413,11 @@ static int ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; - is_not_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), &opline->op2.u.constant TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) != 0)); zval_dtor(free_op1.var); ZEND_VM_NEXT_OPCODE(); @@ -5403,9 +5428,11 @@ static int ZEND_IS_SMALLER_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; - is_smaller_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), &opline->op2.u.constant TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) < 0)); zval_dtor(free_op1.var); ZEND_VM_NEXT_OPCODE(); @@ -5416,9 +5443,11 @@ static int ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_A zend_op *opline = EX(opline); zend_free_op free_op1; - is_smaller_or_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), &opline->op2.u.constant TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) <= 0)); zval_dtor(free_op1.var); ZEND_VM_NEXT_OPCODE(); @@ -5823,9 +5852,10 @@ static int ZEND_IS_NOT_IDENTICAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; - is_not_identical_function(&EX_T(opline->result.u.var).tmp_var, + is_identical_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + Z_LVAL(EX_T(opline->result.u.var).tmp_var) = !Z_LVAL(EX_T(opline->result.u.var).tmp_var); zval_dtor(free_op1.var); zval_dtor(free_op2.var); ZEND_VM_NEXT_OPCODE(); @@ -5836,9 +5866,11 @@ static int ZEND_IS_EQUAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; - is_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) == 0)); zval_dtor(free_op1.var); zval_dtor(free_op2.var); ZEND_VM_NEXT_OPCODE(); @@ -5849,9 +5881,11 @@ static int ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; - is_not_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) != 0)); zval_dtor(free_op1.var); zval_dtor(free_op2.var); ZEND_VM_NEXT_OPCODE(); @@ -5862,9 +5896,11 @@ static int ZEND_IS_SMALLER_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; - is_smaller_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) < 0)); zval_dtor(free_op1.var); zval_dtor(free_op2.var); ZEND_VM_NEXT_OPCODE(); @@ -5875,9 +5911,11 @@ static int ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; - is_smaller_or_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) <= 0)); zval_dtor(free_op1.var); zval_dtor(free_op2.var); ZEND_VM_NEXT_OPCODE(); @@ -6270,9 +6308,10 @@ static int ZEND_IS_NOT_IDENTICAL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; - is_not_identical_function(&EX_T(opline->result.u.var).tmp_var, + is_identical_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + Z_LVAL(EX_T(opline->result.u.var).tmp_var) = !Z_LVAL(EX_T(opline->result.u.var).tmp_var); zval_dtor(free_op1.var); if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; ZEND_VM_NEXT_OPCODE(); @@ -6283,9 +6322,11 @@ static int ZEND_IS_EQUAL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; - is_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) == 0)); zval_dtor(free_op1.var); if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; ZEND_VM_NEXT_OPCODE(); @@ -6296,9 +6337,11 @@ static int ZEND_IS_NOT_EQUAL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; - is_not_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) != 0)); zval_dtor(free_op1.var); if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; ZEND_VM_NEXT_OPCODE(); @@ -6309,9 +6352,11 @@ static int ZEND_IS_SMALLER_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; - is_smaller_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) < 0)); zval_dtor(free_op1.var); if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; ZEND_VM_NEXT_OPCODE(); @@ -6322,9 +6367,11 @@ static int ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; - is_smaller_or_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) <= 0)); zval_dtor(free_op1.var); if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; ZEND_VM_NEXT_OPCODE(); @@ -6810,9 +6857,10 @@ static int ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; - is_not_identical_function(&EX_T(opline->result.u.var).tmp_var, + is_identical_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC); + Z_LVAL(EX_T(opline->result.u.var).tmp_var) = !Z_LVAL(EX_T(opline->result.u.var).tmp_var); zval_dtor(free_op1.var); ZEND_VM_NEXT_OPCODE(); @@ -6823,9 +6871,11 @@ static int ZEND_IS_EQUAL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; - is_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) == 0)); zval_dtor(free_op1.var); ZEND_VM_NEXT_OPCODE(); @@ -6836,9 +6886,11 @@ static int ZEND_IS_NOT_EQUAL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; - is_not_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) != 0)); zval_dtor(free_op1.var); ZEND_VM_NEXT_OPCODE(); @@ -6849,9 +6901,11 @@ static int ZEND_IS_SMALLER_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; - is_smaller_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) < 0)); zval_dtor(free_op1.var); ZEND_VM_NEXT_OPCODE(); @@ -6862,9 +6916,11 @@ static int ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS zend_op *opline = EX(opline); zend_free_op free_op1; - is_smaller_or_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) <= 0)); zval_dtor(free_op1.var); ZEND_VM_NEXT_OPCODE(); @@ -7350,7 +7406,7 @@ static int zend_fetch_var_address_helper_SPEC_VAR(int type, ZEND_OPCODE_HANDLER_ zval tmp_varname; HashTable *target_symbol_table; - if (Z_TYPE_P(varname) != IS_STRING) { + if (IS_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { tmp_varname = *varname; zval_copy_ctor(&tmp_varname); convert_to_string(&tmp_varname); @@ -7409,7 +7465,7 @@ static int zend_fetch_var_address_helper_SPEC_VAR(int type, ZEND_OPCODE_HANDLER_ } - if (varname == &tmp_varname) { + if (IS_VAR != IS_CONST && varname == &tmp_varname) { zval_dtor(varname); } if (!RETURN_VALUE_UNUSED(&opline->result)) { @@ -7513,16 +7569,21 @@ static int ZEND_JMPZNZ_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) int retval = i_zend_is_true(_get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC)); if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; - if (retval) { + + if (UNEXPECTED(EG(exception) != NULL)) { + ZEND_VM_CONTINUE(); + } else if (EXPECTED(retval != 0)) { #if DEBUG_ZEND>=2 printf("Conditional jmp on true to %d\n", opline->extended_value); #endif - ZEND_VM_JMP(&EX(op_array)->opcodes[opline->extended_value]); + ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->extended_value]); + ZEND_VM_CONTINUE(); /* CHECK_ME */ } else { #if DEBUG_ZEND>=2 printf("Conditional jmp on false to %d\n", opline->op2.u.opline_num); #endif - ZEND_VM_JMP(&EX(op_array)->opcodes[opline->op2.u.opline_num]); + ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.u.opline_num]); + ZEND_VM_CONTINUE(); /* CHECK_ME */ } } @@ -7579,7 +7640,7 @@ static int ZEND_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) retval_ptr_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); - if (!retval_ptr_ptr) { + if (IS_VAR == IS_VAR && !retval_ptr_ptr) { zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference"); } @@ -7777,7 +7838,7 @@ static int ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval *varptr; varptr_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); - if (!varptr_ptr) { + if (IS_VAR == IS_VAR && !varptr_ptr) { zend_error_noreturn(E_ERROR, "Only variables can be passed by reference"); } @@ -8669,9 +8730,10 @@ static int ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS zend_op *opline = EX(opline); zend_free_op free_op1; - is_not_identical_function(&EX_T(opline->result.u.var).tmp_var, + is_identical_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), &opline->op2.u.constant TSRMLS_CC); + Z_LVAL(EX_T(opline->result.u.var).tmp_var) = !Z_LVAL(EX_T(opline->result.u.var).tmp_var); if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; ZEND_VM_NEXT_OPCODE(); @@ -8682,9 +8744,11 @@ static int ZEND_IS_EQUAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; - is_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), &opline->op2.u.constant TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) == 0)); if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; ZEND_VM_NEXT_OPCODE(); @@ -8695,9 +8759,11 @@ static int ZEND_IS_NOT_EQUAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; - is_not_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), &opline->op2.u.constant TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) != 0)); if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; ZEND_VM_NEXT_OPCODE(); @@ -8708,9 +8774,11 @@ static int ZEND_IS_SMALLER_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; - is_smaller_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), &opline->op2.u.constant TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) < 0)); if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; ZEND_VM_NEXT_OPCODE(); @@ -8721,9 +8789,11 @@ static int ZEND_IS_SMALLER_OR_EQUAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_A zend_op *opline = EX(opline); zend_free_op free_op1; - is_smaller_or_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), &opline->op2.u.constant TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) <= 0)); if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; ZEND_VM_NEXT_OPCODE(); @@ -8921,8 +8991,12 @@ static int zend_binary_assign_op_helper_SPEC_VAR_CONST(int (*binary_op)(zval *re } else { zend_op *op_data = opline+1; zval *dim = &opline->op2.u.constant; + zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); - zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), container, dim, 0, BP_VAR_RW TSRMLS_CC); value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R); var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC); increment_opline = 1; @@ -9226,13 +9300,18 @@ static int ZEND_FETCH_DIM_R_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; zval *dim = &opline->op2.u.constant; + zval **container; if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_VAR != IS_CV && EX_T(opline->op1.u.var).var.ptr_ptr) { PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr); } - zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC); + container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_R TSRMLS_CC); if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; ZEND_VM_NEXT_OPCODE(); @@ -9243,12 +9322,15 @@ static int ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; zval *dim = &opline->op2.u.constant; + zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_W TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_W TSRMLS_CC); if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -9272,12 +9354,15 @@ static int ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; zval *dim = &opline->op2.u.constant; + zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_RW TSRMLS_CC); if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -9293,8 +9378,12 @@ static int ZEND_FETCH_DIM_IS_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; zval *dim = &opline->op2.u.constant; + zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); - zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_IS TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address_read(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_IS TSRMLS_CC); if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; ZEND_VM_NEXT_OPCODE(); @@ -9305,12 +9394,16 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR zend_op *opline = EX(opline); zend_free_op free_op1; zval *dim = &opline->op2.u.constant; + zval **container; if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) { - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_W TSRMLS_CC); + container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_W TSRMLS_CC); if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -9321,7 +9414,11 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR if (IS_CONST == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC); + container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address_read(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_R TSRMLS_CC); } if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; @@ -9345,11 +9442,13 @@ static int ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SEPARATE_ZVAL_IF_NOT_REF(container); } } - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_UNSET TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_UNSET TSRMLS_CC); if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -9440,8 +9539,9 @@ static int ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; zval *property = &opline->op2.u.constant; + zval **container; - if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_VAR != IS_CV) { + if (IS_VAR == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) { 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; } @@ -9449,15 +9549,21 @@ static int ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), property, BP_VAR_W TSRMLS_CC); + container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_W TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { } if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -9481,19 +9587,25 @@ static int ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; zval *property = &opline->op2.u.constant; + zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), property, BP_VAR_RW TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_RW TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { } if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -9517,19 +9629,25 @@ static int ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR /* Behave like FETCH_OBJ_W */ zend_free_op free_op1; zval *property = &opline->op2.u.constant; + zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), property, BP_VAR_W TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_W TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { } if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -9558,15 +9676,20 @@ static int ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { } if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -9595,6 +9718,9 @@ static int ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (0) { MAKE_REAL_ZVAL_PTR(property_name); } + if (IS_VAR == IS_VAR && !object_ptr) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC); if (0) { zval_ptr_dtor(&property_name); @@ -9640,6 +9766,9 @@ static int ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval *dim = &opline->op2.u.constant; zval **variable_ptr_ptr; + if (IS_VAR == IS_VAR && !object_ptr) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 0, BP_VAR_W TSRMLS_CC); value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R); @@ -9773,10 +9902,9 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDL if(IS_CONST != IS_UNUSED) { char *function_name_strval; int function_name_strlen; - zend_bool is_const = (IS_CONST == IS_CONST); - if (is_const) { + if (IS_CONST == IS_CONST) { function_name_strval = Z_STRVAL(opline->op2.u.constant); function_name_strlen = Z_STRLEN(opline->op2.u.constant); } else { @@ -9795,7 +9923,7 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDL EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC); } - if (!is_const) { + if (IS_CONST != IS_CONST) { efree(function_name_strval); } @@ -10412,9 +10540,10 @@ static int ZEND_IS_NOT_IDENTICAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; - is_not_identical_function(&EX_T(opline->result.u.var).tmp_var, + is_identical_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + Z_LVAL(EX_T(opline->result.u.var).tmp_var) = !Z_LVAL(EX_T(opline->result.u.var).tmp_var); if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; zval_dtor(free_op2.var); ZEND_VM_NEXT_OPCODE(); @@ -10425,9 +10554,11 @@ static int ZEND_IS_EQUAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; - is_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) == 0)); if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; zval_dtor(free_op2.var); ZEND_VM_NEXT_OPCODE(); @@ -10438,9 +10569,11 @@ static int ZEND_IS_NOT_EQUAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; - is_not_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) != 0)); if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; zval_dtor(free_op2.var); ZEND_VM_NEXT_OPCODE(); @@ -10451,9 +10584,11 @@ static int ZEND_IS_SMALLER_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; - is_smaller_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) < 0)); if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; zval_dtor(free_op2.var); ZEND_VM_NEXT_OPCODE(); @@ -10464,9 +10599,11 @@ static int ZEND_IS_SMALLER_OR_EQUAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; - is_smaller_or_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) <= 0)); if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; zval_dtor(free_op2.var); ZEND_VM_NEXT_OPCODE(); @@ -10664,8 +10801,12 @@ static int zend_binary_assign_op_helper_SPEC_VAR_TMP(int (*binary_op)(zval *resu } else { zend_op *op_data = opline+1; zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); - zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 1, BP_VAR_RW TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), container, dim, 1, BP_VAR_RW TSRMLS_CC); value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R); var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC); increment_opline = 1; @@ -10970,13 +11111,18 @@ static int ZEND_FETCH_DIM_R_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container; if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_VAR != IS_CV && EX_T(opline->op1.u.var).var.ptr_ptr) { PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr); } - zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 1, BP_VAR_R TSRMLS_CC); + container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, dim, 1, BP_VAR_R TSRMLS_CC); zval_dtor(free_op2.var); if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; ZEND_VM_NEXT_OPCODE(); @@ -10987,12 +11133,15 @@ static int ZEND_FETCH_DIM_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 1, BP_VAR_W TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 1, BP_VAR_W TSRMLS_CC); zval_dtor(free_op2.var); if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -11016,12 +11165,15 @@ static int ZEND_FETCH_DIM_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 1, BP_VAR_RW TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 1, BP_VAR_RW TSRMLS_CC); zval_dtor(free_op2.var); if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -11037,8 +11189,12 @@ static int ZEND_FETCH_DIM_IS_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); - zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 1, BP_VAR_IS TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address_read(&EX_T(opline->result.u.var), container, dim, 1, BP_VAR_IS TSRMLS_CC); zval_dtor(free_op2.var); if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; ZEND_VM_NEXT_OPCODE(); @@ -11049,12 +11205,16 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container; if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) { - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 1, BP_VAR_W TSRMLS_CC); + container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 1, BP_VAR_W TSRMLS_CC); if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -11065,7 +11225,11 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS if (IS_TMP_VAR == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 1, BP_VAR_R TSRMLS_CC); + container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address_read(&EX_T(opline->result.u.var), container, dim, 1, BP_VAR_R TSRMLS_CC); } zval_dtor(free_op2.var); if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; @@ -11089,11 +11253,13 @@ static int ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SEPARATE_ZVAL_IF_NOT_REF(container); } } - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, dim, 1, BP_VAR_UNSET TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 1, BP_VAR_UNSET TSRMLS_CC); zval_dtor(free_op2.var); if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -11184,8 +11350,9 @@ static int ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container; - if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_VAR != IS_CV) { + if (IS_VAR == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) { 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; } @@ -11193,15 +11360,21 @@ static int ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (1) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), property, BP_VAR_W TSRMLS_CC); + container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_W TSRMLS_CC); + } if (1) { zval_ptr_dtor(&property); } else { zval_dtor(free_op2.var); } if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -11225,19 +11398,25 @@ static int ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); if (1) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), property, BP_VAR_RW TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_RW TSRMLS_CC); + } if (1) { zval_ptr_dtor(&property); } else { zval_dtor(free_op2.var); } if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -11261,19 +11440,25 @@ static int ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS /* Behave like FETCH_OBJ_W */ zend_free_op free_op1, free_op2; zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); if (1) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), property, BP_VAR_W TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_W TSRMLS_CC); + } if (1) { zval_ptr_dtor(&property); } else { zval_dtor(free_op2.var); } if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -11302,15 +11487,20 @@ static int ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (1) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC); + } if (1) { zval_ptr_dtor(&property); } else { zval_dtor(free_op2.var); } if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -11339,6 +11529,9 @@ static int ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (1) { MAKE_REAL_ZVAL_PTR(property_name); } + if (IS_VAR == IS_VAR && !object_ptr) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC); if (1) { zval_ptr_dtor(&property_name); @@ -11384,6 +11577,9 @@ static int ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); zval **variable_ptr_ptr; + if (IS_VAR == IS_VAR && !object_ptr) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 1, BP_VAR_W TSRMLS_CC); zval_dtor(free_op2.var); @@ -11519,10 +11715,9 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER if(IS_TMP_VAR != IS_UNUSED) { char *function_name_strval; int function_name_strlen; - zend_bool is_const = (IS_TMP_VAR == IS_CONST); zend_free_op free_op2; - if (is_const) { + if (IS_TMP_VAR == IS_CONST) { function_name_strval = Z_STRVAL(opline->op2.u.constant); function_name_strlen = Z_STRLEN(opline->op2.u.constant); } else { @@ -11541,7 +11736,7 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC); } - if (!is_const) { + if (IS_TMP_VAR != IS_CONST) { efree(function_name_strval); zval_dtor(free_op2.var); } @@ -12087,9 +12282,10 @@ static int ZEND_IS_NOT_IDENTICAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; - is_not_identical_function(&EX_T(opline->result.u.var).tmp_var, + is_identical_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + Z_LVAL(EX_T(opline->result.u.var).tmp_var) = !Z_LVAL(EX_T(opline->result.u.var).tmp_var); if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; ZEND_VM_NEXT_OPCODE(); @@ -12100,9 +12296,11 @@ static int ZEND_IS_EQUAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; - is_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) == 0)); if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; ZEND_VM_NEXT_OPCODE(); @@ -12113,9 +12311,11 @@ static int ZEND_IS_NOT_EQUAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; - is_not_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) != 0)); if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; ZEND_VM_NEXT_OPCODE(); @@ -12126,9 +12326,11 @@ static int ZEND_IS_SMALLER_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; - is_smaller_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) < 0)); if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; ZEND_VM_NEXT_OPCODE(); @@ -12139,9 +12341,11 @@ static int ZEND_IS_SMALLER_OR_EQUAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; - is_smaller_or_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) <= 0)); if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; ZEND_VM_NEXT_OPCODE(); @@ -12339,8 +12543,12 @@ static int zend_binary_assign_op_helper_SPEC_VAR_VAR(int (*binary_op)(zval *resu } else { zend_op *op_data = opline+1; zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); - zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), container, dim, 0, BP_VAR_RW TSRMLS_CC); value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R); var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC); increment_opline = 1; @@ -12645,13 +12853,18 @@ static int ZEND_FETCH_DIM_R_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container; if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_VAR != IS_CV && EX_T(opline->op1.u.var).var.ptr_ptr) { PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr); } - zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC); + container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_R TSRMLS_CC); if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; ZEND_VM_NEXT_OPCODE(); @@ -12662,12 +12875,15 @@ static int ZEND_FETCH_DIM_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_W TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_W TSRMLS_CC); if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -12691,12 +12907,15 @@ static int ZEND_FETCH_DIM_RW_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_RW TSRMLS_CC); if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -12712,8 +12931,12 @@ static int ZEND_FETCH_DIM_IS_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); - zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_IS TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address_read(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_IS TSRMLS_CC); if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; ZEND_VM_NEXT_OPCODE(); @@ -12724,12 +12947,16 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container; if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) { - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_W TSRMLS_CC); + container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_W TSRMLS_CC); if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -12740,7 +12967,11 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS if (IS_VAR == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC); + container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address_read(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_R TSRMLS_CC); } if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; @@ -12764,11 +12995,13 @@ static int ZEND_FETCH_DIM_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SEPARATE_ZVAL_IF_NOT_REF(container); } } - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_UNSET TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_UNSET TSRMLS_CC); if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -12859,8 +13092,9 @@ static int ZEND_FETCH_OBJ_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container; - if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_VAR != IS_CV) { + if (IS_VAR == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) { 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; } @@ -12868,15 +13102,21 @@ static int ZEND_FETCH_OBJ_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), property, BP_VAR_W TSRMLS_CC); + container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_W TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; } if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -12900,19 +13140,25 @@ static int ZEND_FETCH_OBJ_RW_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), property, BP_VAR_RW TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_RW TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; } if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -12936,19 +13182,25 @@ static int ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS /* Behave like FETCH_OBJ_W */ zend_free_op free_op1, free_op2; zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), property, BP_VAR_W TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_W TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; } if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -12977,15 +13229,20 @@ static int ZEND_FETCH_OBJ_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; } if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -13014,6 +13271,9 @@ static int ZEND_ASSIGN_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (0) { MAKE_REAL_ZVAL_PTR(property_name); } + if (IS_VAR == IS_VAR && !object_ptr) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC); if (0) { zval_ptr_dtor(&property_name); @@ -13059,6 +13319,9 @@ static int ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); zval **variable_ptr_ptr; + if (IS_VAR == IS_VAR && !object_ptr) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 0, BP_VAR_W TSRMLS_CC); if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; @@ -13131,6 +13394,10 @@ static int ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } variable_ptr_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); + if ((IS_VAR == IS_VAR && !value_ptr_ptr) || + (IS_VAR == IS_VAR && !variable_ptr_ptr)) { + zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects"); + } zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC); if (!RETURN_VALUE_UNUSED(&opline->result)) { @@ -13231,10 +13498,9 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER if(IS_VAR != IS_UNUSED) { char *function_name_strval; int function_name_strlen; - zend_bool is_const = (IS_VAR == IS_CONST); zend_free_op free_op2; - if (is_const) { + if (IS_VAR == IS_CONST) { function_name_strval = Z_STRVAL(opline->op2.u.constant); function_name_strlen = Z_STRLEN(opline->op2.u.constant); } else { @@ -13253,7 +13519,7 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC); } - if (!is_const) { + if (IS_VAR != IS_CONST) { efree(function_name_strval); if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; } @@ -13817,8 +14083,12 @@ static int zend_binary_assign_op_helper_SPEC_VAR_UNUSED(int (*binary_op)(zval *r } else { zend_op *op_data = opline+1; zval *dim = NULL; + zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); - zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), container, dim, 0, BP_VAR_RW TSRMLS_CC); value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R); var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC); increment_opline = 1; @@ -13937,12 +14207,15 @@ static int ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; zval *dim = NULL; + zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_W TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_W TSRMLS_CC); if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -13966,12 +14239,15 @@ static int ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; zval *dim = NULL; + zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_RW TSRMLS_CC); if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -13987,12 +14263,16 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_A zend_op *opline = EX(opline); zend_free_op free_op1; zval *dim = NULL; + zval **container; if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) { - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_W TSRMLS_CC); + container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_W TSRMLS_CC); if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -14003,7 +14283,11 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_A if (IS_UNUSED == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC); + container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address_read(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_R TSRMLS_CC); } if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; @@ -14043,6 +14327,9 @@ static int ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval *dim = NULL; zval **variable_ptr_ptr; + if (IS_VAR == IS_VAR && !object_ptr) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 0, BP_VAR_W TSRMLS_CC); value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R); @@ -14095,10 +14382,9 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HAND if(IS_UNUSED != IS_UNUSED) { char *function_name_strval; int function_name_strlen; - zend_bool is_const = (IS_UNUSED == IS_CONST); - if (is_const) { + if (IS_UNUSED == IS_CONST) { function_name_strval = Z_STRVAL(opline->op2.u.constant); function_name_strlen = Z_STRLEN(opline->op2.u.constant); } else { @@ -14117,7 +14403,7 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HAND EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC); } - if (!is_const) { + if (IS_UNUSED != IS_CONST) { efree(function_name_strval); } @@ -14369,9 +14655,10 @@ static int ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; - is_not_identical_function(&EX_T(opline->result.u.var).tmp_var, + is_identical_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC); + Z_LVAL(EX_T(opline->result.u.var).tmp_var) = !Z_LVAL(EX_T(opline->result.u.var).tmp_var); if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; ZEND_VM_NEXT_OPCODE(); @@ -14382,9 +14669,11 @@ static int ZEND_IS_EQUAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; - is_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) == 0)); if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; ZEND_VM_NEXT_OPCODE(); @@ -14395,9 +14684,11 @@ static int ZEND_IS_NOT_EQUAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; - is_not_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) != 0)); if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; ZEND_VM_NEXT_OPCODE(); @@ -14408,9 +14699,11 @@ static int ZEND_IS_SMALLER_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; - is_smaller_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) < 0)); if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; ZEND_VM_NEXT_OPCODE(); @@ -14421,9 +14714,11 @@ static int ZEND_IS_SMALLER_OR_EQUAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS zend_op *opline = EX(opline); zend_free_op free_op1; - is_smaller_or_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) <= 0)); if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; ZEND_VM_NEXT_OPCODE(); @@ -14621,8 +14916,12 @@ static int zend_binary_assign_op_helper_SPEC_VAR_CV(int (*binary_op)(zval *resul } else { zend_op *op_data = opline+1; zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); - zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), container, dim, 0, BP_VAR_RW TSRMLS_CC); value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R); var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC); increment_opline = 1; @@ -14926,13 +15225,18 @@ static int ZEND_FETCH_DIM_R_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC); + zval **container; if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_VAR != IS_CV && EX_T(opline->op1.u.var).var.ptr_ptr) { PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr); } - zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC); + container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_R TSRMLS_CC); if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; ZEND_VM_NEXT_OPCODE(); @@ -14943,12 +15247,15 @@ static int ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_W TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_W TSRMLS_CC); if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -14972,12 +15279,15 @@ static int ZEND_FETCH_DIM_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_RW TSRMLS_CC); if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -14993,8 +15303,12 @@ static int ZEND_FETCH_DIM_IS_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); - zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_IS TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address_read(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_IS TSRMLS_CC); if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; ZEND_VM_NEXT_OPCODE(); @@ -15005,12 +15319,16 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC); + zval **container; if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) { - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_W TSRMLS_CC); + container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_W TSRMLS_CC); if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -15021,7 +15339,11 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (IS_CV == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC); + container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address_read(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_R TSRMLS_CC); } if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; @@ -15045,11 +15367,13 @@ static int ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SEPARATE_ZVAL_IF_NOT_REF(container); } } - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_UNSET TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_UNSET TSRMLS_CC); if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -15140,8 +15464,9 @@ static int ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC); + zval **container; - if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_VAR != IS_CV) { + if (IS_VAR == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) { 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; } @@ -15149,15 +15474,21 @@ static int ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), property, BP_VAR_W TSRMLS_CC); + container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_W TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { } if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -15181,19 +15512,25 @@ static int ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), property, BP_VAR_RW TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_RW TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { } if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -15217,19 +15554,25 @@ static int ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) /* Behave like FETCH_OBJ_W */ zend_free_op free_op1; zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC), property, BP_VAR_W TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_W TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { } if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -15258,15 +15601,20 @@ static int ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC); + if (IS_VAR == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { } if (IS_VAR == IS_VAR && (free_op1.var != NULL) && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -15295,6 +15643,9 @@ static int ZEND_ASSIGN_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (0) { MAKE_REAL_ZVAL_PTR(property_name); } + if (IS_VAR == IS_VAR && !object_ptr) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC); if (0) { zval_ptr_dtor(&property_name); @@ -15340,6 +15691,9 @@ static int ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC); zval **variable_ptr_ptr; + if (IS_VAR == IS_VAR && !object_ptr) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 0, BP_VAR_W TSRMLS_CC); value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R); @@ -15410,6 +15764,10 @@ static int ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } variable_ptr_ptr = _get_zval_ptr_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); + if ((IS_CV == IS_VAR && !value_ptr_ptr) || + (IS_VAR == IS_VAR && !variable_ptr_ptr)) { + zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects"); + } zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC); if (!RETURN_VALUE_UNUSED(&opline->result)) { @@ -15508,10 +15866,9 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ if(IS_CV != IS_UNUSED) { char *function_name_strval; int function_name_strlen; - zend_bool is_const = (IS_CV == IS_CONST); - if (is_const) { + if (IS_CV == IS_CONST) { function_name_strval = Z_STRVAL(opline->op2.u.constant); function_name_strlen = Z_STRLEN(opline->op2.u.constant); } else { @@ -15530,7 +15887,7 @@ static int ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC); } - if (!is_const) { + if (IS_CV != IS_CONST) { efree(function_name_strval); } @@ -16174,8 +16531,12 @@ static int zend_binary_assign_op_helper_SPEC_UNUSED_CONST(int (*binary_op)(zval } else { zend_op *op_data = opline+1; zval *dim = &opline->op2.u.constant; + zval **container = NULL; - zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), NULL, dim, 0, BP_VAR_RW TSRMLS_CC); + if (IS_UNUSED == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), container, dim, 0, BP_VAR_RW TSRMLS_CC); value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R); var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC); increment_opline = 1; @@ -16541,8 +16902,9 @@ static int ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; zval *property = &opline->op2.u.constant; + zval **container; - if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_UNUSED != IS_CV) { + if (IS_UNUSED == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) { 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; } @@ -16550,15 +16912,21 @@ static int ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_obj_zval_ptr_ptr_unused(TSRMLS_C), property, BP_VAR_W TSRMLS_CC); + container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C); + if (IS_UNUSED == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_W TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { } if (IS_UNUSED == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -16581,19 +16949,25 @@ static int ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; zval *property = &opline->op2.u.constant; + zval **container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C); if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_obj_zval_ptr_ptr_unused(TSRMLS_C), property, BP_VAR_RW TSRMLS_CC); + if (IS_UNUSED == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_RW TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { } if (IS_UNUSED == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -16617,19 +16991,25 @@ static int ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER /* Behave like FETCH_OBJ_W */ zend_free_op free_op1; zval *property = &opline->op2.u.constant; + zval **container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C); if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_obj_zval_ptr_ptr_unused(TSRMLS_C), property, BP_VAR_W TSRMLS_CC); + if (IS_UNUSED == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_W TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { } if (IS_UNUSED == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -16658,15 +17038,20 @@ static int ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC); + if (IS_UNUSED == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { } if (IS_UNUSED == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -16694,6 +17079,9 @@ static int ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (0) { MAKE_REAL_ZVAL_PTR(property_name); } + if (IS_UNUSED == IS_VAR && !object_ptr) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC); if (0) { zval_ptr_dtor(&property_name); @@ -17244,8 +17632,12 @@ static int zend_binary_assign_op_helper_SPEC_UNUSED_TMP(int (*binary_op)(zval *r } else { zend_op *op_data = opline+1; zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container = NULL; - zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), NULL, dim, 1, BP_VAR_RW TSRMLS_CC); + if (IS_UNUSED == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), container, dim, 1, BP_VAR_RW TSRMLS_CC); value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R); var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC); increment_opline = 1; @@ -17612,8 +18004,9 @@ static int ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container; - if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_UNUSED != IS_CV) { + if (IS_UNUSED == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) { 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; } @@ -17621,15 +18014,21 @@ static int ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (1) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_obj_zval_ptr_ptr_unused(TSRMLS_C), property, BP_VAR_W TSRMLS_CC); + container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C); + if (IS_UNUSED == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_W TSRMLS_CC); + } if (1) { zval_ptr_dtor(&property); } else { zval_dtor(free_op2.var); } if (IS_UNUSED == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -17652,19 +18051,25 @@ static int ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C); if (1) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_obj_zval_ptr_ptr_unused(TSRMLS_C), property, BP_VAR_RW TSRMLS_CC); + if (IS_UNUSED == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_RW TSRMLS_CC); + } if (1) { zval_ptr_dtor(&property); } else { zval_dtor(free_op2.var); } if (IS_UNUSED == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -17688,19 +18093,25 @@ static int ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_A /* Behave like FETCH_OBJ_W */ zend_free_op free_op1, free_op2; zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C); if (1) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_obj_zval_ptr_ptr_unused(TSRMLS_C), property, BP_VAR_W TSRMLS_CC); + if (IS_UNUSED == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_W TSRMLS_CC); + } if (1) { zval_ptr_dtor(&property); } else { zval_dtor(free_op2.var); } if (IS_UNUSED == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -17729,15 +18140,20 @@ static int ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS if (1) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC); + if (IS_UNUSED == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC); + } if (1) { zval_ptr_dtor(&property); } else { zval_dtor(free_op2.var); } if (IS_UNUSED == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -17765,6 +18181,9 @@ static int ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (1) { MAKE_REAL_ZVAL_PTR(property_name); } + if (IS_UNUSED == IS_VAR && !object_ptr) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC); if (1) { zval_ptr_dtor(&property_name); @@ -18244,8 +18663,12 @@ static int zend_binary_assign_op_helper_SPEC_UNUSED_VAR(int (*binary_op)(zval *r } else { zend_op *op_data = opline+1; zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container = NULL; - zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), NULL, dim, 0, BP_VAR_RW TSRMLS_CC); + if (IS_UNUSED == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), container, dim, 0, BP_VAR_RW TSRMLS_CC); value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R); var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC); increment_opline = 1; @@ -18612,8 +19035,9 @@ static int ZEND_FETCH_OBJ_W_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container; - if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_UNUSED != IS_CV) { + if (IS_UNUSED == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) { 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; } @@ -18621,15 +19045,21 @@ static int ZEND_FETCH_OBJ_W_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_obj_zval_ptr_ptr_unused(TSRMLS_C), property, BP_VAR_W TSRMLS_CC); + container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C); + if (IS_UNUSED == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_W TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; } if (IS_UNUSED == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -18652,19 +19082,25 @@ static int ZEND_FETCH_OBJ_RW_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C); if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_obj_zval_ptr_ptr_unused(TSRMLS_C), property, BP_VAR_RW TSRMLS_CC); + if (IS_UNUSED == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_RW TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; } if (IS_UNUSED == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -18688,19 +19124,25 @@ static int ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_A /* Behave like FETCH_OBJ_W */ zend_free_op free_op1, free_op2; zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C); if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_obj_zval_ptr_ptr_unused(TSRMLS_C), property, BP_VAR_W TSRMLS_CC); + if (IS_UNUSED == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_W TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; } if (IS_UNUSED == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -18729,15 +19171,20 @@ static int ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC); + if (IS_UNUSED == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; } if (IS_UNUSED == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -18765,6 +19212,9 @@ static int ZEND_ASSIGN_OBJ_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (0) { MAKE_REAL_ZVAL_PTR(property_name); } + if (IS_UNUSED == IS_VAR && !object_ptr) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC); if (0) { zval_ptr_dtor(&property_name); @@ -19244,8 +19694,12 @@ static int zend_binary_assign_op_helper_SPEC_UNUSED_UNUSED(int (*binary_op)(zval } else { zend_op *op_data = opline+1; zval *dim = NULL; + zval **container = NULL; - zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), NULL, dim, 0, BP_VAR_RW TSRMLS_CC); + if (IS_UNUSED == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), container, dim, 0, BP_VAR_RW TSRMLS_CC); value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R); var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC); increment_opline = 1; @@ -19512,8 +19966,12 @@ static int zend_binary_assign_op_helper_SPEC_UNUSED_CV(int (*binary_op)(zval *re } else { zend_op *op_data = opline+1; zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC); + zval **container = NULL; - zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), NULL, dim, 0, BP_VAR_RW TSRMLS_CC); + if (IS_UNUSED == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), container, dim, 0, BP_VAR_RW TSRMLS_CC); value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R); var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC); increment_opline = 1; @@ -19879,8 +20337,9 @@ static int ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC); + zval **container; - if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_UNUSED != IS_CV) { + if (IS_UNUSED == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) { 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; } @@ -19888,15 +20347,21 @@ static int ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_obj_zval_ptr_ptr_unused(TSRMLS_C), property, BP_VAR_W TSRMLS_CC); + container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C); + if (IS_UNUSED == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_W TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { } if (IS_UNUSED == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -19919,19 +20384,25 @@ static int ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC); + zval **container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C); if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_obj_zval_ptr_ptr_unused(TSRMLS_C), property, BP_VAR_RW TSRMLS_CC); + if (IS_UNUSED == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_RW TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { } if (IS_UNUSED == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -19955,19 +20426,25 @@ static int ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_AR /* Behave like FETCH_OBJ_W */ zend_free_op free_op1; zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC); + zval **container = _get_obj_zval_ptr_ptr_unused(TSRMLS_C); if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_obj_zval_ptr_ptr_unused(TSRMLS_C), property, BP_VAR_W TSRMLS_CC); + if (IS_UNUSED == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_W TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { } if (IS_UNUSED == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -19996,15 +20473,20 @@ static int ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC); + if (IS_UNUSED == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { } if (IS_UNUSED == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -20032,6 +20514,9 @@ static int ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (0) { MAKE_REAL_ZVAL_PTR(property_name); } + if (IS_UNUSED == IS_VAR && !object_ptr) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC); if (0) { zval_ptr_dtor(&property_name); @@ -20584,7 +21069,7 @@ static int zend_fetch_var_address_helper_SPEC_CV(int type, ZEND_OPCODE_HANDLER_A zval tmp_varname; HashTable *target_symbol_table; - if (Z_TYPE_P(varname) != IS_STRING) { + if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { tmp_varname = *varname; zval_copy_ctor(&tmp_varname); convert_to_string(&tmp_varname); @@ -20643,7 +21128,7 @@ static int zend_fetch_var_address_helper_SPEC_CV(int type, ZEND_OPCODE_HANDLER_A } - if (varname == &tmp_varname) { + if (IS_CV != IS_CONST && varname == &tmp_varname) { zval_dtor(varname); } if (!RETURN_VALUE_UNUSED(&opline->result)) { @@ -20744,16 +21229,20 @@ static int ZEND_JMPZNZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) int retval = i_zend_is_true(_get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC)); - if (retval) { + if (UNEXPECTED(EG(exception) != NULL)) { + ZEND_VM_CONTINUE(); + } else if (EXPECTED(retval != 0)) { #if DEBUG_ZEND>=2 printf("Conditional jmp on true to %d\n", opline->extended_value); #endif - ZEND_VM_JMP(&EX(op_array)->opcodes[opline->extended_value]); + ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->extended_value]); + ZEND_VM_CONTINUE(); /* CHECK_ME */ } else { #if DEBUG_ZEND>=2 printf("Conditional jmp on false to %d\n", opline->op2.u.opline_num); #endif - ZEND_VM_JMP(&EX(op_array)->opcodes[opline->op2.u.opline_num]); + ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->op2.u.opline_num]); + ZEND_VM_CONTINUE(); /* CHECK_ME */ } } @@ -20808,7 +21297,7 @@ static int ZEND_RETURN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) retval_ptr_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC); - if (!retval_ptr_ptr) { + if (IS_CV == IS_VAR && !retval_ptr_ptr) { zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference"); } @@ -21006,7 +21495,7 @@ static int ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval *varptr; varptr_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC); - if (!varptr_ptr) { + if (IS_CV == IS_VAR && !varptr_ptr) { zend_error_noreturn(E_ERROR, "Only variables can be passed by reference"); } @@ -21740,9 +22229,10 @@ static int ZEND_IS_NOT_IDENTICAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); - is_not_identical_function(&EX_T(opline->result.u.var).tmp_var, + is_identical_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), &opline->op2.u.constant TSRMLS_CC); + Z_LVAL(EX_T(opline->result.u.var).tmp_var) = !Z_LVAL(EX_T(opline->result.u.var).tmp_var); ZEND_VM_NEXT_OPCODE(); @@ -21753,9 +22243,11 @@ static int ZEND_IS_EQUAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); - is_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), &opline->op2.u.constant TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) == 0)); ZEND_VM_NEXT_OPCODE(); @@ -21766,9 +22258,11 @@ static int ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); - is_not_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), &opline->op2.u.constant TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) != 0)); ZEND_VM_NEXT_OPCODE(); @@ -21779,9 +22273,11 @@ static int ZEND_IS_SMALLER_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); - is_smaller_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), &opline->op2.u.constant TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) < 0)); ZEND_VM_NEXT_OPCODE(); @@ -21792,9 +22288,11 @@ static int ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR zend_op *opline = EX(opline); - is_smaller_or_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), &opline->op2.u.constant TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) <= 0)); ZEND_VM_NEXT_OPCODE(); @@ -21991,8 +22489,12 @@ static int zend_binary_assign_op_helper_SPEC_CV_CONST(int (*binary_op)(zval *res } else { zend_op *op_data = opline+1; zval *dim = &opline->op2.u.constant; + zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC); - zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), container, dim, 0, BP_VAR_RW TSRMLS_CC); value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R); var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC); increment_opline = 1; @@ -22296,13 +22798,18 @@ static int ZEND_FETCH_DIM_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zval *dim = &opline->op2.u.constant; + zval **container; if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_CV != IS_CV && EX_T(opline->op1.u.var).var.ptr_ptr) { PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr); } - zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC); + container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_R TSRMLS_CC); ZEND_VM_NEXT_OPCODE(); @@ -22313,12 +22820,15 @@ static int ZEND_FETCH_DIM_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; zval *dim = &opline->op2.u.constant; + zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC); - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), dim, 0, BP_VAR_W TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_W TSRMLS_CC); if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -22341,12 +22851,15 @@ static int ZEND_FETCH_DIM_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; zval *dim = &opline->op2.u.constant; + zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC); - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_RW TSRMLS_CC); if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -22362,8 +22875,12 @@ static int ZEND_FETCH_DIM_IS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zval *dim = &opline->op2.u.constant; + zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_IS TSRMLS_CC); - zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_IS TSRMLS_CC), dim, 0, BP_VAR_IS TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address_read(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_IS TSRMLS_CC); ZEND_VM_NEXT_OPCODE(); @@ -22374,12 +22891,16 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG zend_op *opline = EX(opline); zend_free_op free_op1; zval *dim = &opline->op2.u.constant; + zval **container; if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) { - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), dim, 0, BP_VAR_W TSRMLS_CC); + container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_W TSRMLS_CC); if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -22390,7 +22911,11 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG if (IS_CONST == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC); + container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address_read(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_R TSRMLS_CC); } @@ -22414,11 +22939,13 @@ static int ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SEPARATE_ZVAL_IF_NOT_REF(container); } } - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_UNSET TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_UNSET TSRMLS_CC); if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -22508,8 +23035,9 @@ static int ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; zval *property = &opline->op2.u.constant; + zval **container; - if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_CV != IS_CV) { + if (IS_CV == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) { 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; } @@ -22517,15 +23045,21 @@ static int ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), property, BP_VAR_W TSRMLS_CC); + container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_W TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { } if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -22548,19 +23082,25 @@ static int ZEND_FETCH_OBJ_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; zval *property = &opline->op2.u.constant; + zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC); if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), property, BP_VAR_RW TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_RW TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { } if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -22584,19 +23124,25 @@ static int ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG /* Behave like FETCH_OBJ_W */ zend_free_op free_op1; zval *property = &opline->op2.u.constant; + zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC); if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), property, BP_VAR_W TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_W TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { } if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -22625,15 +23171,20 @@ static int ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { } if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -22661,6 +23212,9 @@ static int ZEND_ASSIGN_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (0) { MAKE_REAL_ZVAL_PTR(property_name); } + if (IS_CV == IS_VAR && !object_ptr) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC); if (0) { zval_ptr_dtor(&property_name); @@ -22706,6 +23260,9 @@ static int ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval *dim = &opline->op2.u.constant; zval **variable_ptr_ptr; + if (IS_CV == IS_VAR && !object_ptr) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 0, BP_VAR_W TSRMLS_CC); value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R); @@ -23310,9 +23867,10 @@ static int ZEND_IS_NOT_IDENTICAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op2; - is_not_identical_function(&EX_T(opline->result.u.var).tmp_var, + is_identical_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + Z_LVAL(EX_T(opline->result.u.var).tmp_var) = !Z_LVAL(EX_T(opline->result.u.var).tmp_var); zval_dtor(free_op2.var); ZEND_VM_NEXT_OPCODE(); @@ -23323,9 +23881,11 @@ static int ZEND_IS_EQUAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op2; - is_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) == 0)); zval_dtor(free_op2.var); ZEND_VM_NEXT_OPCODE(); @@ -23336,9 +23896,11 @@ static int ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op2; - is_not_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) != 0)); zval_dtor(free_op2.var); ZEND_VM_NEXT_OPCODE(); @@ -23349,9 +23911,11 @@ static int ZEND_IS_SMALLER_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op2; - is_smaller_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) < 0)); zval_dtor(free_op2.var); ZEND_VM_NEXT_OPCODE(); @@ -23362,9 +23926,11 @@ static int ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS zend_op *opline = EX(opline); zend_free_op free_op2; - is_smaller_or_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) <= 0)); zval_dtor(free_op2.var); ZEND_VM_NEXT_OPCODE(); @@ -23561,8 +24127,12 @@ static int zend_binary_assign_op_helper_SPEC_CV_TMP(int (*binary_op)(zval *resul } else { zend_op *op_data = opline+1; zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC); - zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), dim, 1, BP_VAR_RW TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), container, dim, 1, BP_VAR_RW TSRMLS_CC); value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R); var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC); increment_opline = 1; @@ -23867,13 +24437,18 @@ static int ZEND_FETCH_DIM_R_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op2; zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container; if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_CV != IS_CV && EX_T(opline->op1.u.var).var.ptr_ptr) { PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr); } - zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), dim, 1, BP_VAR_R TSRMLS_CC); + container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, dim, 1, BP_VAR_R TSRMLS_CC); zval_dtor(free_op2.var); ZEND_VM_NEXT_OPCODE(); @@ -23884,12 +24459,15 @@ static int ZEND_FETCH_DIM_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC); - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), dim, 1, BP_VAR_W TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 1, BP_VAR_W TSRMLS_CC); zval_dtor(free_op2.var); if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -23912,12 +24490,15 @@ static int ZEND_FETCH_DIM_RW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC); - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), dim, 1, BP_VAR_RW TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 1, BP_VAR_RW TSRMLS_CC); zval_dtor(free_op2.var); if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -23933,8 +24514,12 @@ static int ZEND_FETCH_DIM_IS_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op2; zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_IS TSRMLS_CC); - zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_IS TSRMLS_CC), dim, 1, BP_VAR_IS TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address_read(&EX_T(opline->result.u.var), container, dim, 1, BP_VAR_IS TSRMLS_CC); zval_dtor(free_op2.var); ZEND_VM_NEXT_OPCODE(); @@ -23945,12 +24530,16 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container; if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) { - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), dim, 1, BP_VAR_W TSRMLS_CC); + container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 1, BP_VAR_W TSRMLS_CC); if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -23961,7 +24550,11 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (IS_TMP_VAR == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), dim, 1, BP_VAR_R TSRMLS_CC); + container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address_read(&EX_T(opline->result.u.var), container, dim, 1, BP_VAR_R TSRMLS_CC); } zval_dtor(free_op2.var); @@ -23985,11 +24578,13 @@ static int ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SEPARATE_ZVAL_IF_NOT_REF(container); } } - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, dim, 1, BP_VAR_UNSET TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 1, BP_VAR_UNSET TSRMLS_CC); zval_dtor(free_op2.var); if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -24079,8 +24674,9 @@ static int ZEND_FETCH_OBJ_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container; - if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_CV != IS_CV) { + if (IS_CV == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) { 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; } @@ -24088,15 +24684,21 @@ static int ZEND_FETCH_OBJ_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (1) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), property, BP_VAR_W TSRMLS_CC); + container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_W TSRMLS_CC); + } if (1) { zval_ptr_dtor(&property); } else { zval_dtor(free_op2.var); } if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -24119,19 +24721,25 @@ static int ZEND_FETCH_OBJ_RW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC); if (1) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), property, BP_VAR_RW TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_RW TSRMLS_CC); + } if (1) { zval_ptr_dtor(&property); } else { zval_dtor(free_op2.var); } if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -24155,19 +24763,25 @@ static int ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) /* Behave like FETCH_OBJ_W */ zend_free_op free_op1, free_op2; zval *property = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC); if (1) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), property, BP_VAR_W TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_W TSRMLS_CC); + } if (1) { zval_ptr_dtor(&property); } else { zval_dtor(free_op2.var); } if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -24196,15 +24810,20 @@ static int ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (1) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC); + } if (1) { zval_ptr_dtor(&property); } else { zval_dtor(free_op2.var); } if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -24232,6 +24851,9 @@ static int ZEND_ASSIGN_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (1) { MAKE_REAL_ZVAL_PTR(property_name); } + if (IS_CV == IS_VAR && !object_ptr) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC); if (1) { zval_ptr_dtor(&property_name); @@ -24277,6 +24899,9 @@ static int ZEND_ASSIGN_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval *dim = _get_zval_ptr_tmp(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); zval **variable_ptr_ptr; + if (IS_CV == IS_VAR && !object_ptr) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 1, BP_VAR_W TSRMLS_CC); zval_dtor(free_op2.var); @@ -24884,9 +25509,10 @@ static int ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op2; - is_not_identical_function(&EX_T(opline->result.u.var).tmp_var, + is_identical_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + Z_LVAL(EX_T(opline->result.u.var).tmp_var) = !Z_LVAL(EX_T(opline->result.u.var).tmp_var); if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; ZEND_VM_NEXT_OPCODE(); @@ -24897,9 +25523,11 @@ static int ZEND_IS_EQUAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op2; - is_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) == 0)); if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; ZEND_VM_NEXT_OPCODE(); @@ -24910,9 +25538,11 @@ static int ZEND_IS_NOT_EQUAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op2; - is_not_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) != 0)); if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; ZEND_VM_NEXT_OPCODE(); @@ -24923,9 +25553,11 @@ static int ZEND_IS_SMALLER_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op2; - is_smaller_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) < 0)); if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; ZEND_VM_NEXT_OPCODE(); @@ -24936,9 +25568,11 @@ static int ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS zend_op *opline = EX(opline); zend_free_op free_op2; - is_smaller_or_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) <= 0)); if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; ZEND_VM_NEXT_OPCODE(); @@ -25135,8 +25769,12 @@ static int zend_binary_assign_op_helper_SPEC_CV_VAR(int (*binary_op)(zval *resul } else { zend_op *op_data = opline+1; zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC); - zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), container, dim, 0, BP_VAR_RW TSRMLS_CC); value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R); var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC); increment_opline = 1; @@ -25441,13 +26079,18 @@ static int ZEND_FETCH_DIM_R_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op2; zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container; if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_CV != IS_CV && EX_T(opline->op1.u.var).var.ptr_ptr) { PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr); } - zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC); + container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_R TSRMLS_CC); if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; ZEND_VM_NEXT_OPCODE(); @@ -25458,12 +26101,15 @@ static int ZEND_FETCH_DIM_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC); - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), dim, 0, BP_VAR_W TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_W TSRMLS_CC); if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -25486,12 +26132,15 @@ static int ZEND_FETCH_DIM_RW_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC); - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_RW TSRMLS_CC); if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -25507,8 +26156,12 @@ static int ZEND_FETCH_DIM_IS_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op2; zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_IS TSRMLS_CC); - zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_IS TSRMLS_CC), dim, 0, BP_VAR_IS TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address_read(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_IS TSRMLS_CC); if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; ZEND_VM_NEXT_OPCODE(); @@ -25519,12 +26172,16 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container; if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) { - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), dim, 0, BP_VAR_W TSRMLS_CC); + container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_W TSRMLS_CC); if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -25535,7 +26192,11 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (IS_VAR == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC); + container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address_read(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_R TSRMLS_CC); } if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; @@ -25559,11 +26220,13 @@ static int ZEND_FETCH_DIM_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SEPARATE_ZVAL_IF_NOT_REF(container); } } - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_UNSET TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_UNSET TSRMLS_CC); if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -25653,8 +26316,9 @@ static int ZEND_FETCH_OBJ_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container; - if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_CV != IS_CV) { + if (IS_CV == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) { 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; } @@ -25662,15 +26326,21 @@ static int ZEND_FETCH_OBJ_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), property, BP_VAR_W TSRMLS_CC); + container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_W TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; } if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -25693,19 +26363,25 @@ static int ZEND_FETCH_OBJ_RW_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1, free_op2; zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC); if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), property, BP_VAR_RW TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_RW TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; } if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -25729,19 +26405,25 @@ static int ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) /* Behave like FETCH_OBJ_W */ zend_free_op free_op1, free_op2; zval *property = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC); if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), property, BP_VAR_W TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_W TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; } if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -25770,15 +26452,20 @@ static int ZEND_FETCH_OBJ_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; } if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -25806,6 +26493,9 @@ static int ZEND_ASSIGN_OBJ_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (0) { MAKE_REAL_ZVAL_PTR(property_name); } + if (IS_CV == IS_VAR && !object_ptr) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC); if (0) { zval_ptr_dtor(&property_name); @@ -25851,6 +26541,9 @@ static int ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval *dim = _get_zval_ptr_var(&opline->op2, EX(Ts), &free_op2 TSRMLS_CC); zval **variable_ptr_ptr; + if (IS_CV == IS_VAR && !object_ptr) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 0, BP_VAR_W TSRMLS_CC); if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; @@ -25921,6 +26614,10 @@ static int ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } variable_ptr_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC); + if ((IS_VAR == IS_VAR && !value_ptr_ptr) || + (IS_CV == IS_VAR && !variable_ptr_ptr)) { + zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects"); + } zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC); if (!RETURN_VALUE_UNUSED(&opline->result)) { @@ -26511,8 +27208,12 @@ static int zend_binary_assign_op_helper_SPEC_CV_UNUSED(int (*binary_op)(zval *re } else { zend_op *op_data = opline+1; zval *dim = NULL; + zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC); - zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), container, dim, 0, BP_VAR_RW TSRMLS_CC); value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R); var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC); increment_opline = 1; @@ -26631,12 +27332,15 @@ static int ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; zval *dim = NULL; + zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC); - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), dim, 0, BP_VAR_W TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_W TSRMLS_CC); if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -26659,12 +27363,15 @@ static int ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; zval *dim = NULL; + zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC); - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_RW TSRMLS_CC); if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -26680,12 +27387,16 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_AR zend_op *opline = EX(opline); zend_free_op free_op1; zval *dim = NULL; + zval **container; if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) { - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), dim, 0, BP_VAR_W TSRMLS_CC); + container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_W TSRMLS_CC); if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -26696,7 +27407,11 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_AR if (IS_UNUSED == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC); + container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address_read(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_R TSRMLS_CC); } @@ -26736,6 +27451,9 @@ static int ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval *dim = NULL; zval **variable_ptr_ptr; + if (IS_CV == IS_VAR && !object_ptr) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 0, BP_VAR_W TSRMLS_CC); value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R); @@ -26973,9 +27691,10 @@ static int ZEND_IS_NOT_IDENTICAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); - is_not_identical_function(&EX_T(opline->result.u.var).tmp_var, + is_identical_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC); + Z_LVAL(EX_T(opline->result.u.var).tmp_var) = !Z_LVAL(EX_T(opline->result.u.var).tmp_var); ZEND_VM_NEXT_OPCODE(); @@ -26986,9 +27705,11 @@ static int ZEND_IS_EQUAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); - is_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) == 0)); ZEND_VM_NEXT_OPCODE(); @@ -26999,9 +27720,11 @@ static int ZEND_IS_NOT_EQUAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); - is_not_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) != 0)); ZEND_VM_NEXT_OPCODE(); @@ -27012,9 +27735,11 @@ static int ZEND_IS_SMALLER_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); - is_smaller_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) < 0)); ZEND_VM_NEXT_OPCODE(); @@ -27025,9 +27750,11 @@ static int ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); - is_smaller_or_equal_function(&EX_T(opline->result.u.var).tmp_var, + compare_function(&EX_T(opline->result.u.var).tmp_var, _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC) TSRMLS_CC); + ZVAL_BOOL(&EX_T(opline->result.u.var).tmp_var, + (Z_LVAL(EX_T(opline->result.u.var).tmp_var) <= 0)); ZEND_VM_NEXT_OPCODE(); @@ -27224,8 +27951,12 @@ static int zend_binary_assign_op_helper_SPEC_CV_CV(int (*binary_op)(zval *result } else { zend_op *op_data = opline+1; zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC); - zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), container, dim, 0, BP_VAR_RW TSRMLS_CC); value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R); var_ptr = _get_zval_ptr_ptr_var(&op_data->op2, EX(Ts), &free_op_data2 TSRMLS_CC); increment_opline = 1; @@ -27529,13 +28260,18 @@ static int ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC); + zval **container; if (opline->extended_value == ZEND_FETCH_ADD_LOCK && IS_CV != IS_CV && EX_T(opline->op1.u.var).var.ptr_ptr) { PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr); } - zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC); + container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_R TSRMLS_CC); ZEND_VM_NEXT_OPCODE(); @@ -27546,12 +28282,15 @@ static int ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC); - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), dim, 0, BP_VAR_W TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_W TSRMLS_CC); if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -27574,12 +28313,15 @@ static int ZEND_FETCH_DIM_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC); - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), dim, 0, BP_VAR_RW TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_RW TSRMLS_CC); if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -27595,8 +28337,12 @@ static int ZEND_FETCH_DIM_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_IS TSRMLS_CC); - zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_IS TSRMLS_CC), dim, 0, BP_VAR_IS TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address_read(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_IS TSRMLS_CC); ZEND_VM_NEXT_OPCODE(); @@ -27607,12 +28353,16 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC); + zval **container; if (ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->extended_value)) { - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), dim, 0, BP_VAR_W TSRMLS_CC); + container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_W TSRMLS_CC); if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -27623,7 +28373,11 @@ static int ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (IS_CV == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - zend_fetch_dimension_address_read(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC), dim, 0, BP_VAR_R TSRMLS_CC); + container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address_read(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_R TSRMLS_CC); } @@ -27647,11 +28401,13 @@ static int ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SEPARATE_ZVAL_IF_NOT_REF(container); } } - zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_UNSET TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } + zend_fetch_dimension_address(&EX_T(opline->result.u.var), container, dim, 0, BP_VAR_UNSET TSRMLS_CC); if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -27741,8 +28497,9 @@ static int ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC); + zval **container; - if ((opline->extended_value & ZEND_FETCH_ADD_LOCK) && IS_CV != IS_CV) { + if (IS_CV == IS_VAR && (opline->extended_value & ZEND_FETCH_ADD_LOCK)) { 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; } @@ -27750,15 +28507,21 @@ static int ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), property, BP_VAR_W TSRMLS_CC); + container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_W TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { } if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -27781,19 +28544,25 @@ static int ZEND_FETCH_OBJ_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_op *opline = EX(opline); zend_free_op free_op1; zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC); if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_RW TSRMLS_CC), property, BP_VAR_RW TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_RW TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { } if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -27817,19 +28586,25 @@ static int ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) /* Behave like FETCH_OBJ_W */ zend_free_op free_op1; zval *property = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC); + zval **container = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC); if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC), property, BP_VAR_W TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_W TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { } if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -27858,15 +28633,20 @@ static int ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (0) { MAKE_REAL_ZVAL_PTR(property); } - zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC); + if (IS_CV == IS_VAR && !container) { + zend_error(E_WARNING, "Cannot use string offset as an array"); + EX_T(opline->result.u.var).var.ptr_ptr = &EG(error_zval_ptr); + PZVAL_LOCK(EG(error_zval_ptr)); + } else { + zend_fetch_property_address(&EX_T(opline->result.u.var), container, property, BP_VAR_UNSET TSRMLS_CC); + } if (0) { zval_ptr_dtor(&property); } else { } if (IS_CV == IS_VAR && 0 && - READY_TO_DESTROY(free_op1.var) && - !RETURN_VALUE_UNUSED(&opline->result)) { + READY_TO_DESTROY(free_op1.var)) { AI_USE_PTR(EX_T(opline->result.u.var).var); if (!PZVAL_IS_REF(*EX_T(opline->result.u.var).var.ptr_ptr) && Z_REFCOUNT_PP(EX_T(opline->result.u.var).var.ptr_ptr) > 2) { @@ -27894,6 +28674,9 @@ static int ZEND_ASSIGN_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (0) { MAKE_REAL_ZVAL_PTR(property_name); } + if (IS_CV == IS_VAR && !object_ptr) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } zend_assign_to_object(&opline->result, object_ptr, property_name, &op_data->op1, EX(Ts), ZEND_ASSIGN_OBJ TSRMLS_CC); if (0) { zval_ptr_dtor(&property_name); @@ -27939,6 +28722,9 @@ static int ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval *dim = _get_zval_ptr_cv(&opline->op2, EX(Ts), BP_VAR_R TSRMLS_CC); zval **variable_ptr_ptr; + if (IS_CV == IS_VAR && !object_ptr) { + zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); + } zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), object_ptr, dim, 0, BP_VAR_W TSRMLS_CC); value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, BP_VAR_R); @@ -28007,6 +28793,10 @@ static int ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } variable_ptr_ptr = _get_zval_ptr_ptr_cv(&opline->op1, EX(Ts), BP_VAR_W TSRMLS_CC); + if ((IS_CV == IS_VAR && !value_ptr_ptr) || + (IS_CV == IS_VAR && !variable_ptr_ptr)) { + zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects"); + } zend_assign_to_variable_reference(variable_ptr_ptr, value_ptr_ptr TSRMLS_CC); if (!RETURN_VALUE_UNUSED(&opline->result)) { |
