Skip to content

Commit a6e63b4

Browse files
committed
Make check in RECV_VARIADIC more precise
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.
1 parent b3e1232 commit a6e63b4

File tree

3 files changed

+17
-18
lines changed

3 files changed

+17
-18
lines changed

Zend/zend_execute.c

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,17 +1051,12 @@ static zend_always_inline int zend_verify_recv_arg_type(zend_function *zf, uint3
10511051
return 1;
10521052
}
10531053

1054-
static zend_always_inline int zend_verify_variadic_arg_type(zend_function *zf, uint32_t arg_num, zval *arg, void **cache_slot)
1054+
static zend_always_inline int zend_verify_variadic_arg_type(
1055+
zend_function *zf, zend_arg_info *arg_info, uint32_t arg_num, zval *arg, void **cache_slot)
10551056
{
1056-
zend_arg_info *cur_arg_info;
1057-
1058-
ZEND_ASSERT(arg_num > zf->common.num_args);
1059-
ZEND_ASSERT(zf->common.fn_flags & ZEND_ACC_VARIADIC);
1060-
cur_arg_info = &zf->common.arg_info[zf->common.num_args];
1061-
1062-
if (ZEND_TYPE_IS_SET(cur_arg_info->type)
1063-
&& UNEXPECTED(!zend_check_type(cur_arg_info->type, arg, cache_slot, zf->common.scope, 0, 0))) {
1064-
zend_verify_arg_error(zf, cur_arg_info, arg_num, cache_slot, arg);
1057+
ZEND_ASSERT(ZEND_TYPE_IS_SET(arg_info->type));
1058+
if (UNEXPECTED(!zend_check_type(arg_info->type, arg, cache_slot, zf->common.scope, 0, 0))) {
1059+
zend_verify_arg_error(zf, arg_info, arg_num, cache_slot, arg);
10651060
return 0;
10661061
}
10671062

Zend/zend_vm_def.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5170,15 +5170,17 @@ ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, NUM, UNUSED, CACHE_SLOT)
51705170
params = EX_VAR(opline->result.var);
51715171

51725172
if (arg_num <= arg_count) {
5173-
zval *param;
5173+
ZEND_ASSERT(EX(func)->common.fn_flags & ZEND_ACC_VARIADIC);
5174+
ZEND_ASSERT(EX(func)->common.num_args == arg_num - 1);
5175+
zend_arg_info *arg_info = &EX(func)->common.arg_info[arg_num - 1];
51745176

51755177
array_init_size(params, arg_count - arg_num + 1);
51765178
zend_hash_real_init_packed(Z_ARRVAL_P(params));
51775179
ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(params)) {
5178-
param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T);
5179-
if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
5180+
zval *param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T);
5181+
if (UNEXPECTED(ZEND_TYPE_IS_SET(arg_info->type))) {
51805182
do {
5181-
if (UNEXPECTED(!zend_verify_variadic_arg_type(EX(func), arg_num, param, CACHE_ADDR(opline->extended_value)))) {
5183+
if (UNEXPECTED(!zend_verify_variadic_arg_type(EX(func), arg_info, arg_num, param, CACHE_ADDR(opline->extended_value)))) {
51825184
ZEND_HASH_FILL_FINISH();
51835185
HANDLE_EXCEPTION();
51845186
}

Zend/zend_vm_execute.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3120,15 +3120,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_VARIADIC_SPEC_UNUSED_HAND
31203120
params = EX_VAR(opline->result.var);
31213121

31223122
if (arg_num <= arg_count) {
3123-
zval *param;
3123+
ZEND_ASSERT(EX(func)->common.fn_flags & ZEND_ACC_VARIADIC);
3124+
ZEND_ASSERT(EX(func)->common.num_args == arg_num - 1);
3125+
zend_arg_info *arg_info = &EX(func)->common.arg_info[arg_num - 1];
31243126

31253127
array_init_size(params, arg_count - arg_num + 1);
31263128
zend_hash_real_init_packed(Z_ARRVAL_P(params));
31273129
ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(params)) {
3128-
param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T);
3129-
if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
3130+
zval *param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T);
3131+
if (UNEXPECTED(ZEND_TYPE_IS_SET(arg_info->type))) {
31303132
do {
3131-
if (UNEXPECTED(!zend_verify_variadic_arg_type(EX(func), arg_num, param, CACHE_ADDR(opline->extended_value)))) {
3133+
if (UNEXPECTED(!zend_verify_variadic_arg_type(EX(func), arg_info, arg_num, param, CACHE_ADDR(opline->extended_value)))) {
31323134
ZEND_HASH_FILL_FINISH();
31333135
HANDLE_EXCEPTION();
31343136
}

0 commit comments

Comments
 (0)