From: Nikita Popov Date: Mon, 22 Jul 2019 14:59:23 +0000 (+0200) Subject: Special-case rc=1 self-referential arrays in ReflectionReference X-Git-Tag: php-7.4.0beta1~9 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c817b8020c8a835946681ca94b9257e78e64dad3;p=php 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. --- 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(); } diff --git a/ext/reflection/tests/ReflectionReference_bug78263.phpt b/ext/reflection/tests/ReflectionReference_bug78263.phpt new file mode 100644 index 0000000000..868edc0812 --- /dev/null +++ b/ext/reflection/tests/ReflectionReference_bug78263.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #78263: Handling of self-referential array special case +--FILE-- + +--EXPECT-- +object(ReflectionReference)#1 (0) { +}