From 868959350ffd1252b00bfbcdcae8c2d7e229f66c Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Fri, 7 Mar 2025 20:47:43 +0100 Subject: [PATCH 1/4] Fix incorrect handling of hooked props without get hook in get_object_vars() Fixes GH-17988 Closes GH-17997 --- NEWS | 2 ++ Zend/tests/property_hooks/gh17988.phpt | 40 ++++++++++++++++++++++++++ Zend/zend_builtin_functions.c | 3 +- ext/json/json_encoder.c | 3 +- 4 files changed, 44 insertions(+), 4 deletions(-) create mode 100644 Zend/tests/property_hooks/gh17988.phpt diff --git a/NEWS b/NEWS index 576a045a02294..aa8ffd81ab6ad 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,8 @@ PHP NEWS results for closures created from magic __call()). (timwolla) . Fixed bug GH-17941 (Stack-use-after-return with lazy objects and hooks). (nielsdos) + . Fixed bug GH-17988 (Incorrect handling of hooked props without get hook in + get_object_vars()). (ilutov) - DOM: . Fixed bug GH-17991 (Assertion failure dom_attr_value_write). (nielsdos) diff --git a/Zend/tests/property_hooks/gh17988.phpt b/Zend/tests/property_hooks/gh17988.phpt new file mode 100644 index 0000000000000..629eec60d010b --- /dev/null +++ b/Zend/tests/property_hooks/gh17988.phpt @@ -0,0 +1,40 @@ +--TEST-- +GH-17988: Incorrect handling of hooked properties without get hook in get_object_vars() +--FILE-- + $value; + } +} + +$c = new C; +$c->prop = 42; + +var_dump($c); +var_dump(get_object_vars($c)); +var_export($c); +echo "\n"; +var_dump(json_encode($c)); +var_dump((array)$c); + +?> +--EXPECTF-- +object(C)#%d (1) { + ["prop"]=> + string(2) "42" +} +array(1) { + ["prop"]=> + string(2) "42" +} +\C::__set_state(array( + 'prop' => '42', +)) +string(13) "{"prop":"42"}" +array(1) { + ["prop"]=> + string(2) "42" +} diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index f2f6b80fc66d7..8ed7939200c79 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -840,7 +840,7 @@ ZEND_FUNCTION(get_object_vars) } const char *unmangled_name_cstr = zend_get_unmangled_property_name(prop_info->name); zend_string *unmangled_name = zend_string_init(unmangled_name_cstr, strlen(unmangled_name_cstr), false); - zend_read_property_ex(prop_info->ce, zobj, unmangled_name, /* silent */ true, &tmp); + value = zend_read_property_ex(prop_info->ce, zobj, unmangled_name, /* silent */ true, &tmp); zend_string_release_ex(unmangled_name, false); if (EG(exception)) { zend_release_properties(properties); @@ -848,7 +848,6 @@ ZEND_FUNCTION(get_object_vars) ZVAL_UNDEF(return_value); RETURN_THROWS(); } - value = &tmp; } Z_TRY_ADDREF_P(value); diff --git a/ext/json/json_encoder.c b/ext/json/json_encoder.c index 7c44a7f5c7a71..4145bc2b6154a 100644 --- a/ext/json/json_encoder.c +++ b/ext/json/json_encoder.c @@ -283,13 +283,12 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options, if ((prop_info->flags & ZEND_ACC_VIRTUAL) && !prop_info->hooks[ZEND_PROPERTY_HOOK_GET]) { continue; } - zend_read_property_ex(prop_info->ce, Z_OBJ_P(val), prop_info->name, /* silent */ true, &tmp); + data = zend_read_property_ex(prop_info->ce, Z_OBJ_P(val), prop_info->name, /* silent */ true, &tmp); if (EG(exception)) { PHP_JSON_HASH_UNPROTECT_RECURSION(recursion_rc); zend_release_properties(prop_ht); return FAILURE; } - data = &tmp; } if (need_comma) { From 9acfe6e11cd7b6fb16b365482ca00ca939a71a38 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Fri, 7 Mar 2025 22:28:19 +0100 Subject: [PATCH 2/4] Fix skipped lazy init on primed SIMPLE_WRITE Go through the normal assignment path, which includes an IS_UNDEF check. Fixes GH-17998 Closes GH-17999 --- NEWS | 2 + Zend/tests/lazy_objects/gh17998.phpt | 31 ++ Zend/zend_vm_def.h | 18 +- Zend/zend_vm_execute.h | 648 +++++++++++++-------------- 4 files changed, 366 insertions(+), 333 deletions(-) create mode 100644 Zend/tests/lazy_objects/gh17998.phpt diff --git a/NEWS b/NEWS index aa8ffd81ab6ad..87c99560ec350 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,8 @@ PHP NEWS (nielsdos) . Fixed bug GH-17988 (Incorrect handling of hooked props without get hook in get_object_vars()). (ilutov) + . Fixed bug GH-17998 (Skipped lazy object initialization on primed + SIMPLE_WRITE cache). (ilutov) - DOM: . Fixed bug GH-17991 (Assertion failure dom_attr_value_write). (nielsdos) diff --git a/Zend/tests/lazy_objects/gh17998.phpt b/Zend/tests/lazy_objects/gh17998.phpt new file mode 100644 index 0000000000000..12d22b4704a13 --- /dev/null +++ b/Zend/tests/lazy_objects/gh17998.phpt @@ -0,0 +1,31 @@ +--TEST-- +GH-17998: Skipped lazy init on primed SIMPLE_WRITE +--FILE-- + $value; + } +} + +$nonLazy = new C; + +$lazy = (new ReflectionClass(C::class))->newLazyProxy(function () { + echo "init\n"; + return new C; +}); + +function foo(C $c) { + $c->prop = 1; + var_dump($c->prop); +} + +foo($nonLazy); +foo($lazy); + +?> +--EXPECT-- +int(1) +init +int(1) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index eea3a4f7e2da1..a4fa8063a5bd4 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2450,12 +2450,14 @@ ZEND_VM_C_LABEL(assign_object): void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +ZEND_VM_C_LABEL(assign_obj_simple): property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); ZEND_VM_C_GOTO(free_and_exit_assign_obj); @@ -2527,14 +2529,12 @@ ZEND_VM_C_LABEL(fast_assign_obj): } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - ZEND_VM_C_GOTO(free_and_exit_assign_obj); - } else { - ZEND_VM_C_GOTO(fast_assign_obj); + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + ZEND_VM_C_GOTO(assign_obj_simple); } /* Fall through to write_property for hooks. */ } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index cb4f3747a02b0..2f6f0af2d872c 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -24037,12 +24037,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -24114,14 +24116,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -24191,12 +24191,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -24268,14 +24270,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -24345,12 +24345,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -24422,14 +24424,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -24499,12 +24499,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -24576,14 +24578,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_D } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -27028,12 +27028,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -27105,14 +27107,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -27182,12 +27182,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -27259,14 +27261,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -27336,12 +27336,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -27413,14 +27415,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -27490,12 +27490,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -27567,14 +27569,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_ } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -31381,12 +31381,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -31458,14 +31460,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -31535,12 +31535,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -31612,14 +31614,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -31689,12 +31689,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -31766,14 +31768,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -31843,12 +31843,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -31920,14 +31922,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -34128,12 +34128,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -34205,14 +34207,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -34282,12 +34282,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -34359,14 +34361,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -34436,12 +34436,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -34513,14 +34515,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -34590,12 +34590,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -34667,14 +34669,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_O } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -36296,12 +36296,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -36373,14 +36375,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -36450,12 +36450,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -36527,14 +36529,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -36604,12 +36604,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -36681,14 +36683,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -36758,12 +36758,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -36835,14 +36837,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_ } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -38942,12 +38942,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -39019,14 +39021,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -39096,12 +39096,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -39173,14 +39175,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -39250,12 +39250,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -39327,14 +39329,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -39404,12 +39404,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -39481,14 +39483,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_D } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -43342,12 +43342,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -43419,14 +43421,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -43496,12 +43496,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -43573,14 +43575,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -43650,12 +43650,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -43727,14 +43729,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -43804,12 +43804,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -43881,14 +43883,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DA } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -47294,12 +47294,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -47371,14 +47373,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -47448,12 +47448,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -47525,14 +47527,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -47602,12 +47602,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -47679,14 +47681,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -47756,12 +47756,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -47833,14 +47835,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_D } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -52793,12 +52793,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -52870,14 +52872,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -52947,12 +52947,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -53024,14 +53026,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -53101,12 +53101,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -53178,14 +53180,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } @@ -53255,12 +53255,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); zval *property_val; + zend_property_info *prop_info; if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: property_val = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property_val) != IS_UNDEF) { - zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (prop_info != NULL) { value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); goto free_and_exit_assign_obj; @@ -53332,14 +53334,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_ } else { ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - property_val = OBJ_PROP(zobj, prop_info->offset); - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { - goto fast_assign_obj; + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; } + goto assign_obj_simple; } /* Fall through to write_property for hooks. */ } From 8254e8de31e7798e66c1f4537fe518677502ea7d Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Fri, 7 Mar 2025 23:30:45 +0100 Subject: [PATCH 3/4] Fix lazy proxy calling set hook twice Writing to an uninitialized lazy proxy will initialize the underlying object and then call zend_std_write_property() on it. If this happens inside a hook, zend_std_write_property() should not call the hook again but directly write to the property slot. This didn't previously work because zend_should_call_hook() would compare the parent frame containing the proxy to the underlying object. This is now handled explicitly. Fixes GH-18000 Closes GH-18001 --- NEWS | 2 ++ Zend/tests/property_hooks/gh18000.phpt | 33 ++++++++++++++++++++++++++ Zend/zend_object_handlers.c | 20 +++++++++++++--- 3 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 Zend/tests/property_hooks/gh18000.phpt diff --git a/NEWS b/NEWS index 87c99560ec350..0ba759b4de8d0 100644 --- a/NEWS +++ b/NEWS @@ -17,6 +17,8 @@ PHP NEWS get_object_vars()). (ilutov) . Fixed bug GH-17998 (Skipped lazy object initialization on primed SIMPLE_WRITE cache). (ilutov) + . Fixed bug GH-17998 (Assignment to backing value in set hook of lazy proxy + calls hook again). (ilutov) - DOM: . Fixed bug GH-17991 (Assertion failure dom_attr_value_write). (nielsdos) diff --git a/Zend/tests/property_hooks/gh18000.phpt b/Zend/tests/property_hooks/gh18000.phpt new file mode 100644 index 0000000000000..61b36034671f9 --- /dev/null +++ b/Zend/tests/property_hooks/gh18000.phpt @@ -0,0 +1,33 @@ +--TEST-- +GH-18000: Lazy proxy calls set hook twice +--FILE-- +prop = $value * 2; + } + } +} + +$rc = new ReflectionClass(C::class); + +$obj = $rc->newLazyProxy(function () { + echo "init\n"; + return new C; +}); + +function foo(C $c) { + $c->prop = 1; + var_dump($c->prop); +} + +foo($obj); + +?> +--EXPECT-- +set +init +int(2) diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index bba40c6bd41ec..a4dba771e3ef5 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -673,9 +673,23 @@ static bool zend_is_in_hook(const zend_property_info *prop_info) static bool zend_should_call_hook(const zend_property_info *prop_info, const zend_object *obj) { - return !zend_is_in_hook(prop_info) - /* execute_data and This are guaranteed to be set if zend_is_in_hook() returns true. */ - || Z_OBJ(EG(current_execute_data)->This) != obj; + if (!zend_is_in_hook(prop_info)) { + return true; + } + + /* execute_data and This are guaranteed to be set if zend_is_in_hook() returns true. */ + zend_object *parent_obj = Z_OBJ(EG(current_execute_data)->This); + if (parent_obj == obj) { + return false; + } + + if (zend_object_is_lazy_proxy(parent_obj) + && zend_lazy_object_initialized(parent_obj) + && zend_lazy_object_get_instance(parent_obj) == obj) { + return false; + } + + return true; } static ZEND_COLD void zend_throw_no_prop_backing_value_access(zend_string *class_name, zend_string *prop_name, bool is_read) From b0858427aaccdae0db6764c0e86ae9489a92032e Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Fri, 24 Mar 2023 10:13:25 +0100 Subject: [PATCH 4/4] Suppress snmp lib memory leak, skip ASAN tests I don't know enough about this library to fix those :( Cherry-picked from: be4db6b5505fb32489a5bf2723ea85b7af8d4fac ba1d9d0ab2cfae4c438513b7016c40b843868ac0 --- .github/lsan-suppressions.txt | 1 + ext/snmp/tests/snmp-object-errno-errstr.phpt | 1 + ext/snmp/tests/snmp-object-error.phpt | 1 + ext/snmp/tests/snmp2_get.phpt | 1 + ext/snmp/tests/snmp2_set-nomib.phpt | 1 + ext/snmp/tests/snmp2_walk.phpt | 1 + ext/snmp/tests/snmp3-error.phpt | 1 + ext/snmp/tests/snmp_getvalue.phpt | 1 + ext/snmp/tests/snmpget.phpt | 1 + ext/snmp/tests/snmpset-nomib.phpt | 1 + ext/snmp/tests/snmpwalk.phpt | 1 + 11 files changed, 11 insertions(+) diff --git a/.github/lsan-suppressions.txt b/.github/lsan-suppressions.txt index 5c2ee76e4607a..f547205d985b9 100644 --- a/.github/lsan-suppressions.txt +++ b/.github/lsan-suppressions.txt @@ -1 +1,2 @@ leak:acommon::DictInfoList::elements +leak:netsnmp_init_mib_internals diff --git a/ext/snmp/tests/snmp-object-errno-errstr.phpt b/ext/snmp/tests/snmp-object-errno-errstr.phpt index 831a9f3319dbb..783191c2c00d8 100644 --- a/ext/snmp/tests/snmp-object-errno-errstr.phpt +++ b/ext/snmp/tests/snmp-object-errno-errstr.phpt @@ -7,6 +7,7 @@ snmp --SKIPIF-- --FILE-- --FILE-- --FILE-- --ENV-- MIBS= diff --git a/ext/snmp/tests/snmp2_walk.phpt b/ext/snmp/tests/snmp2_walk.phpt index 4cd9b3a85b6fd..fcf14424ca057 100644 --- a/ext/snmp/tests/snmp2_walk.phpt +++ b/ext/snmp/tests/snmp2_walk.phpt @@ -7,6 +7,7 @@ snmp --SKIPIF-- --FILE-- --FILE-- --FILE-- --FILE-- --ENV-- MIBS= diff --git a/ext/snmp/tests/snmpwalk.phpt b/ext/snmp/tests/snmpwalk.phpt index b0e8a8a8afd18..61ef33a70a292 100644 --- a/ext/snmp/tests/snmpwalk.phpt +++ b/ext/snmp/tests/snmpwalk.phpt @@ -7,6 +7,7 @@ snmp --SKIPIF-- --FILE--