]> granicus.if.org Git - php/commitdiff
Always invoke zpp in ReflectionProperty::getValue/isInitialized
authorNikita Popov <nikita.ppv@gmail.com>
Mon, 10 Feb 2020 10:05:26 +0000 (11:05 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 10 Feb 2020 10:05:26 +0000 (11:05 +0100)
Make sure we still perform a zpp check for the static case, and
also always enforce that the parameter is ?object. Otherwise we
violate the specified signature.

ext/reflection/php_reflection.c
ext/reflection/php_reflection.stub.php
ext/reflection/php_reflection_arginfo.h
ext/reflection/tests/ReflectionProperty_getValue_error.phpt
ext/reflection/tests/ReflectionProperty_isInitialized.phpt

index 6fb415f2ad29b77f2f1aff4ca3228e722ea8d3d5..95c4859e94cec06692eda6b53d61135e822f143c 100644 (file)
@@ -5467,9 +5467,13 @@ ZEND_METHOD(reflection_property, getValue)
 {
        reflection_object *intern;
        property_reference *ref;
-       zval *object, *name;
+       zval *object = NULL, *name;
        zval *member_p = NULL;
 
+       if (zend_parse_parameters(ZEND_NUM_ARGS(), "|o!", &object) == FAILURE) {
+               RETURN_THROWS();
+       }
+
        GET_REFLECTION_OBJECT_PTR(ref);
 
        if (!(prop_get_flags(ref) & ZEND_ACC_PUBLIC) && intern->ignore_visibility == 0) {
@@ -5487,7 +5491,8 @@ ZEND_METHOD(reflection_property, getValue)
        } else {
                zval rv;
 
-               if (zend_parse_parameters(ZEND_NUM_ARGS(), "o", &object) == FAILURE) {
+               if (!object) {
+                       zend_type_error("No object provided for getValue() on instance property");
                        RETURN_THROWS();
                }
 
@@ -5553,9 +5558,13 @@ ZEND_METHOD(reflection_property, isInitialized)
 {
        reflection_object *intern;
        property_reference *ref;
-       zval *object, *name;
+       zval *object = NULL, *name;
        zval *member_p = NULL;
 
+       if (zend_parse_parameters(ZEND_NUM_ARGS(), "|o!", &object) == FAILURE) {
+               RETURN_THROWS();
+       }
+
        GET_REFLECTION_OBJECT_PTR(ref);
 
        if (!(prop_get_flags(ref) & ZEND_ACC_PUBLIC) && intern->ignore_visibility == 0) {
@@ -5575,7 +5584,8 @@ ZEND_METHOD(reflection_property, isInitialized)
                zend_class_entry *old_scope;
                int retval;
 
-               if (zend_parse_parameters(ZEND_NUM_ARGS(), "o", &object) == FAILURE) {
+               if (!object) {
+                       zend_type_error("No object provided for isInitialized() on instance property");
                        RETURN_THROWS();
                }
 
index 26e38ae37f057006597f8bdfb82ded9f06c302f0..76cbe75dd72224e33f44f929202a62a4452bd511 100644 (file)
@@ -391,7 +391,7 @@ class ReflectionProperty implements Reflector
     public function setValue($object_or_value, $value = UNKNOWN) {}
 
     /** @return bool */
-    public function isInitialized(object $object = UNKNOWN) {}
+    public function isInitialized(?object $object = null) {}
 
     /** @return bool */
     public function isPublic() {}
index 68d61026b0e0740f6e3364ce0cf99f5daa553abc..35ee71373224d2e80fbdefcf691d8e8db0e6142b 100644 (file)
@@ -317,9 +317,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ReflectionProperty_setValue, 0, 0, 1)
        ZEND_ARG_INFO(0, value)
 ZEND_END_ARG_INFO()
 
-ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ReflectionProperty_isInitialized, 0, 0, 0)
-       ZEND_ARG_TYPE_INFO(0, object, IS_OBJECT, 0)
-ZEND_END_ARG_INFO()
+#define arginfo_class_ReflectionProperty_isInitialized arginfo_class_ReflectionProperty_getValue
 
 #define arginfo_class_ReflectionProperty_isPublic arginfo_class_Reflector___toString
 
index 2ffd244501ecb4d12d810088f5e8323c4afa4741..c5da067c32d93d2fa7b6408be49a37144be31fba 100644 (file)
@@ -22,7 +22,11 @@ echo "\nInstance without property:\n";
 $propInfo = new ReflectionProperty('TestClass', 'stat');
 
 echo "\nStatic property / too many args:\n";
-var_dump($propInfo->getValue($instance, true));
+try {
+    var_dump($propInfo->getValue($instance, true));
+} catch (TypeError $e) {
+    echo $e->getMessage(), "\n";
+}
 
 echo "\nProtected property:\n";
 try {
@@ -35,22 +39,31 @@ catch(Exception $exc) {
 
 echo "\n\nInvalid instance:\n";
 $propInfo = new ReflectionProperty('TestClass', 'pub2');
-var_dump($propInfo->getValue($invalidInstance));
+try {
+    var_dump($propInfo->getValue($invalidInstance));
+} catch (ReflectionException $e) {
+    echo $e->getMessage();
+}
+
+echo "\n\nMissing instance:\n";
+try {
+    var_dump($propInfo->getValue());
+} catch (TypeError $e) {
+    echo $e->getMessage();
+}
 
 ?>
---EXPECTF--
+--EXPECT--
 Instance without property:
 
 Static property / too many args:
-string(15) "static property"
+ReflectionProperty::getValue() expects at most 1 parameter, 2 given
 
 Protected property:
 Cannot access non-public member TestClass::$prot
 
 Invalid instance:
+Given object is not an instance of the class this property was declared in
 
-Fatal error: Uncaught ReflectionException: Given object is not an instance of the class this property was declared in in %s:%d
-Stack trace:
-#0 %s(%d): ReflectionProperty->getValue(Object(AnotherClass))
-#1 {main}
-  thrown in %s on line %d
+Missing instance:
+No object provided for getValue() on instance property
index 260084fae45dade648115b0cfe559bf4c32d909f..29541e405b1743690e0633ca6c4200e6c9f05d3f 100644 (file)
@@ -62,6 +62,12 @@ try {
     echo $e->getMessage(), "\n";
 }
 
+try {
+    var_dump($rp->isInitialized());
+} catch (TypeError $e) {
+    echo $e->getMessage(), "\n";
+}
+
 class WithMagic {
     public $prop;
     public int $intProp;
@@ -108,6 +114,7 @@ bool(false)
 Object type:
 bool(false)
 Given object is not an instance of the class this property was declared in
+No object provided for isInitialized() on instance property
 Class with __isset:
 bool(false)
 bool(false)