Skip to content

Commit 584949d

Browse files
committed
Don't leak extra args for internal functions
1 parent ab717aa commit 584949d

File tree

3 files changed

+32
-2
lines changed

3 files changed

+32
-2
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
--TEST--
2+
Named params on internal functions: Variadic functions
3+
--FILE--
4+
<?php
5+
6+
array_merge([1, 2], a: [3, 4]);
7+
8+
?>
9+
--EXPECT--
10+

Zend/zend_vm_def.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3874,6 +3874,7 @@ ZEND_VM_HOT_HANDLER(129, ZEND_DO_ICALL, ANY, ANY, SPEC(RETVAL))
38743874
ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval;
38753875
ZVAL_NULL(ret);
38763876

3877+
/* TODO: Don't use the ICALL specialization if named params are used? */
38773878
if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_MAY_HAVE_UNDEF)) {
38783879
if (zend_handle_icall_undef_args(call) == FAILURE) {
38793880
ZEND_VM_C_GOTO(do_icall_cleanup);
@@ -3897,6 +3898,9 @@ ZEND_VM_HOT_HANDLER(129, ZEND_DO_ICALL, ANY, ANY, SPEC(RETVAL))
38973898
ZEND_VM_C_LABEL(do_icall_cleanup):
38983899
EG(current_execute_data) = execute_data;
38993900
zend_vm_stack_free_args(call);
3901+
if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) {
3902+
zend_array_destroy(call->extra_named_params);
3903+
}
39003904
zend_vm_stack_free_call_frame(call);
39013905

39023906
if (!RETURN_VALUE_USED(opline)) {
@@ -4008,6 +4012,9 @@ ZEND_VM_HOT_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL))
40084012

40094013
ZEND_VM_C_LABEL(fcall_by_name_end):
40104014
zend_vm_stack_free_args(call);
4015+
if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) {
4016+
zend_array_destroy(call->extra_named_params);
4017+
}
40114018
zend_vm_stack_free_call_frame(call);
40124019

40134020
if (!RETURN_VALUE_USED(opline)) {

Zend/zend_vm_execute.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,6 +1237,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETV
12371237
ret = 0 ? EX_VAR(opline->result.var) : &retval;
12381238
ZVAL_NULL(ret);
12391239

1240+
/* TODO: Don't use the ICALL specialization if named params are used? */
12401241
if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_MAY_HAVE_UNDEF)) {
12411242
if (zend_handle_icall_undef_args(call) == FAILURE) {
12421243
goto do_icall_cleanup;
@@ -1260,6 +1261,9 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETV
12601261
do_icall_cleanup:
12611262
EG(current_execute_data) = execute_data;
12621263
zend_vm_stack_free_args(call);
1264+
if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) {
1265+
zend_array_destroy(call->extra_named_params);
1266+
}
12631267
zend_vm_stack_free_call_frame(call);
12641268

12651269
if (!0) {
@@ -1296,6 +1300,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETV
12961300
ret = 1 ? EX_VAR(opline->result.var) : &retval;
12971301
ZVAL_NULL(ret);
12981302

1303+
/* TODO: Don't use the ICALL specialization if named params are used? */
12991304
if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_MAY_HAVE_UNDEF)) {
13001305
if (zend_handle_icall_undef_args(call) == FAILURE) {
13011306
goto do_icall_cleanup;
@@ -1319,6 +1324,9 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_ICALL_SPEC_RETV
13191324
do_icall_cleanup:
13201325
EG(current_execute_data) = execute_data;
13211326
zend_vm_stack_free_args(call);
1327+
if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) {
1328+
zend_array_destroy(call->extra_named_params);
1329+
}
13221330
zend_vm_stack_free_call_frame(call);
13231331

13241332
if (!1) {
@@ -1453,6 +1461,9 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S
14531461

14541462
fcall_by_name_end:
14551463
zend_vm_stack_free_args(call);
1464+
if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) {
1465+
zend_array_destroy(call->extra_named_params);
1466+
}
14561467
zend_vm_stack_free_call_frame(call);
14571468

14581469
if (!0) {
@@ -1541,6 +1552,9 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_S
15411552

15421553
fcall_by_name_end:
15431554
zend_vm_stack_free_args(call);
1555+
if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) {
1556+
zend_array_destroy(call->extra_named_params);
1557+
}
15441558
zend_vm_stack_free_call_frame(call);
15451559

15461560
if (!1) {
@@ -2572,7 +2586,6 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_dispatch_try
25722586
{
25732587
/* May be NULL during generator closing (only finally blocks are executed) */
25742588
zend_object *ex = EG(exception);
2575-
zend_bool is_unwind_exit = ex && zend_is_unwind_exit(ex);
25762589

25772590
/* Walk try/catch/finally structures upwards, performing the necessary actions */
25782591
for (; try_catch_offset != (uint32_t) -1; try_catch_offset--) {
@@ -2585,7 +2598,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_dispatch_try
25852598
ZEND_VM_JMP_EX(&EX(func)->op_array.opcodes[try_catch->catch_op], 0);
25862599

25872600
} else if (op_num < try_catch->finally_op) {
2588-
if (is_unwind_exit) {
2601+
if (ex && zend_is_unwind_exit(ex)) {
25892602
/* Don't execute finally blocks on exit (for now) */
25902603
continue;
25912604
}

0 commit comments

Comments
 (0)