]> granicus.if.org Git - php/commitdiff
- Fixed bug #49719 (ReflectionClass::hasProperty returns true for a private property...
authorFelipe Pena <felipe@php.net>
Sun, 1 Nov 2009 15:12:34 +0000 (15:12 +0000)
committerFelipe Pena <felipe@php.net>
Sun, 1 Nov 2009 15:12:34 +0000 (15:12 +0000)
NEWS
ext/reflection/php_reflection.c
ext/reflection/tests/ReflectionClass_hasProperty_001.phpt
ext/reflection/tests/bug49719.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index dfca2c1b07b7519c0fbe782dd1ba03ff4efa9daa..e663a5acd4ff0888f5adffc6f6824c336d45a5c7 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -16,6 +16,8 @@ PHP                                                                        NEWS
   (Pierre)
 
 - Fixed bug #50023 (pdo_mysql doesn't use PHP_MYSQL_UNIX_SOCK_ADDR). (Ilia)
+- Fixed bug #49719 (ReflectionClass::hasProperty returns true for a private 
+  property in base class). (Felipe)
 - Fixed bug #49142 (crash when exception thrown from __tostring()).
   (David Soria Parra)
 - Fixed bug #49990 (SNMP3 warning message about security level printed twice).
index a1ee0d6eb16c4438129d1ba6b9d8d128368bde8c..9589307f041fea6bdc0924d31b6d8618764c3962 100644 (file)
@@ -3512,6 +3512,7 @@ ZEND_METHOD(reflection_class, getMethods)
 ZEND_METHOD(reflection_class, hasProperty)
 {
        reflection_object *intern;
+       zend_property_info *property_info;
        zend_class_entry *ce;
        char *name; 
        int name_len;
@@ -3523,11 +3524,13 @@ ZEND_METHOD(reflection_class, hasProperty)
        }
 
        GET_REFLECTION_OBJECT_PTR(ce);
-       if (zend_hash_exists(&ce->properties_info, name, name_len + 1)) {
+       if (zend_hash_find(&ce->properties_info, name, name_len+1, (void **) &property_info) == SUCCESS) {
+               if (property_info->flags & ZEND_ACC_SHADOW) {
+                       RETURN_FALSE;
+               }
                RETURN_TRUE;
        } else {
-               if (intern->obj && Z_OBJ_HANDLER_P(intern->obj, has_property))
-               {
+               if (intern->obj && Z_OBJ_HANDLER_P(intern->obj, has_property)) {
                        MAKE_STD_ZVAL(property);
                        ZVAL_STRINGL(property, name, name_len, 1);
                        if (Z_OBJ_HANDLER_P(intern->obj, has_property)(intern->obj, property, 0 TSRMLS_CC)) {
index 94f739c33c7f5f348fbc8b7dd5ea07ee78116b52..88c4cd509aea3341fcc78269ea397ef0ac3a30cd 100644 (file)
@@ -69,7 +69,7 @@ Reflecting on class privf:
   --> Check for doesntExist: bool(false)
 Reflecting on class subprivf: 
   --> Check for s: bool(true)
-  --> Check for a: bool(true)
+  --> Check for a: bool(false)
   --> Check for A: bool(false)
   --> Check for doesntExist: bool(false)
 
diff --git a/ext/reflection/tests/bug49719.phpt b/ext/reflection/tests/bug49719.phpt
new file mode 100644 (file)
index 0000000..215140a
--- /dev/null
@@ -0,0 +1,44 @@
+--TEST--
+Bug #49719 (ReflectionClass::hasProperty returns true for a private property in base class)
+--FILE--
+<?php
+
+class A {
+       private $a;
+}
+class B extends A {
+       private $b;
+}
+
+try {
+       $b = new B;
+       $ref = new ReflectionClass($b);
+       
+       var_dump(property_exists('b', 'a'));
+       var_dump(property_exists($b, 'a'));
+       var_dump($ref->hasProperty('a'));       
+       var_dump($ref->getProperty('a'));
+} catch (Exception $e) {
+       var_dump($e->getMessage());
+}
+
+class A2 {
+       private $a = 1;
+}
+
+class B2 extends A2 {
+       private $a = 2;
+}
+
+$b2 = new ReflectionClass('B2');
+$prop = $b2->getProperty('a');
+$prop->setAccessible(true);
+var_dump($prop->getValue(new b2));
+
+?>
+--EXPECTF--
+bool(false)
+bool(false)
+bool(false)
+%string|unicode%(25) "Property a does not exist"
+int(2)