Skip to content

Commit c817b80

Browse files
committed
Special-case rc=1 self-referential arrays in ReflectionReference
New fix for bug #78263. This is special-cased elsewhere in the engine, so we need to mirror it here.
1 parent 19588a8 commit c817b80

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

ext/reflection/php_reflection.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6143,6 +6143,16 @@ ZEND_METHOD(reflection_reference, __construct)
61436143
}
61446144
/* }}} */
61456145

6146+
static zend_bool is_ignorable_reference(HashTable *ht, zval *ref) {
6147+
if (Z_REFCOUNT_P(ref) != 1) {
6148+
return 0;
6149+
}
6150+
6151+
/* Directly self-referential arrays are treated as proper references
6152+
* in zend_array_dup() despite rc=1. */
6153+
return Z_TYPE_P(Z_REFVAL_P(ref)) != IS_ARRAY || Z_ARRVAL_P(Z_REFVAL_P(ref)) != ht;
6154+
}
6155+
61466156
/* {{{ proto public ReflectionReference|null ReflectionReference::fromArrayElement(array array, mixed key)
61476157
* Create ReflectionReference for array item. Returns null if not a reference. */
61486158
ZEND_METHOD(reflection_reference, fromArrayElement)
@@ -6169,8 +6179,7 @@ ZEND_METHOD(reflection_reference, fromArrayElement)
61696179
return;
61706180
}
61716181

6172-
/* Treat singleton reference as non-reference. */
6173-
if (Z_TYPE_P(item) != IS_REFERENCE || Z_REFCOUNT_P(item) == 1) {
6182+
if (Z_TYPE_P(item) != IS_REFERENCE || is_ignorable_reference(ht, item)) {
61746183
RETURN_NULL();
61756184
}
61766185

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
Bug #78263: Handling of self-referential array special case
3+
--FILE--
4+
<?php
5+
6+
// The case of a directly self-referential array is special and will
7+
// be treated as a proper reference despite rc=1 during array copying.
8+
$a = [&$a];
9+
$b = [$a];
10+
unset($a);
11+
12+
var_dump(ReflectionReference::fromArrayElement($b[0], 0));
13+
14+
?>
15+
--EXPECT--
16+
object(ReflectionReference)#1 (0) {
17+
}

0 commit comments

Comments
 (0)