]> granicus.if.org Git - php/commitdiff
Use int|string Fast ZPP macro in Reflection
authorGeorge Peter Banyard <girgias@php.net>
Sat, 2 May 2020 22:35:13 +0000 (00:35 +0200)
committerGeorge Peter Banyard <girgias@php.net>
Wed, 6 May 2020 19:51:59 +0000 (21:51 +0200)
Moreover, throw a more appropriate ValueError in case the integer
position provided is less than 0.

Closes GH-5513

ext/reflection/php_reflection.c
ext/reflection/php_reflection.stub.php
ext/reflection/php_reflection_arginfo.h
ext/reflection/tests/parameters_001.phpt

index 2856e0c6db77f3c0b246ae3f7a50f86f64f9d459..1ed057d902f894bb9016c5676dff321cde6ef243 100644 (file)
@@ -2112,20 +2112,22 @@ ZEND_METHOD(ReflectionGenerator, getExecutingGenerator)
 ZEND_METHOD(ReflectionParameter, __construct)
 {
        parameter_reference *ref;
-       zval *reference, *parameter;
+       zval *reference;
+       zend_string *arg_name = NULL;
+       zend_long position;
        zval *object;
        zval *prop_name;
        reflection_object *intern;
        zend_function *fptr;
        struct _zend_arg_info *arg_info;
-       int position;
        uint32_t num_args;
        zend_class_entry *ce = NULL;
        zend_bool is_closure = 0;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz", &reference, &parameter) == FAILURE) {
-               RETURN_THROWS();
-       }
+       ZEND_PARSE_PARAMETERS_START(2, 2)
+               Z_PARAM_ZVAL(reference)
+               Z_PARAM_STR_OR_LONG(arg_name, position)
+       ZEND_PARSE_PARAMETERS_END();
 
        object = ZEND_THIS;
        intern = Z_REFLECTION_P(object);
@@ -2223,34 +2225,23 @@ ZEND_METHOD(ReflectionParameter, __construct)
        if (fptr->common.fn_flags & ZEND_ACC_VARIADIC) {
                num_args++;
        }
-       if (Z_TYPE_P(parameter) == IS_LONG) {
-               position= (int)Z_LVAL_P(parameter);
-               if (position < 0 || (uint32_t)position >= num_args) {
-                       _DO_THROW("The parameter specified by its offset could not be found");
-                       goto failure;
-               }
-       } else {
+       if (arg_name != NULL) {
                uint32_t i;
-
                position = -1;
-               if (!try_convert_to_string(parameter)) {
-                       goto failure;
-               }
 
                if (has_internal_arg_info(fptr)) {
                        for (i = 0; i < num_args; i++) {
                                if (arg_info[i].name) {
-                                       if (strcmp(((zend_internal_arg_info*)arg_info)[i].name, Z_STRVAL_P(parameter)) == 0) {
+                                       if (strcmp(((zend_internal_arg_info*)arg_info)[i].name, ZSTR_VAL(arg_name)) == 0) {
                                                position = i;
                                                break;
                                        }
-
                                }
                        }
                } else {
                        for (i = 0; i < num_args; i++) {
                                if (arg_info[i].name) {
-                                       if (strcmp(ZSTR_VAL(arg_info[i].name), Z_STRVAL_P(parameter)) == 0) {
+                                       if (zend_string_equals(arg_name, arg_info[i].name)) {
                                                position = i;
                                                break;
                                        }
@@ -2261,6 +2252,15 @@ ZEND_METHOD(ReflectionParameter, __construct)
                        _DO_THROW("The parameter specified by its name could not be found");
                        goto failure;
                }
+       } else {
+               if (position < 0) {
+                       zend_argument_value_error(2, "must be greater than or equal to 0");
+                       goto failure;
+               }
+               if (position >= num_args) {
+                       _DO_THROW("The parameter specified by its offset could not be found");
+                       goto failure;
+               }
        }
 
        ref = (parameter_reference*) emalloc(sizeof(parameter_reference));
@@ -2292,6 +2292,7 @@ failure:
        if (is_closure) {
                zval_ptr_dtor(reference);
        }
+       RETURN_THROWS();
 }
 /* }}} */
 
index 0adce7921c57355b5af2b51d8c0e6c0842c23f5a..1bcd4221cf3cd8db3ab456df5f2e061c10559779 100644 (file)
@@ -472,10 +472,9 @@ class ReflectionParameter implements Reflector
     final private function __clone() {}
 
     /**
-     * @param string|array|object
-     * @param int|string
+     * @param $function string|array|object
      */
-    public function __construct($function,  $parameter) {}
+    public function __construct($function, int|string $parameter) {}
 
     public function __toString(): string {}
 
index a7f12dba8ca1f5c945816744458dbd7f75e464a0..da896d4150ad7116707b562405e55d77e337547f 100644 (file)
@@ -346,7 +346,7 @@ ZEND_END_ARG_INFO()
 
 ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ReflectionParameter___construct, 0, 0, 2)
        ZEND_ARG_INFO(0, function)
-       ZEND_ARG_INFO(0, parameter)
+       ZEND_ARG_TYPE_MASK(0, parameter, MAY_BE_LONG|MAY_BE_STRING, NULL)
 ZEND_END_ARG_INFO()
 
 #define arginfo_class_ReflectionParameter___toString arginfo_class_ReflectionFunction___toString
index 6c57b2c3077bfcaa9245a50a8202cec33b1b9ad5..8299a63bf9d6940822dbcd5533120c7016fa49c3 100644 (file)
@@ -22,8 +22,13 @@ var_dump($p->isOptional());
 try {
     $p = new ReflectionParameter(array('Test', 'func'), 'z');
     var_dump($p->isOptional());
+} catch (Exception $e) {
+    var_dump($e->getMessage());
 }
-catch (Exception $e) {
+try {
+    $p = new ReflectionParameter(array('Test', 'func'), -1);
+    var_dump($p->isOptional());
+} catch (\ValueError $e) {
     var_dump($e->getMessage());
 }
 
@@ -34,3 +39,4 @@ int(1)
 bool(false)
 bool(true)
 string(54) "The parameter specified by its name could not be found"
+string(95) "ReflectionParameter::__construct(): Argument #2 ($parameter) must be greater than or equal to 0"