1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

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
This commit is contained in:
Ilija Tovilo
2025-03-07 22:28:19 +01:00
parent 868959350f
commit 9acfe6e11c
4 changed files with 366 additions and 333 deletions

2
NEWS
View File

@@ -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)

View File

@@ -0,0 +1,31 @@
--TEST--
GH-17998: Skipped lazy init on primed SIMPLE_WRITE
--FILE--
<?php
class C {
public $prop {
set => $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)

View File

@@ -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. */
}

648
Zend/zend_vm_execute.h generated

File diff suppressed because it is too large Load Diff