From 1a8936cde3a14a1fdcd0f2a4cd567e5a3e206e65 Mon Sep 17 00:00:00 2001 From: Gabriel Caruso Date: Mon, 14 Sep 2020 16:06:18 +0200 Subject: [PATCH] Check `ReflectionReference::fromArrayElement` with union types ReflectionReference::fromArrayElement(array $array, int|string $key): ?ReflectionReference is going to be its official signature for PHP 8.0. Closes GH-5651 --- ext/reflection/php_reflection.c | 20 +++++++++---------- ext/reflection/php_reflection.stub.php | 3 +-- ext/reflection/php_reflection_arginfo.h | 4 ++-- .../tests/ReflectionReference_errors.phpt | 4 ++-- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 403c91c3e4..292e1901e4 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -6084,20 +6084,20 @@ static zend_bool is_ignorable_reference(HashTable *ht, zval *ref) { ZEND_METHOD(ReflectionReference, fromArrayElement) { HashTable *ht; - zval *key, *item; + zval *item; + zend_string *string_key = NULL; + zend_long int_key = 0; reflection_object *intern; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "hz", &ht, &key) == FAILURE) { - RETURN_THROWS(); - } + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_ARRAY_HT(ht) + Z_PARAM_STR_OR_LONG(string_key, int_key) + ZEND_PARSE_PARAMETERS_END(); - if (Z_TYPE_P(key) == IS_LONG) { - item = zend_hash_index_find(ht, Z_LVAL_P(key)); - } else if (Z_TYPE_P(key) == IS_STRING) { - item = zend_symtable_find(ht, Z_STR_P(key)); + if (string_key) { + item = zend_hash_find(ht, string_key); } else { - zend_argument_type_error(2, "must be of type string|int, %s given", zend_zval_type_name(key)); - RETURN_THROWS(); + item = zend_hash_index_find(ht, int_key); } if (!item) { diff --git a/ext/reflection/php_reflection.stub.php b/ext/reflection/php_reflection.stub.php index d1ba2cf624..1f4bbb5e86 100644 --- a/ext/reflection/php_reflection.stub.php +++ b/ext/reflection/php_reflection.stub.php @@ -643,8 +643,7 @@ class ReflectionZendExtension implements Reflector final class ReflectionReference { - /** @param int|string $key */ - public static function fromArrayElement(array $array, $key): ?ReflectionReference {} + public static function fromArrayElement(array $array, int|string $key): ?ReflectionReference {} public function getId(): string {} diff --git a/ext/reflection/php_reflection_arginfo.h b/ext/reflection/php_reflection_arginfo.h index aab74783c8..d28770ccaa 100644 --- a/ext/reflection/php_reflection_arginfo.h +++ b/ext/reflection/php_reflection_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: d698afd338e4bf7c782f0edddfcbe95859eef477 */ + * Stub hash: c2bd96bf9b5ca866860f8f3c04937c9fff5c3afa */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Reflection_getModifierNames, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, modifiers, IS_LONG, 0) @@ -467,7 +467,7 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_ReflectionReference_fromArrayElement, 0, 2, ReflectionReference, 1) ZEND_ARG_TYPE_INFO(0, array, IS_ARRAY, 0) - ZEND_ARG_INFO(0, key) + ZEND_ARG_TYPE_MASK(0, key, MAY_BE_LONG|MAY_BE_STRING, NULL) ZEND_END_ARG_INFO() #define arginfo_class_ReflectionReference_getId arginfo_class_ReflectionFunction___toString diff --git a/ext/reflection/tests/ReflectionReference_errors.phpt b/ext/reflection/tests/ReflectionReference_errors.phpt index 6d7ca3ae3d..c9d75d0467 100644 --- a/ext/reflection/tests/ReflectionReference_errors.phpt +++ b/ext/reflection/tests/ReflectionReference_errors.phpt @@ -16,7 +16,7 @@ try { } try { - ReflectionReference::fromArrayElement([], 1.5); + ReflectionReference::fromArrayElement([], []); } catch (TypeError $e) { echo $e->getMessage(), "\n"; } @@ -42,7 +42,7 @@ var_dump(unserialize('O:19:"ReflectionReference":0:{}')); --EXPECTF-- Call to private ReflectionReference::__construct() from global scope ReflectionReference::fromArrayElement(): Argument #1 ($array) must be of type array, stdClass given -ReflectionReference::fromArrayElement(): Argument #2 ($key) must be of type string|int, float given +ReflectionReference::fromArrayElement(): Argument #2 ($key) must be of type string|int, array given Array key not found Serialization of 'ReflectionReference' is not allowed -- 2.40.0