]> granicus.if.org Git - php/commitdiff
Make check in RECV_VARIADIC more precise
authorNikita Popov <nikita.ppv@gmail.com>
Fri, 31 Jul 2020 10:00:56 +0000 (12:00 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Fri, 31 Jul 2020 10:02:28 +0000 (12:02 +0200)
Fetch arg_info only once (it's always the same one...) and check
ZEND_TYPE_IS_SET on it, rather than checking if *any* parameter
has a type.

Zend/zend_execute.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index 51d4a0d00388ed07adb8dcff90cfe141fd453b6d..d6809cb67011ce799de4a96efa325f170d5077ed 100644 (file)
@@ -1051,17 +1051,12 @@ static zend_always_inline int zend_verify_recv_arg_type(zend_function *zf, uint3
        return 1;
 }
 
-static zend_always_inline int zend_verify_variadic_arg_type(zend_function *zf, uint32_t arg_num, zval *arg, void **cache_slot)
+static zend_always_inline int zend_verify_variadic_arg_type(
+               zend_function *zf, zend_arg_info *arg_info, uint32_t arg_num, zval *arg, void **cache_slot)
 {
-       zend_arg_info *cur_arg_info;
-
-       ZEND_ASSERT(arg_num > zf->common.num_args);
-       ZEND_ASSERT(zf->common.fn_flags & ZEND_ACC_VARIADIC);
-       cur_arg_info = &zf->common.arg_info[zf->common.num_args];
-
-       if (ZEND_TYPE_IS_SET(cur_arg_info->type)
-                       && UNEXPECTED(!zend_check_type(cur_arg_info->type, arg, cache_slot, zf->common.scope, 0, 0))) {
-               zend_verify_arg_error(zf, cur_arg_info, arg_num, cache_slot, arg);
+       ZEND_ASSERT(ZEND_TYPE_IS_SET(arg_info->type));
+       if (UNEXPECTED(!zend_check_type(arg_info->type, arg, cache_slot, zf->common.scope, 0, 0))) {
+               zend_verify_arg_error(zf, arg_info, arg_num, cache_slot, arg);
                return 0;
        }
 
index e69075bd885069da9c1716e4439e08e2edda0646..a9b5c0f4a3c4295ab067d2da97876de083b83a0b 100644 (file)
@@ -5170,15 +5170,17 @@ ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, NUM, UNUSED, CACHE_SLOT)
        params = EX_VAR(opline->result.var);
 
        if (arg_num <= arg_count) {
-               zval *param;
+               ZEND_ASSERT(EX(func)->common.fn_flags & ZEND_ACC_VARIADIC);
+               ZEND_ASSERT(EX(func)->common.num_args == arg_num - 1);
+               zend_arg_info *arg_info = &EX(func)->common.arg_info[arg_num - 1];
 
                array_init_size(params, arg_count - arg_num + 1);
                zend_hash_real_init_packed(Z_ARRVAL_P(params));
                ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(params)) {
-                       param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T);
-                       if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
+                       zval *param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T);
+                       if (UNEXPECTED(ZEND_TYPE_IS_SET(arg_info->type))) {
                                do {
-                                       if (UNEXPECTED(!zend_verify_variadic_arg_type(EX(func), arg_num, param, CACHE_ADDR(opline->extended_value)))) {
+                                       if (UNEXPECTED(!zend_verify_variadic_arg_type(EX(func), arg_info, arg_num, param, CACHE_ADDR(opline->extended_value)))) {
                                                ZEND_HASH_FILL_FINISH();
                                                HANDLE_EXCEPTION();
                                        }
index d265a266f2c09adbd593606ced722db224743c0b..3e6edeb8df597b8b664eccb62eda4ccd0d6239f6 100644 (file)
@@ -3120,15 +3120,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_VARIADIC_SPEC_UNUSED_HAND
        params = EX_VAR(opline->result.var);
 
        if (arg_num <= arg_count) {
-               zval *param;
+               ZEND_ASSERT(EX(func)->common.fn_flags & ZEND_ACC_VARIADIC);
+               ZEND_ASSERT(EX(func)->common.num_args == arg_num - 1);
+               zend_arg_info *arg_info = &EX(func)->common.arg_info[arg_num - 1];
 
                array_init_size(params, arg_count - arg_num + 1);
                zend_hash_real_init_packed(Z_ARRVAL_P(params));
                ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(params)) {
-                       param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T);
-                       if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
+                       zval *param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T);
+                       if (UNEXPECTED(ZEND_TYPE_IS_SET(arg_info->type))) {
                                do {
-                                       if (UNEXPECTED(!zend_verify_variadic_arg_type(EX(func), arg_num, param, CACHE_ADDR(opline->extended_value)))) {
+                                       if (UNEXPECTED(!zend_verify_variadic_arg_type(EX(func), arg_info, arg_num, param, CACHE_ADDR(opline->extended_value)))) {
                                                ZEND_HASH_FILL_FINISH();
                                                HANDLE_EXCEPTION();
                                        }