mirror of
https://github.com/php/php-src.git
synced 2024-11-23 18:04:36 +08:00
Merge branch 'PHP-8.1'
This commit is contained in:
commit
ab1d5a9d2a
@ -861,6 +861,14 @@ static void zend_ffi_callback_hash_dtor(zval *zv) /* {{{ */
|
||||
if (callback_data->fcc.function_handler->common.fn_flags & ZEND_ACC_CLOSURE) {
|
||||
OBJ_RELEASE(ZEND_CLOSURE_OBJECT(callback_data->fcc.function_handler));
|
||||
}
|
||||
for (int i = 0; i < callback_data->arg_count; ++i) {
|
||||
if (callback_data->arg_types[i]->type == FFI_TYPE_STRUCT) {
|
||||
efree(callback_data->arg_types[i]);
|
||||
}
|
||||
}
|
||||
if (callback_data->ret_type->type == FFI_TYPE_STRUCT) {
|
||||
efree(callback_data->ret_type);
|
||||
}
|
||||
efree(callback_data);
|
||||
}
|
||||
/* }}} */
|
||||
@ -914,6 +922,8 @@ static void zend_ffi_callback_trampoline(ffi_cif* cif, void* ret, void** args, v
|
||||
if (ret_type->kind != ZEND_FFI_TYPE_VOID) {
|
||||
zend_ffi_zval_to_cdata(ret, ret_type, &retval);
|
||||
}
|
||||
|
||||
zval_ptr_dtor(&retval);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -964,6 +974,11 @@ static void *zend_ffi_create_callback(zend_ffi_type *type, zval *value) /* {{{ *
|
||||
callback_data->arg_types[n] = zend_ffi_get_type(arg_type);
|
||||
if (!callback_data->arg_types[n]) {
|
||||
zend_ffi_pass_unsupported(arg_type);
|
||||
for (int i = 0; i < n; ++i) {
|
||||
if (callback_data->arg_types[i]->type == FFI_TYPE_STRUCT) {
|
||||
efree(callback_data->arg_types[i]);
|
||||
}
|
||||
}
|
||||
efree(callback_data);
|
||||
ffi_closure_free(callback);
|
||||
return NULL;
|
||||
@ -974,6 +989,11 @@ static void *zend_ffi_create_callback(zend_ffi_type *type, zval *value) /* {{{ *
|
||||
callback_data->ret_type = zend_ffi_get_type(ZEND_FFI_TYPE(type->func.ret_type));
|
||||
if (!callback_data->ret_type) {
|
||||
zend_ffi_return_unsupported(type->func.ret_type);
|
||||
for (int i = 0; i < callback_data->arg_count; ++i) {
|
||||
if (callback_data->arg_types[i]->type == FFI_TYPE_STRUCT) {
|
||||
efree(callback_data->arg_types[i]);
|
||||
}
|
||||
}
|
||||
efree(callback_data);
|
||||
ffi_closure_free(callback);
|
||||
return NULL;
|
||||
@ -981,13 +1001,20 @@ static void *zend_ffi_create_callback(zend_ffi_type *type, zval *value) /* {{{ *
|
||||
|
||||
if (ffi_prep_cif(&callback_data->cif, type->func.abi, callback_data->arg_count, callback_data->ret_type, callback_data->arg_types) != FFI_OK) {
|
||||
zend_throw_error(zend_ffi_exception_ce, "Cannot prepare callback CIF");
|
||||
efree(callback_data);
|
||||
ffi_closure_free(callback);
|
||||
return NULL;
|
||||
goto free_on_failure;
|
||||
}
|
||||
|
||||
if (ffi_prep_closure_loc(callback, &callback_data->cif, zend_ffi_callback_trampoline, callback_data, code) != FFI_OK) {
|
||||
zend_throw_error(zend_ffi_exception_ce, "Cannot prepare callback");
|
||||
free_on_failure: ;
|
||||
for (int i = 0; i < callback_data->arg_count; ++i) {
|
||||
if (callback_data->arg_types[i]->type == FFI_TYPE_STRUCT) {
|
||||
efree(callback_data->arg_types[i]);
|
||||
}
|
||||
}
|
||||
if (callback_data->ret_type->type == FFI_TYPE_STRUCT) {
|
||||
efree(callback_data->ret_type);
|
||||
}
|
||||
efree(callback_data);
|
||||
ffi_closure_free(callback);
|
||||
return NULL;
|
||||
|
20
ext/ffi/tests/gh8433.phpt
Normal file
20
ext/ffi/tests/gh8433.phpt
Normal file
@ -0,0 +1,20 @@
|
||||
--TEST--
|
||||
GH-8433 (Assigning function pointers to structs in FFI leaks memory)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$ffi = FFI::cdef("typedef struct { int a; } bar;");
|
||||
$x = $ffi->new("bar(*)(void)");
|
||||
FFI::addr($x)[0] = function() use ($ffi) {
|
||||
$bar = $ffi->new("bar");
|
||||
$bar->a = 2;
|
||||
return $bar;
|
||||
};
|
||||
var_dump($x());
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
object(FFI\CData:struct <anonymous>)#%d (1) {
|
||||
["a"]=>
|
||||
int(2)
|
||||
}
|
Loading…
Reference in New Issue
Block a user