Skip to content

Commit 9baa3a9

Browse files
committed
Merge branch 'PHP-7.4'
* PHP-7.4: Fixed bug #77632 (FFI Segfaults When Called With Variadics)
2 parents 96a9990 + 5661feb commit 9baa3a9

File tree

2 files changed

+22
-15
lines changed

2 files changed

+22
-15
lines changed

ext/ffi/ffi.c

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1755,14 +1755,12 @@ static int zend_ffi_cdata_get_closure(zend_object *obj, zend_class_entry **ce_pt
17551755
func->common.arg_flags[2] = 0;
17561756
func->common.fn_flags = ZEND_ACC_CALL_VIA_TRAMPOLINE;
17571757
func->common.function_name = ZSTR_KNOWN(ZEND_STR_MAGIC_INVOKE);
1758-
func->common.num_args = func->common.required_num_args = type->func.args ? zend_hash_num_elements(type->func.args) : 0;
1758+
/* set to 0 to avoid arg_info[] allocation, because all values are passed by value anyway */
1759+
func->common.num_args = 0;
1760+
func->common.required_num_args = type->func.args ? zend_hash_num_elements(type->func.args) : 0;
1761+
func->common.arg_info = NULL;
17591762
func->internal_function.handler = ZEND_FN(ffi_trampoline);
17601763

1761-
if (func->common.num_args > MAX_ARG_FLAG_NUM) {
1762-
func->common.arg_info = emalloc(sizeof(zend_arg_info) * func->common.num_args);
1763-
memset(func->common.arg_info, 0, sizeof(zend_arg_info) * func->common.num_args);
1764-
}
1765-
17661764
func->internal_function.reserved[0] = type;
17671765
func->internal_function.reserved[1] = *(void**)cdata->ptr;
17681766

@@ -2416,9 +2414,6 @@ static ZEND_FUNCTION(ffi_trampoline) /* {{{ */
24162414

24172415
zend_string_release(EX(func)->common.function_name);
24182416
if (EX(func)->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
2419-
if (EX(func)->common.arg_info) {
2420-
efree(EX(func)->common.arg_info);
2421-
}
24222417
zend_free_trampoline(EX(func));
24232418
EX(func) = NULL;
24242419
}
@@ -2476,14 +2471,12 @@ static zend_function *zend_ffi_get_func(zend_object **obj, zend_string *name, co
24762471
func->common.arg_flags[2] = 0;
24772472
func->common.fn_flags = ZEND_ACC_CALL_VIA_TRAMPOLINE;
24782473
func->common.function_name = zend_string_copy(name);
2479-
func->common.num_args = func->common.required_num_args = type->func.args ? zend_hash_num_elements(type->func.args) : 0;
2474+
/* set to 0 to avoid arg_info[] allocation, because all values are passed by value anyway */
2475+
func->common.num_args = 0;
2476+
func->common.required_num_args = type->func.args ? zend_hash_num_elements(type->func.args) : 0;
2477+
func->common.arg_info = NULL;
24802478
func->internal_function.handler = ZEND_FN(ffi_trampoline);
24812479

2482-
if (func->common.num_args > MAX_ARG_FLAG_NUM) {
2483-
func->common.arg_info = emalloc(sizeof(zend_arg_info) * func->common.num_args);
2484-
memset(func->common.arg_info, 0, sizeof(zend_arg_info) * func->common.num_args);
2485-
}
2486-
24872480
func->internal_function.reserved[0] = type;
24882481
func->internal_function.reserved[1] = sym->addr;
24892482

ext/ffi/tests/bug77632.phpt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--TEST--
2+
Bug #77632 (FFI Segfaults When Called With Variadics)
3+
--SKIPIF--
4+
<?php require_once('skipif.inc'); ?>
5+
--INI--
6+
ffi.enable=1
7+
--FILE--
8+
<?php
9+
$libc = FFI::cdef("int printf(const char *format, ...);", "libc.so.6");
10+
$args = ["test\n"];
11+
$libc->printf(...$args);
12+
?>
13+
--EXPECT--
14+
test

0 commit comments

Comments
 (0)