summaryrefslogtreecommitdiff
path: root/ext/reflection/php_reflection.c
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-07-22 16:59:23 +0200
committerNikita Popov <nikita.ppv@gmail.com>2019-07-22 16:59:23 +0200
commitc817b8020c8a835946681ca94b9257e78e64dad3 (patch)
tree4ed2b41d6388eb9190e94d8be469a7a1e848f9f7 /ext/reflection/php_reflection.c
parent19588a8f3be1dc223dfb15067eef35e1908a8ba7 (diff)
downloadphp-git-c817b8020c8a835946681ca94b9257e78e64dad3.tar.gz
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.
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();
}