Skip to content

Commit b89e0ef

Browse files
authored
Fix GH-22000: Unwrap references in ReflectionProperty::isReadable() (#22025)
1 parent cde32be commit b89e0ef

2 files changed

Lines changed: 66 additions & 0 deletions

File tree

ext/reflection/php_reflection.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6731,6 +6731,11 @@ ZEND_METHOD(ReflectionProperty, isReadable)
67316731
zval member;
67326732
ZVAL_STR(&member, ref->unmangled_name);
67336733
zend_call_known_instance_method_with_1_params(ce->__isset, obj, return_value, &member);
6734+
6735+
if (Z_TYPE_P(return_value) == IS_REFERENCE) {
6736+
zend_unwrap_reference(return_value);
6737+
}
6738+
67346739
*guard &= ~ZEND_GUARD_PROPERTY_ISSET;
67356740
OBJ_RELEASE(obj);
67366741
return;

ext/reflection/tests/gh22000.phpt

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
--TEST--
2+
GH-22000 - Ensure __isset returning a reference is supported by ReflectionProperty::isReadable()
3+
--FILE--
4+
<?php
5+
class TestClass1 {
6+
public int $a = 1;
7+
public int $b;
8+
public int $c;
9+
10+
public function __construct() {
11+
unset($this->b);
12+
unset($this->c);
13+
}
14+
15+
public function __isset($name) {
16+
return $name === 'b';
17+
}
18+
19+
public function __get($name) {}
20+
}
21+
22+
class TestClass2 {
23+
public int $d;
24+
public int $e;
25+
public int $f;
26+
27+
public function __construct() {
28+
unset($this->e);
29+
unset($this->f);
30+
}
31+
32+
public function &__isset($name) {
33+
return $name === 'f';
34+
}
35+
36+
public function __get($name) {}
37+
}
38+
39+
40+
function test($class) {
41+
$rc = new ReflectionClass($class);
42+
foreach ($rc->getProperties() as $rp) {
43+
echo $rp->getName() . ' from global:';
44+
var_dump($rp->isReadable(null, new $class));
45+
}
46+
}
47+
48+
test('TestClass1');
49+
test('TestClass2');
50+
?>
51+
--EXPECTF--
52+
a from global:bool(true)
53+
b from global:bool(true)
54+
c from global:bool(false)
55+
d from global:bool(false)
56+
e from global:
57+
Notice: Only variable references should be returned by reference in %s on line %d
58+
bool(false)
59+
f from global:
60+
Notice: Only variable references should be returned by reference in %s on line %d
61+
bool(true)

0 commit comments

Comments
 (0)