diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2019-11-04 11:01:56 +0100 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-11-04 11:04:02 +0100 |
commit | c9abfaec6bf61bcef6d9651827b49cc7789018fd (patch) | |
tree | a362fd430d32675f6c21d3b5be20343cf3130b02 | |
parent | e84042cc7216c4d2ec1788756c78b00bfba413c1 (diff) | |
download | php-git-c9abfaec6bf61bcef6d9651827b49cc7789018fd.tar.gz |
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.
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | ext/reflection/php_reflection.c | 14 | ||||
-rw-r--r-- | ext/reflection/tests/bug78774.phpt | 22 |
3 files changed, 38 insertions, 1 deletions
@@ -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" |