Skip to content

Commit ef2130d

Browse files
committed
Fix #79487: ::getStaticProperties() ignores property modifications
When retrieving the static class properties via reflection, we have to cater to possible modifications.
1 parent f3cccfd commit ef2130d

File tree

3 files changed

+69
-4
lines changed

3 files changed

+69
-4
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ PHP NEWS
55
- FTP:
66
. Fixed bug #55857 (ftp_size on large files). (cmb)
77

8+
- Reflection:
9+
. Fixed bug #79487 (::getStaticProperties() ignores property modifications).
10+
(cmb, Nikita)
11+
812
?? ??? 2020, PHP 7.4.8
913

1014
- Core:

ext/reflection/php_reflection.c

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3726,9 +3726,7 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value
37263726
zend_string *key;
37273727

37283728
ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->properties_info, key, prop_info) {
3729-
if (((prop_info->flags & ZEND_ACC_PROTECTED) &&
3730-
!zend_check_protected(prop_info->ce, ce)) ||
3731-
((prop_info->flags & ZEND_ACC_PRIVATE) &&
3729+
if (((prop_info->flags & ZEND_ACC_PRIVATE) &&
37323730
prop_info->ce != ce)) {
37333731
continue;
37343732
}
@@ -3766,6 +3764,9 @@ ZEND_METHOD(reflection_class, getStaticProperties)
37663764
{
37673765
reflection_object *intern;
37683766
zend_class_entry *ce;
3767+
zend_property_info *prop_info;
3768+
zval *prop;
3769+
zend_string *key;
37693770

37703771
if (zend_parse_parameters_none() == FAILURE) {
37713772
return;
@@ -3777,8 +3778,34 @@ ZEND_METHOD(reflection_class, getStaticProperties)
37773778
return;
37783779
}
37793780

3781+
if (ce->default_static_members_count && !CE_STATIC_MEMBERS(ce)) {
3782+
zend_class_init_statics(ce);
3783+
}
3784+
37803785
array_init(return_value);
3781-
add_class_vars(ce, 1, return_value);
3786+
3787+
ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->properties_info, key, prop_info) {
3788+
if (((prop_info->flags & ZEND_ACC_PRIVATE) &&
3789+
prop_info->ce != ce)) {
3790+
continue;
3791+
}
3792+
if ((prop_info->flags & ZEND_ACC_STATIC) == 0) {
3793+
continue;
3794+
}
3795+
3796+
prop = &CE_STATIC_MEMBERS(ce)[prop_info->offset];
3797+
ZVAL_DEINDIRECT(prop);
3798+
3799+
if (prop_info->type && Z_ISUNDEF_P(prop)) {
3800+
continue;
3801+
}
3802+
3803+
/* enforce read only access */
3804+
ZVAL_DEREF(prop);
3805+
Z_TRY_ADDREF_P(prop);
3806+
3807+
zend_hash_update(Z_ARRVAL_P(return_value), key, prop);
3808+
} ZEND_HASH_FOREACH_END();
37823809
}
37833810
/* }}} */
37843811

ext/reflection/tests/bug79487.phpt

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
--TEST--
2+
Bug #79487 (::getStaticProperties() ignores property modifications)
3+
--FILE--
4+
<?php
5+
class Foo {
6+
public static $bar = 'orig';
7+
}
8+
9+
Foo::$bar = 'new';
10+
$rc = new ReflectionClass('Foo');
11+
var_dump($rc->getStaticProperties());
12+
13+
class A {
14+
public static $a = 'A old';
15+
}
16+
class B extends A {
17+
public static $b = 'B old';
18+
}
19+
20+
$rc = new ReflectionClass(B::class);
21+
A::$a = 'A new';
22+
var_dump($rc->getStaticProperties());
23+
?>
24+
--EXPECT--
25+
array(1) {
26+
["bar"]=>
27+
string(3) "new"
28+
}
29+
array(2) {
30+
["b"]=>
31+
string(5) "B old"
32+
["a"]=>
33+
string(5) "A new"
34+
}

0 commit comments

Comments
 (0)