summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2020-02-10 11:05:26 +0100
committerNikita Popov <nikita.ppv@gmail.com>2020-02-10 11:05:26 +0100
commit42fbc76d9cee94241e56c82a8550ee6221d0f239 (patch)
tree8609d3a2538dd70893e5d8902bab91fbe8df97ff
parent87f127d8fa7b03e8f32962fc720da5df1a505fa5 (diff)
downloadphp-git-42fbc76d9cee94241e56c82a8550ee6221d0f239.tar.gz
Always invoke zpp in ReflectionProperty::getValue/isInitialized
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.
-rw-r--r--ext/reflection/php_reflection.c18
-rw-r--r--ext/reflection/php_reflection.stub.php2
-rw-r--r--ext/reflection/php_reflection_arginfo.h4
-rw-r--r--ext/reflection/tests/ReflectionProperty_getValue_error.phpt31
-rw-r--r--ext/reflection/tests/ReflectionProperty_isInitialized.phpt7
5 files changed, 45 insertions, 17 deletions
diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c
index 6fb415f2ad..95c4859e94 100644
--- a/ext/reflection/php_reflection.c
+++ b/ext/reflection/php_reflection.c
@@ -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();
}
diff --git a/ext/reflection/php_reflection.stub.php b/ext/reflection/php_reflection.stub.php
index 26e38ae37f..76cbe75dd7 100644
--- a/ext/reflection/php_reflection.stub.php
+++ b/ext/reflection/php_reflection.stub.php
@@ -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() {}
diff --git a/ext/reflection/php_reflection_arginfo.h b/ext/reflection/php_reflection_arginfo.h
index 68d61026b0..35ee713732 100644
--- a/ext/reflection/php_reflection_arginfo.h
+++ b/ext/reflection/php_reflection_arginfo.h
@@ -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
diff --git a/ext/reflection/tests/ReflectionProperty_getValue_error.phpt b/ext/reflection/tests/ReflectionProperty_getValue_error.phpt
index 2ffd244501..c5da067c32 100644
--- a/ext/reflection/tests/ReflectionProperty_getValue_error.phpt
+++ b/ext/reflection/tests/ReflectionProperty_getValue_error.phpt
@@ -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
diff --git a/ext/reflection/tests/ReflectionProperty_isInitialized.phpt b/ext/reflection/tests/ReflectionProperty_isInitialized.phpt
index 260084fae4..29541e405b 100644
--- a/ext/reflection/tests/ReflectionProperty_isInitialized.phpt
+++ b/ext/reflection/tests/ReflectionProperty_isInitialized.phpt
@@ -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)