Skip to content

Commit 1fa6f03

Browse files
committed
Fix reflection leak if type inside type list is resolved
1 parent 1e62e62 commit 1fa6f03

File tree

2 files changed

+13
-18
lines changed

2 files changed

+13
-18
lines changed

ext/reflection/php_reflection.c

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -231,14 +231,7 @@ static void reflection_free_objects_storage(zend_object *object) /* {{{ */
231231
case REF_TYPE_TYPE:
232232
{
233233
type_reference *type_ref = intern->ptr;
234-
if (ZEND_TYPE_HAS_LIST(type_ref->type)) {
235-
void *entry;
236-
ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(type_ref->type), entry) {
237-
if (ZEND_TYPE_LIST_IS_NAME(entry)) {
238-
zend_string_release(ZEND_TYPE_LIST_GET_NAME(entry));
239-
}
240-
} ZEND_TYPE_LIST_FOREACH_END();
241-
} else if (ZEND_TYPE_HAS_NAME(type_ref->type)) {
234+
if (ZEND_TYPE_HAS_NAME(type_ref->type)) {
242235
zend_string_release(ZEND_TYPE_NAME(type_ref->type));
243236
}
244237
efree(type_ref);
@@ -1174,16 +1167,12 @@ static void reflection_type_factory(zend_type type, zval *object, zend_bool lega
11741167
intern->ptr = reference;
11751168
intern->ref_type = REF_TYPE_TYPE;
11761169

1177-
/* Property types may be resolved during the lifetime of the ReflectionType,
1178-
* so we need to make sure that the strings we reference are not released. */
1179-
if (ZEND_TYPE_HAS_LIST(type)) {
1180-
void *entry;
1181-
ZEND_TYPE_LIST_FOREACH(ZEND_TYPE_LIST(type), entry) {
1182-
if (ZEND_TYPE_LIST_IS_NAME(entry)) {
1183-
zend_string_addref(ZEND_TYPE_LIST_GET_NAME(entry));
1184-
}
1185-
} ZEND_TYPE_LIST_FOREACH_END();
1186-
} else if (ZEND_TYPE_HAS_NAME(type)) {
1170+
/* Property types may be resolved during the lifetime of the ReflectionType.
1171+
* If we reference a string, make sure it doesn't get released. However, only
1172+
* do this for the top-level type, as resolutions inside type lists will be
1173+
* fully visible to us (we'd have to do a fully copy of the type if we wanted
1174+
* to prevent that). */
1175+
if (ZEND_TYPE_HAS_NAME(type)) {
11871176
zend_string_addref(ZEND_TYPE_NAME(type));
11881177
}
11891178
}

ext/reflection/tests/bug78774.phpt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,24 @@ Bug #78774: ReflectionNamedType on Typed Properties Crash
55

66
class Test {
77
public stdClass $prop;
8+
public stdClass|Foo $prop2;
89
}
910

1011
$rc = new ReflectionClass(Test::class);
1112
$rp = $rc->getProperty('prop');
1213
$rt = $rp->getType();
14+
$rp2 = $rc->getProperty('prop2');
15+
$rt2 = $rp2->getType();
1316

1417
// Force a resolution of the property type
1518
$test = new Test;
1619
$test->prop = new stdClass;
20+
$test->prop2 = new stdClass;
1721

1822
var_dump($rt->getName());
23+
var_dump((string) $rt2);
1924

2025
?>
2126
--EXPECT--
2227
string(8) "stdClass"
28+
string(12) "stdClass|Foo"

0 commit comments

Comments
 (0)