From: Antony Dovgal Date: Sat, 10 Feb 2007 20:52:42 +0000 (+0000) Subject: MFH X-Git-Tag: php-5.2.2RC1~433 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9c100b20e626e1feb11f6d5af9444c3b97d27bf4;p=php MFH --- diff --git a/NEWS b/NEWS index 50bd51052c..b04eda72b8 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,8 @@ PHP NEWS - Upgraded SQLite 3 to version 3.3.12 (Ilia) - Upgraded PCRE to version 7.0 (Nuno) - Add --ri switch to CLI which allows to check extension information. (Marcus) +- Fixed bug #40431 (dynamic properties may cause crash in ReflectionProperty + methods). (Tony) - Fixed bug #40410 (ext/posix does not compile on MacOS 10.3.9). (Tony) - Fixed bug #39836 (SplObjectStorage empty after unserialize). (Marcus) diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index d47d680549..ac755ea61d 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -1142,14 +1142,19 @@ static void reflection_property_factory(zend_class_entry *ce, zend_property_info if (!(prop->flags & ZEND_ACC_PRIVATE)) { /* we have to search the class hierarchy for this (implicit) public or protected property */ - zend_class_entry *tmp_ce = ce; - zend_property_info *tmp_info; - + zend_class_entry *tmp_ce = ce, *store_ce = ce; + zend_property_info *tmp_info = NULL; + while (tmp_ce && zend_hash_find(&tmp_ce->properties_info, prop_name, strlen(prop_name) + 1, (void **) &tmp_info) != SUCCESS) { ce = tmp_ce; - prop = tmp_info; tmp_ce = tmp_ce->parent; } + + if (tmp_info && !(tmp_info->flags & ZEND_ACC_SHADOW)) { /* found something and it's not a parent's private */ + prop = tmp_info; + } else { /* not found, use initial value */ + ce = store_ce; + } } MAKE_STD_ZVAL(name); diff --git a/ext/reflection/tests/bug40431.phpt b/ext/reflection/tests/bug40431.phpt new file mode 100644 index 0000000000..6e6e4c5eb1 --- /dev/null +++ b/ext/reflection/tests/bug40431.phpt @@ -0,0 +1,138 @@ +--TEST-- +Bug #40431 (dynamic properties may cause crash in ReflectionProperty methods) +--FILE-- +value = 'value'; +$RefObj = new ReflectionObject($Obj); + +$props = $RefObj->getProperties(); + +var_dump($props); +var_dump($props[0]->isStatic()); +var_dump($props[0]->isPrivate()); +var_dump($props[0]->isPublic()); +var_dump($props[0]->isProtected()); + +echo "=== 2nd test ===\n"; + +class test1 { +} + +class test2 extends test1{ +} + +$Obj = new test2; +$Obj->value = 'value'; +$RefObj = new ReflectionObject($Obj); + +$props = $RefObj->getProperties(); + +var_dump($props); +var_dump($props[0]->isStatic()); +var_dump($props[0]->isPrivate()); +var_dump($props[0]->isPublic()); +var_dump($props[0]->isProtected()); + +echo "=== 3rd test ===\n"; + +class test3 { +} + +$Obj = new test3; +$Obj->value = 'value'; +$RefObj = new ReflectionObject($Obj); + +$props = $RefObj->getProperties(); + +var_dump($props); +var_dump($props[0]->isStatic()); +var_dump($props[0]->isPrivate()); +var_dump($props[0]->isPublic()); +var_dump($props[0]->isProtected()); + +echo "=== 4th test ===\n"; + +class test5 { + private $value = 1; +} + +class test4 extends test5{ +} + +$Obj = new test4; +$Obj->value = 'value'; +$RefObj = new ReflectionObject($Obj); + +$props = $RefObj->getProperties(); + +var_dump($props); +var_dump($props[0]->isStatic()); +var_dump($props[0]->isPrivate()); +var_dump($props[0]->isPublic()); +var_dump($props[0]->isProtected()); + +echo "Done\n"; +?> +--EXPECTF-- +=== 1st test === + +Strict Standards: Creating default object from empty value in %s on line %d +array(1) { + [0]=> + &object(ReflectionProperty)#%d (2) { + ["name"]=> + string(5) "value" + ["class"]=> + string(8) "stdClass" + } +} +bool(false) +bool(false) +bool(true) +bool(false) +=== 2nd test === +array(1) { + [0]=> + &object(ReflectionProperty)#%d (2) { + ["name"]=> + string(5) "value" + ["class"]=> + string(5) "test2" + } +} +bool(false) +bool(false) +bool(true) +bool(false) +=== 3rd test === +array(1) { + [0]=> + &object(ReflectionProperty)#%d (2) { + ["name"]=> + string(5) "value" + ["class"]=> + string(5) "test3" + } +} +bool(false) +bool(false) +bool(true) +bool(false) +=== 4th test === +array(1) { + [0]=> + &object(ReflectionProperty)#%d (2) { + ["name"]=> + string(5) "value" + ["class"]=> + string(5) "test4" + } +} +bool(false) +bool(false) +bool(true) +bool(false) +Done