Skip to content

Commit cbce0cb

Browse files
committed
Merge branch 'PHP-7.4'
* PHP-7.4: Fix #69804: ::getStaticPropertyValue() throws on protected props
2 parents 59c4c82 + 26aefb7 commit cbce0cb

File tree

4 files changed

+81
-37
lines changed

4 files changed

+81
-37
lines changed

ext/reflection/php_reflection.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3933,7 +3933,7 @@ ZEND_METHOD(ReflectionClass, getStaticProperties)
39333933
ZEND_METHOD(ReflectionClass, getStaticPropertyValue)
39343934
{
39353935
reflection_object *intern;
3936-
zend_class_entry *ce;
3936+
zend_class_entry *ce, *old_scope;
39373937
zend_string *name;
39383938
zval *prop, *def_value = NULL;
39393939

@@ -3946,7 +3946,12 @@ ZEND_METHOD(ReflectionClass, getStaticPropertyValue)
39463946
if (UNEXPECTED(zend_update_class_constants(ce) != SUCCESS)) {
39473947
return;
39483948
}
3949+
3950+
old_scope = EG(fake_scope);
3951+
EG(fake_scope) = ce;
39493952
prop = zend_std_get_static_property(ce, name, BP_VAR_IS);
3953+
EG(fake_scope) = old_scope;
3954+
39503955
if (!prop) {
39513956
if (def_value) {
39523957
ZVAL_COPY(return_value, def_value);
@@ -3966,7 +3971,7 @@ ZEND_METHOD(ReflectionClass, getStaticPropertyValue)
39663971
ZEND_METHOD(ReflectionClass, setStaticPropertyValue)
39673972
{
39683973
reflection_object *intern;
3969-
zend_class_entry *ce;
3974+
zend_class_entry *ce, *old_scope;
39703975
zend_property_info *prop_info;
39713976
zend_string *name;
39723977
zval *variable_ptr, *value;
@@ -3980,7 +3985,10 @@ ZEND_METHOD(ReflectionClass, setStaticPropertyValue)
39803985
if (UNEXPECTED(zend_update_class_constants(ce) != SUCCESS)) {
39813986
return;
39823987
}
3983-
variable_ptr = zend_std_get_static_property_with_info(ce, name, BP_VAR_W, &prop_info);
3988+
old_scope = EG(fake_scope);
3989+
EG(fake_scope) = ce;
3990+
variable_ptr = zend_std_get_static_property_with_info(ce, name, BP_VAR_W, &prop_info);
3991+
EG(fake_scope) = old_scope;
39843992
if (!variable_ptr) {
39853993
zend_clear_exception();
39863994
zend_throw_exception_ex(reflection_exception_ptr, 0,

ext/reflection/tests/006.phpt

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,15 +86,27 @@ TestDerived::testing();
8686
string(3) "pub"
8787
string(3) "pub"
8888
string(7) "updated"
89-
EXCEPTION
90-
EXCEPTION
89+
string(3) "pro"
90+
string(3) "pro"
91+
string(7) "updated"
92+
string(3) "pri"
93+
string(3) "pri"
94+
string(7) "updated"
95+
string(7) "updated"
96+
string(7) "updated"
97+
string(7) "updated"
98+
string(7) "updated"
99+
string(7) "updated"
100+
string(7) "updated"
101+
string(7) "updated"
102+
string(7) "updated"
103+
string(7) "updated"
104+
string(7) "updated"
105+
string(7) "updated"
106+
string(7) "updated"
91107
string(7) "updated"
92108
string(7) "updated"
93109
string(7) "updated"
94-
EXCEPTION
95-
EXCEPTION
96110
string(7) "updated"
97111
string(7) "updated"
98112
string(7) "updated"
99-
EXCEPTION
100-
EXCEPTION

ext/reflection/tests/ReflectionClass_getStaticPropertyValue_001.phpt

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,41 +19,47 @@ class B extends A {
1919

2020
echo "Retrieving static values from A:\n";
2121
$rcA = new ReflectionClass('A');
22-
var_dump($rcA->getStaticPropertyValue("privateOverridden", "default value"));
23-
var_dump($rcA->getStaticPropertyValue("\0A\0privateOverridden"));
24-
var_dump($rcA->getStaticPropertyValue("protectedOverridden", "default value"));
25-
var_dump($rcA->getStaticPropertyValue("\0*\0protectedOverridden"));
22+
var_dump($rcA->getStaticPropertyValue("privateDoesNotExist", "default value"));
23+
var_dump($rcA->getStaticPropertyValue("privateOverridden"));
24+
var_dump($rcA->getStaticPropertyValue("protectedDoesNotExist", "default value"));
25+
var_dump($rcA->getStaticPropertyValue("protectedOverridden"));
2626
var_dump($rcA->getStaticPropertyValue("publicOverridden"));
2727

2828
echo "\nRetrieving static values from B:\n";
2929
$rcB = new ReflectionClass('B');
30-
var_dump($rcB->getStaticPropertyValue("\0A\0privateOverridden"));
31-
var_dump($rcB->getStaticPropertyValue("\0B\0privateOverridden"));
32-
var_dump($rcB->getStaticPropertyValue("\0*\0protectedOverridden"));
30+
var_dump($rcB->getStaticPropertyValue("privateOverridden"));
31+
var_dump($rcB->getStaticPropertyValue("protectedOverridden"));
3332
var_dump($rcB->getStaticPropertyValue("publicOverridden"));
3433

3534
echo "\nRetrieving non-existent values from A with no default value:\n";
3635
try {
37-
var_dump($rcA->getStaticPropertyValue("protectedOverridden"));
36+
var_dump($rcA->getStaticPropertyValue("protectedDoesNotExist"));
3837
echo "you should not see this";
3938
} catch (Exception $e) {
4039
echo $e->getMessage() . "\n";
4140
}
4241

4342
try {
44-
var_dump($rcA->getStaticPropertyValue("privateOverridden"));
43+
var_dump($rcA->getStaticPropertyValue("privateDoesNotExist"));
4544
echo "you should not see this";
4645
} catch (Exception $e) {
4746
echo $e->getMessage() . "\n";
4847
}
4948

5049
?>
51-
--EXPECTF--
50+
--EXPECT--
5251
Retrieving static values from A:
5352
string(13) "default value"
53+
string(16) "original private"
54+
string(13) "default value"
55+
string(18) "original protected"
56+
string(15) "original public"
57+
58+
Retrieving static values from B:
59+
string(15) "changed private"
60+
string(17) "changed protected"
61+
string(14) "changed public"
5462

55-
Fatal error: Uncaught ReflectionException: Class A does not have a property named in %s:%d
56-
Stack trace:
57-
#0 %s(%d): ReflectionClass->getStaticPropertyValue('\x00A\x00privateOverr...')
58-
#1 {main}
59-
thrown in %s on line %d
63+
Retrieving non-existent values from A with no default value:
64+
Class A does not have a property named protectedDoesNotExist
65+
Class A does not have a property named privateDoesNotExist

ext/reflection/tests/ReflectionClass_setStaticPropertyValue_001.phpt

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,41 +19,59 @@ class B extends A {
1919

2020
echo "Set static values in A:\n";
2121
$rcA = new ReflectionClass('A');
22-
$rcA->setStaticPropertyValue("\0A\0privateOverridden", "new value 1");
23-
$rcA->setStaticPropertyValue("\0*\0protectedOverridden", "new value 2");
22+
$rcA->setStaticPropertyValue("privateOverridden", "new value 1");
23+
$rcA->setStaticPropertyValue("protectedOverridden", "new value 2");
2424
$rcA->setStaticPropertyValue("publicOverridden", "new value 3");
2525
print_r($rcA->getStaticProperties());
2626

2727
echo "\nSet static values in B:\n";
2828
$rcB = new ReflectionClass('B');
29-
$rcB->setStaticPropertyValue("\0A\0privateOverridden", "new value 4");
30-
$rcB->setStaticPropertyValue("\0B\0privateOverridden", "new value 5");
31-
$rcB->setStaticPropertyValue("\0*\0protectedOverridden", "new value 6");
29+
$rcB->setStaticPropertyValue("privateOverridden", "new value 4");
30+
$rcB->setStaticPropertyValue("privateOverridden", "new value 5");
31+
$rcB->setStaticPropertyValue("protectedOverridden", "new value 6");
3232
$rcB->setStaticPropertyValue("publicOverridden", "new value 7");
3333
print_r($rcA->getStaticProperties());
3434
print_r($rcB->getStaticProperties());
3535

3636
echo "\nSet non-existent values from A with no default value:\n";
3737
try {
38-
var_dump($rcA->setStaticPropertyValue("protectedOverridden", "new value 8"));
38+
var_dump($rcA->setStaticPropertyValue("protectedDoesNotExist", "new value 8"));
3939
echo "you should not see this";
4040
} catch (Exception $e) {
4141
echo $e->getMessage() . "\n";
4242
}
4343

4444
try {
45-
var_dump($rcA->setStaticPropertyValue("privateOverridden", "new value 9"));
45+
var_dump($rcA->setStaticPropertyValue("privateDoesNotExist", "new value 9"));
4646
echo "you should not see this";
4747
} catch (Exception $e) {
4848
echo $e->getMessage() . "\n";
4949
}
5050

5151
?>
52-
--EXPECTF--
52+
--EXPECT--
5353
Set static values in A:
54+
Array
55+
(
56+
[privateOverridden] => new value 1
57+
[protectedOverridden] => new value 2
58+
[publicOverridden] => new value 3
59+
)
5460

55-
Fatal error: Uncaught ReflectionException: Class A does not have a property named in %s:%d
56-
Stack trace:
57-
#0 %s(%d): ReflectionClass->setStaticPropertyValue('\x00A\x00privateOverr...', 'new value 1')
58-
#1 {main}
59-
thrown in %s on line %d
61+
Set static values in B:
62+
Array
63+
(
64+
[privateOverridden] => new value 1
65+
[protectedOverridden] => new value 2
66+
[publicOverridden] => new value 3
67+
)
68+
Array
69+
(
70+
[privateOverridden] => new value 5
71+
[protectedOverridden] => new value 6
72+
[publicOverridden] => new value 7
73+
)
74+
75+
Set non-existent values from A with no default value:
76+
Class A does not have a property named protectedDoesNotExist
77+
Class A does not have a property named privateDoesNotExist

0 commit comments

Comments
 (0)