Skip to content

Commit f9d8d48

Browse files
committed
Merge branch 'PHP-8.4'
* PHP-8.4: Fix lazy proxy calling set hook twice
2 parents 9fd6273 + 8254e8d commit f9d8d48

File tree

2 files changed

+50
-3
lines changed

2 files changed

+50
-3
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--TEST--
2+
GH-18000: Lazy proxy calls set hook twice
3+
--FILE--
4+
<?php
5+
6+
class C {
7+
public $prop {
8+
set {
9+
echo "set\n";
10+
$this->prop = $value * 2;
11+
}
12+
}
13+
}
14+
15+
$rc = new ReflectionClass(C::class);
16+
17+
$obj = $rc->newLazyProxy(function () {
18+
echo "init\n";
19+
return new C;
20+
});
21+
22+
function foo(C $c) {
23+
$c->prop = 1;
24+
var_dump($c->prop);
25+
}
26+
27+
foo($obj);
28+
29+
?>
30+
--EXPECT--
31+
set
32+
init
33+
int(2)

Zend/zend_object_handlers.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -673,9 +673,23 @@ static bool zend_is_in_hook(const zend_property_info *prop_info)
673673

674674
static bool zend_should_call_hook(const zend_property_info *prop_info, const zend_object *obj)
675675
{
676-
return !zend_is_in_hook(prop_info)
677-
/* execute_data and This are guaranteed to be set if zend_is_in_hook() returns true. */
678-
|| Z_OBJ(EG(current_execute_data)->This) != obj;
676+
if (!zend_is_in_hook(prop_info)) {
677+
return true;
678+
}
679+
680+
/* execute_data and This are guaranteed to be set if zend_is_in_hook() returns true. */
681+
zend_object *parent_obj = Z_OBJ(EG(current_execute_data)->This);
682+
if (parent_obj == obj) {
683+
return false;
684+
}
685+
686+
if (zend_object_is_lazy_proxy(parent_obj)
687+
&& zend_lazy_object_initialized(parent_obj)
688+
&& zend_lazy_object_get_instance(parent_obj) == obj) {
689+
return false;
690+
}
691+
692+
return true;
679693
}
680694

681695
static ZEND_COLD void zend_throw_no_prop_backing_value_access(zend_string *class_name, zend_string *prop_name, bool is_read)

0 commit comments

Comments
 (0)