From c9abfaec6bf61bcef6d9651827b49cc7789018fd Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 4 Nov 2019 11:01:56 +0100 Subject: Fixed bug #78774 The string held by the zend_type may be released if the property type gets resolved to a CE. I initially wanted to fix this by storing a zend_type* instead (so the property type resolution propagates to the ReflectionType), but decided against this in light of upcoming union types support, where we also need to represent parts of the union, and will not have a single zend_type* we can reference. --- NEWS | 3 +++ ext/reflection/php_reflection.c | 14 +++++++++++++- ext/reflection/tests/bug78774.phpt | 22 ++++++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 ext/reflection/tests/bug78774.phpt 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-- +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" -- cgit v1.2.1