summaryrefslogtreecommitdiff
path: root/ext/reflection/php_reflection.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/reflection/php_reflection.c')
-rw-r--r--ext/reflection/php_reflection.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c
index dcb98b0653..4011d8954e 100644
--- a/ext/reflection/php_reflection.c
+++ b/ext/reflection/php_reflection.c
@@ -6143,6 +6143,16 @@ ZEND_METHOD(reflection_reference, __construct)
}
/* }}} */
+static zend_bool is_ignorable_reference(HashTable *ht, zval *ref) {
+ if (Z_REFCOUNT_P(ref) != 1) {
+ return 0;
+ }
+
+ /* Directly self-referential arrays are treated as proper references
+ * in zend_array_dup() despite rc=1. */
+ return Z_TYPE_P(Z_REFVAL_P(ref)) != IS_ARRAY || Z_ARRVAL_P(Z_REFVAL_P(ref)) != ht;
+}
+
/* {{{ proto public ReflectionReference|null ReflectionReference::fromArrayElement(array array, mixed key)
* Create ReflectionReference for array item. Returns null if not a reference. */
ZEND_METHOD(reflection_reference, fromArrayElement)
@@ -6169,8 +6179,7 @@ ZEND_METHOD(reflection_reference, fromArrayElement)
return;
}
- /* Treat singleton reference as non-reference. */
- if (Z_TYPE_P(item) != IS_REFERENCE || Z_REFCOUNT_P(item) == 1) {
+ if (Z_TYPE_P(item) != IS_REFERENCE || is_ignorable_reference(ht, item)) {
RETURN_NULL();
}