Skip to content

Commit 9acfe6e

Browse files
committed
Fix skipped lazy init on primed SIMPLE_WRITE
Go through the normal assignment path, which includes an IS_UNDEF check. Fixes phpGH-17998 Closes phpGH-17999
1 parent 8689593 commit 9acfe6e

File tree

4 files changed

+366
-333
lines changed

4 files changed

+366
-333
lines changed

NEWS

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ PHP NEWS
1515
(nielsdos)
1616
. Fixed bug GH-17988 (Incorrect handling of hooked props without get hook in
1717
get_object_vars()). (ilutov)
18+
. Fixed bug GH-17998 (Skipped lazy object initialization on primed
19+
SIMPLE_WRITE cache). (ilutov)
1820

1921
- DOM:
2022
. Fixed bug GH-17991 (Assertion failure dom_attr_value_write). (nielsdos)

Zend/tests/lazy_objects/gh17998.phpt

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
--TEST--
2+
GH-17998: Skipped lazy init on primed SIMPLE_WRITE
3+
--FILE--
4+
<?php
5+
6+
class C {
7+
public $prop {
8+
set => $value;
9+
}
10+
}
11+
12+
$nonLazy = new C;
13+
14+
$lazy = (new ReflectionClass(C::class))->newLazyProxy(function () {
15+
echo "init\n";
16+
return new C;
17+
});
18+
19+
function foo(C $c) {
20+
$c->prop = 1;
21+
var_dump($c->prop);
22+
}
23+
24+
foo($nonLazy);
25+
foo($lazy);
26+
27+
?>
28+
--EXPECT--
29+
int(1)
30+
init
31+
int(1)

Zend/zend_vm_def.h

+9-9
Original file line numberDiff line numberDiff line change
@@ -2450,12 +2450,14 @@ ZEND_VM_C_LABEL(assign_object):
24502450
void **cache_slot = CACHE_ADDR(opline->extended_value);
24512451
uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1);
24522452
zval *property_val;
2453+
zend_property_info *prop_info;
24532454

24542455
if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) {
2456+
prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
2457+
2458+
ZEND_VM_C_LABEL(assign_obj_simple):
24552459
property_val = OBJ_PROP(zobj, prop_offset);
24562460
if (Z_TYPE_P(property_val) != IS_UNDEF) {
2457-
zend_property_info *prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2);
2458-
24592461
if (prop_info != NULL) {
24602462
value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
24612463
ZEND_VM_C_GOTO(free_and_exit_assign_obj);
@@ -2527,14 +2529,12 @@ ZEND_VM_C_LABEL(fast_assign_obj):
25272529
} else {
25282530
ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset));
25292531
if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) {
2530-
zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2);
2531-
property_val = OBJ_PROP(zobj, prop_info->offset);
2532-
if (ZEND_TYPE_IS_SET(prop_info->type)) {
2533-
value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC);
2534-
ZEND_VM_C_GOTO(free_and_exit_assign_obj);
2535-
} else {
2536-
ZEND_VM_C_GOTO(fast_assign_obj);
2532+
prop_info = CACHED_PTR_EX(cache_slot + 2);
2533+
prop_offset = prop_info->offset;
2534+
if (!ZEND_TYPE_IS_SET(prop_info->type)) {
2535+
prop_info = NULL;
25372536
}
2537+
ZEND_VM_C_GOTO(assign_obj_simple);
25382538
}
25392539
/* Fall through to write_property for hooks. */
25402540
}

0 commit comments

Comments
 (0)