Skip to content

Commit cd11a77

Browse files
committed
Test all paths
1 parent b00d154 commit cd11a77

7 files changed

+151
-4
lines changed

ext/reflection/php_reflection.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6783,6 +6783,10 @@ ZEND_METHOD(ReflectionProperty, isWritable)
67836783
if (!(ce->ce_flags & ZEND_ACC_NO_DYNAMIC_PROPERTIES)) {
67846784
RETURN_TRUE;
67856785
}
6786+
/* This path is effectively unreachable, but theoretically possible for
6787+
* two internal classes where ZEND_ACC_NO_DYNAMIC_PROPERTIES is only
6788+
* added to the subclass, in which case a ReflectionProperty can be
6789+
* constructed on the parent class, and then tested on the subclass. */
67866790
handle_magic_set:
67876791
RETURN_BOOL(ce->__set);
67886792
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
Test ReflectionProperty::isReadable() invalid scope
3+
--FILE--
4+
<?php
5+
6+
class A {
7+
public $prop;
8+
}
9+
10+
$r = new ReflectionProperty('A', 'prop');
11+
12+
try {
13+
$r->isReadable('B', null);
14+
} catch (Error $e) {
15+
echo $e::class, ': ', $e->getMessage(), "\n";
16+
}
17+
18+
?>
19+
--EXPECT--
20+
Error: Class "B" not found
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
--TEST--
2+
Test ReflectionProperty::isReadable() unrelated object
3+
--FILE--
4+
<?php
5+
6+
class A {
7+
}
8+
9+
class B extends A {
10+
public $prop;
11+
}
12+
13+
class C extends B {}
14+
15+
class D {}
16+
17+
function test($obj) {
18+
$r = new ReflectionProperty('B', 'prop');
19+
try {
20+
var_dump($r->isReadable(null, $obj));
21+
} catch (Exception $e) {
22+
echo $e::class, ': ', $e->getMessage(), "\n";
23+
}
24+
}
25+
26+
test(new A);
27+
test(new B);
28+
test(new C);
29+
test(new D);
30+
31+
?>
32+
--EXPECT--
33+
ReflectionException: Given object is not an instance of the class this property was declared in
34+
bool(true)
35+
bool(true)
36+
ReflectionException: Given object is not an instance of the class this property was declared in

ext/reflection/tests/ReflectionProperty_isReadable_visibility.phpt

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,32 @@ class B extends A {
99
public $a;
1010
protected $b;
1111
private $c;
12-
public protected(set) int $d;
12+
public protected(set) int $d = 42;
1313
}
1414

1515
class C extends B {}
1616

17+
class D extends C {
18+
public function __get($name) {}
19+
}
20+
21+
class E extends D {
22+
private $f;
23+
24+
public function __isset($name) {
25+
return $name === 'f';
26+
}
27+
}
28+
1729
$test = static function ($scope) {
1830
$rc = new ReflectionClass(B::class);
1931
foreach ($rc->getProperties() as $rp) {
2032
echo $rp->getName() . ' from ' . ($scope ?? 'global') . ': ';
21-
var_dump($rp->isReadable($scope, null));
33+
var_dump($rp->isReadable($scope, $scope && $scope !== 'A' ? new $scope : null));
2234
}
2335
};
2436

25-
foreach (['A', 'B', 'C'] as $scope) {
37+
foreach (['A', 'B', 'C', 'D', 'E'] as $scope) {
2638
$test($scope);
2739
}
2840
$test(null);
@@ -41,6 +53,14 @@ a from C: bool(true)
4153
b from C: bool(true)
4254
c from C: bool(false)
4355
d from C: bool(true)
56+
a from D: bool(true)
57+
b from D: bool(true)
58+
c from D: bool(true)
59+
d from D: bool(true)
60+
a from E: bool(true)
61+
b from E: bool(true)
62+
c from E: bool(false)
63+
d from E: bool(true)
4464
a from global: bool(true)
4565
b from global: bool(false)
4666
c from global: bool(false)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
Test ReflectionProperty::isWritable() invalid scope
3+
--FILE--
4+
<?php
5+
6+
class A {
7+
public $prop;
8+
}
9+
10+
$r = new ReflectionProperty('A', 'prop');
11+
12+
try {
13+
$r->isWritable('B', null);
14+
} catch (Error $e) {
15+
echo $e::class, ': ', $e->getMessage(), "\n";
16+
}
17+
18+
?>
19+
--EXPECT--
20+
Error: Class "B" not found
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
--TEST--
2+
Test ReflectionProperty::isWritable() unrelated object
3+
--FILE--
4+
<?php
5+
6+
class A {
7+
}
8+
9+
class B extends A {
10+
public $prop;
11+
}
12+
13+
class C extends B {}
14+
15+
class D {}
16+
17+
function test($obj) {
18+
$r = new ReflectionProperty('B', 'prop');
19+
try {
20+
var_dump($r->isWritable(null, $obj));
21+
} catch (Exception $e) {
22+
echo $e::class, ': ', $e->getMessage(), "\n";
23+
}
24+
}
25+
26+
test(new A);
27+
test(new B);
28+
test(new C);
29+
test(new D);
30+
31+
?>
32+
--EXPECT--
33+
ReflectionException: Given object is not an instance of the class this property was declared in
34+
bool(true)
35+
bool(true)
36+
ReflectionException: Given object is not an instance of the class this property was declared in

ext/reflection/tests/ReflectionProperty_isWritable_visibility.phpt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,22 @@ class B extends A {
1616

1717
class C extends B {}
1818

19+
class D extends C {
20+
public function __set($name, $value) {}
21+
}
22+
1923
$test = static function ($scope) {
2024
$rc = new ReflectionClass(B::class);
2125
foreach ($rc->getProperties() as $rp) {
2226
echo $rp->getName() . ' from ' . ($scope ?? 'global') . ': ';
23-
var_dump($rp->isWritable($scope, null));
27+
var_dump($rp->isWritable($scope, $scope && $scope !== 'A' ? new $scope : null));
2428
}
2529
};
2630

2731
$test('A');
2832
$test('B');
2933
$test('C');
34+
$test('D');
3035
$test(null);
3136

3237
?>
@@ -49,6 +54,12 @@ c from C: bool(false)
4954
d from C: bool(false)
5055
e from C: bool(true)
5156
f from C: bool(true)
57+
a from D: bool(true)
58+
b from D: bool(true)
59+
c from D: bool(true)
60+
d from D: bool(false)
61+
e from D: bool(true)
62+
f from D: bool(true)
5263
a from global: bool(true)
5364
b from global: bool(false)
5465
c from global: bool(false)

0 commit comments

Comments
 (0)