summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS3
-rw-r--r--ext/reflection/php_reflection.c14
-rw-r--r--ext/reflection/tests/bug78774.phpt22
3 files changed, 38 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index a1f89a732d..4af45dc1e6 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,9 @@ PHP NEWS
. Fixed bug #77930 (stream_copy_to_stream should use mmap more often).
(Nikita)
+- Reflection:
+ . Fixed bug #78774 (ReflectionNamedType on Typed Properties Crash). (Nikita)
+
31 Oct 2019, PHP 7.4.0RC5
- Core:
diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c
index 94b2709763..d669ff6da2 100644
--- a/ext/reflection/php_reflection.c
+++ b/ext/reflection/php_reflection.c
@@ -224,8 +224,14 @@ static void reflection_free_objects_storage(zend_object *object) /* {{{ */
efree(intern->ptr);
break;
case REF_TYPE_TYPE:
- efree(intern->ptr);
+ {
+ type_reference *type_ref = intern->ptr;
+ if (ZEND_TYPE_IS_NAME(type_ref->type)) {
+ zend_string_release(ZEND_TYPE_NAME(type_ref->type));
+ }
+ efree(type_ref);
break;
+ }
case REF_TYPE_FUNCTION:
_free_function(intern->ptr);
break;
@@ -1152,6 +1158,12 @@ static void reflection_type_factory(zend_type type, zval *object)
reference->type = type;
intern->ptr = reference;
intern->ref_type = REF_TYPE_TYPE;
+
+ /* Property types may be resolved during the lifetime of the ReflectionType,
+ * so we need to make sure that the strings we reference are not released. */
+ if (ZEND_TYPE_IS_NAME(type)) {
+ zend_string_addref(ZEND_TYPE_NAME(type));
+ }
}
/* }}} */
diff --git a/ext/reflection/tests/bug78774.phpt b/ext/reflection/tests/bug78774.phpt
new file mode 100644
index 0000000000..1e419b1138
--- /dev/null
+++ b/ext/reflection/tests/bug78774.phpt
@@ -0,0 +1,22 @@
+--TEST--
+Bug #78774: ReflectionNamedType on Typed Properties Crash
+--FILE--
+<?php
+
+class Test {
+ public stdClass $prop;
+}
+
+$rc = new ReflectionClass(Test::class);
+$rp = $rc->getProperty('prop');
+$rt = $rp->getType();
+
+// Force a resolution of the property type
+$test = new Test;
+$test->prop = new stdClass;
+
+var_dump($rt->getName());
+
+?>
+--EXPECT--
+string(8) "stdClass"