Skip to content

Commit 3b68610

Browse files
committed
Fix lazy __isset case
Lazy objects call magic methods before initializing lazy objects when undeclared proeprties are accessed.
1 parent edc53a4 commit 3b68610

File tree

2 files changed

+44
-14
lines changed

2 files changed

+44
-14
lines changed

ext/reflection/php_reflection.c

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6676,20 +6676,8 @@ ZEND_METHOD(ReflectionProperty, isReadable)
66766676

66776677
zend_class_entry *ce = obj ? obj->ce : intern->ce;
66786678
if (!prop) {
6679-
if (obj) {
6680-
/* __isset call needs to happen on lazy object, so copy obj. */
6681-
zend_object *instance = obj;
6682-
retry_dynamic:
6683-
if (zend_lazy_object_must_init(instance)) {
6684-
instance = zend_lazy_object_init(instance);
6685-
if (!instance) {
6686-
RETURN_THROWS();
6687-
}
6688-
goto retry_dynamic;
6689-
}
6690-
if (instance->properties && zend_hash_find_ptr(instance->properties, ref->unmangled_name)) {
6691-
RETURN_TRUE;
6692-
}
6679+
if (obj && obj->properties && zend_hash_find_ptr(obj->properties, ref->unmangled_name)) {
6680+
RETURN_TRUE;
66936681
}
66946682
handle_magic_get:
66956683
if (ce->__get) {
@@ -6708,6 +6696,15 @@ ZEND_METHOD(ReflectionProperty, isReadable)
67086696
}
67096697
RETURN_TRUE;
67106698
}
6699+
if (obj && zend_lazy_object_must_init(obj)) {
6700+
obj = zend_lazy_object_init(obj);
6701+
if (!obj) {
6702+
RETURN_THROWS();
6703+
}
6704+
if (obj->properties && zend_hash_find_ptr(obj->properties, ref->unmangled_name)) {
6705+
RETURN_TRUE;
6706+
}
6707+
}
67116708
RETURN_FALSE;
67126709
}
67136710

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--TEST--
2+
Test ReflectionProperty::isReadable() lazy isset
3+
--CREDITS--
4+
Arnaud Le Blanc (arnaud-lb)
5+
--FILE--
6+
<?php
7+
8+
#[AllowDynamicProperties]
9+
class A {
10+
public $_;
11+
12+
public function __construct() {
13+
$this->prop = 1;
14+
}
15+
16+
public function __isset($name) {
17+
return false;
18+
}
19+
20+
public function __get($name) {
21+
return null;
22+
}
23+
}
24+
25+
$rc = new ReflectionClass(A::class);
26+
$obj = $rc->newLazyProxy(fn() => new A);
27+
28+
$rp = new ReflectionProperty(new A, 'prop');
29+
var_dump($rp->isReadable(null, $obj));
30+
31+
?>
32+
--EXPECT--
33+
bool(false)

0 commit comments

Comments
 (0)