diff options
| author | Xinchen Hui <laruence@php.net> | 2015-04-02 09:03:48 +0800 |
|---|---|---|
| committer | Xinchen Hui <laruence@php.net> | 2015-04-02 09:03:48 +0800 |
| commit | f8461d4aa31ff12a513a0e0e4d19b160889f279e (patch) | |
| tree | 60ceccb15d58243e98a6eff45e4a506ce04dacb8 | |
| parent | ed43b7a5487c7ea245ae5b7ecd4f0a4f349e1b3b (diff) | |
| parent | 53d20140fbe4a5fa4339a7429280b4a964f5791d (diff) | |
| download | php-git-f8461d4aa31ff12a513a0e0e4d19b160889f279e.tar.gz | |
Merge branch 'master' of https://git.php.net/repository/php-src
30 files changed, 956 insertions, 673 deletions
diff --git a/Zend/tests/bug43201.phpt b/Zend/tests/bug43201.phpt index 89e1b66727..53bb5ba98d 100644 --- a/Zend/tests/bug43201.phpt +++ b/Zend/tests/bug43201.phpt @@ -1,5 +1,5 @@ --TEST-- -Bug #43201 (Crash on using unitialized vals and __get/__set) +Bug #43201 (Crash on using uninitialized vals and __get/__set) --FILE-- <?php class Foo { diff --git a/Zend/zend_API.c b/Zend/zend_API.c index d10587aec1..bc7c0ffc46 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -1119,7 +1119,7 @@ static int zval_update_class_constant(zval *pp, int is_static, uint32_t offset) int ret; zend_class_entry *old_scope = *scope; *scope = prop_info->ce; - ret = zval_update_constant(pp, 1); + ret = zval_update_constant_ex(pp, 1, NULL); *scope = old_scope; return ret; } @@ -1128,13 +1128,13 @@ static int zval_update_class_constant(zval *pp, int is_static, uint32_t offset) } while (ce); } - return zval_update_constant(pp, 1); + return zval_update_constant_ex(pp, 1, NULL); } - return 0; + return SUCCESS; } /* }}} */ -ZEND_API void zend_update_class_constants(zend_class_entry *class_type) /* {{{ */ +ZEND_API int zend_update_class_constants(zend_class_entry *class_type) /* {{{ */ { int i; @@ -1143,7 +1143,9 @@ ZEND_API void zend_update_class_constants(zend_class_entry *class_type) /* {{{ * zval *p; if (class_type->parent) { - zend_update_class_constants(class_type->parent); + if (UNEXPECTED(zend_update_class_constants(class_type->parent) != SUCCESS)) { + return FAILURE; + } } #if ZTS CG(static_members_table)[(zend_intptr_t)(class_type->static_members_table)] = emalloc(sizeof(zval) * class_type->default_static_members_count); @@ -1177,22 +1179,29 @@ ZEND_API void zend_update_class_constants(zend_class_entry *class_type) /* {{{ * *scope = class_type; ZEND_HASH_FOREACH_VAL(&class_type->constants_table, val) { - zval_update_constant(val, 1); + if (UNEXPECTED(zval_update_constant_ex(val, 1, class_type) != SUCCESS)) { + return FAILURE; + } } ZEND_HASH_FOREACH_END(); for (i = 0; i < class_type->default_properties_count; i++) { if (Z_TYPE(class_type->default_properties_table[i]) != IS_UNDEF) { - zval_update_class_constant(&class_type->default_properties_table[i], 0, OBJ_PROP_TO_OFFSET(i)); + if (UNEXPECTED(zval_update_class_constant(&class_type->default_properties_table[i], 0, OBJ_PROP_TO_OFFSET(i)) != SUCCESS)) { + return FAILURE; + } } } for (i = 0; i < class_type->default_static_members_count; i++) { - zval_update_class_constant(&CE_STATIC_MEMBERS(class_type)[i], 1, i); + if (UNEXPECTED(zval_update_class_constant(&CE_STATIC_MEMBERS(class_type)[i], 1, i) != SUCCESS)) { + return FAILURE; + } } *scope = old_scope; class_type->ce_flags |= ZEND_ACC_CONSTANTS_UPDATED; } + return SUCCESS; } /* }}} */ @@ -1271,17 +1280,24 @@ ZEND_API void object_properties_load(zend_object *object, HashTable *properties) * calling zend_merge_properties(). */ ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *class_type, HashTable *properties ZEND_FILE_LINE_DC) /* {{{ */ { - if (class_type->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) { + if (UNEXPECTED(class_type->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))) { if (class_type->ce_flags & ZEND_ACC_INTERFACE) { - zend_error_noreturn(E_ERROR, "Cannot instantiate interface %s", class_type->name->val); + zend_error(E_EXCEPTION | E_ERROR, "Cannot instantiate interface %s", class_type->name->val); } else if (class_type->ce_flags & ZEND_ACC_TRAIT) { - zend_error_noreturn(E_ERROR, "Cannot instantiate trait %s", class_type->name->val); + zend_error(E_EXCEPTION | E_ERROR, "Cannot instantiate trait %s", class_type->name->val); } else { - zend_error_noreturn(E_ERROR, "Cannot instantiate abstract class %s", class_type->name->val); + zend_error(E_EXCEPTION | E_ERROR, "Cannot instantiate abstract class %s", class_type->name->val); } + ZVAL_NULL(arg); + Z_OBJ_P(arg) = NULL; + return FAILURE; } - zend_update_class_constants(class_type); + if (UNEXPECTED(zend_update_class_constants(class_type) != SUCCESS)) { + ZVAL_NULL(arg); + Z_OBJ_P(arg) = NULL; + return FAILURE; + } if (class_type->create_object == NULL) { ZVAL_OBJ(arg, zend_objects_new(class_type)); @@ -3103,7 +3119,7 @@ get_function_via_handler: verb = "should not"; } else { /* An internal function assumes $this is present and won't check that. So PHP would crash by allowing the call. */ - severity = E_ERROR; + severity = E_ERROR; //TODO: add E_EXCEPTION??? verb = "cannot"; } if ((check_flags & IS_CALLABLE_CHECK_IS_STATIC) != 0) { diff --git a/Zend/zend_API.h b/Zend/zend_API.h index b8547e685e..23ec35f00c 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -325,7 +325,8 @@ ZEND_API int zend_declare_class_constant_double(zend_class_entry *ce, const char ZEND_API int zend_declare_class_constant_stringl(zend_class_entry *ce, const char *name, size_t name_length, const char *value, size_t value_length); ZEND_API int zend_declare_class_constant_string(zend_class_entry *ce, const char *name, size_t name_length, const char *value); -ZEND_API void zend_update_class_constants(zend_class_entry *class_type); +ZEND_API int zend_update_class_constants(zend_class_entry *class_type); + ZEND_API void zend_update_property(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zval *value); ZEND_API void zend_update_property_null(zend_class_entry *scope, zval *object, const char *name, size_t name_length); ZEND_API void zend_update_property_bool(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_long value); diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index b8a2d45474..d538a2191f 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -177,7 +177,7 @@ ZEND_API zend_ast *zend_ast_list_add(zend_ast *ast, zend_ast *op) { return (zend_ast *) list; } -static void zend_ast_add_array_element(zval *result, zval *offset, zval *expr) +static int zend_ast_add_array_element(zval *result, zval *offset, zval *expr) { switch (Z_TYPE_P(offset)) { case IS_UNDEF: @@ -203,68 +203,90 @@ static void zend_ast_add_array_element(zval *result, zval *offset, zval *expr) zend_hash_index_update(Z_ARRVAL_P(result), zend_dval_to_lval(Z_DVAL_P(offset)), expr); break; default: - zend_error_noreturn(E_ERROR, "Illegal offset type"); - break; + zend_error(E_EXCEPTION | E_ERROR, "Illegal offset type"); + return FAILURE; } + return SUCCESS; } -ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *scope) +ZEND_API int zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *scope) { zval op1, op2; + int ret = SUCCESS; switch (ast->kind) { case ZEND_AST_BINARY_OP: - { - binary_op_type op = get_binary_op(ast->attr); - zend_ast_evaluate(&op1, ast->child[0], scope); - zend_ast_evaluate(&op2, ast->child[1], scope); - op(result, &op1, &op2); - zval_dtor(&op1); - zval_dtor(&op2); + if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) { + ret = FAILURE; + } else if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[1], scope) != SUCCESS)) { + zval_dtor(&op1); + ret = FAILURE; + } else { + binary_op_type op = get_binary_op(ast->attr); + ret = op(result, &op1, &op2); + zval_dtor(&op1); + zval_dtor(&op2); + } break; - } case ZEND_AST_GREATER: case ZEND_AST_GREATER_EQUAL: - { - /* op1 > op2 is the same as op2 < op1 */ - binary_op_type op = ast->kind == ZEND_AST_GREATER - ? is_smaller_function : is_smaller_or_equal_function; - zend_ast_evaluate(&op1, ast->child[0], scope); - zend_ast_evaluate(&op2, ast->child[1], scope); - op(result, &op2, &op1); - zval_dtor(&op1); - zval_dtor(&op2); + if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) { + ret = FAILURE; + } else if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[1], scope) != SUCCESS)) { + zval_dtor(&op1); + ret = FAILURE; + } else { + /* op1 > op2 is the same as op2 < op1 */ + binary_op_type op = ast->kind == ZEND_AST_GREATER + ? is_smaller_function : is_smaller_or_equal_function; + ret = op(result, &op2, &op1); + zval_dtor(&op1); + zval_dtor(&op2); + } break; - } case ZEND_AST_UNARY_OP: - { - unary_op_type op = get_unary_op(ast->attr); - zend_ast_evaluate(&op1, ast->child[0], scope); - op(result, &op1); - zval_dtor(&op1); + if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) { + ret = FAILURE; + } else { + unary_op_type op = get_unary_op(ast->attr); + ret = op(result, &op1); + zval_dtor(&op1); + } break; - } case ZEND_AST_ZVAL: { zval *zv = zend_ast_get_zval(ast); if (scope) { /* class constants may be updated in-place */ if (Z_OPT_CONSTANT_P(zv)) { - zval_update_constant_ex(zv, 1, scope); + if (UNEXPECTED(zval_update_constant_ex(zv, 1, scope) != SUCCESS)) { + ret = FAILURE; + break; + } } ZVAL_DUP(result, zv); } else { ZVAL_DUP(result, zv); if (Z_OPT_CONSTANT_P(result)) { - zval_update_constant_ex(result, 1, scope); + if (UNEXPECTED(zval_update_constant_ex(result, 1, scope) != SUCCESS)) { + ret = FAILURE; + break; + } } } break; } case ZEND_AST_AND: - zend_ast_evaluate(&op1, ast->child[0], scope); + if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) { + ret = FAILURE; + break; + } if (zend_is_true(&op1)) { - zend_ast_evaluate(&op2, ast->child[1], scope); + if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[1], scope) != SUCCESS)) { + zval_dtor(&op1); + ret = FAILURE; + break; + } ZVAL_BOOL(result, zend_is_true(&op2)); zval_dtor(&op2); } else { @@ -273,41 +295,65 @@ ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *s zval_dtor(&op1); break; case ZEND_AST_OR: - zend_ast_evaluate(&op1, ast->child[0], scope); + if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) { + ret = FAILURE; + break; + } if (zend_is_true(&op1)) { ZVAL_TRUE(result); } else { - zend_ast_evaluate(&op2, ast->child[1], scope); + if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[1], scope) != SUCCESS)) { + zval_dtor(&op1); + ret = FAILURE; + break; + } ZVAL_BOOL(result, zend_is_true(&op2)); zval_dtor(&op2); } zval_dtor(&op1); break; case ZEND_AST_CONDITIONAL: - zend_ast_evaluate(&op1, ast->child[0], scope); + if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) { + ret = FAILURE; + break; + } if (zend_is_true(&op1)) { if (!ast->child[1]) { *result = op1; } else { - zend_ast_evaluate(result, ast->child[1], scope); + if (UNEXPECTED(zend_ast_evaluate(result, ast->child[1], scope) != SUCCESS)) { + zval_dtor(&op1); + ret = FAILURE; + break; + } zval_dtor(&op1); } } else { - zend_ast_evaluate(result, ast->child[2], scope); + if (UNEXPECTED(zend_ast_evaluate(result, ast->child[2], scope) != SUCCESS)) { + zval_dtor(&op1); + ret = FAILURE; + break; + } zval_dtor(&op1); } break; case ZEND_AST_UNARY_PLUS: - ZVAL_LONG(&op1, 0); - zend_ast_evaluate(&op2, ast->child[0], scope); - add_function(result, &op1, &op2); - zval_dtor(&op2); + if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[0], scope) != SUCCESS)) { + ret = FAILURE; + } else { + ZVAL_LONG(&op1, 0); + ret = add_function(result, &op1, &op2); + zval_dtor(&op2); + } break; case ZEND_AST_UNARY_MINUS: - ZVAL_LONG(&op1, 0); - zend_ast_evaluate(&op2, ast->child[0], scope); - sub_function(result, &op1, &op2); - zval_dtor(&op2); + if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[0], scope) != SUCCESS)) { + ret = FAILURE; + } else { + ZVAL_LONG(&op1, 0); + ret = sub_function(result, &op1, &op2); + zval_dtor(&op2); + } break; case ZEND_AST_ARRAY: array_init(result); @@ -317,29 +363,47 @@ ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *s for (i = 0; i < list->children; i++) { zend_ast *elem = list->child[i]; if (elem->child[1]) { - zend_ast_evaluate(&op1, elem->child[1], scope); + if (UNEXPECTED(zend_ast_evaluate(&op1, elem->child[1], scope) != SUCCESS)) { + zval_dtor(result); + return FAILURE; + } } else { ZVAL_UNDEF(&op1); } - zend_ast_evaluate(&op2, elem->child[0], scope); - zend_ast_add_array_element(result, &op1, &op2); + if (UNEXPECTED(zend_ast_evaluate(&op2, elem->child[0], scope) != SUCCESS)) { + zval_dtor(&op1); + zval_dtor(result); + return FAILURE; + } + if (UNEXPECTED(zend_ast_add_array_element(result, &op1, &op2) != SUCCESS)) { + zval_dtor(&op1); + zval_dtor(&op2); + zval_dtor(result); + return FAILURE; + } } } break; case ZEND_AST_DIM: - zend_ast_evaluate(&op1, ast->child[0], scope); - zend_ast_evaluate(&op2, ast->child[1], scope); - { + if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) { + ret = FAILURE; + } else if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[1], scope) != SUCCESS)) { + zval_dtor(&op1); + ret = FAILURE; + } else { zval tmp; + zend_fetch_dimension_by_zval(&tmp, &op1, &op2); ZVAL_ZVAL(result, &tmp, 1, 1); + zval_dtor(&op1); + zval_dtor(&op2); } - zval_dtor(&op1); - zval_dtor(&op2); break; default: - zend_error_noreturn(E_ERROR, "Unsupported constant expression"); + zend_error(E_EXCEPTION | E_ERROR, "Unsupported constant expression"); + ret = FAILURE; } + return ret; } ZEND_API zend_ast *zend_ast_copy(zend_ast *ast) diff --git a/Zend/zend_ast.h b/Zend/zend_ast.h index 8cd06419be..553578f848 100644 --- a/Zend/zend_ast.h +++ b/Zend/zend_ast.h @@ -203,7 +203,7 @@ ZEND_API zend_ast *zend_ast_create_decl( ZEND_API zend_ast *zend_ast_create_list(uint32_t init_children, zend_ast_kind kind, ...); ZEND_API zend_ast *zend_ast_list_add(zend_ast *list, zend_ast *op); -ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *scope); +ZEND_API int zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *scope); ZEND_API zend_string *zend_ast_export(const char *prefix, zend_ast *ast, const char *suffix); ZEND_API zend_ast *zend_ast_copy(zend_ast *ast); diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 275fcf9cff..0d9e3c002c 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -1075,7 +1075,9 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value /* this is necessary to make it able to work with default array * properties, returned to user */ if (Z_OPT_CONSTANT_P(prop)) { - zval_update_constant(prop, 0); + if (UNEXPECTED(zval_update_constant_ex(prop, 0, NULL) != SUCCESS)) { + return; + } } zend_hash_add_new(Z_ARRVAL_P(return_value), key, prop); @@ -1099,7 +1101,9 @@ ZEND_FUNCTION(get_class_vars) RETURN_FALSE; } else { array_init(return_value); - zend_update_class_constants(ce); + if (UNEXPECTED(zend_update_class_constants(ce) != SUCCESS)) { + return; + } add_class_vars(ce, 0, return_value); add_class_vars(ce, 1, return_value); } diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 298fa8c58f..70359123c4 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -983,12 +983,12 @@ ZEND_API int do_bind_function(const zend_op_array *op_array, const zend_op *opli if ((old_function = zend_hash_find_ptr(function_table, Z_STR_P(op2))) != NULL && old_function->type == ZEND_USER_FUNCTION && old_function->op_array.last > 0) { - zend_error(error_level, "Cannot redeclare %s() (previously declared in %s:%d)", + zend_error_noreturn(error_level, "Cannot redeclare %s() (previously declared in %s:%d)", function->common.function_name->val, old_function->op_array.filename->val, old_function->op_array.opcodes[0].lineno); } else { - zend_error(error_level, "Cannot redeclare %s()", function->common.function_name->val); + zend_error_noreturn(error_level, "Cannot redeclare %s()", function->common.function_name->val); } return FAILURE; } else { @@ -2060,7 +2060,7 @@ static inline void zend_set_class_name_op1(zend_op *opline, znode *class_node) / } /* }}} */ -static zend_op *zend_compile_class_ref(znode *result, zend_ast *name_ast) /* {{{ */ +static zend_op *zend_compile_class_ref(znode *result, zend_ast *name_ast, int throw_exception) /* {{{ */ { zend_op *opline; znode name_node; @@ -2071,7 +2071,7 @@ static zend_op *zend_compile_class_ref(znode *result, zend_ast *name_ast) /* {{{ uint32_t fetch_type = zend_get_class_fetch_type(name); opline = zend_emit_op(result, ZEND_FETCH_CLASS, NULL, NULL); - opline->extended_value = fetch_type; + opline->extended_value = fetch_type | (throw_exception ? ZEND_FETCH_CLASS_EXCEPTION : 0); if (fetch_type == ZEND_FETCH_CLASS_DEFAULT) { uint32_t type = name_ast->kind == ZEND_AST_ZVAL ? name_ast->attr : ZEND_NAME_FQ; @@ -2083,7 +2083,7 @@ static zend_op *zend_compile_class_ref(znode *result, zend_ast *name_ast) /* {{{ zend_string_release(name); } else { opline = zend_emit_op(result, ZEND_FETCH_CLASS, NULL, &name_node); - opline->extended_value = ZEND_FETCH_CLASS_DEFAULT; + opline->extended_value = ZEND_FETCH_CLASS_DEFAULT | (throw_exception ? ZEND_FETCH_CLASS_EXCEPTION : 0); } return opline; @@ -2300,7 +2300,7 @@ zend_op *zend_compile_static_prop_common(znode *result, zend_ast *ast, uint32_t class_node.op_type = IS_CONST; ZVAL_STR(&class_node.u.constant, zend_resolve_class_name_ast(class_ast)); } else { - zend_compile_class_ref(&class_node, class_ast); + zend_compile_class_ref(&class_node, class_ast, 1); } zend_compile_expr(&prop_node, prop_ast); @@ -3191,7 +3191,7 @@ void zend_compile_static_call(znode *result, zend_ast *ast, uint32_t type) /* {{ class_node.op_type = IS_CONST; ZVAL_STR(&class_node.u.constant, zend_resolve_class_name_ast(class_ast)); } else { - opline = zend_compile_class_ref(&class_node, class_ast); + opline = zend_compile_class_ref(&class_node, class_ast, 1); extended_value = opline->extended_value; } @@ -3243,7 +3243,7 @@ void zend_compile_new(znode *result, zend_ast *ast) /* {{{ */ class_node.op_type = IS_CONST; ZVAL_STR(&class_node.u.constant, zend_resolve_class_name_ast(class_ast)); } else { - zend_compile_class_ref(&class_node, class_ast); + zend_compile_class_ref(&class_node, class_ast, 1); } opnum = get_next_op_number(CG(active_op_array)); @@ -4924,7 +4924,7 @@ void zend_compile_class_decl(zend_ast *ast) /* {{{ */ "Cannot use '%s' as class name as it is reserved", extends_name->val); } - zend_compile_class_ref(&extends_node, extends_ast); + zend_compile_class_ref(&extends_node, extends_ast, 0); } opline = get_next_op(CG(active_op_array)); @@ -5915,7 +5915,7 @@ void zend_compile_instanceof(znode *result, zend_ast *ast) /* {{{ */ class_node.op_type = IS_CONST; ZVAL_STR(&class_node.u.constant, zend_resolve_class_name_ast(class_ast)); } else { - opline = zend_compile_class_ref(&class_node, class_ast); + opline = zend_compile_class_ref(&class_node, class_ast, 0); opline->extended_value |= ZEND_FETCH_CLASS_NO_AUTOLOAD; } @@ -6192,7 +6192,7 @@ void zend_compile_class_const(znode *result, zend_ast *ast) /* {{{ */ if (class_ast->kind == ZEND_AST_ZVAL) { zend_string_release(resolved_name); } - zend_compile_class_ref(&class_node, class_ast); + zend_compile_class_ref(&class_node, class_ast, 1); } zend_compile_expr(&const_node, const_ast); diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index c53833f149..322a7d32e7 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -770,6 +770,7 @@ ZEND_API void zend_assert_valid_class_name(const zend_string *const_name); #define ZEND_FETCH_CLASS_MASK 0x0f #define ZEND_FETCH_CLASS_NO_AUTOLOAD 0x80 #define ZEND_FETCH_CLASS_SILENT 0x0100 +#define ZEND_FETCH_CLASS_EXCEPTION 0x0200 /* variable parsing type (compile-time) */ #define ZEND_PARSED_MEMBER (1<<0) diff --git a/Zend/zend_constants.c b/Zend/zend_constants.c index cd8b58803d..32f249ce08 100644 --- a/Zend/zend_constants.c +++ b/Zend/zend_constants.c @@ -331,27 +331,30 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope, if (class_name_len == sizeof("self")-1 && !memcmp(lcname, "self", sizeof("self")-1)) { - if (scope) { - ce = scope; - } else { - zend_error_noreturn(E_ERROR, "Cannot access self:: when no class scope is active"); + if (UNEXPECTED(!scope)) { + zend_error(E_EXCEPTION | E_ERROR, "Cannot access self:: when no class scope is active"); + return NULL; } + ce = scope; } else if (class_name_len == sizeof("parent")-1 && !memcmp(lcname, "parent", sizeof("parent")-1)) { - if (!scope) { - zend_error_noreturn(E_ERROR, "Cannot access parent:: when no class scope is active"); - } else if (!scope->parent) { - zend_error_noreturn(E_ERROR, "Cannot access parent:: when current class scope has no parent"); + if (UNEXPECTED(!scope)) { + zend_error(E_EXCEPTION | E_ERROR, "Cannot access parent:: when no class scope is active"); + return NULL; + } else if (UNEXPECTED(!scope->parent)) { + zend_error(E_EXCEPTION | E_ERROR, "Cannot access parent:: when current class scope has no parent"); + return NULL; } else { ce = scope->parent; } } else if (class_name_len == sizeof("static")-1 && !memcmp(lcname, "static", sizeof("static")-1)) { - if (EG(current_execute_data) && EG(current_execute_data)->called_scope) { - ce = EG(current_execute_data)->called_scope; - } else { - zend_error_noreturn(E_ERROR, "Cannot access static:: when no class scope is active"); + if (UNEXPECTED(!EG(current_execute_data)) || + UNEXPECTED(!EG(current_execute_data)->called_scope)) { + zend_error(E_EXCEPTION | E_ERROR, "Cannot access static:: when no class scope is active"); + return NULL; } + ce = EG(current_execute_data)->called_scope; } else { ce = zend_fetch_class(class_name, flags); } @@ -360,7 +363,10 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope, ret_constant = zend_hash_find(&ce->constants_table, constant_name); if (ret_constant == NULL) { if ((flags & ZEND_FETCH_CLASS_SILENT) == 0) { - zend_error_noreturn(E_ERROR, "Undefined class constant '%s::%s'", class_name->val, constant_name->val); + zend_error(E_EXCEPTION | E_ERROR, "Undefined class constant '%s::%s'", class_name->val, constant_name->val); + zend_string_release(class_name); + zend_string_free(constant_name); + return NULL; } } else if (Z_ISREF_P(ret_constant)) { ret_constant = Z_REFVAL_P(ret_constant); @@ -369,7 +375,9 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope, zend_string_release(class_name); zend_string_free(constant_name); if (ret_constant && Z_CONSTANT_P(ret_constant)) { - zval_update_constant_ex(ret_constant, 1, ce); + if (UNEXPECTED(zval_update_constant_ex(ret_constant, 1, ce) != SUCCESS)) { + return NULL; + } } return ret_constant; } diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 06c25c7bc1..424f4888e9 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -629,7 +629,9 @@ static int is_null_constant(zval *default_value) zval constant; ZVAL_COPY_VALUE(&constant, default_value); - zval_update_constant(&constant, 0); + if (UNEXPECTED(zval_update_constant_ex(&constant, 0, NULL) != SUCCESS)) { + return 0; + } if (Z_TYPE(constant) == IS_NULL) { return 1; } @@ -1714,7 +1716,6 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c static inline zend_brk_cont_element* zend_brk_cont(int nest_levels, int array_offset, const zend_op_array *op_array, const zend_execute_data *execute_data) { - int original_nest_levels = nest_levels; zend_brk_cont_element *jmp_to; do { diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index 239185ccb7..dce9e1c040 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -113,8 +113,6 @@ static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval } ZEND_API int zval_update_constant(zval *pp, zend_bool inline_change); -ZEND_API int zval_update_constant_inline_change(zval *pp, zend_class_entry *scope); -ZEND_API int zval_update_constant_no_inline_change(zval *pp, zend_class_entry *scope); ZEND_API int zval_update_constant_ex(zval *pp, zend_bool inline_change, zend_class_entry *scope); /* dedicated Zend executor functions - do not use! */ diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index fc212dbbd7..f6090685d9 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -520,6 +520,7 @@ ZEND_API void _zval_internal_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC) /* {{{ * #define IS_VISITED_CONSTANT 0x80 #define IS_CONSTANT_VISITED(p) (Z_TYPE_P(p) & IS_VISITED_CONSTANT) #define MARK_CONSTANT_VISITED(p) Z_TYPE_INFO_P(p) |= IS_VISITED_CONSTANT +#define RESET_CONSTANT_VISITED(p) Z_TYPE_INFO_P(p) &= ~IS_VISITED_CONSTANT ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_class_entry *scope) /* {{{ */ { @@ -527,7 +528,8 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas char *colon; if (IS_CONSTANT_VISITED(p)) { - zend_error_noreturn(E_ERROR, "Cannot declare self-referencing constant '%s'", Z_STRVAL_P(p)); + zend_error(E_EXCEPTION | E_ERROR, "Cannot declare self-referencing constant '%s'", Z_STRVAL_P(p)); + return FAILURE; } else if (Z_TYPE_P(p) == IS_CONSTANT) { int refcount; @@ -544,22 +546,18 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas } else { ZVAL_EMPTY_STRING(p); } - } else if ((const_value = zend_get_constant_ex(Z_STR_P(p), scope, Z_CONST_FLAGS_P(p))) == NULL) { + } else if (UNEXPECTED((const_value = zend_get_constant_ex(Z_STR_P(p), scope, Z_CONST_FLAGS_P(p))) == NULL)) { char *actual = Z_STRVAL_P(p); - if ((colon = (char*)zend_memrchr(Z_STRVAL_P(p), ':', Z_STRLEN_P(p)))) { + if (UNEXPECTED(EG(exception))) { + RESET_CONSTANT_VISITED(p); + return FAILURE; + } else if ((colon = (char*)zend_memrchr(Z_STRVAL_P(p), ':', Z_STRLEN_P(p)))) { size_t len; - zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(p)); - len = Z_STRLEN_P(p) - ((colon - Z_STRVAL_P(p)) + 1); - if (inline_change) { - zend_string *tmp = zend_string_init(colon + 1, len, 0); - zend_string_release(Z_STR_P(p)); - Z_STR_P(p) = tmp; - } else { - Z_STR_P(p) = zend_string_init(colon + 1, len, 0); - } - Z_TYPE_FLAGS_P(p) = IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE; + zend_error(E_EXCEPTION | E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(p)); + RESET_CONSTANT_VISITED(p); + return FAILURE; } else { zend_string *save = Z_STR_P(p); char *slash; @@ -584,23 +582,25 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas } if ((Z_CONST_FLAGS_P(p) & IS_CONSTANT_UNQUALIFIED) == 0) { if (save->val[0] == '\\') { - zend_error_noreturn(E_ERROR, "Undefined constant '%s'", save->val + 1); + zend_error(E_EXCEPTION | E_ERROR, "Undefined constant '%s'", save->val + 1); } else { - zend_error_noreturn(E_ERROR, "Undefined constant '%s'", save->val); + zend_error(E_EXCEPTION | E_ERROR, "Undefined constant '%s'", save->val); } if (inline_change) { zend_string_release(save); } - save = NULL; - } - zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual); - if (!inline_change) { - ZVAL_STRINGL(p, actual, actual_len); + RESET_CONSTANT_VISITED(p); + return FAILURE; } else { - Z_TYPE_INFO_P(p) = Z_REFCOUNTED_P(p) ? - IS_STRING_EX : IS_INTERNED_STRING_EX; - if (save && save->val != actual) { - zend_string_release(save); + zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual); + if (!inline_change) { + ZVAL_STRINGL(p, actual, actual_len); + } else { + Z_TYPE_INFO_P(p) = Z_REFCOUNTED_P(p) ? + IS_STRING_EX : IS_INTERNED_STRING_EX; + if (save && save->val != actual) { + zend_string_release(save); + } } } } @@ -610,7 +610,10 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas } ZVAL_COPY_VALUE(p, const_value); if (Z_OPT_CONSTANT_P(p)) { - zval_update_constant_ex(p, 1, NULL); + if (UNEXPECTED(zval_update_constant_ex(p, 1, NULL) != SUCCESS)) { + RESET_CONSTANT_VISITED(p); + return FAILURE; + } } zval_opt_copy_ctor(p); } @@ -618,29 +621,16 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas if (Z_REFCOUNTED_P(p)) Z_SET_REFCOUNT_P(p, refcount); } else if (Z_TYPE_P(p) == IS_CONSTANT_AST) { zval tmp; - if (inline_change) { - SEPARATE_ZVAL_NOREF(p); + + if (UNEXPECTED(zend_ast_evaluate(&tmp, Z_ASTVAL_P(p), scope) != SUCCESS)) { + return FAILURE; } - zend_ast_evaluate(&tmp, Z_ASTVAL_P(p), scope); if (inline_change) { - zend_ast_destroy_and_free(Z_ASTVAL_P(p)); - efree_size(Z_AST_P(p), sizeof(zend_ast_ref)); + zval_ptr_dtor(p); } ZVAL_COPY_VALUE(p, &tmp); } - return 0; -} -/* }}} */ - -ZEND_API int zval_update_constant_inline_change(zval *pp, zend_class_entry *scope) /* {{{ */ -{ - return zval_update_constant_ex(pp, 1, scope); -} -/* }}} */ - -ZEND_API int zval_update_constant_no_inline_change(zval *pp, zend_class_entry *scope) /* {{{ */ -{ - return zval_update_constant_ex(pp, 0, scope); + return SUCCESS; } /* }}} */ @@ -1311,50 +1301,59 @@ void zend_unset_timeout(void) /* {{{ */ zend_class_entry *zend_fetch_class(zend_string *class_name, int fetch_type) /* {{{ */ { zend_class_entry *ce; - int use_autoload = (fetch_type & ZEND_FETCH_CLASS_NO_AUTOLOAD) == 0; - int silent = (fetch_type & ZEND_FETCH_CLASS_SILENT) != 0; - - fetch_type &= ZEND_FETCH_CLASS_MASK; + int fetch_sub_type = fetch_type & ZEND_FETCH_CLASS_MASK; check_fetch_type: - switch (fetch_type) { + switch (fetch_sub_type) { case ZEND_FETCH_CLASS_SELF: - if (!EG(scope)) { - zend_error_noreturn(E_ERROR, "Cannot access self:: when no class scope is active"); + if (UNEXPECTED(!EG(scope))) { + int error_type = (fetch_type & ZEND_FETCH_CLASS_EXCEPTION) ? + (E_EXCEPTION | E_ERROR) : E_ERROR; + zend_error(error_type, "Cannot access self:: when no class scope is active"); } return EG(scope); case ZEND_FETCH_CLASS_PARENT: - if (!EG(scope)) { - zend_error_noreturn(E_ERROR, "Cannot access parent:: when no class scope is active"); + if (UNEXPECTED(!EG(scope))) { + int error_type = (fetch_type & ZEND_FETCH_CLASS_EXCEPTION) ? + (E_EXCEPTION | E_ERROR) : E_ERROR; + zend_error(error_type, "Cannot access parent:: when no class scope is active"); + return NULL; } - if (!EG(scope)->parent) { - zend_error_noreturn(E_ERROR, "Cannot access parent:: when current class scope has no parent"); + if (UNEXPECTED(!EG(scope)->parent)) { + int error_type = (fetch_type & ZEND_FETCH_CLASS_EXCEPTION) ? + (E_EXCEPTION | E_ERROR) : E_ERROR; + zend_error(error_type, "Cannot access parent:: when current class scope has no parent"); } return EG(scope)->parent; case ZEND_FETCH_CLASS_STATIC: - if (!EG(current_execute_data) || !EG(current_execute_data)->called_scope) { - zend_error_noreturn(E_ERROR, "Cannot access static:: when no class scope is active"); + if (UNEXPECTED(!EG(current_execute_data)) || UNEXPECTED(!EG(current_execute_data)->called_scope)) { + int error_type = (fetch_type & ZEND_FETCH_CLASS_EXCEPTION) ? + (E_EXCEPTION | E_ERROR) : E_ERROR; + zend_error(error_type, "Cannot access static:: when no class scope is active"); + return NULL; } return EG(current_execute_data)->called_scope; case ZEND_FETCH_CLASS_AUTO: { - fetch_type = zend_get_class_fetch_type(class_name); - if (fetch_type!=ZEND_FETCH_CLASS_DEFAULT) { + fetch_sub_type = zend_get_class_fetch_type(class_name); + if (UNEXPECTED(fetch_sub_type != ZEND_FETCH_CLASS_DEFAULT)) { goto check_fetch_type; } } break; } - if ((ce = zend_lookup_class_ex(class_name, NULL, use_autoload)) == NULL) { - if (use_autoload) { - if (!silent && !EG(exception)) { - if (fetch_type == ZEND_FETCH_CLASS_INTERFACE) { - zend_error_noreturn(E_ERROR, "Interface '%s' not found", class_name->val); - } else if (fetch_type == ZEND_FETCH_CLASS_TRAIT) { - zend_error_noreturn(E_ERROR, "Trait '%s' not found", class_name->val); - } else { - zend_error_noreturn(E_ERROR, "Class '%s' not found", class_name->val); - } + if (fetch_type & ZEND_FETCH_CLASS_NO_AUTOLOAD) { + return zend_lookup_class_ex(class_name, NULL, 0); + } else if ((ce = zend_lookup_class_ex(class_name, NULL, 1)) == NULL) { + if (!(fetch_type & ZEND_FETCH_CLASS_SILENT) && !EG(exception)) { + int error_type = (fetch_type & ZEND_FETCH_CLASS_EXCEPTION) ? + (E_EXCEPTION | E_ERROR) : E_ERROR; + if (fetch_sub_type == ZEND_FETCH_CLASS_INTERFACE) { + zend_error(error_type, "Interface '%s' not found", class_name->val); + } else if (fetch_sub_type == ZEND_FETCH_CLASS_TRAIT) { + zend_error(error_type, "Trait '%s' not found", class_name->val); + } else { + zend_error(error_type, "Class '%s' not found", class_name->val); } } return NULL; @@ -1366,18 +1365,19 @@ check_fetch_type: zend_class_entry *zend_fetch_class_by_name(zend_string *class_name, const zval *key, int fetch_type) /* {{{ */ { zend_class_entry *ce; - int use_autoload = (fetch_type & ZEND_FETCH_CLASS_NO_AUTOLOAD) == 0; - - if ((ce = zend_lookup_class_ex(class_name, key, use_autoload)) == NULL) { - if (use_autoload) { - if ((fetch_type & ZEND_FETCH_CLASS_SILENT) == 0 && !EG(exception)) { - if ((fetch_type & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_INTERFACE) { - zend_error_noreturn(E_ERROR, "Interface '%s' not found", class_name->val); - } else if ((fetch_type & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_TRAIT) { - zend_error_noreturn(E_ERROR, "Trait '%s' not found", class_name->val); - } else { - zend_error_noreturn(E_ERROR, "Class '%s' not found", class_name->val); - } + + if (fetch_type & ZEND_FETCH_CLASS_NO_AUTOLOAD) { + return zend_lookup_class_ex(class_name, key, 0); + } else if ((ce = zend_lookup_class_ex(class_name, key, 1)) == NULL) { + if ((fetch_type & ZEND_FETCH_CLASS_SILENT) == 0 && !EG(exception)) { + int error_type = (fetch_type & ZEND_FETCH_CLASS_EXCEPTION) ? + (E_EXCEPTION | E_ERROR) : E_ERROR; + if ((fetch_type & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_INTERFACE) { + zend_error(error_type, "Interface '%s' not found", class_name->val); + } else if ((fetch_type & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_TRAIT) { + zend_error(error_type, "Trait '%s' not found", class_name->val); + } else { + zend_error(error_type, "Class '%s' not found", class_name->val); } } return NULL; diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index bd4fc373e0..e203599aea 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -772,7 +772,7 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent if (parent_ce->type != ce->type) { /* User class extends internal class */ - zend_update_class_constants(parent_ce ); + zend_update_class_constants(parent_ce); if (parent_ce->default_static_members_count) { int i = ce->default_static_members_count + parent_ce->default_static_members_count; diff --git a/Zend/zend_interfaces.c b/Zend/zend_interfaces.c index 28f651cc85..93c0209a96 100644 --- a/Zend/zend_interfaces.c +++ b/Zend/zend_interfaces.c @@ -447,7 +447,9 @@ ZEND_API int zend_user_unserialize(zval *object, zend_class_entry *ce, const uns { zval zdata; - object_init_ex(object, ce); + if (UNEXPECTED(object_init_ex(object, ce) != SUCCESS)) { + return FAILURE; + } ZVAL_STRINGL(&zdata, (char*)buf, buf_len); diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 07d5039961..1ce666b719 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -1314,7 +1314,9 @@ ZEND_API zval *zend_std_get_static_property(zend_class_entry *ce, zend_string *p goto undeclared_property; } - zend_update_class_constants(ce); + if (UNEXPECTED(zend_update_class_constants(ce)) != SUCCESS) { + return NULL; + } ret = CE_STATIC_MEMBERS(ce) + property_info->offset; /* check if static properties were destoyed */ diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c index 6f95e440cc..ffdd9df573 100644 --- a/Zend/zend_objects.c +++ b/Zend/zend_objects.c @@ -84,7 +84,7 @@ ZEND_API void zend_objects_destroy_object(zend_object *object) if (object->ce != EG(scope)) { zend_class_entry *ce = object->ce; - zend_error(EG(current_execute_data) ? E_ERROR : E_WARNING, + zend_error(EG(current_execute_data) ? E_EXCEPTION | E_ERROR : E_WARNING, "Call to private %s::__destruct() from context '%s'%s", ce->name->val, EG(scope) ? EG(scope)->name->val : "", @@ -97,7 +97,7 @@ ZEND_API void zend_objects_destroy_object(zend_object *object) if (!zend_check_protected(zend_get_function_root_class(destructor), EG(scope))) { zend_class_entry *ce = object->ce; - zend_error(EG(current_execute_data) ? E_ERROR : E_WARNING, + zend_error(EG(current_execute_data) ? E_EXCEPTION | E_ERROR : E_WARNING, "Call to protected %s::__destruct() from context '%s'%s", ce->name->val, EG(scope) ? EG(scope)->name->val : "", diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 7a06fdb04c..8ded1f2de9 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -1544,10 +1544,10 @@ ZEND_API int ZEND_FASTCALL concat_function(zval *result, zval *op1, zval *op2) / size_t result_len = op1_len + op2_len; zend_string *result_str; - if (op1_len > SIZE_MAX - op2_len) { + if (UNEXPECTED(op1_len > SIZE_MAX - op2_len)) { zend_error(E_EXCEPTION | E_ERROR, "String size overflow"); ZVAL_FALSE(result); - return; + return FAILURE; } if (result == op1 && Z_REFCOUNTED_P(result)) { diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 6a0f3d2b24..bd0ba8dd78 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -631,13 +631,16 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR| SAVE_OPLINE(); object = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW); - property = GET_OP2_ZVAL_PTR(BP_VAR_R); + if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); - FREE_OP2(); + FREE_UNFETCHED_OP2(); HANDLE_EXCEPTION(); } + + property = GET_OP2_ZVAL_PTR(BP_VAR_R); + if (OP1_TYPE == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object"); FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); @@ -1057,19 +1060,19 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|C zend_free_op free_op1, free_op2; zval *object; zval *property; - zval *retval; zval *zptr; SAVE_OPLINE(); object = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW); - property = GET_OP2_ZVAL_PTR(BP_VAR_R); - retval = EX_VAR(opline->result.var); if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - FREE_OP2(); + FREE_UNFETCHED_OP2(); HANDLE_EXCEPTION(); } + + property = GET_OP2_ZVAL_PTR(BP_VAR_R); + if (OP1_TYPE == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); FREE_OP2(); @@ -1083,7 +1086,7 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|C if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); } break; } @@ -1099,7 +1102,7 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|C incdec_op(zptr); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(retval, zptr); + ZVAL_COPY(EX_VAR(opline->result.var), zptr); } } else { zval rv; @@ -1124,7 +1127,7 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|C SEPARATE_ZVAL_NOREF(z); incdec_op(z); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(retval, z); + ZVAL_COPY(EX_VAR(opline->result.var), z); } Z_OBJ_HT(obj)->write_property(&obj, property, z, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); OBJ_RELEASE(Z_OBJ(obj)); @@ -1132,7 +1135,7 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|C } else { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); } } } @@ -1160,19 +1163,19 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR| zend_free_op free_op1, free_op2; zval *object; zval *property; - zval *retval; zval *zptr; SAVE_OPLINE(); object = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW); - property = GET_OP2_ZVAL_PTR(BP_VAR_R); - retval = EX_VAR(opline->result.var); if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - FREE_OP2(); + FREE_UNFETCHED_OP2(); HANDLE_EXCEPTION(); } + + property = GET_OP2_ZVAL_PTR(BP_VAR_R); + if (OP1_TYPE == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); FREE_OP2(); @@ -1185,7 +1188,7 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR| ZVAL_DEREF(object); if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); break; } } @@ -1196,7 +1199,7 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR| && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); - ZVAL_COPY_VALUE(retval, zptr); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr); zval_opt_copy_ctor(zptr); incdec_op(zptr); } else { @@ -1217,7 +1220,7 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR| } ZVAL_COPY_VALUE(z, value); } - ZVAL_DUP(retval, z); + ZVAL_DUP(EX_VAR(opline->result.var), z); ZVAL_DUP(&z_copy, z); incdec_op(&z_copy); if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z); @@ -1227,7 +1230,7 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR| zval_ptr_dtor(z); } else { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); } } } while (0); @@ -1496,7 +1499,7 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED|CONST|V } else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { if (OP1_TYPE != IS_CONST) { zend_string_release(name); @@ -1576,7 +1579,10 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED|CONST|V } if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { if (Z_CONSTANT_P(retval)) { - zval_update_constant(retval, 1); + if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) { + FREE_OP1(); + HANDLE_EXCEPTION(); + } } } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { FREE_OP1(); @@ -1794,13 +1800,15 @@ ZEND_VM_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMP|VAR|UNUSED|CV, CONST|TMPVAR|CV) SAVE_OPLINE(); container = GET_OP1_OBJ_ZVAL_PTR(BP_VAR_R); - offset = GET_OP2_ZVAL_PTR(BP_VAR_R); if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - FREE_OP2(); + FREE_UNFETCHED_OP2(); HANDLE_EXCEPTION(); } + + offset = GET_OP2_ZVAL_PTR(BP_VAR_R); + if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -1930,13 +1938,15 @@ ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMPVAR|UNUSED|CV, CONST|TMPVAR|CV) SAVE_OPLINE(); container = GET_OP1_OBJ_ZVAL_PTR(BP_VAR_IS); - offset = GET_OP2_ZVAL_PTR(BP_VAR_R); if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - FREE_OP2(); + FREE_UNFETCHED_OP2(); HANDLE_EXCEPTION(); } + + offset = GET_OP2_ZVAL_PTR(BP_VAR_R); + if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -2043,13 +2053,15 @@ ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|CV, CONST|TMPVAR|CV) SAVE_OPLINE(); container = GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_UNSET); - property = GET_OP2_ZVAL_PTR(BP_VAR_R); if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - FREE_OP2(); + FREE_UNFETCHED_OP2(); HANDLE_EXCEPTION(); } + + property = GET_OP2_ZVAL_PTR(BP_VAR_R); + if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object"); FREE_OP2(); @@ -2111,13 +2123,15 @@ ZEND_VM_HANDLER(136, ZEND_ASSIGN_OBJ, VAR|UNUSED|CV, CONST|TMPVAR|CV) SAVE_OPLINE(); object = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_W); - property_name = GET_OP2_ZVAL_PTR(BP_VAR_R); if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - FREE_OP2(); + FREE_UNFETCHED_OP2(); HANDLE_EXCEPTION(); } + + property_name = GET_OP2_ZVAL_PTR(BP_VAR_R); + if (OP1_TYPE == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array"); FREE_OP2(); @@ -2921,7 +2935,7 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMPVAR|UNUSE if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -3021,7 +3035,8 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMPVAR|UNUSE if (OP1_TYPE != IS_CONST) { /* previous opcode is ZEND_FETCH_CLASS */ - if ((opline-1)->extended_value == ZEND_FETCH_CLASS_PARENT || (opline-1)->extended_value == ZEND_FETCH_CLASS_SELF) { + if (((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + ((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { ce = EX(called_scope); } } @@ -3134,7 +3149,7 @@ ZEND_VM_C_LABEL(try_function_name): if (Z_TYPE_P(obj) == IS_STRING) { object = NULL; - called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, 0); + called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(called_scope == NULL)) { CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -4537,7 +4552,10 @@ ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST) if (arg_num > EX_NUM_ARGS()) { ZVAL_COPY_VALUE(param, EX_CONSTANT(opline->op2)); if (Z_OPT_CONSTANT_P(param)) { - zval_update_constant(param, 0); + if (UNEXPECTED(zval_update_constant_ex(param, 0, NULL) != SUCCESS)) { + ZVAL_UNDEF(param); + HANDLE_EXCEPTION(); + } } else { /* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */ if (UNEXPECTED(Z_OPT_COPYABLE_P(param))) { @@ -4740,7 +4758,7 @@ ZEND_VM_HANDLER(68, ZEND_NEW, CONST|VAR, ANY) if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -4750,17 +4768,9 @@ ZEND_VM_HANDLER(68, ZEND_NEW, CONST|VAR, ANY) } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } - if (UNEXPECTED((ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) != 0)) { - if (ce->ce_flags & ZEND_ACC_INTERFACE) { - zend_error(E_EXCEPTION | E_ERROR, "Cannot instantiate interface %s", ce->name->val); - } else if (ce->ce_flags & ZEND_ACC_TRAIT) { - zend_error(E_EXCEPTION | E_ERROR, "Cannot instantiate trait %s", ce->name->val); - } else { - zend_error(E_EXCEPTION | E_ERROR, "Cannot instantiate abstract class %s", ce->name->val); - } + if (UNEXPECTED(object_init_ex(&object_zval, ce) != SUCCESS)) { HANDLE_EXCEPTION(); } - object_init_ex(&object_zval, ce); constructor = Z_OBJ_HT(object_zval)->get_constructor(Z_OBJ(object_zval)); if (constructor == NULL) { @@ -4925,7 +4935,7 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST) } else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -4948,7 +4958,7 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST) ZVAL_DEREF(value); if (Z_CONSTANT_P(value)) { EG(scope) = ce; - zval_update_constant(value, 1); + zval_update_constant_ex(value, 1, NULL); EG(scope) = EX(func)->op_array.scope; } if (OP1_TYPE == IS_CONST) { @@ -4962,7 +4972,6 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST) ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name); } else { zend_error(E_EXCEPTION | E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - HANDLE_EXCEPTION(); } } ZEND_VM_C_LABEL(constant_fetch_end): @@ -5367,7 +5376,7 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMPVAR|CV, UNUSED|CONST|VAR) if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(EG(exception) != NULL)) { if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { zend_string_release(Z_STR(tmp)); @@ -6198,7 +6207,7 @@ ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMPVAR|CV, UNUSED|CONST|VAR) } else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -6262,13 +6271,15 @@ ZEND_VM_HANDLER(115, ZEND_ISSET_ISEMPTY_DIM_OBJ, CONST|TMPVAR|UNUSED|CV, CONST|T SAVE_OPLINE(); container = GET_OP1_OBJ_ZVAL_PTR(BP_VAR_IS); - offset = GET_OP2_ZVAL_PTR(BP_VAR_R); if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - FREE_OP2(); + FREE_UNFETCHED_OP2(); HANDLE_EXCEPTION(); } + + offset = GET_OP2_ZVAL_PTR(BP_VAR_R); + ZEND_VM_C_LABEL(isset_dim_obj_again): if (OP1_TYPE != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht = Z_ARRVAL_P(container); @@ -6384,13 +6395,15 @@ ZEND_VM_HANDLER(148, ZEND_ISSET_ISEMPTY_PROP_OBJ, CONST|TMPVAR|UNUSED|CV, CONST| SAVE_OPLINE(); container = GET_OP1_OBJ_ZVAL_PTR(BP_VAR_IS); - offset = GET_OP2_ZVAL_PTR(BP_VAR_R); if (OP1_TYPE == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - FREE_OP2(); + FREE_UNFETCHED_OP2(); HANDLE_EXCEPTION(); } + + offset = GET_OP2_ZVAL_PTR(BP_VAR_R); + if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -7064,7 +7077,11 @@ ZEND_VM_HANDLER(143, ZEND_DECLARE_CONST, CONST, CONST) ZVAL_COPY_VALUE(&c.value, val); if (Z_OPT_CONSTANT(c.value)) { - zval_update_constant(&c.value, 0); + if (UNEXPECTED(zval_update_constant_ex(&c.value, 0, NULL) != SUCCESS)) { + FREE_OP1(); + FREE_OP2(); + HANDLE_EXCEPTION(); + } } else { /* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */ if (UNEXPECTED(Z_OPT_COPYABLE(c.value))) { diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index b98c14735b..fde4caed16 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1938,7 +1938,7 @@ try_function_name: if (Z_TYPE_P(obj) == IS_STRING) { object = NULL; - called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, 0); + called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(called_scope == NULL)) { CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -2076,7 +2076,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_INIT_SPEC_CONST_HANDLER(Z if (arg_num > EX_NUM_ARGS()) { ZVAL_COPY_VALUE(param, EX_CONSTANT(opline->op2)); if (Z_OPT_CONSTANT_P(param)) { - zval_update_constant(param, 0); + if (UNEXPECTED(zval_update_constant_ex(param, 0, NULL) != SUCCESS)) { + ZVAL_UNDEF(param); + HANDLE_EXCEPTION(); + } } else { /* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */ if (UNEXPECTED(Z_OPT_COPYABLE_P(param))) { @@ -2330,7 +2333,7 @@ try_function_name: if (Z_TYPE_P(obj) == IS_STRING) { object = NULL; - called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, 0); + called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(called_scope == NULL)) { CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -2519,7 +2522,7 @@ try_function_name: if (Z_TYPE_P(obj) == IS_STRING) { object = NULL; - called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, 0); + called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(called_scope == NULL)) { CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -3069,7 +3072,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_CONST_HANDLER(ZEND_OP if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -3079,17 +3082,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_CONST_HANDLER(ZEND_OP } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } - if (UNEXPECTED((ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) != 0)) { - if (ce->ce_flags & ZEND_ACC_INTERFACE) { - zend_error(E_EXCEPTION | E_ERROR, "Cannot instantiate interface %s", ce->name->val); - } else if (ce->ce_flags & ZEND_ACC_TRAIT) { - zend_error(E_EXCEPTION | E_ERROR, "Cannot instantiate trait %s", ce->name->val); - } else { - zend_error(E_EXCEPTION | E_ERROR, "Cannot instantiate abstract class %s", ce->name->val); - } + if (UNEXPECTED(object_init_ex(&object_zval, ce) != SUCCESS)) { HANDLE_EXCEPTION(); } - object_init_ex(&object_zval, ce); constructor = Z_OBJ_HT(object_zval)->get_constructor(Z_OBJ(object_zval)); if (constructor == NULL) { @@ -4525,7 +4520,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ } else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { if (IS_CONST != IS_CONST) { zend_string_release(name); @@ -4604,7 +4599,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ } if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { if (Z_CONSTANT_P(retval)) { - zval_update_constant(retval, 1); + if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) { + + HANDLE_EXCEPTION(); + } } } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { @@ -4749,13 +4747,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_H SAVE_OPLINE(); container = EX_CONSTANT(opline->op1); - offset = EX_CONSTANT(opline->op2); if (IS_CONST == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + offset = EX_CONSTANT(opline->op2); + if (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -4819,13 +4819,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST_ SAVE_OPLINE(); container = EX_CONSTANT(opline->op1); - offset = EX_CONSTANT(opline->op2); if (IS_CONST == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + offset = EX_CONSTANT(opline->op2); + if (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -5010,7 +5012,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -5110,7 +5112,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (IS_CONST != IS_CONST) { /* previous opcode is ZEND_FETCH_CLASS */ - if ((opline-1)->extended_value == ZEND_FETCH_CLASS_PARENT || (opline-1)->extended_value == ZEND_FETCH_CLASS_SELF) { + if (((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + ((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { ce = EX(called_scope); } } @@ -5301,7 +5304,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_CONST_CONS } else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -5324,7 +5327,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_CONST_CONS ZVAL_DEREF(value); if (Z_CONSTANT_P(value)) { EG(scope) = ce; - zval_update_constant(value, 1); + zval_update_constant_ex(value, 1, NULL); EG(scope) = EX(func)->op_array.scope; } if (IS_CONST == IS_CONST) { @@ -5338,7 +5341,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_CONST_CONS ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name); } else { zend_error(E_EXCEPTION | E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - HANDLE_EXCEPTION(); } } constant_fetch_end: @@ -5513,7 +5515,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_CONST_HAN if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(EG(exception) != NULL)) { if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { zend_string_release(Z_STR(tmp)); @@ -5597,7 +5599,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_C } else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -5660,13 +5662,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CON SAVE_OPLINE(); container = EX_CONSTANT(opline->op1); - offset = EX_CONSTANT(opline->op2); if (IS_CONST == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + offset = EX_CONSTANT(opline->op2); + isset_dim_obj_again: if (IS_CONST != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht = Z_ARRVAL_P(container); @@ -5781,13 +5785,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CO SAVE_OPLINE(); container = EX_CONSTANT(opline->op1); - offset = EX_CONSTANT(opline->op2); if (IS_CONST == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + offset = EX_CONSTANT(opline->op2); + if (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -5829,7 +5835,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_CONST_SPEC_CONST_CONST ZVAL_COPY_VALUE(&c.value, val); if (Z_OPT_CONSTANT(c.value)) { - zval_update_constant(&c.value, 0); + if (UNEXPECTED(zval_update_constant_ex(&c.value, 0, NULL) != SUCCESS)) { + + + HANDLE_EXCEPTION(); + } } else { /* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */ if (UNEXPECTED(Z_OPT_COPYABLE(c.value))) { @@ -6242,7 +6252,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ } else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { if (IS_CONST != IS_CONST) { zend_string_release(name); @@ -6321,7 +6331,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ } if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { if (Z_CONSTANT_P(retval)) { - zval_update_constant(retval, 1); + if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) { + + HANDLE_EXCEPTION(); + } } } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { @@ -6427,7 +6440,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_VAR_HANDL if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(EG(exception) != NULL)) { if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { zend_string_release(Z_STR(tmp)); @@ -6511,7 +6524,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_V } else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -6742,7 +6755,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ } else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { if (IS_CONST != IS_CONST) { zend_string_release(name); @@ -6821,7 +6834,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ } if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { if (Z_CONSTANT_P(retval)) { - zval_update_constant(retval, 1); + if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) { + + HANDLE_EXCEPTION(); + } } } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { @@ -6941,7 +6957,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -7041,7 +7057,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (IS_CONST != IS_CONST) { /* previous opcode is ZEND_FETCH_CLASS */ - if ((opline-1)->extended_value == ZEND_FETCH_CLASS_PARENT || (opline-1)->extended_value == ZEND_FETCH_CLASS_SELF) { + if (((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + ((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { ce = EX(called_scope); } } @@ -7269,7 +7286,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HA if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(EG(exception) != NULL)) { if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { zend_string_release(Z_STR(tmp)); @@ -7353,7 +7370,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_U } else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -8212,13 +8229,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_CV_HAND SAVE_OPLINE(); container = EX_CONSTANT(opline->op1); - offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); if (IS_CONST == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + if (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -8282,13 +8301,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_CV_HAN SAVE_OPLINE(); container = EX_CONSTANT(opline->op1); - offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); if (IS_CONST == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + if (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -8437,7 +8458,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -8537,7 +8558,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (IS_CONST != IS_CONST) { /* previous opcode is ZEND_FETCH_CLASS */ - if ((opline-1)->extended_value == ZEND_FETCH_CLASS_PARENT || (opline-1)->extended_value == ZEND_FETCH_CLASS_SELF) { + if (((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + ((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { ce = EX(called_scope); } } @@ -8856,13 +8878,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CON SAVE_OPLINE(); container = EX_CONSTANT(opline->op1); - offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); if (IS_CONST == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + isset_dim_obj_again: if (IS_CONST != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht = Z_ARRVAL_P(container); @@ -8977,13 +9001,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CO SAVE_OPLINE(); container = EX_CONSTANT(opline->op1); - offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); if (IS_CONST == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + if (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -9779,13 +9805,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_ SAVE_OPLINE(); container = EX_CONSTANT(opline->op1); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_CONST == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } + + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -9850,13 +9878,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR SAVE_OPLINE(); container = EX_CONSTANT(opline->op1); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_CONST == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } + + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -10006,7 +10036,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -10106,7 +10136,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C if (IS_CONST != IS_CONST) { /* previous opcode is ZEND_FETCH_CLASS */ - if ((opline-1)->extended_value == ZEND_FETCH_CLASS_PARENT || (opline-1)->extended_value == ZEND_FETCH_CLASS_SELF) { + if (((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + ((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { ce = EX(called_scope); } } @@ -10375,13 +10406,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CON SAVE_OPLINE(); container = EX_CONSTANT(opline->op1); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_CONST == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } + + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + isset_dim_obj_again: if (IS_CONST != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht = Z_ARRVAL_P(container); @@ -10497,13 +10530,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CO SAVE_OPLINE(); container = EX_CONSTANT(opline->op1); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_CONST == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } + + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -11367,13 +11402,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_CONST_HAN SAVE_OPLINE(); container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); - offset = EX_CONSTANT(opline->op2); if (IS_TMP_VAR == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + offset = EX_CONSTANT(opline->op2); + if (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -12566,13 +12603,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_CV_HANDLE SAVE_OPLINE(); container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); - offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); if (IS_TMP_VAR == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + if (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -13043,13 +13082,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_TMPVAR_HA SAVE_OPLINE(); container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_TMP_VAR == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } + + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -13887,7 +13928,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_VAR_HANDLER(ZEND_OPCO if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -13897,17 +13938,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_VAR_HANDLER(ZEND_OPCO } else { ce = Z_CE_P(EX_VAR(opline->op1.var)); } - if (UNEXPECTED((ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) != 0)) { - if (ce->ce_flags & ZEND_ACC_INTERFACE) { - zend_error(E_EXCEPTION | E_ERROR, "Cannot instantiate interface %s", ce->name->val); - } else if (ce->ce_flags & ZEND_ACC_TRAIT) { - zend_error(E_EXCEPTION | E_ERROR, "Cannot instantiate trait %s", ce->name->val); - } else { - zend_error(E_EXCEPTION | E_ERROR, "Cannot instantiate abstract class %s", ce->name->val); - } + if (UNEXPECTED(object_init_ex(&object_zval, ce) != SUCCESS)) { HANDLE_EXCEPTION(); } - object_init_ex(&object_zval, ce); constructor = Z_OBJ_HT(object_zval)->get_constructor(Z_OBJ(object_zval)); if (constructor == NULL) { @@ -14836,13 +14869,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP SAVE_OPLINE(); object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - property = EX_CONSTANT(opline->op2); + if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); HANDLE_EXCEPTION(); } + + property = EX_CONSTANT(opline->op2); + if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object"); FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); @@ -15260,19 +15296,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE zend_free_op free_op1; zval *object; zval *property; - zval *retval; zval *zptr; SAVE_OPLINE(); object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - property = EX_CONSTANT(opline->op2); - retval = EX_VAR(opline->result.var); if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + property = EX_CONSTANT(opline->op2); + if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); @@ -15286,7 +15322,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); } break; } @@ -15302,7 +15338,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE incdec_op(zptr); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(retval, zptr); + ZVAL_COPY(EX_VAR(opline->result.var), zptr); } } else { zval rv; @@ -15327,7 +15363,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE SEPARATE_ZVAL_NOREF(z); incdec_op(z); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(retval, z); + ZVAL_COPY(EX_VAR(opline->result.var), z); } Z_OBJ_HT(obj)->write_property(&obj, property, z, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); OBJ_RELEASE(Z_OBJ(obj)); @@ -15335,7 +15371,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE } else { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); } } } @@ -15362,19 +15398,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP zend_free_op free_op1; zval *object; zval *property; - zval *retval; zval *zptr; SAVE_OPLINE(); object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - property = EX_CONSTANT(opline->op2); - retval = EX_VAR(opline->result.var); if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + property = EX_CONSTANT(opline->op2); + if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); @@ -15387,7 +15423,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP ZVAL_DEREF(object); if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); break; } } @@ -15398,7 +15434,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); - ZVAL_COPY_VALUE(retval, zptr); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr); zval_opt_copy_ctor(zptr); incdec_op(zptr); } else { @@ -15419,7 +15455,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP } ZVAL_COPY_VALUE(z, value); } - ZVAL_DUP(retval, z); + ZVAL_DUP(EX_VAR(opline->result.var), z); ZVAL_DUP(&z_copy, z); incdec_op(&z_copy); if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z); @@ -15429,7 +15465,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP zval_ptr_dtor(z); } else { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); } } } while (0); @@ -15576,13 +15612,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_CONST_HAN SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); - offset = EX_CONSTANT(opline->op2); if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + offset = EX_CONSTANT(opline->op2); + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -15753,13 +15791,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - property = EX_CONSTANT(opline->op2); if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + property = EX_CONSTANT(opline->op2); + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object"); @@ -15785,13 +15825,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_HAND SAVE_OPLINE(); object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - property_name = EX_CONSTANT(opline->op2); if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + property_name = EX_CONSTANT(opline->op2); + if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array"); @@ -15962,7 +16004,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -16062,7 +16104,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (IS_VAR != IS_CONST) { /* previous opcode is ZEND_FETCH_CLASS */ - if ((opline-1)->extended_value == ZEND_FETCH_CLASS_PARENT || (opline-1)->extended_value == ZEND_FETCH_CLASS_SELF) { + if (((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + ((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { ce = EX(called_scope); } } @@ -16130,7 +16173,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_ } else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -16153,7 +16196,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_ ZVAL_DEREF(value); if (Z_CONSTANT_P(value)) { EG(scope) = ce; - zval_update_constant(value, 1); + zval_update_constant_ex(value, 1, NULL); EG(scope) = EX(func)->op_array.scope; } if (IS_VAR == IS_CONST) { @@ -16167,7 +16210,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_ ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name); } else { zend_error(E_EXCEPTION | E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - HANDLE_EXCEPTION(); } } constant_fetch_end: @@ -17555,7 +17597,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -17655,7 +17697,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (IS_VAR != IS_CONST) { /* previous opcode is ZEND_FETCH_CLASS */ - if ((opline-1)->extended_value == ZEND_FETCH_CLASS_PARENT || (opline-1)->extended_value == ZEND_FETCH_CLASS_SELF) { + if (((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + ((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { ce = EX(called_scope); } } @@ -18037,13 +18080,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP SAVE_OPLINE(); object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); HANDLE_EXCEPTION(); } + + property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object"); FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); @@ -18461,19 +18507,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE zend_free_op free_op1; zval *object; zval *property; - zval *retval; zval *zptr; SAVE_OPLINE(); object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); - retval = EX_VAR(opline->result.var); if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); @@ -18487,7 +18533,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); } break; } @@ -18503,7 +18549,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE incdec_op(zptr); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(retval, zptr); + ZVAL_COPY(EX_VAR(opline->result.var), zptr); } } else { zval rv; @@ -18528,7 +18574,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE SEPARATE_ZVAL_NOREF(z); incdec_op(z); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(retval, z); + ZVAL_COPY(EX_VAR(opline->result.var), z); } Z_OBJ_HT(obj)->write_property(&obj, property, z, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); OBJ_RELEASE(Z_OBJ(obj)); @@ -18536,7 +18582,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE } else { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); } } } @@ -18563,19 +18609,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP zend_free_op free_op1; zval *object; zval *property; - zval *retval; zval *zptr; SAVE_OPLINE(); object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); - retval = EX_VAR(opline->result.var); if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); @@ -18588,7 +18634,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP ZVAL_DEREF(object); if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); break; } } @@ -18599,7 +18645,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); - ZVAL_COPY_VALUE(retval, zptr); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr); zval_opt_copy_ctor(zptr); incdec_op(zptr); } else { @@ -18620,7 +18666,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP } ZVAL_COPY_VALUE(z, value); } - ZVAL_DUP(retval, z); + ZVAL_DUP(EX_VAR(opline->result.var), z); ZVAL_DUP(&z_copy, z); incdec_op(&z_copy); if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z); @@ -18630,7 +18676,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP zval_ptr_dtor(z); } else { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); } } } while (0); @@ -18777,13 +18823,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_CV_HANDLE SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); - offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -18954,13 +19002,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_HA SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object"); @@ -18986,13 +19036,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_HANDLER SAVE_OPLINE(); object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array"); @@ -19226,7 +19278,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -19326,7 +19378,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (IS_VAR != IS_CONST) { /* previous opcode is ZEND_FETCH_CLASS */ - if ((opline-1)->extended_value == ZEND_FETCH_CLASS_PARENT || (opline-1)->extended_value == ZEND_FETCH_CLASS_SELF) { + if (((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + ((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { ce = EX(called_scope); } } @@ -19750,13 +19803,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP SAVE_OPLINE(); object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } + + property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object"); FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); @@ -20176,19 +20232,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE zend_free_op free_op1, free_op2; zval *object; zval *property; - zval *retval; zval *zptr; SAVE_OPLINE(); object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - retval = EX_VAR(opline->result.var); if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } + + property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); zval_ptr_dtor_nogc(free_op2); @@ -20202,7 +20258,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); } break; } @@ -20218,7 +20274,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE incdec_op(zptr); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(retval, zptr); + ZVAL_COPY(EX_VAR(opline->result.var), zptr); } } else { zval rv; @@ -20243,7 +20299,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE SEPARATE_ZVAL_NOREF(z); incdec_op(z); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(retval, z); + ZVAL_COPY(EX_VAR(opline->result.var), z); } Z_OBJ_HT(obj)->write_property(&obj, property, z, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); OBJ_RELEASE(Z_OBJ(obj)); @@ -20251,7 +20307,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE } else { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); } } } @@ -20279,19 +20335,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP zend_free_op free_op1, free_op2; zval *object; zval *property; - zval *retval; zval *zptr; SAVE_OPLINE(); object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - retval = EX_VAR(opline->result.var); if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } + + property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); zval_ptr_dtor_nogc(free_op2); @@ -20304,7 +20360,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP ZVAL_DEREF(object); if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); break; } } @@ -20315,7 +20371,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); - ZVAL_COPY_VALUE(retval, zptr); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr); zval_opt_copy_ctor(zptr); incdec_op(zptr); } else { @@ -20336,7 +20392,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP } ZVAL_COPY_VALUE(z, value); } - ZVAL_DUP(retval, z); + ZVAL_DUP(EX_VAR(opline->result.var), z); ZVAL_DUP(&z_copy, z); incdec_op(&z_copy); if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z); @@ -20346,7 +20402,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP zval_ptr_dtor(z); } else { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); } } } while (0); @@ -20494,13 +20550,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_TMPVAR_HA SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } + + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -20672,13 +20730,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVA SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } + + property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object"); zval_ptr_dtor_nogc(free_op2); @@ -20704,13 +20764,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_HAN SAVE_OPLINE(); object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); - property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_VAR == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } + + property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array"); zval_ptr_dtor_nogc(free_op2); @@ -20849,7 +20911,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -20949,7 +21011,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V if (IS_VAR != IS_CONST) { /* previous opcode is ZEND_FETCH_CLASS */ - if ((opline-1)->extended_value == ZEND_FETCH_CLASS_PARENT || (opline-1)->extended_value == ZEND_FETCH_CLASS_SELF) { + if (((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + ((opline-1)->extended_value & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF) { ce = EX(called_scope); } } @@ -21345,13 +21408,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP SAVE_OPLINE(); object = _get_obj_zval_ptr_unused(execute_data); - property = EX_CONSTANT(opline->op2); + if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); HANDLE_EXCEPTION(); } + + property = EX_CONSTANT(opline->op2); + if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object"); FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); @@ -21731,19 +21797,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE zval *object; zval *property; - zval *retval; zval *zptr; SAVE_OPLINE(); object = _get_obj_zval_ptr_unused(execute_data); - property = EX_CONSTANT(opline->op2); - retval = EX_VAR(opline->result.var); if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + property = EX_CONSTANT(opline->op2); + if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); @@ -21757,7 +21823,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); } break; } @@ -21773,7 +21839,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE incdec_op(zptr); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(retval, zptr); + ZVAL_COPY(EX_VAR(opline->result.var), zptr); } } else { zval rv; @@ -21798,7 +21864,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE SEPARATE_ZVAL_NOREF(z); incdec_op(z); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(retval, z); + ZVAL_COPY(EX_VAR(opline->result.var), z); } Z_OBJ_HT(obj)->write_property(&obj, property, z, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); OBJ_RELEASE(Z_OBJ(obj)); @@ -21806,7 +21872,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE } else { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); } } } @@ -21833,19 +21899,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP zval *object; zval *property; - zval *retval; zval *zptr; SAVE_OPLINE(); object = _get_obj_zval_ptr_unused(execute_data); - property = EX_CONSTANT(opline->op2); - retval = EX_VAR(opline->result.var); if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + property = EX_CONSTANT(opline->op2); + if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); @@ -21858,7 +21924,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP ZVAL_DEREF(object); if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); break; } } @@ -21869,7 +21935,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); - ZVAL_COPY_VALUE(retval, zptr); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr); zval_opt_copy_ctor(zptr); incdec_op(zptr); } else { @@ -21890,7 +21956,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP } ZVAL_COPY_VALUE(z, value); } - ZVAL_DUP(retval, z); + ZVAL_DUP(EX_VAR(opline->result.var), z); ZVAL_DUP(&z_copy, z); incdec_op(&z_copy); if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z); @@ -21900,7 +21966,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP zval_ptr_dtor(z); } else { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); } } } while (0); @@ -21930,13 +21996,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_ SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(execute_data); - offset = EX_CONSTANT(opline->op2); if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + offset = EX_CONSTANT(opline->op2); + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -22065,13 +22133,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(execute_data); - offset = EX_CONSTANT(opline->op2); if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + offset = EX_CONSTANT(opline->op2); + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -22177,13 +22247,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CO SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(execute_data); - property = EX_CONSTANT(opline->op2); if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + property = EX_CONSTANT(opline->op2); + if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object"); @@ -22209,13 +22281,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_H SAVE_OPLINE(); object = _get_obj_zval_ptr_unused(execute_data); - property_name = EX_CONSTANT(opline->op2); if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + property_name = EX_CONSTANT(opline->op2); + if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array"); @@ -22409,7 +22483,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CON } else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -22432,7 +22506,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CON ZVAL_DEREF(value); if (Z_CONSTANT_P(value)) { EG(scope) = ce; - zval_update_constant(value, 1); + zval_update_constant_ex(value, 1, NULL); EG(scope) = EX(func)->op_array.scope; } if (IS_UNUSED == IS_CONST) { @@ -22446,7 +22520,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CON ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name); } else { zend_error(E_EXCEPTION | E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - HANDLE_EXCEPTION(); } } constant_fetch_end: @@ -22631,13 +22704,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNU SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(execute_data); - offset = EX_CONSTANT(opline->op2); if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + offset = EX_CONSTANT(opline->op2); + isset_dim_obj_again: if (IS_UNUSED != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht = Z_ARRVAL_P(container); @@ -22752,13 +22827,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UN SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(execute_data); - offset = EX_CONSTANT(opline->op2); if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + offset = EX_CONSTANT(opline->op2); + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -23724,13 +23801,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP SAVE_OPLINE(); object = _get_obj_zval_ptr_unused(execute_data); - property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); HANDLE_EXCEPTION(); } + + property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object"); FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); @@ -24110,19 +24190,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE zval *object; zval *property; - zval *retval; zval *zptr; SAVE_OPLINE(); object = _get_obj_zval_ptr_unused(execute_data); - property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); - retval = EX_VAR(opline->result.var); if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); @@ -24136,7 +24216,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); } break; } @@ -24152,7 +24232,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE incdec_op(zptr); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(retval, zptr); + ZVAL_COPY(EX_VAR(opline->result.var), zptr); } } else { zval rv; @@ -24177,7 +24257,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE SEPARATE_ZVAL_NOREF(z); incdec_op(z); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(retval, z); + ZVAL_COPY(EX_VAR(opline->result.var), z); } Z_OBJ_HT(obj)->write_property(&obj, property, z, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); OBJ_RELEASE(Z_OBJ(obj)); @@ -24185,7 +24265,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE } else { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); } } } @@ -24212,19 +24292,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP zval *object; zval *property; - zval *retval; zval *zptr; SAVE_OPLINE(); object = _get_obj_zval_ptr_unused(execute_data); - property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); - retval = EX_VAR(opline->result.var); if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); @@ -24237,7 +24317,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP ZVAL_DEREF(object); if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); break; } } @@ -24248,7 +24328,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); - ZVAL_COPY_VALUE(retval, zptr); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr); zval_opt_copy_ctor(zptr); incdec_op(zptr); } else { @@ -24269,7 +24349,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP } ZVAL_COPY_VALUE(z, value); } - ZVAL_DUP(retval, z); + ZVAL_DUP(EX_VAR(opline->result.var), z); ZVAL_DUP(&z_copy, z); incdec_op(&z_copy); if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z); @@ -24279,7 +24359,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP zval_ptr_dtor(z); } else { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); } } } while (0); @@ -24309,13 +24389,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HAN SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(execute_data); - offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -24444,13 +24526,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_HA SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(execute_data); - offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -24556,13 +24640,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(execute_data); - property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object"); @@ -24588,13 +24674,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_HAND SAVE_OPLINE(); object = _get_obj_zval_ptr_unused(execute_data); - property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array"); @@ -24909,13 +24997,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNU SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(execute_data); - offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + isset_dim_obj_again: if (IS_UNUSED != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht = Z_ARRVAL_P(container); @@ -25030,13 +25120,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UN SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(execute_data); - offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -25213,13 +25305,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP SAVE_OPLINE(); object = _get_obj_zval_ptr_unused(execute_data); - property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } + + property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object"); FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); @@ -25600,19 +25695,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE zend_free_op free_op2; zval *object; zval *property; - zval *retval; zval *zptr; SAVE_OPLINE(); object = _get_obj_zval_ptr_unused(execute_data); - property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - retval = EX_VAR(opline->result.var); if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } + + property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); zval_ptr_dtor_nogc(free_op2); @@ -25626,7 +25721,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); } break; } @@ -25642,7 +25737,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE incdec_op(zptr); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(retval, zptr); + ZVAL_COPY(EX_VAR(opline->result.var), zptr); } } else { zval rv; @@ -25667,7 +25762,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE SEPARATE_ZVAL_NOREF(z); incdec_op(z); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(retval, z); + ZVAL_COPY(EX_VAR(opline->result.var), z); } Z_OBJ_HT(obj)->write_property(&obj, property, z, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); OBJ_RELEASE(Z_OBJ(obj)); @@ -25675,7 +25770,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE } else { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); } } } @@ -25703,19 +25798,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP zend_free_op free_op2; zval *object; zval *property; - zval *retval; zval *zptr; SAVE_OPLINE(); object = _get_obj_zval_ptr_unused(execute_data); - property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - retval = EX_VAR(opline->result.var); if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } + + property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); zval_ptr_dtor_nogc(free_op2); @@ -25728,7 +25823,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP ZVAL_DEREF(object); if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); break; } } @@ -25739,7 +25834,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); - ZVAL_COPY_VALUE(retval, zptr); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr); zval_opt_copy_ctor(zptr); incdec_op(zptr); } else { @@ -25760,7 +25855,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP } ZVAL_COPY_VALUE(z, value); } - ZVAL_DUP(retval, z); + ZVAL_DUP(EX_VAR(opline->result.var), z); ZVAL_DUP(&z_copy, z); incdec_op(&z_copy); if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z); @@ -25770,7 +25865,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP zval_ptr_dtor(z); } else { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); } } } while (0); @@ -25801,13 +25896,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(execute_data); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } + + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -25937,13 +26034,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVA SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(execute_data); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } + + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -26050,13 +26149,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TM SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(execute_data); - property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } + + property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object"); zval_ptr_dtor_nogc(free_op2); @@ -26082,13 +26183,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ SAVE_OPLINE(); object = _get_obj_zval_ptr_unused(execute_data); - property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } + + property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array"); zval_ptr_dtor_nogc(free_op2); @@ -26405,13 +26508,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNU SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(execute_data); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } + + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + isset_dim_obj_again: if (IS_UNUSED != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht = Z_ARRVAL_P(container); @@ -26527,13 +26632,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UN SAVE_OPLINE(); container = _get_obj_zval_ptr_unused(execute_data); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_UNUSED == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } + + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -28715,13 +28822,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP SAVE_OPLINE(); object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var); - property = EX_CONSTANT(opline->op2); + if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); HANDLE_EXCEPTION(); } + + property = EX_CONSTANT(opline->op2); + if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object"); FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); @@ -29139,19 +29249,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE zval *object; zval *property; - zval *retval; zval *zptr; SAVE_OPLINE(); object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var); - property = EX_CONSTANT(opline->op2); - retval = EX_VAR(opline->result.var); if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + property = EX_CONSTANT(opline->op2); + if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); @@ -29165,7 +29275,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); } break; } @@ -29181,7 +29291,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE incdec_op(zptr); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(retval, zptr); + ZVAL_COPY(EX_VAR(opline->result.var), zptr); } } else { zval rv; @@ -29206,7 +29316,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE SEPARATE_ZVAL_NOREF(z); incdec_op(z); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(retval, z); + ZVAL_COPY(EX_VAR(opline->result.var), z); } Z_OBJ_HT(obj)->write_property(&obj, property, z, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); OBJ_RELEASE(Z_OBJ(obj)); @@ -29214,7 +29324,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE } else { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); } } } @@ -29241,19 +29351,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP zval *object; zval *property; - zval *retval; zval *zptr; SAVE_OPLINE(); object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var); - property = EX_CONSTANT(opline->op2); - retval = EX_VAR(opline->result.var); if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + property = EX_CONSTANT(opline->op2); + if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); @@ -29266,7 +29376,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP ZVAL_DEREF(object); if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); break; } } @@ -29277,7 +29387,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); - ZVAL_COPY_VALUE(retval, zptr); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr); zval_opt_copy_ctor(zptr); incdec_op(zptr); } else { @@ -29298,7 +29408,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP } ZVAL_COPY_VALUE(z, value); } - ZVAL_DUP(retval, z); + ZVAL_DUP(EX_VAR(opline->result.var), z); ZVAL_DUP(&z_copy, z); incdec_op(&z_copy); if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z); @@ -29308,7 +29418,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP zval_ptr_dtor(z); } else { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); } } } while (0); @@ -29369,7 +29479,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ } else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { if (IS_CV != IS_CONST) { zend_string_release(name); @@ -29448,7 +29558,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ } if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { if (Z_CONSTANT_P(retval)) { - zval_update_constant(retval, 1); + if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) { + + HANDLE_EXCEPTION(); + } } } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { @@ -29666,13 +29779,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HAND SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var); - offset = EX_CONSTANT(opline->op2); if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + offset = EX_CONSTANT(opline->op2); + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -29801,13 +29916,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HAN SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var); - offset = EX_CONSTANT(opline->op2); if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + offset = EX_CONSTANT(opline->op2); + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -29913,13 +30030,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_ SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var); - property = EX_CONSTANT(opline->op2); if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + property = EX_CONSTANT(opline->op2); + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object"); @@ -29981,13 +30100,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_HANDL SAVE_OPLINE(); object = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); - property_name = EX_CONSTANT(opline->op2); if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + property_name = EX_CONSTANT(opline->op2); + if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array"); @@ -30509,7 +30630,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_CONST_HANDLE if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(EG(exception) != NULL)) { if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { zend_string_release(Z_STR(tmp)); @@ -30728,7 +30849,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_CONS } else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -30791,13 +30912,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_ SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var); - offset = EX_CONSTANT(opline->op2); if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + offset = EX_CONSTANT(opline->op2); + isset_dim_obj_again: if (IS_CV != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht = Z_ARRVAL_P(container); @@ -30912,13 +31035,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var); - offset = EX_CONSTANT(opline->op2); if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + offset = EX_CONSTANT(opline->op2); + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -31476,7 +31601,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ } else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { if (IS_CV != IS_CONST) { zend_string_release(name); @@ -31555,7 +31680,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ } if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { if (Z_CONSTANT_P(retval)) { - zval_update_constant(retval, 1); + if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) { + + HANDLE_EXCEPTION(); + } } } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { @@ -31757,7 +31885,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_VAR_HANDLER( if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(EG(exception) != NULL)) { if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { zend_string_release(Z_STR(tmp)); @@ -31841,7 +31969,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_VAR_ } else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -32410,7 +32538,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ } else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { if (IS_CV != IS_CONST) { zend_string_release(name); @@ -32489,7 +32617,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ } if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { if (Z_CONSTANT_P(retval)) { - zval_update_constant(retval, 1); + if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) { + + HANDLE_EXCEPTION(); + } } } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { @@ -32966,7 +33097,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDL if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(EG(exception) != NULL)) { if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { zend_string_release(Z_STR(tmp)); @@ -33050,7 +33181,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUS } else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -33813,13 +33944,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP SAVE_OPLINE(); object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var); - property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); HANDLE_EXCEPTION(); } + + property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object"); FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); @@ -34237,19 +34371,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE zval *object; zval *property; - zval *retval; zval *zptr; SAVE_OPLINE(); object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var); - property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); - retval = EX_VAR(opline->result.var); if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); @@ -34263,7 +34397,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); } break; } @@ -34279,7 +34413,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE incdec_op(zptr); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(retval, zptr); + ZVAL_COPY(EX_VAR(opline->result.var), zptr); } } else { zval rv; @@ -34304,7 +34438,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE SEPARATE_ZVAL_NOREF(z); incdec_op(z); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(retval, z); + ZVAL_COPY(EX_VAR(opline->result.var), z); } Z_OBJ_HT(obj)->write_property(&obj, property, z, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); OBJ_RELEASE(Z_OBJ(obj)); @@ -34312,7 +34446,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE } else { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); } } } @@ -34339,19 +34473,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP zval *object; zval *property; - zval *retval; zval *zptr; SAVE_OPLINE(); object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var); - property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); - retval = EX_VAR(opline->result.var); if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); @@ -34364,7 +34498,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP ZVAL_DEREF(object); if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); break; } } @@ -34375,7 +34509,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); - ZVAL_COPY_VALUE(retval, zptr); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr); zval_opt_copy_ctor(zptr); incdec_op(zptr); } else { @@ -34396,7 +34530,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP } ZVAL_COPY_VALUE(z, value); } - ZVAL_DUP(retval, z); + ZVAL_DUP(EX_VAR(opline->result.var), z); ZVAL_DUP(&z_copy, z); incdec_op(&z_copy); if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z); @@ -34406,7 +34540,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP zval_ptr_dtor(z); } else { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); } } } while (0); @@ -34583,13 +34717,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var); - offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -34718,13 +34854,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLE SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var); - offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -34830,13 +34968,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HAN SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var); - property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object"); @@ -34862,13 +35002,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_HANDLER( SAVE_OPLINE(); object = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); - property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array"); @@ -35553,13 +35695,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_ SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var); - offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + isset_dim_obj_again: if (IS_CV != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht = Z_ARRVAL_P(container); @@ -35674,13 +35818,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var); - offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -36408,13 +36554,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP SAVE_OPLINE(); object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var); - property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } + + property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object"); FREE_UNFETCHED_OP((opline+1)->op1_type, (opline+1)->op1.var); @@ -36834,19 +36983,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE zend_free_op free_op2; zval *object; zval *property; - zval *retval; zval *zptr; SAVE_OPLINE(); object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var); - property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - retval = EX_VAR(opline->result.var); if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } + + property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); zval_ptr_dtor_nogc(free_op2); @@ -36860,7 +37009,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); } break; } @@ -36876,7 +37025,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE incdec_op(zptr); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(retval, zptr); + ZVAL_COPY(EX_VAR(opline->result.var), zptr); } } else { zval rv; @@ -36901,7 +37050,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE SEPARATE_ZVAL_NOREF(z); incdec_op(z); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(retval, z); + ZVAL_COPY(EX_VAR(opline->result.var), z); } Z_OBJ_HT(obj)->write_property(&obj, property, z, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); OBJ_RELEASE(Z_OBJ(obj)); @@ -36909,7 +37058,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE } else { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); } } } @@ -36937,19 +37086,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP zend_free_op free_op2; zval *object; zval *property; - zval *retval; zval *zptr; SAVE_OPLINE(); object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var); - property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - retval = EX_VAR(opline->result.var); if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } + + property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); zval_ptr_dtor_nogc(free_op2); @@ -36962,7 +37111,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP ZVAL_DEREF(object); if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); break; } } @@ -36973,7 +37122,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); - ZVAL_COPY_VALUE(retval, zptr); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), zptr); zval_opt_copy_ctor(zptr); incdec_op(zptr); } else { @@ -36994,7 +37143,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP } ZVAL_COPY_VALUE(z, value); } - ZVAL_DUP(retval, z); + ZVAL_DUP(EX_VAR(opline->result.var), z); ZVAL_DUP(&z_copy, z); incdec_op(&z_copy); if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z); @@ -37004,7 +37153,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP zval_ptr_dtor(z); } else { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - ZVAL_NULL(retval); + ZVAL_NULL(EX_VAR(opline->result.var)); } } } while (0); @@ -37182,13 +37331,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HAN SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } + + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -37318,13 +37469,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HA SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } + + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -37431,13 +37584,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var); - property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } + + property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an object"); zval_ptr_dtor_nogc(free_op2); @@ -37463,13 +37618,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_HAND SAVE_OPLINE(); object = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var); - property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(object) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } + + property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Cannot use string offset as an array"); zval_ptr_dtor_nogc(free_op2); @@ -38062,13 +38219,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_ SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } + + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + isset_dim_obj_again: if (IS_CV != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht = Z_ARRVAL_P(container); @@ -38184,13 +38343,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_CV == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } + + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -39370,7 +39531,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ } else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { zend_string_release(name); @@ -39450,7 +39611,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ } if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { if (Z_CONSTANT_P(retval)) { - zval_update_constant(retval, 1); + if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) { + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); + } } } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { zval_ptr_dtor_nogc(free_op1); @@ -39551,13 +39715,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); - offset = EX_CONSTANT(opline->op2); if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + offset = EX_CONSTANT(opline->op2); + if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -39892,7 +40058,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMPVAR_CONST_HA if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(EG(exception) != NULL)) { if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { zend_string_release(Z_STR(tmp)); @@ -39976,7 +40142,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_ } else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -40040,13 +40206,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); - offset = EX_CONSTANT(opline->op2); if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + offset = EX_CONSTANT(opline->op2); + isset_dim_obj_again: if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht = Z_ARRVAL_P(container); @@ -40161,13 +40329,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TM SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); - offset = EX_CONSTANT(opline->op2); if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + offset = EX_CONSTANT(opline->op2); + if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -40294,7 +40464,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ } else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { zend_string_release(name); @@ -40374,7 +40544,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ } if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { if (Z_CONSTANT_P(retval)) { - zval_update_constant(retval, 1); + if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) { + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); + } } } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { zval_ptr_dtor_nogc(free_op1); @@ -40480,7 +40653,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMPVAR_VAR_HAND if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(EG(exception) != NULL)) { if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { zend_string_release(Z_STR(tmp)); @@ -40564,7 +40737,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_ } else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -40701,7 +40874,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ } else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { zend_string_release(name); @@ -40781,7 +40954,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_ } if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) == ZEND_FETCH_STATIC) { if (Z_CONSTANT_P(retval)) { - zval_update_constant(retval, 1); + if (UNEXPECTED(zval_update_constant_ex(retval, 1, NULL) != SUCCESS)) { + zval_ptr_dtor_nogc(free_op1); + HANDLE_EXCEPTION(); + } } } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { zval_ptr_dtor_nogc(free_op1); @@ -40887,7 +41063,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED_H if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(EG(exception) != NULL)) { if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { zend_string_release(Z_STR(tmp)); @@ -40971,7 +41147,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_ } else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); } else { - ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0); + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -41595,13 +41771,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_HA SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); - offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -41866,13 +42044,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); - offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + isset_dim_obj_again: if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht = Z_ARRVAL_P(container); @@ -41987,13 +42167,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TM SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); - offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); HANDLE_EXCEPTION(); } + + offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -42607,13 +42789,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVA SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } + + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); @@ -42880,13 +43064,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } + + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + isset_dim_obj_again: if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht = Z_ARRVAL_P(container); @@ -43002,13 +43188,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TM SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED && UNEXPECTED(Z_OBJ_P(container) == NULL)) { zend_error(E_EXCEPTION | E_ERROR, "Using $this when not in object context"); - zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } + + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 7ca3aad266..8c6b2e5a1f 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -183,10 +183,6 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_date_format, 0, 0, 2) ZEND_ARG_INFO(0, format) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_date_method_create_from_immutable, 0, 0, 1) - ZEND_ARG_INFO(0, DateTimeImmutable) -ZEND_END_ARG_INFO() - ZEND_BEGIN_ARG_INFO_EX(arginfo_date_method_format, 0, 0, 1) ZEND_ARG_INFO(0, format) ZEND_END_ARG_INFO() @@ -470,7 +466,6 @@ const zend_function_entry date_funcs_date[] = { PHP_ME(DateTime, __construct, arginfo_date_create, ZEND_ACC_CTOR|ZEND_ACC_PUBLIC) PHP_ME(DateTime, __wakeup, NULL, ZEND_ACC_PUBLIC) PHP_ME(DateTime, __set_state, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - PHP_ME(DateTime, createFromImmutable, arginfo_date_method_create_from_immutable, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) PHP_ME_MAPPING(createFromFormat, date_create_from_format, arginfo_date_create_from_format, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) PHP_ME_MAPPING(getLastErrors, date_get_last_errors, arginfo_date_get_last_errors, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) PHP_ME_MAPPING(format, date_format, arginfo_date_method_format, 0) @@ -2835,34 +2830,6 @@ PHP_METHOD(DateTime, __wakeup) } /* }}} */ -/* {{{ proto DateTime::createFromImmutable(DateTimeImmutable object) - Creates new DateTime object from an existing DateTimeImmutable object. -*/ -PHP_METHOD(DateTime, createFromImmutable) -{ - zval *datetimeimmutable_object = NULL; - php_date_obj *new_obj = NULL; - php_date_obj *old_obj = NULL; - - if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &datetimeimmutable_object, date_ce_immutable) == FAILURE) { - return; - } - - php_date_instantiate(date_ce_date, return_value); - old_obj = Z_PHPDATE_P(datetimeimmutable_object); - new_obj = Z_PHPDATE_P(return_value); - - new_obj->time = timelib_time_ctor(); - *new_obj->time = *old_obj->time; - if (old_obj->time->tz_abbr) { - new_obj->time->tz_abbr = strdup(old_obj->time->tz_abbr); - } - if (old_obj->time->tz_info) { - new_obj->time->tz_info = old_obj->time->tz_info; - } -} -/* }}} */ - /* Helper function used to add an associative array of warnings and errors to a zval */ static void zval_from_error_container(zval *z, timelib_error_container *error) /* {{{ */ { diff --git a/ext/date/php_date.h b/ext/date/php_date.h index e887093c39..a2f5261ee6 100644 --- a/ext/date/php_date.h +++ b/ext/date/php_date.h @@ -53,7 +53,6 @@ PHP_FUNCTION(getdate); PHP_METHOD(DateTime, __construct); PHP_METHOD(DateTime, __wakeup); PHP_METHOD(DateTime, __set_state); -PHP_METHOD(DateTime, createFromImmutable); PHP_FUNCTION(date_create); PHP_FUNCTION(date_create_immutable); PHP_FUNCTION(date_create_from_format); diff --git a/ext/date/tests/DateTime_createFromImmutable.phpt b/ext/date/tests/DateTime_createFromImmutable.phpt deleted file mode 100644 index bfde94d825..0000000000 --- a/ext/date/tests/DateTime_createFromImmutable.phpt +++ /dev/null @@ -1,26 +0,0 @@ ---TEST-- -Tests for DateTime::createFromImmutable. ---INI-- -date.timezone=America/New_York ---FILE-- -<?php -$current = "2015-03-05 07:00:16"; - -$i = DateTime::createFromImmutable(date_create_immutable($current)); -var_dump($i); - -$i = DateTime::createFromImmutable(date_create($current)); -var_dump($i); -?> ---EXPECTF-- -object(DateTime)#%d (3) { - ["date"]=> - string(26) "2015-03-05 07:00:16.000000" - ["timezone_type"]=> - int(3) - ["timezone"]=> - string(16) "America/New_York" -} - -Warning: DateTime::createFromImmutable() expects parameter 1 to be DateTimeImmutable, object given in %stests%eDateTime_createFromImmutable.php on line %d -NULL diff --git a/ext/date/tests/DateTime_verify.phpt b/ext/date/tests/DateTime_verify.phpt index 6045274940..33768969dc 100644 --- a/ext/date/tests/DateTime_verify.phpt +++ b/ext/date/tests/DateTime_verify.phpt @@ -27,7 +27,7 @@ object(ReflectionClass)#%d (1) { string(8) "DateTime" } ..and get names of all its methods -array(19) { +array(18) { [0]=> object(ReflectionMethod)#%d (2) { ["name"]=> @@ -52,109 +52,102 @@ array(19) { [3]=> object(ReflectionMethod)#%d (2) { ["name"]=> - string(19) "createFromImmutable" - ["class"]=> - string(8) "DateTime" - } - [4]=> - object(ReflectionMethod)#%d (2) { - ["name"]=> string(16) "createFromFormat" ["class"]=> string(8) "DateTime" } - [5]=> + [4]=> object(ReflectionMethod)#%d (2) { ["name"]=> string(13) "getLastErrors" ["class"]=> string(8) "DateTime" } - [6]=> + [5]=> object(ReflectionMethod)#%d (2) { ["name"]=> string(6) "format" ["class"]=> string(8) "DateTime" } - [7]=> + [6]=> object(ReflectionMethod)#%d (2) { ["name"]=> string(6) "modify" ["class"]=> string(8) "DateTime" } - [8]=> + [7]=> object(ReflectionMethod)#%d (2) { ["name"]=> string(3) "add" ["class"]=> string(8) "DateTime" } - [9]=> + [8]=> object(ReflectionMethod)#%d (2) { ["name"]=> string(3) "sub" ["class"]=> string(8) "DateTime" } - [10]=> + [9]=> object(ReflectionMethod)#%d (2) { ["name"]=> string(11) "getTimezone" ["class"]=> string(8) "DateTime" } - [11]=> + [10]=> object(ReflectionMethod)#%d (2) { ["name"]=> string(11) "setTimezone" ["class"]=> string(8) "DateTime" } - [12]=> + [11]=> object(ReflectionMethod)#%d (2) { ["name"]=> string(9) "getOffset" ["class"]=> string(8) "DateTime" } - [13]=> + [12]=> object(ReflectionMethod)#%d (2) { ["name"]=> string(7) "setTime" ["class"]=> string(8) "DateTime" } - [14]=> + [13]=> object(ReflectionMethod)#%d (2) { ["name"]=> string(7) "setDate" ["class"]=> string(8) "DateTime" } - [15]=> + [14]=> object(ReflectionMethod)#%d (2) { ["name"]=> string(10) "setISODate" ["class"]=> string(8) "DateTime" } - [16]=> + [15]=> object(ReflectionMethod)#%d (2) { ["name"]=> string(12) "setTimestamp" ["class"]=> string(8) "DateTime" } - [17]=> + [16]=> object(ReflectionMethod)#%d (2) { ["name"]=> string(12) "getTimestamp" ["class"]=> string(8) "DateTime" } - [18]=> + [17]=> object(ReflectionMethod)#%d (2) { ["name"]=> string(4) "diff" diff --git a/ext/mysqli/tests/mysqli_fetch_field_flags.phpt b/ext/mysqli/tests/mysqli_fetch_field_flags.phpt index 8259d2f505..06b936aeed 100644 --- a/ext/mysqli/tests/mysqli_fetch_field_flags.phpt +++ b/ext/mysqli/tests/mysqli_fetch_field_flags.phpt @@ -199,7 +199,6 @@ mysqli_close($link); if (!mysqli_query($link, 'DROP TABLE IF EXISTS test')) { printf("[008] %s [%d] %s\n", $column_def, mysqli_errno($link), mysqli_error($link)); - continue; } $column_def = array('col1 CHAR(1)', 'col2 CHAR(2)','INDEX idx_col1_col2(col1, col2)'); @@ -220,7 +219,6 @@ mysqli_close($link); while ($field = mysqli_fetch_field($res)) { if (!isset($expected_flags[$field->name])) { printf("[010] Found unexpected field '%s'\n", $field->name); - continue; } list($missing_flags, $unexpected_flags, $flags_found) = checkFlags($field->flags, $expected_flags[$field->name], $flags); if ($unexpected_flags) diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index ed541543f9..41d3974b72 100644 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -424,7 +424,9 @@ static zval *pdo_stmt_instantiate(pdo_dbh_t *dbh, zval *object, zend_class_entry } } - object_init_ex(object, dbstmt_ce); + if (UNEXPECTED(object_init_ex(object, dbstmt_ce) != SUCCESS)) { + return NULL; + } // ??? Z_SET_REFCOUNT_P(object, 1); //Z_SET_ISREF_P(object); @@ -538,9 +540,11 @@ static PHP_METHOD(PDO, prepare) } if (!pdo_stmt_instantiate(dbh, return_value, dbstmt_ce, &ctor_args)) { - pdo_raise_impl_error(dbh, NULL, "HY000", - "failed to instantiate user-supplied statement class" - ); + if (EXPECTED(!EG(exception))) { + pdo_raise_impl_error(dbh, NULL, "HY000", + "failed to instantiate user-supplied statement class" + ); + } PDO_HANDLE_DBH_ERR(); RETURN_FALSE; } @@ -1077,7 +1081,9 @@ static PHP_METHOD(PDO, query) PDO_CONSTRUCT_CHECK; if (!pdo_stmt_instantiate(dbh, return_value, dbh->def_stmt_ce, &dbh->def_stmt_ctor_args)) { - pdo_raise_impl_error(dbh, NULL, "HY000", "failed to instantiate user supplied statement class"); + if (EXPECTED(!EG(exception))) { + pdo_raise_impl_error(dbh, NULL, "HY000", "failed to instantiate user supplied statement class"); + } return; } stmt = Z_PDO_STMT_P(return_value); diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c index d221c9ed22..346aba7eb0 100644 --- a/ext/pdo/pdo_stmt.c +++ b/ext/pdo/pdo_stmt.c @@ -945,7 +945,9 @@ static int do_fetch(pdo_stmt_t *stmt, int do_bind, zval *return_value, enum pdo_ return 0; } if ((flags & PDO_FETCH_SERIALIZE) == 0) { - object_init_ex(return_value, ce); + if (UNEXPECTED(object_init_ex(return_value, ce) != SUCCESS)) { + return 0; + } if (!stmt->fetch.cls.fci.size) { if (!do_fetch_class_prepare(stmt)) { diff --git a/ext/pdo_mysql/tests/pdo_mysql_pconnect.phpt b/ext/pdo_mysql/tests/pdo_mysql_pconnect.phpt index 5990ab812e..d59c930328 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_pconnect.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_pconnect.phpt @@ -85,10 +85,12 @@ MySQLPDOTest::skip(); } catch (PDOException $e) { - printf("[001] %s, [%s] %s\n", + printf("[001] %s, [%s] %s [%s] %s\n", $e->getMessage(), - (is_object($db)) ? $db->errorCode() : 'n/a', - (is_object($db)) ? implode(' ', $db->errorInfo()) : 'n/a'); + (is_object($db1)) ? $db1->errorCode() : 'n/a', + (is_object($db1)) ? implode(' ', $db1->errorInfo()) : 'n/a', + (is_object($db2)) ? $db2->errorCode() : 'n/a', + (is_object($db2)) ? implode(' ', $db2->errorInfo()) : 'n/a'); } print "done!"; diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 4dc0ed6868..b4dd978f08 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -428,7 +428,6 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in /* Constants */ if (&ce->constants_table) { - zend_hash_apply_with_argument(&ce->constants_table, (apply_func_arg_t) zval_update_constant, (void*)1); string_printf(str, "\n"); count = zend_hash_num_elements(&ce->constants_table); string_printf(str, "%s - Constants [%d] {\n", indent, count); @@ -437,6 +436,7 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in zval *value; ZEND_HASH_FOREACH_STR_KEY_VAL(&ce->constants_table, key, value) { + zval_update_constant_ex(value, 1, NULL); _const_string(str, key->val, value, indent); } ZEND_HASH_FOREACH_END(); } @@ -1851,6 +1851,7 @@ ZEND_METHOD(reflection_function, getStaticVariables) { reflection_object *intern; zend_function *fptr; + zval *val; if (zend_parse_parameters_none() == FAILURE) { return; @@ -1866,7 +1867,11 @@ ZEND_METHOD(reflection_function, getStaticVariables) } fptr->op_array.static_variables = zend_array_dup(fptr->op_array.static_variables); } - zend_hash_apply_with_argument(fptr->op_array.static_variables, (apply_func_arg_t) zval_update_constant_inline_change, fptr->common.scope); + ZEND_HASH_FOREACH_VAL(fptr->op_array.static_variables, val) { + if (UNEXPECTED(zval_update_constant_ex(val, 1, fptr->common.scope) != SUCCESS)) { + return; + } + } ZEND_HASH_FOREACH_END(); zend_hash_copy(Z_ARRVAL_P(return_value), fptr->op_array.static_variables, zval_add_ref); } } @@ -3430,7 +3435,9 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value /* this is necessary to make it able to work with default array * properties, returned to user */ if (Z_CONSTANT(prop_copy)) { - zval_update_constant(&prop_copy, 1); + if (UNEXPECTED(zval_update_constant_ex(&prop_copy, 1, NULL) != SUCCESS)) { + return; + } } zend_hash_update(Z_ARRVAL_P(return_value), key, &prop_copy); @@ -3451,7 +3458,9 @@ ZEND_METHOD(reflection_class, getStaticProperties) GET_REFLECTION_OBJECT_PTR(ce); - zend_update_class_constants(ce); + if (UNEXPECTED(zend_update_class_constants(ce) != SUCCESS)) { + return; + } array_init(return_value); add_class_vars(ce, 1, return_value); @@ -3473,7 +3482,9 @@ ZEND_METHOD(reflection_class, getStaticPropertyValue) GET_REFLECTION_OBJECT_PTR(ce); - zend_update_class_constants(ce); + if (UNEXPECTED(zend_update_class_constants(ce) != SUCCESS)) { + return; + } prop = zend_std_get_static_property(ce, name, 1); if (!prop) { if (def_value) { @@ -3504,7 +3515,9 @@ ZEND_METHOD(reflection_class, setStaticPropertyValue) GET_REFLECTION_OBJECT_PTR(ce); - zend_update_class_constants(ce); + if (UNEXPECTED(zend_update_class_constants(ce) != SUCCESS)) { + return; + } variable_ptr = zend_std_get_static_property(ce, name, 1); if (!variable_ptr) { zend_throw_exception_ex(reflection_exception_ptr, 0, @@ -3528,7 +3541,9 @@ ZEND_METHOD(reflection_class, getDefaultProperties) } GET_REFLECTION_OBJECT_PTR(ce); array_init(return_value); - zend_update_class_constants(ce); + if (UNEXPECTED(zend_update_class_constants(ce) != SUCCESS)) { + return; + } add_class_vars(ce, 1, return_value); add_class_vars(ce, 0, return_value); } @@ -4049,13 +4064,18 @@ ZEND_METHOD(reflection_class, getConstants) { reflection_object *intern; zend_class_entry *ce; + zval *val; if (zend_parse_parameters_none() == FAILURE) { return; } GET_REFLECTION_OBJECT_PTR(ce); array_init(return_value); - zend_hash_apply_with_argument(&ce->constants_table, (apply_func_arg_t)zval_update_constant_inline_change, ce); + ZEND_HASH_FOREACH_VAL(&ce->constants_table, val) { + if (UNEXPECTED(zval_update_constant_ex(val, 1, ce) != SUCCESS)) { + return; + } + } ZEND_HASH_FOREACH_END(); zend_hash_copy(Z_ARRVAL_P(return_value), &ce->constants_table, zval_add_ref_unref); } /* }}} */ @@ -4075,7 +4095,11 @@ ZEND_METHOD(reflection_class, getConstant) } GET_REFLECTION_OBJECT_PTR(ce); - zend_hash_apply_with_argument(&ce->constants_table, (apply_func_arg_t)zval_update_constant_inline_change, ce); + ZEND_HASH_FOREACH_VAL(&ce->constants_table, value) { + if (UNEXPECTED(zval_update_constant_ex(value, 1, ce) != SUCCESS)) { + return; + } + } ZEND_HASH_FOREACH_END(); if ((value = zend_hash_find(&ce->constants_table, name)) == NULL) { RETURN_FALSE; } @@ -4147,7 +4171,9 @@ ZEND_METHOD(reflection_class, isCloneable) if (ce->clone) { RETURN_BOOL(ce->clone->common.fn_flags & ZEND_ACC_PUBLIC); } else { - object_init_ex(&obj, ce); + if (UNEXPECTED(object_init_ex(&obj, ce) != SUCCESS)) { + return; + } RETVAL_BOOL(Z_OBJ_HANDLER(obj, clone_obj) != NULL); zval_dtor(&obj); } @@ -4232,7 +4258,9 @@ ZEND_METHOD(reflection_class, newInstance) METHOD_NOTSTATIC(reflection_class_ptr); GET_REFLECTION_OBJECT_PTR(ce); - object_init_ex(return_value, ce); + if (UNEXPECTED(object_init_ex(return_value, ce) != SUCCESS)) { + return; + } old_scope = EG(scope); EG(scope) = ce; @@ -4334,7 +4362,9 @@ ZEND_METHOD(reflection_class, newInstanceArgs) argc = args->nNumOfElements; } - object_init_ex(return_value, ce); + if (UNEXPECTED(object_init_ex(return_value, ce) != SUCCESS)) { + return; + } old_scope = EG(scope); EG(scope) = ce; @@ -5012,7 +5042,9 @@ ZEND_METHOD(reflection_property, getValue) } if ((ref->prop.flags & ZEND_ACC_STATIC)) { - zend_update_class_constants(intern->ce); + if (UNEXPECTED(zend_update_class_constants(intern->ce) != SUCCESS)) { + return; + } if (Z_TYPE(CE_STATIC_MEMBERS(intern->ce)[ref->prop.offset]) == IS_UNDEF) { php_error_docref(NULL, E_ERROR, "Internal error: Could not find the property %s::%s", intern->ce->name->val, ref->prop.name->val); /* Bails out */ @@ -5061,7 +5093,9 @@ ZEND_METHOD(reflection_property, setValue) return; } } - zend_update_class_constants(intern->ce); + if (UNEXPECTED(zend_update_class_constants(intern->ce) != SUCCESS)) { + return; + } if (Z_TYPE(CE_STATIC_MEMBERS(intern->ce)[ref->prop.offset]) == IS_UNDEF) { php_error_docref(NULL, E_ERROR, "Internal error: Could not find the property %s::%s", intern->ce->name->val, ref->prop.name->val); diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index 9e51626cbd..b91e8b0558 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -480,7 +480,9 @@ static spl_filesystem_object *spl_filesystem_object_create_type(int ht, spl_file case SPL_FS_INFO: ce = ce ? ce : source->info_class; - zend_update_class_constants(ce); + if (UNEXPECTED(zend_update_class_constants(ce) != SUCCESS)) { + break; + } intern = spl_filesystem_from_obj(spl_filesystem_object_new_ex(ce)); ZVAL_OBJ(return_value, &intern->std); @@ -500,7 +502,9 @@ static spl_filesystem_object *spl_filesystem_object_create_type(int ht, spl_file case SPL_FS_FILE: ce = ce ? ce : source->file_class; - zend_update_class_constants(ce); + if (UNEXPECTED(zend_update_class_constants(ce) != SUCCESS)) { + break; + } intern = spl_filesystem_from_obj(spl_filesystem_object_new_ex(ce)); diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 7bf51eb5d5..36d530d47b 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -3827,7 +3827,9 @@ PHP_FUNCTION(constant) if (c) { ZVAL_COPY_VALUE(return_value, c); if (Z_CONSTANT_P(return_value)) { - zval_update_constant_ex(return_value, 1, NULL); + if (UNEXPECTED(zval_update_constant_ex(return_value, 1, NULL) != SUCCESS)) { + return; + } } zval_copy_ctor(return_value); } else { |
