diff options
author | Christoph M. Becker <cmbecker69@gmx.de> | 2020-06-24 10:03:46 +0200 |
---|---|---|
committer | Christoph M. Becker <cmbecker69@gmx.de> | 2020-06-24 10:05:51 +0200 |
commit | ef2130db88e3a1038c485eea9708cb2677dc9adc (patch) | |
tree | 74411d99659eff5aa9e93cad05d7c1e8b16e35f1 | |
parent | f3cccfde9e895a8760a94b87c6516e66eda05761 (diff) | |
download | php-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-- | NEWS | 4 | ||||
-rw-r--r-- | ext/reflection/php_reflection.c | 35 | ||||
-rw-r--r-- | ext/reflection/tests/bug79487.phpt | 34 |
3 files changed, 69 insertions, 4 deletions
@@ -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" +} |