summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph M. Becker <cmbecker69@gmx.de>2020-06-24 10:03:46 +0200
committerChristoph M. Becker <cmbecker69@gmx.de>2020-06-24 10:05:51 +0200
commitef2130db88e3a1038c485eea9708cb2677dc9adc (patch)
tree74411d99659eff5aa9e93cad05d7c1e8b16e35f1
parentf3cccfde9e895a8760a94b87c6516e66eda05761 (diff)
downloadphp-git-ef2130db88e3a1038c485eea9708cb2677dc9adc.tar.gz
Fix #79487: ::getStaticProperties() ignores property modifications
When retrieving the static class properties via reflection, we have to cater to possible modifications.
-rw-r--r--NEWS4
-rw-r--r--ext/reflection/php_reflection.c35
-rw-r--r--ext/reflection/tests/bug79487.phpt34
3 files changed, 69 insertions, 4 deletions
diff --git a/NEWS b/NEWS
index 61513e9174..a2e1aca953 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,10 @@ PHP NEWS
- FTP:
. Fixed bug #55857 (ftp_size on large files). (cmb)
+- Reflection:
+ . Fixed bug #79487 (::getStaticProperties() ignores property modifications).
+ (cmb, Nikita)
+
?? ??? 2020, PHP 7.4.8
- Core:
diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c
index dbfb67386e..f4d27b580b 100644
--- a/ext/reflection/php_reflection.c
+++ b/ext/reflection/php_reflection.c
@@ -3726,9 +3726,7 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value
zend_string *key;
ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->properties_info, key, prop_info) {
- if (((prop_info->flags & ZEND_ACC_PROTECTED) &&
- !zend_check_protected(prop_info->ce, ce)) ||
- ((prop_info->flags & ZEND_ACC_PRIVATE) &&
+ if (((prop_info->flags & ZEND_ACC_PRIVATE) &&
prop_info->ce != ce)) {
continue;
}
@@ -3766,6 +3764,9 @@ ZEND_METHOD(reflection_class, getStaticProperties)
{
reflection_object *intern;
zend_class_entry *ce;
+ zend_property_info *prop_info;
+ zval *prop;
+ zend_string *key;
if (zend_parse_parameters_none() == FAILURE) {
return;
@@ -3777,8 +3778,34 @@ ZEND_METHOD(reflection_class, getStaticProperties)
return;
}
+ if (ce->default_static_members_count && !CE_STATIC_MEMBERS(ce)) {
+ zend_class_init_statics(ce);
+ }
+
array_init(return_value);
- add_class_vars(ce, 1, return_value);
+
+ ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->properties_info, key, prop_info) {
+ if (((prop_info->flags & ZEND_ACC_PRIVATE) &&
+ prop_info->ce != ce)) {
+ continue;
+ }
+ if ((prop_info->flags & ZEND_ACC_STATIC) == 0) {
+ continue;
+ }
+
+ prop = &CE_STATIC_MEMBERS(ce)[prop_info->offset];
+ ZVAL_DEINDIRECT(prop);
+
+ if (prop_info->type && Z_ISUNDEF_P(prop)) {
+ continue;
+ }
+
+ /* enforce read only access */
+ ZVAL_DEREF(prop);
+ Z_TRY_ADDREF_P(prop);
+
+ zend_hash_update(Z_ARRVAL_P(return_value), key, prop);
+ } ZEND_HASH_FOREACH_END();
}
/* }}} */
diff --git a/ext/reflection/tests/bug79487.phpt b/ext/reflection/tests/bug79487.phpt
new file mode 100644
index 0000000000..5185c98bba
--- /dev/null
+++ b/ext/reflection/tests/bug79487.phpt
@@ -0,0 +1,34 @@
+--TEST--
+Bug #79487 (::getStaticProperties() ignores property modifications)
+--FILE--
+<?php
+class Foo {
+ public static $bar = 'orig';
+}
+
+Foo::$bar = 'new';
+$rc = new ReflectionClass('Foo');
+var_dump($rc->getStaticProperties());
+
+class A {
+ public static $a = 'A old';
+}
+class B extends A {
+ public static $b = 'B old';
+}
+
+$rc = new ReflectionClass(B::class);
+A::$a = 'A new';
+var_dump($rc->getStaticProperties());
+?>
+--EXPECT--
+array(1) {
+ ["bar"]=>
+ string(3) "new"
+}
+array(2) {
+ ["b"]=>
+ string(5) "B old"
+ ["a"]=>
+ string(5) "A new"
+}