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:
2
NEWS
2
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)
|
||||
|
||||
31
Zend/tests/lazy_objects/gh17998.phpt
Normal file
31
Zend/tests/lazy_objects/gh17998.phpt
Normal 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)
|
||||
@@ -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
648
Zend/zend_vm_execute.h
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user