diff options
Diffstat (limited to 'Zend/zend_vm_execute.h')
| -rw-r--r-- | Zend/zend_vm_execute.h | 2145 |
1 files changed, 1019 insertions, 1126 deletions
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index f1ab7e85c4..d575db0018 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -736,7 +736,7 @@ send_again: zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, zend_hash_num_elements(ht) TSRMLS_CC); if (opline->op1_type != IS_CONST && opline->op1_type != IS_TMP_VAR && Z_IMMUTABLE_P(args)) { - int i; + uint32_t i; int separate = 0; /* check if any of arguments are going to be passed by reference */ @@ -1111,6 +1111,7 @@ static int ZEND_FASTCALL ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_AR ZVAL_LONG(EX_VAR(opline->result.var), EG(error_reporting)); if (Z_TYPE(EX(old_error_reporting)) == IS_UNDEF) { ZVAL_LONG(&EX(old_error_reporting), EG(error_reporting)); + EX(old_error_reporting).u2.silence_num = opline->op2.num; } if (EG(error_reporting)) { @@ -1131,15 +1132,10 @@ static int ZEND_FASTCALL ZEND_BEGIN_SILENCE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_AR } if (EXPECTED(zend_hash_str_add_ptr(EG(modified_ini_directives), "error_reporting", sizeof("error_reporting")-1, EG(error_reporting_ini_entry)) != NULL)) { EG(error_reporting_ini_entry)->orig_value = EG(error_reporting_ini_entry)->value; - EG(error_reporting_ini_entry)->orig_value_length = EG(error_reporting_ini_entry)->value_length; EG(error_reporting_ini_entry)->orig_modifiable = EG(error_reporting_ini_entry)->modifiable; EG(error_reporting_ini_entry)->modified = 1; } - } else if (EG(error_reporting_ini_entry)->value != EG(error_reporting_ini_entry)->orig_value) { - efree(EG(error_reporting_ini_entry)->value); } - EG(error_reporting_ini_entry)->value = estrndup("0", sizeof("0")-1); - EG(error_reporting_ini_entry)->value_length = sizeof("0")-1; } while (0); } CHECK_EXCEPTION(); @@ -1366,15 +1362,7 @@ static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER /* restore previous error_reporting value */ if (!EG(error_reporting) && Z_TYPE(EX(old_error_reporting)) != IS_UNDEF && Z_LVAL(EX(old_error_reporting)) != 0) { - zval restored_error_reporting; - zend_string *key; - - ZVAL_LONG(&restored_error_reporting, Z_LVAL(EX(old_error_reporting))); - convert_to_string(&restored_error_reporting); - key = zend_string_init("error_reporting", sizeof("error_reporting")-1, 0); - zend_alter_ini_entry_ex(key, Z_STRVAL(restored_error_reporting), Z_STRLEN(restored_error_reporting), ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME, 1 TSRMLS_CC); - zend_string_free(key); - zval_dtor(&restored_error_reporting); + EG(error_reporting) = Z_LVAL(EX(old_error_reporting)); } ZVAL_UNDEF(&EX(old_error_reporting)); @@ -2665,7 +2653,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CONST_HANDLER(ZEND_OPCODE_HAND retval_ptr = NULL; - if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_STR_OFFSET)) { + if (IS_CONST == IS_VAR && UNEXPECTED(retval_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference"); } @@ -2972,9 +2960,9 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HA zend_file_handle file_handle; char *resolved_path; - resolved_path = zend_resolve_path(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename) TSRMLS_CC); + resolved_path = zend_resolve_path(Z_STRVAL_P(inc_filename), (int)Z_STRLEN_P(inc_filename) TSRMLS_CC); if (resolved_path) { - failure_retval = zend_hash_str_exists(&EG(included_files), resolved_path, strlen(resolved_path)); + failure_retval = zend_hash_str_exists(&EG(included_files), resolved_path, (int)strlen(resolved_path)); } else { resolved_path = Z_STRVAL_P(inc_filename); } @@ -2987,7 +2975,7 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HA file_handle.opened_path = estrdup(resolved_path); } - if (zend_hash_str_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path))) { + if (zend_hash_str_add_empty_element(&EG(included_files), file_handle.opened_path, (int)strlen(file_handle.opened_path))) { new_op_array = zend_compile_file(&file_handle, (opline->extended_value==ZEND_INCLUDE_ONCE?ZEND_INCLUDE:ZEND_REQUIRE) TSRMLS_CC); zend_destroy_file_handle(&file_handle TSRMLS_CC); } else { @@ -3082,17 +3070,15 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A ZVAL_DEREF(array_ptr); if (Z_TYPE_P(array_ptr) == IS_ARRAY) { if (!Z_ISREF_P(array_ref)) { - SEPARATE_ZVAL_NOREF(array_ptr); + SEPARATE_ARRAY(array_ptr); array_ref = array_ptr; if (opline->extended_value & ZEND_FE_FETCH_BYREF) { ZVAL_NEW_REF(array_ptr, array_ptr); array_ref = array_ptr; array_ptr = Z_REFVAL_P(array_ptr); } - } else if (Z_IMMUTABLE_P(array_ptr)) { + } else if (Z_IMMUTABLE_P(array_ptr) || Z_REFCOUNT_P(array_ptr) > 1) { zval_copy_ctor(array_ptr); - } else { - SEPARATE_ZVAL_NOREF(array_ptr); } if (Z_REFCOUNTED_P(array_ref)) Z_ADDREF_P(array_ref); } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) { @@ -3103,9 +3089,6 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A ce = Z_OBJCE_P(array_ptr); if (!ce || ce->get_iterator == NULL) { - if (!Z_ISREF_P(array_ref)) { - SEPARATE_ZVAL_NOREF(array_ptr); - } Z_ADDREF_P(array_ptr); } array_ref = array_ptr; @@ -3218,25 +3201,37 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A } iter->index = -1; /* will be set to 0 before using next handler */ } else if ((fe_ht = HASH_OF(array_ptr)) != NULL) { - zend_hash_internal_pointer_reset(fe_ht); - if (ce) { - zend_object *zobj = Z_OBJ_P(array_ptr); - while (zend_hash_has_more_elements(fe_ht) == SUCCESS) { - zend_string *str_key; - zend_ulong int_key; - zend_uchar key_type; - - key_type = zend_hash_get_current_key(fe_ht, &str_key, &int_key, 0); - if (key_type != HASH_KEY_NON_EXISTENT && - (key_type == HASH_KEY_IS_LONG || - zend_check_property_access(zobj, str_key TSRMLS_CC) == SUCCESS)) { - break; + HashPointer *ptr = (HashPointer*)EX_VAR((opline+2)->op1.var); + HashPosition pos = 0; + Bucket *p; + + while (1) { + if (pos >= fe_ht->nNumUsed) { + is_empty = 1; + if (IS_CONST == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { + } - zend_hash_move_forward(fe_ht); + ZEND_VM_JMP(opline->op2.jmp_addr); + } + p = fe_ht->arData + pos; + if (Z_TYPE(p->val) == IS_UNDEF || + (Z_TYPE(p->val) == IS_INDIRECT && + Z_TYPE_P(Z_INDIRECT(p->val)) == IS_UNDEF)) { + pos++; + continue; } + if (!ce || + !p->key || + zend_check_property_access(Z_OBJ_P(array_ptr), p->key TSRMLS_CC) == SUCCESS) { + break; + } + pos++; } - is_empty = zend_hash_has_more_elements(fe_ht) != SUCCESS; - zend_hash_get_pointer(fe_ht, (HashPointer*)EX_VAR((opline+2)->op1.var)); + fe_ht->nInternalPointer = pos; + ptr->pos = pos; + ptr->ht = fe_ht; + ptr->h = fe_ht->arData[pos].h; + is_empty = 0; } else { zend_error(E_WARNING, "Invalid argument supplied for foreach()"); is_empty = 1; @@ -3280,10 +3275,15 @@ static int ZEND_FASTCALL ZEND_JMP_SET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR USE_OPLINE zval *value; + int is_ref = 0; SAVE_OPLINE(); value = opline->op1.zv; + if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && Z_ISREF_P(value)) { + is_ref = 1; + value = Z_REFVAL_P(value); + } if (i_zend_is_true(value TSRMLS_CC)) { ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); if (IS_CONST == IS_CONST) { @@ -3292,6 +3292,9 @@ static int ZEND_FASTCALL ZEND_JMP_SET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR } } else if (IS_CONST == IS_CV) { if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); + } else if (IS_CONST == IS_VAR && is_ref) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); + } ZEND_VM_JMP(opline->op2.jmp_addr); } @@ -3300,7 +3303,7 @@ static int ZEND_FASTCALL ZEND_JMP_SET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR ZEND_VM_NEXT_OPCODE(); } -static int ZEND_FASTCALL ZEND_JMP_SET_VAR_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static int ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -3309,7 +3312,10 @@ static int ZEND_FASTCALL ZEND_JMP_SET_VAR_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLE SAVE_OPLINE(); value = opline->op1.zv; - if (i_zend_is_true(value TSRMLS_CC)) { + if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && Z_ISREF_P(value)) { + ZVAL_COPY(EX_VAR(opline->result.var), Z_REFVAL_P(value)); + + } else { ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); if (IS_CONST == IS_CONST) { if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { @@ -3318,49 +3324,6 @@ static int ZEND_FASTCALL ZEND_JMP_SET_VAR_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLE } else if (IS_CONST == IS_CV) { if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } - ZEND_VM_JMP(opline->op2.jmp_addr); - } - - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); -} - -static int ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *value; - - SAVE_OPLINE(); - value = opline->op1.zv; - - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); - if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { - zval_copy_ctor_func(EX_VAR(opline->result.var)); - } - } else if (IS_CONST == IS_CV) { - if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); - } - ZEND_VM_NEXT_OPCODE(); -} - -static int ZEND_FASTCALL ZEND_QM_ASSIGN_VAR_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *value; - - SAVE_OPLINE(); - value = opline->op1.zv; - - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); - if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { - zval_copy_ctor_func(EX_VAR(opline->result.var)); - } - } else if (IS_CONST == IS_CV) { - if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } ZEND_VM_NEXT_OPCODE(); } @@ -3803,8 +3766,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_CONST(int type zend_error(E_NOTICE,"Undefined variable: %s", name->val); /* break missing intentionally */ case BP_VAR_IS: - retval = EX_VAR(opline->result.var); - ZVAL_NULL(retval); + retval = &EG(uninitialized_zval); break; case BP_VAR_RW: zend_error(E_NOTICE,"Undefined variable: %s", name->val); @@ -3824,8 +3786,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_CONST(int type zend_error(E_NOTICE,"Undefined variable: %s", name->val); /* break missing intentionally */ case BP_VAR_IS: - retval = EX_VAR(opline->result.var); - ZVAL_NULL(retval); + retval = &EG(uninitialized_zval); break; case BP_VAR_RW: zend_error(E_NOTICE,"Undefined variable: %s", name->val); @@ -4054,7 +4015,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CONST_HANDLER(ZEND_ if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); } - if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); @@ -4350,8 +4311,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCO ZVAL_DUP(EX_VAR(opline->result.var), value); } else if (Z_STRLEN_P(opline->op2.zv) == sizeof("class")-1 && memcmp(Z_STRVAL_P(opline->op2.zv), "class", sizeof("class") - 1) == 0) { /* "class" is assigned as a case-sensitive keyword from zend_do_resolve_class_name */ - ZVAL_STR(EX_VAR(opline->result.var), ce->name); - zend_string_addref(ce->name); + ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name); } else { zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(opline->op2.zv)); } @@ -4371,7 +4331,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER(ZEND_O if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { expr_ptr = NULL; - if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { + if (IS_CONST == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } ZVAL_MAKE_REF(expr_ptr); @@ -4725,7 +4685,7 @@ num_index_prop: } } if (Z_TYPE_P(offset) == IS_LONG) { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) { + if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) { if ((opline->extended_value & ZEND_ISSET) || Z_STRVAL_P(container)[offset->value.lval] != '0') { result = 1; @@ -4850,7 +4810,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLE } else { zval *value_ptr = NULL; - if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { + if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); } @@ -5384,7 +5344,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMP_HANDLER(ZEND_OP if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); } - if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); @@ -5584,7 +5544,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP_HANDLER(ZEND_OPC if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { expr_ptr = NULL; - if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { + if (IS_CONST == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } ZVAL_MAKE_REF(expr_ptr); @@ -5786,7 +5746,7 @@ num_index_prop: } } if (Z_TYPE_P(offset) == IS_LONG) { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) { + if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) { if ((opline->extended_value & ZEND_ISSET) || Z_STRVAL_P(container)[offset->value.lval] != '0') { result = 1; @@ -5880,7 +5840,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ } else { zval *value_ptr = NULL; - if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { + if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); } @@ -6314,8 +6274,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_VAR(int type, zend_error(E_NOTICE,"Undefined variable: %s", name->val); /* break missing intentionally */ case BP_VAR_IS: - retval = EX_VAR(opline->result.var); - ZVAL_NULL(retval); + retval = &EG(uninitialized_zval); break; case BP_VAR_RW: zend_error(E_NOTICE,"Undefined variable: %s", name->val); @@ -6335,8 +6294,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_VAR(int type, zend_error(E_NOTICE,"Undefined variable: %s", name->val); /* break missing intentionally */ case BP_VAR_IS: - retval = EX_VAR(opline->result.var); - ZVAL_NULL(retval); + retval = &EG(uninitialized_zval); break; case BP_VAR_RW: zend_error(E_NOTICE,"Undefined variable: %s", name->val); @@ -6567,7 +6525,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_VAR_HANDLER(ZEND_OP if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); } - if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); @@ -6767,7 +6725,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_VAR_HANDLER(ZEND_OPC if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { expr_ptr = NULL; - if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { + if (IS_CONST == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } ZVAL_MAKE_REF(expr_ptr); @@ -7121,7 +7079,7 @@ num_index_prop: } } if (Z_TYPE_P(offset) == IS_LONG) { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) { + if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) { if ((opline->extended_value & ZEND_ISSET) || Z_STRVAL_P(container)[offset->value.lval] != '0') { result = 1; @@ -7215,7 +7173,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ } else { zval *value_ptr = NULL; - if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { + if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); } @@ -7374,8 +7332,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_UNUSED(int typ zend_error(E_NOTICE,"Undefined variable: %s", name->val); /* break missing intentionally */ case BP_VAR_IS: - retval = EX_VAR(opline->result.var); - ZVAL_NULL(retval); + retval = &EG(uninitialized_zval); break; case BP_VAR_RW: zend_error(E_NOTICE,"Undefined variable: %s", name->val); @@ -7395,8 +7352,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_UNUSED(int typ zend_error(E_NOTICE,"Undefined variable: %s", name->val); /* break missing intentionally */ case BP_VAR_IS: - retval = EX_VAR(opline->result.var); - ZVAL_NULL(retval); + retval = &EG(uninitialized_zval); break; case BP_VAR_RW: zend_error(E_NOTICE,"Undefined variable: %s", name->val); @@ -7634,7 +7590,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER(ZEND_ if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { expr_ptr = NULL; - if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { + if (IS_CONST == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } ZVAL_MAKE_REF(expr_ptr); @@ -7960,7 +7916,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDL } else { zval *value_ptr = NULL; - if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { + if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); } @@ -8477,7 +8433,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CV_HANDLER(ZEND_OPC if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); } - if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); @@ -8728,7 +8684,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER(ZEND_OPCO if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { expr_ptr = NULL; - if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { + if (IS_CONST == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } ZVAL_MAKE_REF(expr_ptr); @@ -8930,7 +8886,7 @@ num_index_prop: } } if (Z_TYPE_P(offset) == IS_LONG) { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) { + if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) { if ((opline->extended_value & ZEND_ISSET) || Z_STRVAL_P(container)[offset->value.lval] != '0') { result = 1; @@ -9022,7 +8978,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_A } else { zval *value_ptr = NULL; - if (IS_CONST == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { + if (IS_CONST == IS_VAR && UNEXPECTED(value_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); } @@ -9415,7 +9371,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLE retval_ptr = NULL; - if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_STR_OFFSET)) { + if (IS_TMP_VAR == IS_VAR && UNEXPECTED(retval_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference"); } @@ -9724,9 +9680,9 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HAND zend_file_handle file_handle; char *resolved_path; - resolved_path = zend_resolve_path(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename) TSRMLS_CC); + resolved_path = zend_resolve_path(Z_STRVAL_P(inc_filename), (int)Z_STRLEN_P(inc_filename) TSRMLS_CC); if (resolved_path) { - failure_retval = zend_hash_str_exists(&EG(included_files), resolved_path, strlen(resolved_path)); + failure_retval = zend_hash_str_exists(&EG(included_files), resolved_path, (int)strlen(resolved_path)); } else { resolved_path = Z_STRVAL_P(inc_filename); } @@ -9739,7 +9695,7 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HAND file_handle.opened_path = estrdup(resolved_path); } - if (zend_hash_str_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path))) { + if (zend_hash_str_add_empty_element(&EG(included_files), file_handle.opened_path, (int)strlen(file_handle.opened_path))) { new_op_array = zend_compile_file(&file_handle, (opline->extended_value==ZEND_INCLUDE_ONCE?ZEND_INCLUDE:ZEND_REQUIRE) TSRMLS_CC); zend_destroy_file_handle(&file_handle TSRMLS_CC); } else { @@ -9834,17 +9790,15 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG ZVAL_DEREF(array_ptr); if (Z_TYPE_P(array_ptr) == IS_ARRAY) { if (!Z_ISREF_P(array_ref)) { - SEPARATE_ZVAL_NOREF(array_ptr); + SEPARATE_ARRAY(array_ptr); array_ref = array_ptr; if (opline->extended_value & ZEND_FE_FETCH_BYREF) { ZVAL_NEW_REF(array_ptr, array_ptr); array_ref = array_ptr; array_ptr = Z_REFVAL_P(array_ptr); } - } else if (Z_IMMUTABLE_P(array_ptr)) { + } else if (Z_IMMUTABLE_P(array_ptr) || Z_REFCOUNT_P(array_ptr) > 1) { zval_copy_ctor(array_ptr); - } else { - SEPARATE_ZVAL_NOREF(array_ptr); } if (Z_REFCOUNTED_P(array_ref)) Z_ADDREF_P(array_ref); } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) { @@ -9855,9 +9809,6 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG ce = Z_OBJCE_P(array_ptr); if (!ce || ce->get_iterator == NULL) { - if (!Z_ISREF_P(array_ref)) { - SEPARATE_ZVAL_NOREF(array_ptr); - } Z_ADDREF_P(array_ptr); } array_ref = array_ptr; @@ -9970,25 +9921,37 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG } iter->index = -1; /* will be set to 0 before using next handler */ } else if ((fe_ht = HASH_OF(array_ptr)) != NULL) { - zend_hash_internal_pointer_reset(fe_ht); - if (ce) { - zend_object *zobj = Z_OBJ_P(array_ptr); - while (zend_hash_has_more_elements(fe_ht) == SUCCESS) { - zend_string *str_key; - zend_ulong int_key; - zend_uchar key_type; - - key_type = zend_hash_get_current_key(fe_ht, &str_key, &int_key, 0); - if (key_type != HASH_KEY_NON_EXISTENT && - (key_type == HASH_KEY_IS_LONG || - zend_check_property_access(zobj, str_key TSRMLS_CC) == SUCCESS)) { - break; + HashPointer *ptr = (HashPointer*)EX_VAR((opline+2)->op1.var); + HashPosition pos = 0; + Bucket *p; + + while (1) { + if (pos >= fe_ht->nNumUsed) { + is_empty = 1; + if (IS_TMP_VAR == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { + } - zend_hash_move_forward(fe_ht); + ZEND_VM_JMP(opline->op2.jmp_addr); + } + p = fe_ht->arData + pos; + if (Z_TYPE(p->val) == IS_UNDEF || + (Z_TYPE(p->val) == IS_INDIRECT && + Z_TYPE_P(Z_INDIRECT(p->val)) == IS_UNDEF)) { + pos++; + continue; + } + if (!ce || + !p->key || + zend_check_property_access(Z_OBJ_P(array_ptr), p->key TSRMLS_CC) == SUCCESS) { + break; } + pos++; } - is_empty = zend_hash_has_more_elements(fe_ht) != SUCCESS; - zend_hash_get_pointer(fe_ht, (HashPointer*)EX_VAR((opline+2)->op1.var)); + fe_ht->nInternalPointer = pos; + ptr->pos = pos; + ptr->ht = fe_ht; + ptr->h = fe_ht->arData[pos].h; + is_empty = 0; } else { zend_error(E_WARNING, "Invalid argument supplied for foreach()"); is_empty = 1; @@ -10030,26 +9993,15 @@ static int ZEND_FASTCALL ZEND_EXIT_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) static int ZEND_FASTCALL ZEND_END_SILENCE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - char buf[MAX_LENGTH_OF_LONG + 1]; - char *res; SAVE_OPLINE(); if (!EG(error_reporting) && Z_LVAL_P(EX_VAR(opline->op1.var)) != 0) { EG(error_reporting) = Z_LVAL_P(EX_VAR(opline->op1.var)); - _zend_print_signed_to_buf(buf + sizeof(buf) - 1, EG(error_reporting), zend_ulong, res); - if (EXPECTED(EG(error_reporting_ini_entry) != NULL)) { - if (EXPECTED(EG(error_reporting_ini_entry)->modified && - EG(error_reporting_ini_entry)->value != EG(error_reporting_ini_entry)->orig_value)) { - efree(EG(error_reporting_ini_entry)->value); - } - EG(error_reporting_ini_entry)->value_length = buf + sizeof(buf) - 1 - res; - EG(error_reporting_ini_entry)->value = estrndup(res, EG(error_reporting_ini_entry)->value_length); - } } -//??? if (EX(old_error_reporting) == EX_VAR(opline->op1.var)) { -//??? EX(old_error_reporting) = NULL; -//??? } - CHECK_EXCEPTION(); + if (Z_TYPE(EX(old_error_reporting)) != IS_UNDEF && + EX(old_error_reporting).u2.silence_num == opline->op2.num) { + ZVAL_UNDEF(&EX(old_error_reporting)); + } ZEND_VM_NEXT_OPCODE(); } @@ -10058,10 +10010,15 @@ static int ZEND_FASTCALL ZEND_JMP_SET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS USE_OPLINE zend_free_op free_op1; zval *value; + int is_ref = 0; SAVE_OPLINE(); value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && Z_ISREF_P(value)) { + is_ref = 1; + value = Z_REFVAL_P(value); + } if (i_zend_is_true(value TSRMLS_CC)) { ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); if (IS_TMP_VAR == IS_CONST) { @@ -10070,6 +10027,9 @@ static int ZEND_FASTCALL ZEND_JMP_SET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS } } else if (IS_TMP_VAR == IS_CV) { if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); + } else if (IS_TMP_VAR == IS_VAR && is_ref) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); + zval_dtor(free_op1.var); } ZEND_VM_JMP(opline->op2.jmp_addr); } @@ -10079,7 +10039,7 @@ static int ZEND_FASTCALL ZEND_JMP_SET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS ZEND_VM_NEXT_OPCODE(); } -static int ZEND_FASTCALL ZEND_JMP_SET_VAR_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static int ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zend_free_op free_op1; @@ -10088,7 +10048,10 @@ static int ZEND_FASTCALL ZEND_JMP_SET_VAR_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ SAVE_OPLINE(); value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (i_zend_is_true(value TSRMLS_CC)) { + if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && Z_ISREF_P(value)) { + ZVAL_COPY(EX_VAR(opline->result.var), Z_REFVAL_P(value)); + zval_dtor(free_op1.var); + } else { ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); if (IS_TMP_VAR == IS_CONST) { if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { @@ -10097,50 +10060,6 @@ static int ZEND_FASTCALL ZEND_JMP_SET_VAR_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ } else if (IS_TMP_VAR == IS_CV) { if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } - ZEND_VM_JMP(opline->op2.jmp_addr); - } - - zval_dtor(free_op1.var); - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); -} - -static int ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *value; - - SAVE_OPLINE(); - value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); - if (IS_TMP_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { - zval_copy_ctor_func(EX_VAR(opline->result.var)); - } - } else if (IS_TMP_VAR == IS_CV) { - if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); - } - ZEND_VM_NEXT_OPCODE(); -} - -static int ZEND_FASTCALL ZEND_QM_ASSIGN_VAR_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *value; - - SAVE_OPLINE(); - value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); - if (IS_TMP_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { - zval_copy_ctor_func(EX_VAR(opline->result.var)); - } - } else if (IS_TMP_VAR == IS_CV) { - if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } ZEND_VM_NEXT_OPCODE(); } @@ -10586,8 +10505,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_CONST(int type, zend_error(E_NOTICE,"Undefined variable: %s", name->val); /* break missing intentionally */ case BP_VAR_IS: - retval = EX_VAR(opline->result.var); - ZVAL_NULL(retval); + retval = &EG(uninitialized_zval); break; case BP_VAR_RW: zend_error(E_NOTICE,"Undefined variable: %s", name->val); @@ -10607,8 +10525,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_CONST(int type, zend_error(E_NOTICE,"Undefined variable: %s", name->val); /* break missing intentionally */ case BP_VAR_IS: - retval = EX_VAR(opline->result.var); - ZVAL_NULL(retval); + retval = &EG(uninitialized_zval); break; case BP_VAR_RW: zend_error(E_NOTICE,"Undefined variable: %s", name->val); @@ -10837,7 +10754,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OP if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); } - if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); @@ -11008,7 +10925,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPC if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { expr_ptr = NULL; - if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { + if (IS_TMP_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } ZVAL_MAKE_REF(expr_ptr); @@ -11362,7 +11279,7 @@ num_index_prop: } } if (Z_TYPE_P(offset) == IS_LONG) { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) { + if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) { if ((opline->extended_value & ZEND_ISSET) || Z_STRVAL_P(container)[offset->value.lval] != '0') { result = 1; @@ -11454,7 +11371,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ } else { zval *value_ptr = NULL; - if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { + if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); } @@ -11988,7 +11905,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMP_HANDLER(ZEND_OPCO if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); } - if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); @@ -12145,7 +12062,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_HANDLER(ZEND_OPCOD if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { expr_ptr = NULL; - if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { + if (IS_TMP_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } ZVAL_MAKE_REF(expr_ptr); @@ -12347,7 +12264,7 @@ num_index_prop: } } if (Z_TYPE_P(offset) == IS_LONG) { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) { + if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) { if ((opline->extended_value & ZEND_ISSET) || Z_STRVAL_P(container)[offset->value.lval] != '0') { result = 1; @@ -12441,7 +12358,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR } else { zval *value_ptr = NULL; - if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { + if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); } @@ -12875,8 +12792,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_VAR(int type, ZE zend_error(E_NOTICE,"Undefined variable: %s", name->val); /* break missing intentionally */ case BP_VAR_IS: - retval = EX_VAR(opline->result.var); - ZVAL_NULL(retval); + retval = &EG(uninitialized_zval); break; case BP_VAR_RW: zend_error(E_NOTICE,"Undefined variable: %s", name->val); @@ -12896,8 +12812,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_VAR(int type, ZE zend_error(E_NOTICE,"Undefined variable: %s", name->val); /* break missing intentionally */ case BP_VAR_IS: - retval = EX_VAR(opline->result.var); - ZVAL_NULL(retval); + retval = &EG(uninitialized_zval); break; case BP_VAR_RW: zend_error(E_NOTICE,"Undefined variable: %s", name->val); @@ -13128,7 +13043,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_VAR_HANDLER(ZEND_OPCO if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); } - if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); @@ -13285,7 +13200,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_VAR_HANDLER(ZEND_OPCOD if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { expr_ptr = NULL; - if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { + if (IS_TMP_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } ZVAL_MAKE_REF(expr_ptr); @@ -13639,7 +13554,7 @@ num_index_prop: } } if (Z_TYPE_P(offset) == IS_LONG) { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) { + if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) { if ((opline->extended_value & ZEND_ISSET) || Z_STRVAL_P(container)[offset->value.lval] != '0') { result = 1; @@ -13733,7 +13648,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR } else { zval *value_ptr = NULL; - if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { + if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); } @@ -13892,8 +13807,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_UNUSED(int type, zend_error(E_NOTICE,"Undefined variable: %s", name->val); /* break missing intentionally */ case BP_VAR_IS: - retval = EX_VAR(opline->result.var); - ZVAL_NULL(retval); + retval = &EG(uninitialized_zval); break; case BP_VAR_RW: zend_error(E_NOTICE,"Undefined variable: %s", name->val); @@ -13913,8 +13827,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_UNUSED(int type, zend_error(E_NOTICE,"Undefined variable: %s", name->val); /* break missing intentionally */ case BP_VAR_IS: - retval = EX_VAR(opline->result.var); - ZVAL_NULL(retval); + retval = &EG(uninitialized_zval); break; case BP_VAR_RW: zend_error(E_NOTICE,"Undefined variable: %s", name->val); @@ -14036,7 +13949,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OP if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { expr_ptr = NULL; - if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { + if (IS_TMP_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } ZVAL_MAKE_REF(expr_ptr); @@ -14337,7 +14250,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER } else { zval *value_ptr = NULL; - if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { + if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); } @@ -14854,7 +14767,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV_HANDLER(ZEND_OPCOD if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); } - if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); @@ -15008,7 +14921,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { expr_ptr = NULL; - if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { + if (IS_TMP_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } ZVAL_MAKE_REF(expr_ptr); @@ -15210,7 +15123,7 @@ num_index_prop: } } if (Z_TYPE_P(offset) == IS_LONG) { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) { + if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) { if ((opline->extended_value & ZEND_ISSET) || Z_STRVAL_P(container)[offset->value.lval] != '0') { result = 1; @@ -15302,7 +15215,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG } else { zval *value_ptr = NULL; - if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { + if (IS_TMP_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); } @@ -15442,6 +15355,10 @@ static int ZEND_FASTCALL ZEND_PRE_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) { + zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); + } + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { fast_increment_function(var_ptr); if (RETURN_VALUE_USED(opline)) { @@ -15450,9 +15367,6 @@ static int ZEND_FASTCALL ZEND_PRE_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS ZEND_VM_NEXT_OPCODE(); } - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { - zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); - } if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { if (RETURN_VALUE_USED(opline)) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -15497,6 +15411,10 @@ static int ZEND_FASTCALL ZEND_PRE_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) { + zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); + } + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { fast_decrement_function(var_ptr); if (RETURN_VALUE_USED(opline)) { @@ -15505,9 +15423,6 @@ static int ZEND_FASTCALL ZEND_PRE_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS ZEND_VM_NEXT_OPCODE(); } - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { - zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); - } if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { if (RETURN_VALUE_USED(opline)) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -15552,15 +15467,16 @@ static int ZEND_FASTCALL ZEND_POST_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG SAVE_OPLINE(); var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) { + zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); + } + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); fast_increment_function(var_ptr); ZEND_VM_NEXT_OPCODE(); } - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { - zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); - } if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { ZVAL_NULL(EX_VAR(opline->result.var)); if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; @@ -15606,15 +15522,16 @@ static int ZEND_FASTCALL ZEND_POST_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG SAVE_OPLINE(); var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) { + zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); + } + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); fast_decrement_function(var_ptr); ZEND_VM_NEXT_OPCODE(); } - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { - zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); - } if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { ZVAL_NULL(EX_VAR(opline->result.var)); if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; @@ -15913,7 +15830,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE retval_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(retval_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference"); } @@ -16043,7 +15960,7 @@ static int ZEND_FASTCALL ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG SAVE_OPLINE(); varptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(varptr) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(varptr == NULL)) { zend_error_noreturn(E_ERROR, "Only variables can be passed by reference"); } @@ -16398,9 +16315,9 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND zend_file_handle file_handle; char *resolved_path; - resolved_path = zend_resolve_path(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename) TSRMLS_CC); + resolved_path = zend_resolve_path(Z_STRVAL_P(inc_filename), (int)Z_STRLEN_P(inc_filename) TSRMLS_CC); if (resolved_path) { - failure_retval = zend_hash_str_exists(&EG(included_files), resolved_path, strlen(resolved_path)); + failure_retval = zend_hash_str_exists(&EG(included_files), resolved_path, (int)strlen(resolved_path)); } else { resolved_path = Z_STRVAL_P(inc_filename); } @@ -16413,7 +16330,7 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND file_handle.opened_path = estrdup(resolved_path); } - if (zend_hash_str_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path))) { + if (zend_hash_str_add_empty_element(&EG(included_files), file_handle.opened_path, (int)strlen(file_handle.opened_path))) { new_op_array = zend_compile_file(&file_handle, (opline->extended_value==ZEND_INCLUDE_ONCE?ZEND_INCLUDE:ZEND_REQUIRE) TSRMLS_CC); zend_destroy_file_handle(&file_handle TSRMLS_CC); } else { @@ -16508,17 +16425,15 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG ZVAL_DEREF(array_ptr); if (Z_TYPE_P(array_ptr) == IS_ARRAY) { if (!Z_ISREF_P(array_ref)) { - SEPARATE_ZVAL_NOREF(array_ptr); + SEPARATE_ARRAY(array_ptr); array_ref = array_ptr; if (opline->extended_value & ZEND_FE_FETCH_BYREF) { ZVAL_NEW_REF(array_ptr, array_ptr); array_ref = array_ptr; array_ptr = Z_REFVAL_P(array_ptr); } - } else if (Z_IMMUTABLE_P(array_ptr)) { + } else if (Z_IMMUTABLE_P(array_ptr) || Z_REFCOUNT_P(array_ptr) > 1) { zval_copy_ctor(array_ptr); - } else { - SEPARATE_ZVAL_NOREF(array_ptr); } if (Z_REFCOUNTED_P(array_ref)) Z_ADDREF_P(array_ref); } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) { @@ -16529,9 +16444,6 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG ce = Z_OBJCE_P(array_ptr); if (!ce || ce->get_iterator == NULL) { - if (!Z_ISREF_P(array_ref)) { - SEPARATE_ZVAL_NOREF(array_ptr); - } Z_ADDREF_P(array_ptr); } array_ref = array_ptr; @@ -16644,25 +16556,37 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG } iter->index = -1; /* will be set to 0 before using next handler */ } else if ((fe_ht = HASH_OF(array_ptr)) != NULL) { - zend_hash_internal_pointer_reset(fe_ht); - if (ce) { - zend_object *zobj = Z_OBJ_P(array_ptr); - while (zend_hash_has_more_elements(fe_ht) == SUCCESS) { - zend_string *str_key; - zend_ulong int_key; - zend_uchar key_type; - - key_type = zend_hash_get_current_key(fe_ht, &str_key, &int_key, 0); - if (key_type != HASH_KEY_NON_EXISTENT && - (key_type == HASH_KEY_IS_LONG || - zend_check_property_access(zobj, str_key TSRMLS_CC) == SUCCESS)) { - break; + HashPointer *ptr = (HashPointer*)EX_VAR((opline+2)->op1.var); + HashPosition pos = 0; + Bucket *p; + + while (1) { + if (pos >= fe_ht->nNumUsed) { + is_empty = 1; + if (IS_VAR == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { + if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; } - zend_hash_move_forward(fe_ht); + ZEND_VM_JMP(opline->op2.jmp_addr); + } + p = fe_ht->arData + pos; + if (Z_TYPE(p->val) == IS_UNDEF || + (Z_TYPE(p->val) == IS_INDIRECT && + Z_TYPE_P(Z_INDIRECT(p->val)) == IS_UNDEF)) { + pos++; + continue; + } + if (!ce || + !p->key || + zend_check_property_access(Z_OBJ_P(array_ptr), p->key TSRMLS_CC) == SUCCESS) { + break; } + pos++; } - is_empty = zend_hash_has_more_elements(fe_ht) != SUCCESS; - zend_hash_get_pointer(fe_ht, (HashPointer*)EX_VAR((opline+2)->op1.var)); + fe_ht->nInternalPointer = pos; + ptr->pos = pos; + ptr->ht = fe_ht; + ptr->h = fe_ht->arData[pos].h; + is_empty = 0; } else { zend_error(E_WARNING, "Invalid argument supplied for foreach()"); is_empty = 1; @@ -16686,8 +16610,9 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG zval *array, *array_ref; zval *value; HashTable *fe_ht; - zend_object_iterator *iter = NULL; - zval *key = NULL; + HashPointer *ptr; + HashPosition pos; + Bucket *p; array = array_ref = EX_VAR(opline->op1.var); if (Z_ISREF_P(array)) { @@ -16697,81 +16622,174 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG zval_copy_ctor(array); } } - if (opline->extended_value & ZEND_FE_FETCH_WITH_KEY) { - key = EX_VAR((opline+1)->result.var); - } SAVE_OPLINE(); - switch (zend_iterator_unwrap(array, &iter TSRMLS_CC)) { - default: - case ZEND_ITER_INVALID: - zend_error(E_WARNING, "Invalid argument supplied for foreach()"); + if (EXPECTED(Z_TYPE_P(array) == IS_ARRAY)) { + fe_ht = Z_ARRVAL_P(array); + ptr = (HashPointer*)EX_VAR((opline+1)->op1.var); + pos = ptr->pos; + if (UNEXPECTED(pos == INVALID_IDX)) { + /* reached end of iteration */ ZEND_VM_JMP(opline->op2.jmp_addr); + } else if (UNEXPECTED(ptr->ht != fe_ht)) { + ptr->ht = fe_ht; + pos = 0; + } else if (UNEXPECTED(fe_ht->nInternalPointer != ptr->pos)) { + if (fe_ht->u.flags & HASH_FLAG_PACKED) { + pos = ptr->h; + } else { + pos = fe_ht->arHash[ptr->h & fe_ht->nTableMask]; + while (pos != INVALID_IDX) { + if (fe_ht->arData[pos].h == ptr->h && pos == ptr->pos) { + break; + } + pos = Z_NEXT(fe_ht->arData[pos].val); + } + } + } + while (1) { + if (UNEXPECTED(pos >= fe_ht->nNumUsed)) { + /* reached end of iteration */ + ZEND_VM_JMP(opline->op2.jmp_addr); + } + p = fe_ht->arData + pos; + value = &p->val; + if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + pos++; + continue; + } else if (UNEXPECTED(Z_TYPE_P(value) == IS_INDIRECT)) { + value = Z_INDIRECT_P(value); + if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + pos++; + continue; + } + } + if (opline->extended_value & ZEND_FE_FETCH_BYREF) { + ZVAL_MAKE_REF(value); + Z_ADDREF_P(value); + ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(value)); + } else { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (opline->extended_value & ZEND_FE_FETCH_WITH_KEY) { + if (!p->key) { + ZVAL_LONG(EX_VAR((opline+1)->result.var), p->h); + } else { + ZVAL_STR_COPY(EX_VAR((opline+1)->result.var), p->key); + } + } + break; + } + do { + pos++; + if (pos >= fe_ht->nNumUsed) { + fe_ht->nInternalPointer = ptr->pos = INVALID_IDX; + ZEND_VM_INC_OPCODE(); + ZEND_VM_NEXT_OPCODE(); + } + p = fe_ht->arData + pos; + } while (Z_TYPE(p->val) == IS_UNDEF || + (Z_TYPE(p->val) == IS_INDIRECT && + Z_TYPE_P(Z_INDIRECT(p->val)) == IS_UNDEF)); + fe_ht->nInternalPointer = ptr->pos = pos; + ptr->h = fe_ht->arData[pos].h; + ZEND_VM_INC_OPCODE(); + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_P(array) == IS_OBJECT)) { + zend_object_iterator *iter; - case ZEND_ITER_PLAIN_OBJECT: { - zend_object *zobj = Z_OBJ_P(array); - int key_type; - zend_string *str_key; - zend_ulong int_key; + if ((iter = zend_iterator_unwrap(array TSRMLS_CC)) == NULL) { + /* plain object */ + zend_object *zobj = Z_OBJ_P(array); - fe_ht = Z_OBJPROP_P(array); - zend_hash_set_pointer(fe_ht, (HashPointer*)EX_VAR((opline+1)->op1.var)); + fe_ht = Z_OBJPROP_P(array); + ptr = (HashPointer*)EX_VAR((opline+1)->op1.var); + pos = ptr->pos; + if (pos == INVALID_IDX) { + /* reached end of iteration */ + ZEND_VM_JMP(opline->op2.jmp_addr); + } else if (UNEXPECTED(ptr->ht != fe_ht)) { + ptr->ht = fe_ht; + pos = 0; + } else if (UNEXPECTED(fe_ht->nInternalPointer != ptr->pos)) { + if (fe_ht->u.flags & HASH_FLAG_PACKED) { + pos = ptr->h; + } else { + pos = fe_ht->arHash[ptr->h & fe_ht->nTableMask]; + while (pos != INVALID_IDX) { + if (fe_ht->arData[pos].h == ptr->h && pos == ptr->pos) { + break; + } + pos = Z_NEXT(fe_ht->arData[pos].val); + } + } + } while (1) { - if ((value = zend_hash_get_current_data(fe_ht)) == NULL) { + if (UNEXPECTED(pos >= fe_ht->nNumUsed)) { /* reached end of iteration */ ZEND_VM_JMP(opline->op2.jmp_addr); } - if (Z_TYPE_P(value) == IS_INDIRECT) { + p = fe_ht->arData + pos; + value = &p->val; + if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + pos++; + continue; + } else if (UNEXPECTED(Z_TYPE_P(value) == IS_INDIRECT)) { value = Z_INDIRECT_P(value); - if (Z_TYPE_P(value) == IS_UNDEF) { - zend_hash_move_forward(fe_ht); + if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + pos++; continue; } } - key_type = zend_hash_get_current_key(fe_ht, &str_key, &int_key, 0); - - zend_hash_move_forward(fe_ht); - if (key_type == HASH_KEY_IS_LONG || - zend_check_property_access(zobj, str_key TSRMLS_CC) == SUCCESS) { + if (UNEXPECTED(!p->key)) { + if (opline->extended_value & ZEND_FE_FETCH_WITH_KEY) { + ZVAL_LONG(EX_VAR((opline+1)->result.var), p->h); + } + break; + } else if (zend_check_property_access(zobj, p->key TSRMLS_CC) == SUCCESS) { + if (opline->extended_value & ZEND_FE_FETCH_WITH_KEY) { + if (p->key->val[0]) { + ZVAL_STR_COPY(EX_VAR((opline+1)->result.var), p->key); + } else { + const char *class_name, *prop_name; + size_t prop_name_len; + zend_unmangle_property_name_ex( + p->key, &class_name, &prop_name, &prop_name_len); + ZVAL_STRINGL(EX_VAR((opline+1)->result.var), prop_name, prop_name_len); + } + } break; } + pos++; } - - if (key) { - if (key_type == HASH_KEY_IS_LONG) { - ZVAL_LONG(key, int_key); - } else { - const char *class_name, *prop_name; - int prop_name_len; - zend_unmangle_property_name_ex( - str_key->val, str_key->len, &class_name, &prop_name, &prop_name_len - ); - ZVAL_STRINGL(key, prop_name, prop_name_len); - } - } - - zend_hash_get_pointer(fe_ht, (HashPointer*)EX_VAR((opline+1)->op1.var)); - break; - } - - case ZEND_ITER_PLAIN_ARRAY: - fe_ht = Z_ARRVAL_P(array); - zend_hash_set_pointer(fe_ht, (HashPointer*)EX_VAR((opline+1)->op1.var)); - if ((value = zend_hash_get_current_data(fe_ht)) == NULL) { - /* reached end of iteration */ - ZEND_VM_JMP(opline->op2.jmp_addr); - } - if (key) { - zend_hash_get_current_key_zval(fe_ht, key); + if (opline->extended_value & ZEND_FE_FETCH_BYREF) { + ZVAL_MAKE_REF(value); + Z_ADDREF_P(value); + ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(value)); + } else { + ZVAL_COPY(EX_VAR(opline->result.var), value); } - zend_hash_move_forward(fe_ht); - zend_hash_get_pointer(fe_ht, (HashPointer*)EX_VAR((opline+1)->op1.var)); - break; - - case ZEND_ITER_OBJECT: + do { + pos++; + if (pos >= fe_ht->nNumUsed) { + fe_ht->nInternalPointer = ptr->pos = INVALID_IDX; + ZEND_VM_INC_OPCODE(); + ZEND_VM_NEXT_OPCODE(); + } + p = fe_ht->arData + pos; + } while (Z_TYPE(p->val) == IS_UNDEF || + (Z_TYPE(p->val) == IS_INDIRECT && + Z_TYPE_P(Z_INDIRECT(p->val)) == IS_UNDEF) || + (EXPECTED(p->key != NULL) && + zend_check_property_access(zobj, p->key TSRMLS_CC) == FAILURE)); + fe_ht->nInternalPointer = ptr->pos = pos; + ptr->h = fe_ht->arData[pos].h; + ZEND_VM_INC_OPCODE(); + ZEND_VM_NEXT_OPCODE(); + } else { /* !iter happens from exception */ if (iter && ++iter->index > 0) { /* This could cause an endless loop if index becomes zero again. @@ -16800,31 +16818,31 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG /* failure in get_current_data */ ZEND_VM_JMP(opline->op2.jmp_addr); } - if (key) { + if (opline->extended_value & ZEND_FE_FETCH_BYREF) { + ZVAL_MAKE_REF(value); + Z_ADDREF_P(value); + ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(value)); + } else { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (opline->extended_value & ZEND_FE_FETCH_WITH_KEY) { if (iter->funcs->get_current_key) { - iter->funcs->get_current_key(iter, key TSRMLS_CC); + iter->funcs->get_current_key(iter, EX_VAR((opline+1)->result.var) TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { zval_ptr_dtor(array_ref); HANDLE_EXCEPTION(); } } else { - ZVAL_LONG(key, iter->index); + ZVAL_LONG(EX_VAR((opline+1)->result.var), iter->index); } } - break; - } - - if (opline->extended_value & ZEND_FE_FETCH_BYREF) { - ZVAL_MAKE_REF(value); - Z_ADDREF_P(value); - ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(value)); + ZEND_VM_INC_OPCODE(); + ZEND_VM_NEXT_OPCODE(); + } } else { - ZVAL_COPY(EX_VAR(opline->result.var), value); + zend_error(E_WARNING, "Invalid argument supplied for foreach()"); + ZEND_VM_JMP(opline->op2.jmp_addr); } - - CHECK_EXCEPTION(); - ZEND_VM_INC_OPCODE(); - ZEND_VM_NEXT_OPCODE(); } static int ZEND_FASTCALL ZEND_EXIT_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -16854,10 +16872,15 @@ static int ZEND_FASTCALL ZEND_JMP_SET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS USE_OPLINE zend_free_op free_op1; zval *value; + int is_ref = 0; SAVE_OPLINE(); value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && Z_ISREF_P(value)) { + is_ref = 1; + value = Z_REFVAL_P(value); + } if (i_zend_is_true(value TSRMLS_CC)) { ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); if (IS_VAR == IS_CONST) { @@ -16866,6 +16889,9 @@ static int ZEND_FASTCALL ZEND_JMP_SET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS } } else if (IS_VAR == IS_CV) { if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); + } else if (IS_VAR == IS_VAR && is_ref) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); + zval_ptr_dtor_nogc(free_op1.var); } ZEND_VM_JMP(opline->op2.jmp_addr); } @@ -16875,7 +16901,7 @@ static int ZEND_FASTCALL ZEND_JMP_SET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS ZEND_VM_NEXT_OPCODE(); } -static int ZEND_FASTCALL ZEND_JMP_SET_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static int ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zend_free_op free_op1; @@ -16884,7 +16910,10 @@ static int ZEND_FASTCALL ZEND_JMP_SET_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ SAVE_OPLINE(); value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (i_zend_is_true(value TSRMLS_CC)) { + if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && Z_ISREF_P(value)) { + ZVAL_COPY(EX_VAR(opline->result.var), Z_REFVAL_P(value)); + zval_ptr_dtor_nogc(free_op1.var); + } else { ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); if (IS_VAR == IS_CONST) { if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { @@ -16893,50 +16922,6 @@ static int ZEND_FASTCALL ZEND_JMP_SET_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ } else if (IS_VAR == IS_CV) { if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } - ZEND_VM_JMP(opline->op2.jmp_addr); - } - - zval_ptr_dtor_nogc(free_op1.var); - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); -} - -static int ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *value; - - SAVE_OPLINE(); - value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { - zval_copy_ctor_func(EX_VAR(opline->result.var)); - } - } else if (IS_VAR == IS_CV) { - if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); - } - ZEND_VM_NEXT_OPCODE(); -} - -static int ZEND_FASTCALL ZEND_QM_ASSIGN_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_free_op free_op1; - zval *value; - - SAVE_OPLINE(); - value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { - zval_copy_ctor_func(EX_VAR(opline->result.var)); - } - } else if (IS_VAR == IS_CV) { - if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } ZEND_VM_NEXT_OPCODE(); } @@ -17337,7 +17322,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b zval *value; int have_get_ptr = 0; - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } @@ -17431,7 +17416,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CONST(int (*b SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) { @@ -17446,7 +17431,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CONST(int (*b var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); } - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { + if (UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); } @@ -17498,7 +17483,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CONST(int (*binar value = opline->op2.zv; var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); } @@ -17693,7 +17678,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CONST(incdec_t property = opline->op2.zv; retval = EX_VAR(opline->result.var); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); } @@ -17784,7 +17769,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CONST(incdec_ property = opline->op2.zv; retval = EX_VAR(opline->result.var); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); } @@ -17911,8 +17896,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_CONST(int type, zend_error(E_NOTICE,"Undefined variable: %s", name->val); /* break missing intentionally */ case BP_VAR_IS: - retval = EX_VAR(opline->result.var); - ZVAL_NULL(retval); + retval = &EG(uninitialized_zval); break; case BP_VAR_RW: zend_error(E_NOTICE,"Undefined variable: %s", name->val); @@ -17932,8 +17916,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_CONST(int type, zend_error(E_NOTICE,"Undefined variable: %s", name->val); /* break missing intentionally */ case BP_VAR_IS: - retval = EX_VAR(opline->result.var); - ZVAL_NULL(retval); + retval = &EG(uninitialized_zval); break; case BP_VAR_RW: zend_error(E_NOTICE,"Undefined variable: %s", name->val); @@ -18036,7 +18019,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } if (EXPECTED(opline->extended_value == 0)) { @@ -18062,7 +18045,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); @@ -18134,7 +18117,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCOD SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); @@ -18195,7 +18178,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA property = opline->op2.zv; container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } @@ -18220,7 +18203,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H property = opline->op2.zv; container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); @@ -18281,7 +18264,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OP if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); } - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); @@ -18307,7 +18290,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCOD container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); property = opline->op2.zv; - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); @@ -18331,7 +18314,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); property_name = opline->op2.zv; - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); @@ -18352,7 +18335,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN SAVE_OPLINE(); object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) { @@ -18370,34 +18353,30 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN zval *dim = opline->op2.zv; zval *variable_ptr; - zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CONST TSRMLS_CC); + variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CONST TSRMLS_CC); - value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); - variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) { - zend_assign_to_string_offset(variable_ptr, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); - } else if (UNEXPECTED(variable_ptr == &EG(error_zval))) { - if (IS_TMP_FREE(free_op_data1)) { - zval_dtor(value); - } - if (RETURN_VALUE_USED(opline)) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - FREE_OP_VAR_PTR(free_op_data2); + value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); + if (UNEXPECTED(variable_ptr != NULL)) { + zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); } else { - if ((opline+1)->op1_type == IS_TMP_VAR) { - value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); - } else if ((opline+1)->op1_type == IS_CONST) { - value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); + variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); + if (UNEXPECTED(variable_ptr == &EG(error_zval))) { + if (IS_TMP_FREE(free_op_data1)) { + zval_dtor(value); + } + if (RETURN_VALUE_USED(opline)) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + FREE_OP_VAR_PTR(free_op_data2); } else { - value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); - } - if (RETURN_VALUE_USED(opline)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); + value = zend_assign_to_variable(variable_ptr, value, (opline+1)->op1_type TSRMLS_CC); + if (RETURN_VALUE_USED(opline)) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + FREE_OP_VAR_PTR(free_op_data2); } - FREE_OP_VAR_PTR(free_op_data2); } - FREE_OP_IF_VAR(free_op_data1); + FREE_OP_IF_VAR(free_op_data1); } if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; /* assign_dim has two opcodes! */ @@ -18417,9 +18396,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER value = opline->op2.zv; variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) { - zend_assign_to_string_offset(variable_ptr, value, IS_CONST, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); - } else if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) { + if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) { if (0) { zval_dtor(value); } @@ -18427,13 +18404,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - if (IS_CONST == IS_TMP_VAR) { - value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); - } else if (IS_CONST == IS_CONST) { - value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); - } else { - value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); - } + value = zend_assign_to_variable(variable_ptr, value, IS_CONST TSRMLS_CC); if (RETURN_VALUE_USED(opline)) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -18734,8 +18705,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE ZVAL_DUP(EX_VAR(opline->result.var), value); } else if (Z_STRLEN_P(opline->op2.zv) == sizeof("class")-1 && memcmp(Z_STRVAL_P(opline->op2.zv), "class", sizeof("class") - 1) == 0) { /* "class" is assigned as a case-sensitive keyword from zend_do_resolve_class_name */ - ZVAL_STR(EX_VAR(opline->result.var), ce->name); - zend_string_addref(ce->name); + ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name); } else { zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(opline->op2.zv)); } @@ -18755,7 +18725,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPC if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } ZVAL_MAKE_REF(expr_ptr); @@ -18946,6 +18916,9 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { + zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); + } if (IS_VAR != IS_UNUSED) { ZVAL_DEREF(container); SEPARATE_ZVAL_NOREF(container); @@ -19024,7 +18997,6 @@ numeric_index_dim: break; case IS_STRING: - case IS_STR_OFFSET: zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); ZEND_VM_CONTINUE(); /* bailed out before */ default: @@ -19045,7 +19017,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && Z_TYPE_P(container) == IS_STR_OFFSET) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); } offset = opline->op2.zv; @@ -19237,7 +19209,7 @@ num_index_prop: } } if (Z_TYPE_P(offset) == IS_LONG) { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) { + if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) { if ((opline->extended_value & ZEND_ISSET) || Z_STRVAL_P(container)[offset->value.lval] != '0') { result = 1; @@ -19329,7 +19301,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ } else { zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); } @@ -19724,7 +19696,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*bin zval *value; int have_get_ptr = 0; - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } @@ -19819,7 +19791,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_TMP(int (*bin SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) { @@ -19834,7 +19806,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_TMP(int (*bin var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); } - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { + if (UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); } @@ -19886,7 +19858,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_TMP(int (*binary_ value = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); } @@ -20081,7 +20053,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_TMP(incdec_t i property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); retval = EX_VAR(opline->result.var); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); } @@ -20173,7 +20145,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_TMP(incdec_t property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); retval = EX_VAR(opline->result.var); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); } @@ -20273,7 +20245,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } if (EXPECTED(opline->extended_value == 0)) { @@ -20299,7 +20271,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); @@ -20371,7 +20343,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_ SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); @@ -20433,7 +20405,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } @@ -20458,7 +20430,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); @@ -20520,7 +20492,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCO if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); } - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); @@ -20546,7 +20518,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); @@ -20570,7 +20542,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); property_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); @@ -20591,7 +20563,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL SAVE_OPLINE(); object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) { @@ -20609,35 +20581,30 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); zval *variable_ptr; - zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_TMP_VAR TSRMLS_CC); + variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_TMP_VAR TSRMLS_CC); zval_dtor(free_op2.var); - - value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); - variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) { - zend_assign_to_string_offset(variable_ptr, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); - } else if (UNEXPECTED(variable_ptr == &EG(error_zval))) { - if (IS_TMP_FREE(free_op_data1)) { - zval_dtor(value); - } - if (RETURN_VALUE_USED(opline)) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - FREE_OP_VAR_PTR(free_op_data2); + value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); + if (UNEXPECTED(variable_ptr != NULL)) { + zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); } else { - if ((opline+1)->op1_type == IS_TMP_VAR) { - value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); - } else if ((opline+1)->op1_type == IS_CONST) { - value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); + variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); + if (UNEXPECTED(variable_ptr == &EG(error_zval))) { + if (IS_TMP_FREE(free_op_data1)) { + zval_dtor(value); + } + if (RETURN_VALUE_USED(opline)) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + FREE_OP_VAR_PTR(free_op_data2); } else { - value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); - } - if (RETURN_VALUE_USED(opline)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); + value = zend_assign_to_variable(variable_ptr, value, (opline+1)->op1_type TSRMLS_CC); + if (RETURN_VALUE_USED(opline)) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + FREE_OP_VAR_PTR(free_op_data2); } - FREE_OP_VAR_PTR(free_op_data2); } - FREE_OP_IF_VAR(free_op_data1); + FREE_OP_IF_VAR(free_op_data1); } if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; /* assign_dim has two opcodes! */ @@ -20657,9 +20624,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_A value = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) { - zend_assign_to_string_offset(variable_ptr, value, IS_TMP_VAR, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); - } else if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) { + if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) { if (1) { zval_dtor(value); } @@ -20667,13 +20632,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_A ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - if (IS_TMP_VAR == IS_TMP_VAR) { - value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); - } else if (IS_TMP_VAR == IS_CONST) { - value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); - } else { - value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); - } + value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR TSRMLS_CC); if (RETURN_VALUE_USED(opline)) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -20900,7 +20859,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_HANDLER(ZEND_OPCOD if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } ZVAL_MAKE_REF(expr_ptr); @@ -21019,6 +20978,9 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLE SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { + zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); + } if (IS_VAR != IS_UNUSED) { ZVAL_DEREF(container); SEPARATE_ZVAL_NOREF(container); @@ -21097,7 +21059,6 @@ numeric_index_dim: zval_dtor(free_op2.var); break; case IS_STRING: - case IS_STR_OFFSET: zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); ZEND_VM_CONTINUE(); /* bailed out before */ default: @@ -21118,7 +21079,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLE SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && Z_TYPE_P(container) == IS_STR_OFFSET) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); } offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); @@ -21230,7 +21191,7 @@ num_index_prop: } } if (Z_TYPE_P(offset) == IS_LONG) { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) { + if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) { if ((opline->extended_value & ZEND_ISSET) || Z_STRVAL_P(container)[offset->value.lval] != '0') { result = 1; @@ -21324,7 +21285,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR } else { zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); } @@ -21719,7 +21680,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin zval *value; int have_get_ptr = 0; - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } @@ -21814,7 +21775,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_VAR(int (*bin SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) { @@ -21829,7 +21790,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_VAR(int (*bin var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); } - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { + if (UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); } @@ -21881,7 +21842,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_VAR(int (*binary_ value = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); } @@ -22076,7 +22037,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_VAR(incdec_t i property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); retval = EX_VAR(opline->result.var); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); } @@ -22168,7 +22129,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_VAR(incdec_t property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); retval = EX_VAR(opline->result.var); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); } @@ -22296,8 +22257,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_VAR(int type, ZE zend_error(E_NOTICE,"Undefined variable: %s", name->val); /* break missing intentionally */ case BP_VAR_IS: - retval = EX_VAR(opline->result.var); - ZVAL_NULL(retval); + retval = &EG(uninitialized_zval); break; case BP_VAR_RW: zend_error(E_NOTICE,"Undefined variable: %s", name->val); @@ -22317,8 +22277,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_VAR(int type, ZE zend_error(E_NOTICE,"Undefined variable: %s", name->val); /* break missing intentionally */ case BP_VAR_IS: - retval = EX_VAR(opline->result.var); - ZVAL_NULL(retval); + retval = &EG(uninitialized_zval); break; case BP_VAR_RW: zend_error(E_NOTICE,"Undefined variable: %s", name->val); @@ -22421,7 +22380,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } if (EXPECTED(opline->extended_value == 0)) { @@ -22447,7 +22406,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); @@ -22519,7 +22478,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_ SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); @@ -22581,7 +22540,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } @@ -22606,7 +22565,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); @@ -22668,7 +22627,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCO if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); } - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); @@ -22694,7 +22653,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_ container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); @@ -22718,7 +22677,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); @@ -22739,7 +22698,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL SAVE_OPLINE(); object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) { @@ -22757,35 +22716,30 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); zval *variable_ptr; - zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_VAR TSRMLS_CC); + variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_VAR TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); - - value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); - variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) { - zend_assign_to_string_offset(variable_ptr, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); - } else if (UNEXPECTED(variable_ptr == &EG(error_zval))) { - if (IS_TMP_FREE(free_op_data1)) { - zval_dtor(value); - } - if (RETURN_VALUE_USED(opline)) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - FREE_OP_VAR_PTR(free_op_data2); + value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); + if (UNEXPECTED(variable_ptr != NULL)) { + zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); } else { - if ((opline+1)->op1_type == IS_TMP_VAR) { - value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); - } else if ((opline+1)->op1_type == IS_CONST) { - value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); + variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); + if (UNEXPECTED(variable_ptr == &EG(error_zval))) { + if (IS_TMP_FREE(free_op_data1)) { + zval_dtor(value); + } + if (RETURN_VALUE_USED(opline)) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + FREE_OP_VAR_PTR(free_op_data2); } else { - value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); - } - if (RETURN_VALUE_USED(opline)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); + value = zend_assign_to_variable(variable_ptr, value, (opline+1)->op1_type TSRMLS_CC); + if (RETURN_VALUE_USED(opline)) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + FREE_OP_VAR_PTR(free_op_data2); } - FREE_OP_VAR_PTR(free_op_data2); } - FREE_OP_IF_VAR(free_op_data1); + FREE_OP_IF_VAR(free_op_data1); } if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; /* assign_dim has two opcodes! */ @@ -22802,12 +22756,10 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_A zval *variable_ptr; SAVE_OPLINE(); - value = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + value = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) { - zend_assign_to_string_offset(variable_ptr, value, IS_VAR, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); - } else if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) { + if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) { if (0) { zval_dtor(value); } @@ -22815,13 +22767,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_A ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - if (IS_VAR == IS_TMP_VAR) { - value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); - } else if (IS_VAR == IS_CONST) { - value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); - } else { - value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); - } + value = zend_assign_to_variable(variable_ptr, value, IS_VAR TSRMLS_CC); if (RETURN_VALUE_USED(opline)) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -22870,8 +22816,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL UNEXPECTED(!Z_ISREF_P(variable_ptr))) { zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object"); } - if ((IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) || - (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET))) { + if ((IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) || + (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == NULL))) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects"); } if ((IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) || @@ -23112,7 +23058,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_VAR_HANDLER(ZEND_OPCOD if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } ZVAL_MAKE_REF(expr_ptr); @@ -23303,6 +23249,9 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { + zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); + } if (IS_VAR != IS_UNUSED) { ZVAL_DEREF(container); SEPARATE_ZVAL_NOREF(container); @@ -23381,7 +23330,6 @@ numeric_index_dim: zval_ptr_dtor_nogc(free_op2.var); break; case IS_STRING: - case IS_STR_OFFSET: zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); ZEND_VM_CONTINUE(); /* bailed out before */ default: @@ -23402,7 +23350,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && Z_TYPE_P(container) == IS_STR_OFFSET) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); } offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); @@ -23594,7 +23542,7 @@ num_index_prop: } } if (Z_TYPE_P(offset) == IS_LONG) { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) { + if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) { if ((opline->extended_value & ZEND_ISSET) || Z_STRVAL_P(container)[offset->value.lval] != '0') { result = 1; @@ -23688,7 +23636,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR } else { zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); } @@ -23808,7 +23756,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (* zval *value; int have_get_ptr = 0; - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } @@ -23902,7 +23850,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_UNUSED(int (* SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) { @@ -23917,7 +23865,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_UNUSED(int (* var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); } - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { + if (UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); } @@ -23969,7 +23917,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_UNUSED(int (*bina value = NULL; var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); } @@ -24204,8 +24152,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_UNUSED(int type, zend_error(E_NOTICE,"Undefined variable: %s", name->val); /* break missing intentionally */ case BP_VAR_IS: - retval = EX_VAR(opline->result.var); - ZVAL_NULL(retval); + retval = &EG(uninitialized_zval); break; case BP_VAR_RW: zend_error(E_NOTICE,"Undefined variable: %s", name->val); @@ -24225,8 +24172,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_UNUSED(int type, zend_error(E_NOTICE,"Undefined variable: %s", name->val); /* break missing intentionally */ case BP_VAR_IS: - retval = EX_VAR(opline->result.var); - ZVAL_NULL(retval); + retval = &EG(uninitialized_zval); break; case BP_VAR_RW: zend_error(E_NOTICE,"Undefined variable: %s", name->val); @@ -24312,7 +24258,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_H SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } if (EXPECTED(opline->extended_value == 0)) { @@ -24338,7 +24284,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_ SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC); @@ -24395,7 +24341,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA SAVE_OPLINE(); object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) { @@ -24413,34 +24359,30 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA zval *dim = NULL; zval *variable_ptr; - zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_UNUSED TSRMLS_CC); + variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_UNUSED TSRMLS_CC); - value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); - variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) { - zend_assign_to_string_offset(variable_ptr, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); - } else if (UNEXPECTED(variable_ptr == &EG(error_zval))) { - if (IS_TMP_FREE(free_op_data1)) { - zval_dtor(value); - } - if (RETURN_VALUE_USED(opline)) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - FREE_OP_VAR_PTR(free_op_data2); + value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); + if (UNEXPECTED(variable_ptr != NULL)) { + zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); } else { - if ((opline+1)->op1_type == IS_TMP_VAR) { - value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); - } else if ((opline+1)->op1_type == IS_CONST) { - value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); + variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); + if (UNEXPECTED(variable_ptr == &EG(error_zval))) { + if (IS_TMP_FREE(free_op_data1)) { + zval_dtor(value); + } + if (RETURN_VALUE_USED(opline)) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + FREE_OP_VAR_PTR(free_op_data2); } else { - value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); - } - if (RETURN_VALUE_USED(opline)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); + value = zend_assign_to_variable(variable_ptr, value, (opline+1)->op1_type TSRMLS_CC); + if (RETURN_VALUE_USED(opline)) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + FREE_OP_VAR_PTR(free_op_data2); } - FREE_OP_VAR_PTR(free_op_data2); } - FREE_OP_IF_VAR(free_op_data1); + FREE_OP_IF_VAR(free_op_data1); } if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; /* assign_dim has two opcodes! */ @@ -24575,7 +24517,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OP if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } ZVAL_MAKE_REF(expr_ptr); @@ -24894,7 +24836,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER } else { zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); } @@ -25274,7 +25216,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina zval *value; int have_get_ptr = 0; - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } @@ -25368,7 +25310,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CV(int (*bina SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) { @@ -25383,7 +25325,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CV(int (*bina var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); } - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { + if (UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); } @@ -25435,7 +25377,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CV(int (*binary_o value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); } @@ -25630,7 +25572,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CV(incdec_t in property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); retval = EX_VAR(opline->result.var); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); } @@ -25721,7 +25663,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CV(incdec_t i property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); retval = EX_VAR(opline->result.var); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); } @@ -25820,7 +25762,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } if (EXPECTED(opline->extended_value == 0)) { @@ -25846,7 +25788,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); @@ -25918,7 +25860,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_H SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); @@ -25979,7 +25921,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } @@ -26004,7 +25946,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); @@ -26065,7 +26007,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCOD if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); } - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); @@ -26091,7 +26033,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_H container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); @@ -26115,7 +26057,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); @@ -26136,7 +26078,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE SAVE_OPLINE(); object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) { @@ -26154,34 +26096,30 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE zval *dim = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); zval *variable_ptr; - zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CV TSRMLS_CC); + variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CV TSRMLS_CC); - value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); - variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) { - zend_assign_to_string_offset(variable_ptr, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); - } else if (UNEXPECTED(variable_ptr == &EG(error_zval))) { - if (IS_TMP_FREE(free_op_data1)) { - zval_dtor(value); - } - if (RETURN_VALUE_USED(opline)) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - FREE_OP_VAR_PTR(free_op_data2); + value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); + if (UNEXPECTED(variable_ptr != NULL)) { + zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); } else { - if ((opline+1)->op1_type == IS_TMP_VAR) { - value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); - } else if ((opline+1)->op1_type == IS_CONST) { - value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); + variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); + if (UNEXPECTED(variable_ptr == &EG(error_zval))) { + if (IS_TMP_FREE(free_op_data1)) { + zval_dtor(value); + } + if (RETURN_VALUE_USED(opline)) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + FREE_OP_VAR_PTR(free_op_data2); } else { - value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); - } - if (RETURN_VALUE_USED(opline)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); + value = zend_assign_to_variable(variable_ptr, value, (opline+1)->op1_type TSRMLS_CC); + if (RETURN_VALUE_USED(opline)) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + FREE_OP_VAR_PTR(free_op_data2); } - FREE_OP_VAR_PTR(free_op_data2); } - FREE_OP_IF_VAR(free_op_data1); + FREE_OP_IF_VAR(free_op_data1); } if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; /* assign_dim has two opcodes! */ @@ -26198,12 +26136,10 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_AR zval *variable_ptr; SAVE_OPLINE(); - value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); + value = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) { - zend_assign_to_string_offset(variable_ptr, value, IS_CV, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); - } else if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) { + if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) { if (0) { zval_dtor(value); } @@ -26211,13 +26147,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_AR ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - if (IS_CV == IS_TMP_VAR) { - value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); - } else if (IS_CV == IS_CONST) { - value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); - } else { - value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); - } + value = zend_assign_to_variable(variable_ptr, value, IS_CV TSRMLS_CC); if (RETURN_VALUE_USED(opline)) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -26265,8 +26195,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE UNEXPECTED(!Z_ISREF_P(variable_ptr))) { zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object"); } - if ((IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) || - (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET))) { + if ((IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) || + (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == NULL))) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects"); } if ((IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) || @@ -26504,7 +26434,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } ZVAL_MAKE_REF(expr_ptr); @@ -26623,6 +26553,9 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { + zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); + } if (IS_VAR != IS_UNUSED) { ZVAL_DEREF(container); SEPARATE_ZVAL_NOREF(container); @@ -26701,7 +26634,6 @@ numeric_index_dim: break; case IS_STRING: - case IS_STR_OFFSET: zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); ZEND_VM_CONTINUE(); /* bailed out before */ default: @@ -26722,7 +26654,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && Z_TYPE_P(container) == IS_STR_OFFSET) { + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); } offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); @@ -26834,7 +26766,7 @@ num_index_prop: } } if (Z_TYPE_P(offset) == IS_LONG) { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) { + if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) { if ((opline->extended_value & ZEND_ISSET) || Z_STRVAL_P(container)[offset->value.lval] != '0') { result = 1; @@ -26926,7 +26858,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG } else { zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { + if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); } @@ -27126,7 +27058,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int zval *value; int have_get_ptr = 0; - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } @@ -27219,7 +27151,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CONST(int SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(TSRMLS_C); - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (IS_UNUSED == IS_VAR && !0) { @@ -27234,7 +27166,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CONST(int var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); } - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { + if (UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); } @@ -27286,7 +27218,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_CONST(int (*bi value = opline->op2.zv; var_ptr = NULL; - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); } @@ -27481,7 +27413,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(incde property = opline->op2.zv; retval = EX_VAR(opline->result.var); - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); } @@ -27572,7 +27504,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CONST(incd property = opline->op2.zv; retval = EX_VAR(opline->result.var); - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); } @@ -27693,7 +27625,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE property = opline->op2.zv; container = _get_obj_zval_ptr_unused(TSRMLS_C); - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } @@ -27718,7 +27650,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCOD property = opline->op2.zv; container = _get_obj_zval_ptr_unused(TSRMLS_C); - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); @@ -27779,7 +27711,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST_HANDLER(ZEND if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); } - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); @@ -27805,7 +27737,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST_HANDLER(ZEND_OP container = _get_obj_zval_ptr_unused(TSRMLS_C); property = opline->op2.zv; - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); @@ -27829,7 +27761,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_ object = _get_obj_zval_ptr_unused(TSRMLS_C); property_name = opline->op2.zv; - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); @@ -28035,8 +27967,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPC ZVAL_DUP(EX_VAR(opline->result.var), value); } else if (Z_STRLEN_P(opline->op2.zv) == sizeof("class")-1 && memcmp(Z_STRVAL_P(opline->op2.zv), "class", sizeof("class") - 1) == 0) { /* "class" is assigned as a case-sensitive keyword from zend_do_resolve_class_name */ - ZVAL_STR(EX_VAR(opline->result.var), ce->name); - zend_string_addref(ce->name); + ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name); } else { zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(opline->op2.zv)); } @@ -28087,6 +28018,9 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_H SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(TSRMLS_C); + if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { + zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); + } if (IS_UNUSED != IS_UNUSED) { ZVAL_DEREF(container); SEPARATE_ZVAL_NOREF(container); @@ -28165,7 +28099,6 @@ numeric_index_dim: break; case IS_STRING: - case IS_STR_OFFSET: zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); ZEND_VM_CONTINUE(); /* bailed out before */ default: @@ -28186,7 +28119,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_H SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(TSRMLS_C); - if (IS_UNUSED == IS_VAR && Z_TYPE_P(container) == IS_STR_OFFSET) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); } offset = opline->op2.zv; @@ -28298,7 +28231,7 @@ num_index_prop: } } if (Z_TYPE_P(offset) == IS_LONG) { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) { + if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) { if ((opline->extended_value & ZEND_ISSET) || Z_STRVAL_P(container)[offset->value.lval] != '0') { result = 1; @@ -28390,7 +28323,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDL } else { zval *value_ptr = NULL; - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); } @@ -28494,7 +28427,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (* zval *value; int have_get_ptr = 0; - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } @@ -28588,7 +28521,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_TMP(int (* SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(TSRMLS_C); - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (IS_UNUSED == IS_VAR && !0) { @@ -28603,7 +28536,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_TMP(int (* var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); } - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { + if (UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); } @@ -28655,7 +28588,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_TMP(int (*bina value = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); var_ptr = NULL; - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); } @@ -28850,7 +28783,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_TMP(incdec_ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); retval = EX_VAR(opline->result.var); - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); } @@ -28942,7 +28875,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_TMP(incdec property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); retval = EX_VAR(opline->result.var); - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); } @@ -29065,7 +28998,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_H property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); container = _get_obj_zval_ptr_unused(TSRMLS_C); - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } @@ -29090,7 +29023,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_ property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); container = _get_obj_zval_ptr_unused(TSRMLS_C); - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); @@ -29152,7 +29085,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP_HANDLER(ZEND_O if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); } - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); @@ -29178,7 +29111,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCO container = _get_obj_zval_ptr_unused(TSRMLS_C); property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); @@ -29202,7 +29135,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HA object = _get_obj_zval_ptr_unused(TSRMLS_C); property_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); @@ -29370,6 +29303,9 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HAN SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(TSRMLS_C); + if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { + zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); + } if (IS_UNUSED != IS_UNUSED) { ZVAL_DEREF(container); SEPARATE_ZVAL_NOREF(container); @@ -29448,7 +29384,6 @@ numeric_index_dim: zval_dtor(free_op2.var); break; case IS_STRING: - case IS_STR_OFFSET: zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); ZEND_VM_CONTINUE(); /* bailed out before */ default: @@ -29469,7 +29404,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HAN SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(TSRMLS_C); - if (IS_UNUSED == IS_VAR && Z_TYPE_P(container) == IS_STR_OFFSET) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); } offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); @@ -29581,7 +29516,7 @@ num_index_prop: } } if (Z_TYPE_P(offset) == IS_LONG) { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) { + if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) { if ((opline->extended_value & ZEND_ISSET) || Z_STRVAL_P(container)[offset->value.lval] != '0') { result = 1; @@ -29675,7 +29610,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER } else { zval *value_ptr = NULL; - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); } @@ -29779,7 +29714,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (* zval *value; int have_get_ptr = 0; - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } @@ -29873,7 +29808,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_VAR(int (* SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(TSRMLS_C); - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (IS_UNUSED == IS_VAR && !0) { @@ -29888,7 +29823,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_VAR(int (* var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); } - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { + if (UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); } @@ -29940,7 +29875,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_VAR(int (*bina value = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); var_ptr = NULL; - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); } @@ -30135,7 +30070,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_VAR(incdec_ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); retval = EX_VAR(opline->result.var); - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); } @@ -30227,7 +30162,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_VAR(incdec property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); retval = EX_VAR(opline->result.var); - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); } @@ -30350,7 +30285,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_H property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); container = _get_obj_zval_ptr_unused(TSRMLS_C); - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } @@ -30375,7 +30310,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_ property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); container = _get_obj_zval_ptr_unused(TSRMLS_C); - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); @@ -30437,7 +30372,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_VAR_HANDLER(ZEND_O if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); } - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); @@ -30463,7 +30398,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCO container = _get_obj_zval_ptr_unused(TSRMLS_C); property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); @@ -30487,7 +30422,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HA object = _get_obj_zval_ptr_unused(TSRMLS_C); property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); @@ -30655,6 +30590,9 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HAN SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(TSRMLS_C); + if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { + zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); + } if (IS_UNUSED != IS_UNUSED) { ZVAL_DEREF(container); SEPARATE_ZVAL_NOREF(container); @@ -30733,7 +30671,6 @@ numeric_index_dim: zval_ptr_dtor_nogc(free_op2.var); break; case IS_STRING: - case IS_STR_OFFSET: zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); ZEND_VM_CONTINUE(); /* bailed out before */ default: @@ -30754,7 +30691,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HAN SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(TSRMLS_C); - if (IS_UNUSED == IS_VAR && Z_TYPE_P(container) == IS_STR_OFFSET) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); } offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); @@ -30866,7 +30803,7 @@ num_index_prop: } } if (Z_TYPE_P(offset) == IS_LONG) { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) { + if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) { if ((opline->extended_value & ZEND_ISSET) || Z_STRVAL_P(container)[offset->value.lval] != '0') { result = 1; @@ -30960,7 +30897,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER } else { zval *value_ptr = NULL; - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); } @@ -31064,7 +31001,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int zval *value; int have_get_ptr = 0; - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } @@ -31157,7 +31094,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_UNUSED(int SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(TSRMLS_C); - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (IS_UNUSED == IS_VAR && !0) { @@ -31172,7 +31109,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_UNUSED(int var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); } - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { + if (UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); } @@ -31224,7 +31161,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_UNUSED(int (*b value = NULL; var_ptr = NULL; - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); } @@ -31476,7 +31413,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HAND } else { zval *value_ptr = NULL; - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); } @@ -31580,7 +31517,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*b zval *value; int have_get_ptr = 0; - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } @@ -31673,7 +31610,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CV(int (*b SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(TSRMLS_C); - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (IS_UNUSED == IS_VAR && !0) { @@ -31688,7 +31625,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CV(int (*b var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); } - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { + if (UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); } @@ -31740,7 +31677,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_CV(int (*binar value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); var_ptr = NULL; - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); } @@ -31935,7 +31872,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CV(incdec_t property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); retval = EX_VAR(opline->result.var); - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); } @@ -32026,7 +31963,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CV(incdec_ property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); retval = EX_VAR(opline->result.var); - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); } @@ -32147,7 +32084,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HA property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); container = _get_obj_zval_ptr_unused(TSRMLS_C); - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } @@ -32172,7 +32109,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_H property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); container = _get_obj_zval_ptr_unused(TSRMLS_C); - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); @@ -32233,7 +32170,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV_HANDLER(ZEND_OP if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); } - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); @@ -32259,7 +32196,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV_HANDLER(ZEND_OPCOD container = _get_obj_zval_ptr_unused(TSRMLS_C); property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); @@ -32283,7 +32220,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HAN object = _get_obj_zval_ptr_unused(TSRMLS_C); property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); @@ -32449,6 +32386,9 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HAND SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(TSRMLS_C); + if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { + zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); + } if (IS_UNUSED != IS_UNUSED) { ZVAL_DEREF(container); SEPARATE_ZVAL_NOREF(container); @@ -32527,7 +32467,6 @@ numeric_index_dim: break; case IS_STRING: - case IS_STR_OFFSET: zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); ZEND_VM_CONTINUE(); /* bailed out before */ default: @@ -32548,7 +32487,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HAND SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(TSRMLS_C); - if (IS_UNUSED == IS_VAR && Z_TYPE_P(container) == IS_STR_OFFSET) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); } offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); @@ -32660,7 +32599,7 @@ num_index_prop: } } if (Z_TYPE_P(offset) == IS_LONG) { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) { + if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) { if ((opline->extended_value & ZEND_ISSET) || Z_STRVAL_P(container)[offset->value.lval] != '0') { result = 1; @@ -32752,7 +32691,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ } else { zval *value_ptr = NULL; - if (IS_UNUSED == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { + if (IS_UNUSED == IS_VAR && UNEXPECTED(value_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); } @@ -32882,6 +32821,10 @@ static int ZEND_FASTCALL ZEND_PRE_INC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); var_ptr = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); + if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) { + zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); + } + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { fast_increment_function(var_ptr); if (RETURN_VALUE_USED(opline)) { @@ -32890,9 +32833,6 @@ static int ZEND_FASTCALL ZEND_PRE_INC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) ZEND_VM_NEXT_OPCODE(); } - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { - zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); - } if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { if (RETURN_VALUE_USED(opline)) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -32936,6 +32876,10 @@ static int ZEND_FASTCALL ZEND_PRE_DEC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); var_ptr = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); + if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) { + zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); + } + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { fast_decrement_function(var_ptr); if (RETURN_VALUE_USED(opline)) { @@ -32944,9 +32888,6 @@ static int ZEND_FASTCALL ZEND_PRE_DEC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) ZEND_VM_NEXT_OPCODE(); } - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { - zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); - } if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { if (RETURN_VALUE_USED(opline)) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -32990,15 +32931,16 @@ static int ZEND_FASTCALL ZEND_POST_INC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); var_ptr = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); + if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) { + zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); + } + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); fast_increment_function(var_ptr); ZEND_VM_NEXT_OPCODE(); } - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { - zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); - } if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -33043,15 +32985,16 @@ static int ZEND_FASTCALL ZEND_POST_DEC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); var_ptr = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); + if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) { + zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); + } + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); fast_decrement_function(var_ptr); ZEND_VM_NEXT_OPCODE(); } - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { - zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); - } if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -33334,7 +33277,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER retval_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(retval_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference"); } @@ -33463,7 +33406,7 @@ static int ZEND_FASTCALL ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); varptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(varptr) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(varptr == NULL)) { zend_error_noreturn(E_ERROR, "Only variables can be passed by reference"); } @@ -33802,9 +33745,9 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL zend_file_handle file_handle; char *resolved_path; - resolved_path = zend_resolve_path(Z_STRVAL_P(inc_filename), Z_STRLEN_P(inc_filename) TSRMLS_CC); + resolved_path = zend_resolve_path(Z_STRVAL_P(inc_filename), (int)Z_STRLEN_P(inc_filename) TSRMLS_CC); if (resolved_path) { - failure_retval = zend_hash_str_exists(&EG(included_files), resolved_path, strlen(resolved_path)); + failure_retval = zend_hash_str_exists(&EG(included_files), resolved_path, (int)strlen(resolved_path)); } else { resolved_path = Z_STRVAL_P(inc_filename); } @@ -33817,7 +33760,7 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL file_handle.opened_path = estrdup(resolved_path); } - if (zend_hash_str_add_empty_element(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path))) { + if (zend_hash_str_add_empty_element(&EG(included_files), file_handle.opened_path, (int)strlen(file_handle.opened_path))) { new_op_array = zend_compile_file(&file_handle, (opline->extended_value==ZEND_INCLUDE_ONCE?ZEND_INCLUDE:ZEND_REQUIRE) TSRMLS_CC); zend_destroy_file_handle(&file_handle TSRMLS_CC); } else { @@ -33912,17 +33855,15 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS ZVAL_DEREF(array_ptr); if (Z_TYPE_P(array_ptr) == IS_ARRAY) { if (!Z_ISREF_P(array_ref)) { - SEPARATE_ZVAL_NOREF(array_ptr); + SEPARATE_ARRAY(array_ptr); array_ref = array_ptr; if (opline->extended_value & ZEND_FE_FETCH_BYREF) { ZVAL_NEW_REF(array_ptr, array_ptr); array_ref = array_ptr; array_ptr = Z_REFVAL_P(array_ptr); } - } else if (Z_IMMUTABLE_P(array_ptr)) { + } else if (Z_IMMUTABLE_P(array_ptr) || Z_REFCOUNT_P(array_ptr) > 1) { zval_copy_ctor(array_ptr); - } else { - SEPARATE_ZVAL_NOREF(array_ptr); } if (Z_REFCOUNTED_P(array_ref)) Z_ADDREF_P(array_ref); } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) { @@ -33933,9 +33874,6 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS ce = Z_OBJCE_P(array_ptr); if (!ce || ce->get_iterator == NULL) { - if (!Z_ISREF_P(array_ref)) { - SEPARATE_ZVAL_NOREF(array_ptr); - } Z_ADDREF_P(array_ptr); } array_ref = array_ptr; @@ -34048,25 +33986,37 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS } iter->index = -1; /* will be set to 0 before using next handler */ } else if ((fe_ht = HASH_OF(array_ptr)) != NULL) { - zend_hash_internal_pointer_reset(fe_ht); - if (ce) { - zend_object *zobj = Z_OBJ_P(array_ptr); - while (zend_hash_has_more_elements(fe_ht) == SUCCESS) { - zend_string *str_key; - zend_ulong int_key; - zend_uchar key_type; - - key_type = zend_hash_get_current_key(fe_ht, &str_key, &int_key, 0); - if (key_type != HASH_KEY_NON_EXISTENT && - (key_type == HASH_KEY_IS_LONG || - zend_check_property_access(zobj, str_key TSRMLS_CC) == SUCCESS)) { - break; + HashPointer *ptr = (HashPointer*)EX_VAR((opline+2)->op1.var); + HashPosition pos = 0; + Bucket *p; + + while (1) { + if (pos >= fe_ht->nNumUsed) { + is_empty = 1; + if (IS_CV == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) { + } - zend_hash_move_forward(fe_ht); + ZEND_VM_JMP(opline->op2.jmp_addr); + } + p = fe_ht->arData + pos; + if (Z_TYPE(p->val) == IS_UNDEF || + (Z_TYPE(p->val) == IS_INDIRECT && + Z_TYPE_P(Z_INDIRECT(p->val)) == IS_UNDEF)) { + pos++; + continue; + } + if (!ce || + !p->key || + zend_check_property_access(Z_OBJ_P(array_ptr), p->key TSRMLS_CC) == SUCCESS) { + break; } + pos++; } - is_empty = zend_hash_has_more_elements(fe_ht) != SUCCESS; - zend_hash_get_pointer(fe_ht, (HashPointer*)EX_VAR((opline+2)->op1.var)); + fe_ht->nInternalPointer = pos; + ptr->pos = pos; + ptr->ht = fe_ht; + ptr->h = fe_ht->arData[pos].h; + is_empty = 0; } else { zend_error(E_WARNING, "Invalid argument supplied for foreach()"); is_empty = 1; @@ -34110,10 +34060,15 @@ static int ZEND_FASTCALL ZEND_JMP_SET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) USE_OPLINE zval *value; + int is_ref = 0; SAVE_OPLINE(); value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); + if ((IS_CV == IS_VAR || IS_CV == IS_CV) && Z_ISREF_P(value)) { + is_ref = 1; + value = Z_REFVAL_P(value); + } if (i_zend_is_true(value TSRMLS_CC)) { ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); if (IS_CV == IS_CONST) { @@ -34122,6 +34077,9 @@ static int ZEND_FASTCALL ZEND_JMP_SET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } } else if (IS_CV == IS_CV) { if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); + } else if (IS_CV == IS_VAR && is_ref) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); + } ZEND_VM_JMP(opline->op2.jmp_addr); } @@ -34130,7 +34088,7 @@ static int ZEND_FASTCALL ZEND_JMP_SET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) ZEND_VM_NEXT_OPCODE(); } -static int ZEND_FASTCALL ZEND_JMP_SET_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static int ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -34139,7 +34097,10 @@ static int ZEND_FASTCALL ZEND_JMP_SET_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_A SAVE_OPLINE(); value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); - if (i_zend_is_true(value TSRMLS_CC)) { + if ((IS_CV == IS_VAR || IS_CV == IS_CV) && Z_ISREF_P(value)) { + ZVAL_COPY(EX_VAR(opline->result.var), Z_REFVAL_P(value)); + + } else { ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); if (IS_CV == IS_CONST) { if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { @@ -34148,49 +34109,6 @@ static int ZEND_FASTCALL ZEND_JMP_SET_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_A } else if (IS_CV == IS_CV) { if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } - ZEND_VM_JMP(opline->op2.jmp_addr); - } - - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); -} - -static int ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *value; - - SAVE_OPLINE(); - value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); - - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); - if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { - zval_copy_ctor_func(EX_VAR(opline->result.var)); - } - } else if (IS_CV == IS_CV) { - if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); - } - ZEND_VM_NEXT_OPCODE(); -} - -static int ZEND_FASTCALL ZEND_QM_ASSIGN_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *value; - - SAVE_OPLINE(); - value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); - - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); - if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { - zval_copy_ctor_func(EX_VAR(opline->result.var)); - } - } else if (IS_CV == IS_CV) { - if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } ZEND_VM_NEXT_OPCODE(); } @@ -34591,7 +34509,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*bi zval *value; int have_get_ptr = 0; - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } @@ -34684,7 +34602,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CONST(int (*bi SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (IS_CV == IS_VAR && !0) { @@ -34699,7 +34617,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CONST(int (*bi var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); } - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { + if (UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); } @@ -34751,7 +34669,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_CONST(int (*binary value = opline->op2.zv; var_ptr = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); } @@ -34946,7 +34864,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CONST(incdec_t property = opline->op2.zv; retval = EX_VAR(opline->result.var); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); } @@ -35037,7 +34955,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CONST(incdec_t property = opline->op2.zv; retval = EX_VAR(opline->result.var); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); } @@ -35164,8 +35082,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_CONST(int type, Z zend_error(E_NOTICE,"Undefined variable: %s", name->val); /* break missing intentionally */ case BP_VAR_IS: - retval = EX_VAR(opline->result.var); - ZVAL_NULL(retval); + retval = &EG(uninitialized_zval); break; case BP_VAR_RW: zend_error(E_NOTICE,"Undefined variable: %s", name->val); @@ -35185,8 +35102,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_CONST(int type, Z zend_error(E_NOTICE,"Undefined variable: %s", name->val); /* break missing intentionally */ case BP_VAR_IS: - retval = EX_VAR(opline->result.var); - ZVAL_NULL(retval); + retval = &EG(uninitialized_zval); break; case BP_VAR_RW: zend_error(E_NOTICE,"Undefined variable: %s", name->val); @@ -35289,7 +35205,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } if (EXPECTED(opline->extended_value == 0)) { @@ -35315,7 +35231,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); @@ -35387,7 +35303,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); @@ -35448,7 +35364,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN property = opline->op2.zv; container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } @@ -35473,7 +35389,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA property = opline->op2.zv; container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); @@ -35534,7 +35450,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPC if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); } - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); @@ -35560,7 +35476,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC); property = opline->op2.zv; - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); @@ -35584,7 +35500,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND object = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); property_name = opline->op2.zv; - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); @@ -35605,7 +35521,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND SAVE_OPLINE(); object_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) { @@ -35623,34 +35539,30 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND zval *dim = opline->op2.zv; zval *variable_ptr; - zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CONST TSRMLS_CC); + variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CONST TSRMLS_CC); - value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); - variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) { - zend_assign_to_string_offset(variable_ptr, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); - } else if (UNEXPECTED(variable_ptr == &EG(error_zval))) { - if (IS_TMP_FREE(free_op_data1)) { - zval_dtor(value); - } - if (RETURN_VALUE_USED(opline)) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - FREE_OP_VAR_PTR(free_op_data2); + value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); + if (UNEXPECTED(variable_ptr != NULL)) { + zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); } else { - if ((opline+1)->op1_type == IS_TMP_VAR) { - value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); - } else if ((opline+1)->op1_type == IS_CONST) { - value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); + variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); + if (UNEXPECTED(variable_ptr == &EG(error_zval))) { + if (IS_TMP_FREE(free_op_data1)) { + zval_dtor(value); + } + if (RETURN_VALUE_USED(opline)) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + FREE_OP_VAR_PTR(free_op_data2); } else { - value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); - } - if (RETURN_VALUE_USED(opline)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); + value = zend_assign_to_variable(variable_ptr, value, (opline+1)->op1_type TSRMLS_CC); + if (RETURN_VALUE_USED(opline)) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + FREE_OP_VAR_PTR(free_op_data2); } - FREE_OP_VAR_PTR(free_op_data2); } - FREE_OP_IF_VAR(free_op_data1); + FREE_OP_IF_VAR(free_op_data1); } /* assign_dim has two opcodes! */ @@ -35670,9 +35582,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ value = opline->op2.zv; variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) { - zend_assign_to_string_offset(variable_ptr, value, IS_CONST, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); - } else if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) { + if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) { if (0) { zval_dtor(value); } @@ -35680,13 +35590,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - if (IS_CONST == IS_TMP_VAR) { - value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); - } else if (IS_CONST == IS_CONST) { - value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); - } else { - value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); - } + value = zend_assign_to_variable(variable_ptr, value, IS_CONST TSRMLS_CC); if (RETURN_VALUE_USED(opline)) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -35794,7 +35698,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCO if ((IS_CV == IS_VAR || IS_CV == IS_CV) && (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { expr_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } ZVAL_MAKE_REF(expr_ptr); @@ -35985,6 +35889,9 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDL SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC); + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { + zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); + } if (IS_CV != IS_UNUSED) { ZVAL_DEREF(container); SEPARATE_ZVAL_NOREF(container); @@ -36063,7 +35970,6 @@ numeric_index_dim: break; case IS_STRING: - case IS_STR_OFFSET: zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); ZEND_VM_CONTINUE(); /* bailed out before */ default: @@ -36084,7 +35990,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDL SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && Z_TYPE_P(container) == IS_STR_OFFSET) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); } offset = opline->op2.zv; @@ -36276,7 +36182,7 @@ num_index_prop: } } if (Z_TYPE_P(offset) == IS_LONG) { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) { + if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) { if ((opline->extended_value & ZEND_ISSET) || Z_STRVAL_P(container)[offset->value.lval] != '0') { result = 1; @@ -36368,7 +36274,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_A } else { zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); } @@ -36485,19 +36391,46 @@ static int ZEND_FASTCALL ZEND_BIND_GLOBAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN zval *varname; zval *value; zval *variable_ptr; - zend_string *name; + Bucket *p; + uint32_t idx; SAVE_OPLINE(); varname = opline->op2.zv; - name = Z_STR_P(varname); - value = zend_hash_find(&EG(symbol_table).ht, name); - if (value == NULL) { - value = zend_hash_add_new(&EG(symbol_table).ht, name, &EG(uninitialized_zval)); + idx = (uint32_t)(uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(varname)); + /* index 0 can't be cached (NULL is a mark of uninitialized cache slot) */ + p = EG(symbol_table).ht.arData + idx; + if (EXPECTED(idx > 0) && + EXPECTED(idx < EG(symbol_table).ht.nNumUsed) && + EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && + (EXPECTED(p->key == Z_STR_P(varname)) || + (EXPECTED(p->h == Z_STR_P(varname)->h) && + EXPECTED(p->key != NULL) && + EXPECTED(p->key->len == Z_STRLEN_P(varname)) && + EXPECTED(memcmp(p->key->val, Z_STRVAL_P(varname), Z_STRLEN_P(varname)) == 0)))) { + value = &EG(symbol_table).ht.arData[idx].val; /* GLOBAL variable may be an INDIRECT pointer to CV */ - } else if (Z_TYPE_P(value) == IS_INDIRECT) { - value = Z_INDIRECT_P(value); - if (Z_TYPE_P(value) == IS_UNDEF) { - ZVAL_NULL(value); + if (UNEXPECTED(Z_TYPE_P(value) == IS_INDIRECT)) { + value = Z_INDIRECT_P(value); + if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + ZVAL_NULL(value); + } + } + } else { + value = zend_hash_find(&EG(symbol_table).ht, Z_STR_P(varname)); + if (UNEXPECTED(value == NULL)) { + value = zend_hash_add_new(&EG(symbol_table).ht, Z_STR_P(varname), &EG(uninitialized_zval)); + idx = ((char*)value - (char*)EG(symbol_table).ht.arData) / sizeof(Bucket); + CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(uintptr_t)idx); + } else { + idx = ((char*)value - (char*)EG(symbol_table).ht.arData) / sizeof(Bucket); + CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(uintptr_t)idx); + /* GLOBAL variable may be an INDIRECT pointer to CV */ + if (UNEXPECTED(Z_TYPE_P(value) == IS_INDIRECT)) { + value = Z_INDIRECT_P(value); + if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + ZVAL_NULL(value); + } + } } } @@ -36792,7 +36725,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*bina zval *value; int have_get_ptr = 0; - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } @@ -36886,7 +36819,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_TMP(int (*bina SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (IS_CV == IS_VAR && !0) { @@ -36901,7 +36834,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_TMP(int (*bina var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); } - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { + if (UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); } @@ -36953,7 +36886,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_TMP(int (*binary_o value = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); var_ptr = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); } @@ -37148,7 +37081,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_TMP(incdec_t in property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); retval = EX_VAR(opline->result.var); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); } @@ -37240,7 +37173,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_TMP(incdec_t i property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); retval = EX_VAR(opline->result.var); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); } @@ -37340,7 +37273,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } if (EXPECTED(opline->extended_value == 0)) { @@ -37366,7 +37299,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); @@ -37438,7 +37371,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_H SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); @@ -37500,7 +37433,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } @@ -37525,7 +37458,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); @@ -37587,7 +37520,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCOD if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); } - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); @@ -37613,7 +37546,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_H container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC); property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); @@ -37637,7 +37570,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE object = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); property_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); @@ -37658,7 +37591,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE SAVE_OPLINE(); object_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) { @@ -37676,35 +37609,30 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); zval *variable_ptr; - zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_TMP_VAR TSRMLS_CC); + variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_TMP_VAR TSRMLS_CC); zval_dtor(free_op2.var); - - value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); - variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) { - zend_assign_to_string_offset(variable_ptr, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); - } else if (UNEXPECTED(variable_ptr == &EG(error_zval))) { - if (IS_TMP_FREE(free_op_data1)) { - zval_dtor(value); - } - if (RETURN_VALUE_USED(opline)) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - FREE_OP_VAR_PTR(free_op_data2); + value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); + if (UNEXPECTED(variable_ptr != NULL)) { + zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); } else { - if ((opline+1)->op1_type == IS_TMP_VAR) { - value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); - } else if ((opline+1)->op1_type == IS_CONST) { - value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); + variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); + if (UNEXPECTED(variable_ptr == &EG(error_zval))) { + if (IS_TMP_FREE(free_op_data1)) { + zval_dtor(value); + } + if (RETURN_VALUE_USED(opline)) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + FREE_OP_VAR_PTR(free_op_data2); } else { - value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); - } - if (RETURN_VALUE_USED(opline)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); + value = zend_assign_to_variable(variable_ptr, value, (opline+1)->op1_type TSRMLS_CC); + if (RETURN_VALUE_USED(opline)) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + FREE_OP_VAR_PTR(free_op_data2); } - FREE_OP_VAR_PTR(free_op_data2); } - FREE_OP_IF_VAR(free_op_data1); + FREE_OP_IF_VAR(free_op_data1); } /* assign_dim has two opcodes! */ @@ -37724,9 +37652,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR value = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) { - zend_assign_to_string_offset(variable_ptr, value, IS_TMP_VAR, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); - } else if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) { + if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) { if (1) { zval_dtor(value); } @@ -37734,13 +37660,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - if (IS_TMP_VAR == IS_TMP_VAR) { - value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); - } else if (IS_TMP_VAR == IS_CONST) { - value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); - } else { - value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); - } + value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR TSRMLS_CC); if (RETURN_VALUE_USED(opline)) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -37850,7 +37770,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE if ((IS_CV == IS_VAR || IS_CV == IS_CV) && (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { expr_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } ZVAL_MAKE_REF(expr_ptr); @@ -37969,6 +37889,9 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC); + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { + zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); + } if (IS_CV != IS_UNUSED) { ZVAL_DEREF(container); SEPARATE_ZVAL_NOREF(container); @@ -38047,7 +37970,6 @@ numeric_index_dim: zval_dtor(free_op2.var); break; case IS_STRING: - case IS_STR_OFFSET: zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); ZEND_VM_CONTINUE(); /* bailed out before */ default: @@ -38068,7 +37990,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && Z_TYPE_P(container) == IS_STR_OFFSET) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); } offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); @@ -38180,7 +38102,7 @@ num_index_prop: } } if (Z_TYPE_P(offset) == IS_LONG) { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) { + if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) { if ((opline->extended_value & ZEND_ISSET) || Z_STRVAL_P(container)[offset->value.lval] != '0') { result = 1; @@ -38274,7 +38196,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG } else { zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); } @@ -38668,7 +38590,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina zval *value; int have_get_ptr = 0; - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } @@ -38762,7 +38684,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_VAR(int (*bina SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (IS_CV == IS_VAR && !0) { @@ -38777,7 +38699,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_VAR(int (*bina var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); } - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { + if (UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); } @@ -38829,7 +38751,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_VAR(int (*binary_o value = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); var_ptr = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); } @@ -39024,7 +38946,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_VAR(incdec_t in property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); retval = EX_VAR(opline->result.var); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); } @@ -39116,7 +39038,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_VAR(incdec_t i property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); retval = EX_VAR(opline->result.var); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); } @@ -39244,8 +39166,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_VAR(int type, ZEN zend_error(E_NOTICE,"Undefined variable: %s", name->val); /* break missing intentionally */ case BP_VAR_IS: - retval = EX_VAR(opline->result.var); - ZVAL_NULL(retval); + retval = &EG(uninitialized_zval); break; case BP_VAR_RW: zend_error(E_NOTICE,"Undefined variable: %s", name->val); @@ -39265,8 +39186,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_VAR(int type, ZEN zend_error(E_NOTICE,"Undefined variable: %s", name->val); /* break missing intentionally */ case BP_VAR_IS: - retval = EX_VAR(opline->result.var); - ZVAL_NULL(retval); + retval = &EG(uninitialized_zval); break; case BP_VAR_RW: zend_error(E_NOTICE,"Undefined variable: %s", name->val); @@ -39369,7 +39289,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } if (EXPECTED(opline->extended_value == 0)) { @@ -39395,7 +39315,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); @@ -39467,7 +39387,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_H SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); @@ -39529,7 +39449,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } @@ -39554,7 +39474,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); @@ -39616,7 +39536,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCOD if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); } - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); @@ -39642,7 +39562,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_H container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC); property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); @@ -39666,7 +39586,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE object = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); @@ -39687,7 +39607,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE SAVE_OPLINE(); object_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) { @@ -39705,35 +39625,30 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); zval *variable_ptr; - zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_VAR TSRMLS_CC); + variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_VAR TSRMLS_CC); zval_ptr_dtor_nogc(free_op2.var); - - value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); - variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) { - zend_assign_to_string_offset(variable_ptr, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); - } else if (UNEXPECTED(variable_ptr == &EG(error_zval))) { - if (IS_TMP_FREE(free_op_data1)) { - zval_dtor(value); - } - if (RETURN_VALUE_USED(opline)) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - FREE_OP_VAR_PTR(free_op_data2); + value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); + if (UNEXPECTED(variable_ptr != NULL)) { + zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); } else { - if ((opline+1)->op1_type == IS_TMP_VAR) { - value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); - } else if ((opline+1)->op1_type == IS_CONST) { - value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); + variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); + if (UNEXPECTED(variable_ptr == &EG(error_zval))) { + if (IS_TMP_FREE(free_op_data1)) { + zval_dtor(value); + } + if (RETURN_VALUE_USED(opline)) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + FREE_OP_VAR_PTR(free_op_data2); } else { - value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); - } - if (RETURN_VALUE_USED(opline)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); + value = zend_assign_to_variable(variable_ptr, value, (opline+1)->op1_type TSRMLS_CC); + if (RETURN_VALUE_USED(opline)) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + FREE_OP_VAR_PTR(free_op_data2); } - FREE_OP_VAR_PTR(free_op_data2); } - FREE_OP_IF_VAR(free_op_data1); + FREE_OP_IF_VAR(free_op_data1); } /* assign_dim has two opcodes! */ @@ -39750,12 +39665,10 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR zval *variable_ptr; SAVE_OPLINE(); - value = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + value = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) { - zend_assign_to_string_offset(variable_ptr, value, IS_VAR, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); - } else if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) { + if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) { if (0) { zval_dtor(value); } @@ -39763,13 +39676,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - if (IS_VAR == IS_TMP_VAR) { - value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); - } else if (IS_VAR == IS_CONST) { - value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); - } else { - value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); - } + value = zend_assign_to_variable(variable_ptr, value, IS_VAR TSRMLS_CC); if (RETURN_VALUE_USED(opline)) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -39818,8 +39725,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE UNEXPECTED(!Z_ISREF_P(variable_ptr))) { zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object"); } - if ((IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) || - (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET))) { + if ((IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) || + (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == NULL))) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects"); } if ((IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) || @@ -39942,7 +39849,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_VAR_HANDLER(ZEND_OPCODE if ((IS_CV == IS_VAR || IS_CV == IS_CV) && (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { expr_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } ZVAL_MAKE_REF(expr_ptr); @@ -40133,6 +40040,9 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC); + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { + zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); + } if (IS_CV != IS_UNUSED) { ZVAL_DEREF(container); SEPARATE_ZVAL_NOREF(container); @@ -40211,7 +40121,6 @@ numeric_index_dim: zval_ptr_dtor_nogc(free_op2.var); break; case IS_STRING: - case IS_STR_OFFSET: zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); ZEND_VM_CONTINUE(); /* bailed out before */ default: @@ -40232,7 +40141,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && Z_TYPE_P(container) == IS_STR_OFFSET) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); } offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); @@ -40424,7 +40333,7 @@ num_index_prop: } } if (Z_TYPE_P(offset) == IS_LONG) { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) { + if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) { if ((opline->extended_value & ZEND_ISSET) || Z_STRVAL_P(container)[offset->value.lval] != '0') { result = 1; @@ -40518,7 +40427,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG } else { zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); } @@ -40637,7 +40546,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*b zval *value; int have_get_ptr = 0; - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } @@ -40730,7 +40639,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_UNUSED(int (*b SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (IS_CV == IS_VAR && !0) { @@ -40745,7 +40654,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_UNUSED(int (*b var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); } - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { + if (UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); } @@ -40797,7 +40706,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_UNUSED(int (*binar value = NULL; var_ptr = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); } @@ -41032,8 +40941,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_UNUSED(int type, zend_error(E_NOTICE,"Undefined variable: %s", name->val); /* break missing intentionally */ case BP_VAR_IS: - retval = EX_VAR(opline->result.var); - ZVAL_NULL(retval); + retval = &EG(uninitialized_zval); break; case BP_VAR_RW: zend_error(E_NOTICE,"Undefined variable: %s", name->val); @@ -41053,8 +40961,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_UNUSED(int type, zend_error(E_NOTICE,"Undefined variable: %s", name->val); /* break missing intentionally */ case BP_VAR_IS: - retval = EX_VAR(opline->result.var); - ZVAL_NULL(retval); + retval = &EG(uninitialized_zval); break; case BP_VAR_RW: zend_error(E_NOTICE,"Undefined variable: %s", name->val); @@ -41140,7 +41047,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HA SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } if (EXPECTED(opline->extended_value == 0)) { @@ -41166,7 +41073,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_H SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC); @@ -41223,7 +41130,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAN SAVE_OPLINE(); object_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) { @@ -41241,34 +41148,30 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAN zval *dim = NULL; zval *variable_ptr; - zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_UNUSED TSRMLS_CC); + variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_UNUSED TSRMLS_CC); - value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); - variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) { - zend_assign_to_string_offset(variable_ptr, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); - } else if (UNEXPECTED(variable_ptr == &EG(error_zval))) { - if (IS_TMP_FREE(free_op_data1)) { - zval_dtor(value); - } - if (RETURN_VALUE_USED(opline)) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - FREE_OP_VAR_PTR(free_op_data2); + value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); + if (UNEXPECTED(variable_ptr != NULL)) { + zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); } else { - if ((opline+1)->op1_type == IS_TMP_VAR) { - value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); - } else if ((opline+1)->op1_type == IS_CONST) { - value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); + variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); + if (UNEXPECTED(variable_ptr == &EG(error_zval))) { + if (IS_TMP_FREE(free_op_data1)) { + zval_dtor(value); + } + if (RETURN_VALUE_USED(opline)) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + FREE_OP_VAR_PTR(free_op_data2); } else { - value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); - } - if (RETURN_VALUE_USED(opline)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); + value = zend_assign_to_variable(variable_ptr, value, (opline+1)->op1_type TSRMLS_CC); + if (RETURN_VALUE_USED(opline)) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + FREE_OP_VAR_PTR(free_op_data2); } - FREE_OP_VAR_PTR(free_op_data2); } - FREE_OP_IF_VAR(free_op_data1); + FREE_OP_IF_VAR(free_op_data1); } /* assign_dim has two opcodes! */ @@ -41287,7 +41190,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPC if ((IS_CV == IS_VAR || IS_CV == IS_CV) && (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { expr_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } ZVAL_MAKE_REF(expr_ptr); @@ -41588,7 +41491,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ } else { zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); } @@ -41967,7 +41870,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binar zval *value; int have_get_ptr = 0; - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } @@ -42060,7 +41963,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CV(int (*binar SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (IS_CV == IS_VAR && !0) { @@ -42075,7 +41978,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_CV(int (*binar var_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); } - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { + if (UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); } @@ -42127,7 +42030,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_CV(int (*binary_op value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); var_ptr = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); } @@ -42322,7 +42225,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CV(incdec_t inc property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); retval = EX_VAR(opline->result.var); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); } @@ -42413,7 +42316,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CV(incdec_t in property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); retval = EX_VAR(opline->result.var); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); } @@ -42512,7 +42415,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } if (EXPECTED(opline->extended_value == 0)) { @@ -42538,7 +42441,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); @@ -42610,7 +42513,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HA SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); @@ -42671,7 +42574,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } @@ -42696,7 +42599,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW, 0 TSRMLS_CC); @@ -42757,7 +42660,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); } - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W, 0 TSRMLS_CC); @@ -42783,7 +42686,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HA container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC); property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(container) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } zend_fetch_property_address(EX_VAR(opline->result.var), container, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET, 0 TSRMLS_CC); @@ -42807,7 +42710,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER object = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); @@ -42828,7 +42731,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER SAVE_OPLINE(); object_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(object_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } if (UNEXPECTED(Z_ISREF_P(object_ptr)) && Z_TYPE_P(Z_REFVAL_P(object_ptr)) == IS_OBJECT) { @@ -42846,34 +42749,30 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER zval *dim = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); zval *variable_ptr; - zend_fetch_dimension_address_W(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CV TSRMLS_CC); + variable_ptr = zend_fetch_dimension_address_W_str(EX_VAR((opline+1)->op2.var), object_ptr, dim, IS_CV TSRMLS_CC); - value = get_zval_ptr((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); - variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); - if (UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) { - zend_assign_to_string_offset(variable_ptr, value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); - } else if (UNEXPECTED(variable_ptr == &EG(error_zval))) { - if (IS_TMP_FREE(free_op_data1)) { - zval_dtor(value); - } - if (RETURN_VALUE_USED(opline)) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - FREE_OP_VAR_PTR(free_op_data2); + value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); + if (UNEXPECTED(variable_ptr != NULL)) { + zend_assign_to_string_offset(variable_ptr, Z_LVAL_P(EX_VAR((opline+1)->op2.var)), value, (opline+1)->op1_type, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); } else { - if ((opline+1)->op1_type == IS_TMP_VAR) { - value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); - } else if ((opline+1)->op1_type == IS_CONST) { - value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); + variable_ptr = _get_zval_ptr_ptr_var((opline+1)->op2.var, execute_data, &free_op_data2 TSRMLS_CC); + if (UNEXPECTED(variable_ptr == &EG(error_zval))) { + if (IS_TMP_FREE(free_op_data1)) { + zval_dtor(value); + } + if (RETURN_VALUE_USED(opline)) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + FREE_OP_VAR_PTR(free_op_data2); } else { - value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); - } - if (RETURN_VALUE_USED(opline)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); + value = zend_assign_to_variable(variable_ptr, value, (opline+1)->op1_type TSRMLS_CC); + if (RETURN_VALUE_USED(opline)) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + FREE_OP_VAR_PTR(free_op_data2); } - FREE_OP_VAR_PTR(free_op_data2); } - FREE_OP_IF_VAR(free_op_data1); + FREE_OP_IF_VAR(free_op_data1); } /* assign_dim has two opcodes! */ @@ -42890,12 +42789,10 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG zval *variable_ptr; SAVE_OPLINE(); - value = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); + value = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET)) { - zend_assign_to_string_offset(variable_ptr, value, IS_CV, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); - } else if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) { + if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) { if (0) { zval_dtor(value); } @@ -42903,13 +42800,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - if (IS_CV == IS_TMP_VAR) { - value = zend_assign_tmp_to_variable(variable_ptr, value TSRMLS_CC); - } else if (IS_CV == IS_CONST) { - value = zend_assign_const_to_variable(variable_ptr, value TSRMLS_CC); - } else { - value = zend_assign_to_variable(variable_ptr, value TSRMLS_CC); - } + value = zend_assign_to_variable(variable_ptr, value, IS_CV TSRMLS_CC); if (RETURN_VALUE_USED(opline)) { ZVAL_COPY(EX_VAR(opline->result.var), value); } @@ -42957,8 +42848,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER UNEXPECTED(!Z_ISREF_P(variable_ptr))) { zend_error_noreturn(E_ERROR, "Cannot assign by reference to overloaded object"); } - if ((IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) || - (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(variable_ptr) == IS_STR_OFFSET))) { + if ((IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) || + (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == NULL))) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects"); } if ((IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) || @@ -43078,7 +42969,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_ if ((IS_CV == IS_VAR || IS_CV == IS_CV) && (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { expr_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(expr_ptr) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } ZVAL_MAKE_REF(expr_ptr); @@ -43197,6 +43088,9 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC); + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { + zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); + } if (IS_CV != IS_UNUSED) { ZVAL_DEREF(container); SEPARATE_ZVAL_NOREF(container); @@ -43275,7 +43169,6 @@ numeric_index_dim: break; case IS_STRING: - case IS_STR_OFFSET: zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); ZEND_VM_CONTINUE(); /* bailed out before */ default: @@ -43296,7 +43189,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && Z_TYPE_P(container) == IS_STR_OFFSET) { + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); } offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); @@ -43408,7 +43301,7 @@ num_index_prop: } } if (Z_TYPE_P(offset) == IS_LONG) { - if (offset->value.lval >= 0 && offset->value.lval < Z_STRLEN_P(container)) { + if (offset->value.lval >= 0 && (size_t)offset->value.lval < Z_STRLEN_P(container)) { if ((opline->extended_value & ZEND_ISSET) || Z_STRVAL_P(container)[offset->value.lval] != '0') { result = 1; @@ -43500,7 +43393,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS } else { zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); - if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(value_ptr) == IS_STR_OFFSET)) { + if (IS_CV == IS_VAR && UNEXPECTED(value_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); } @@ -47545,56 +47438,56 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_QM_ASSIGN_VAR_SPEC_CONST_HANDLER, - ZEND_QM_ASSIGN_VAR_SPEC_CONST_HANDLER, - ZEND_QM_ASSIGN_VAR_SPEC_CONST_HANDLER, - ZEND_QM_ASSIGN_VAR_SPEC_CONST_HANDLER, - ZEND_QM_ASSIGN_VAR_SPEC_CONST_HANDLER, - ZEND_QM_ASSIGN_VAR_SPEC_TMP_HANDLER, - ZEND_QM_ASSIGN_VAR_SPEC_TMP_HANDLER, - ZEND_QM_ASSIGN_VAR_SPEC_TMP_HANDLER, - ZEND_QM_ASSIGN_VAR_SPEC_TMP_HANDLER, - ZEND_QM_ASSIGN_VAR_SPEC_TMP_HANDLER, - ZEND_QM_ASSIGN_VAR_SPEC_VAR_HANDLER, - ZEND_QM_ASSIGN_VAR_SPEC_VAR_HANDLER, - ZEND_QM_ASSIGN_VAR_SPEC_VAR_HANDLER, - ZEND_QM_ASSIGN_VAR_SPEC_VAR_HANDLER, - ZEND_QM_ASSIGN_VAR_SPEC_VAR_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_QM_ASSIGN_VAR_SPEC_CV_HANDLER, - ZEND_QM_ASSIGN_VAR_SPEC_CV_HANDLER, - ZEND_QM_ASSIGN_VAR_SPEC_CV_HANDLER, - ZEND_QM_ASSIGN_VAR_SPEC_CV_HANDLER, - ZEND_QM_ASSIGN_VAR_SPEC_CV_HANDLER, - ZEND_JMP_SET_VAR_SPEC_CONST_HANDLER, - ZEND_JMP_SET_VAR_SPEC_CONST_HANDLER, - ZEND_JMP_SET_VAR_SPEC_CONST_HANDLER, - ZEND_JMP_SET_VAR_SPEC_CONST_HANDLER, - ZEND_JMP_SET_VAR_SPEC_CONST_HANDLER, - ZEND_JMP_SET_VAR_SPEC_TMP_HANDLER, - ZEND_JMP_SET_VAR_SPEC_TMP_HANDLER, - ZEND_JMP_SET_VAR_SPEC_TMP_HANDLER, - ZEND_JMP_SET_VAR_SPEC_TMP_HANDLER, - ZEND_JMP_SET_VAR_SPEC_TMP_HANDLER, - ZEND_JMP_SET_VAR_SPEC_VAR_HANDLER, - ZEND_JMP_SET_VAR_SPEC_VAR_HANDLER, - ZEND_JMP_SET_VAR_SPEC_VAR_HANDLER, - ZEND_JMP_SET_VAR_SPEC_VAR_HANDLER, - ZEND_JMP_SET_VAR_SPEC_VAR_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_JMP_SET_VAR_SPEC_CV_HANDLER, - ZEND_JMP_SET_VAR_SPEC_CV_HANDLER, - ZEND_JMP_SET_VAR_SPEC_CV_HANDLER, - ZEND_JMP_SET_VAR_SPEC_CV_HANDLER, - ZEND_JMP_SET_VAR_SPEC_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_DISCARD_EXCEPTION_SPEC_HANDLER, ZEND_DISCARD_EXCEPTION_SPEC_HANDLER, ZEND_DISCARD_EXCEPTION_SPEC_HANDLER, |
