@@ -863,6 +863,14 @@ static void zend_ffi_callback_hash_dtor(zval *zv) /* {{{ */
863
863
if (callback_data -> fcc .function_handler -> common .fn_flags & ZEND_ACC_CLOSURE ) {
864
864
OBJ_RELEASE (ZEND_CLOSURE_OBJECT (callback_data -> fcc .function_handler ));
865
865
}
866
+ for (int i = 0 ; i < callback_data -> arg_count ; ++ i ) {
867
+ if (callback_data -> arg_types [i ]-> type == FFI_TYPE_STRUCT ) {
868
+ efree (callback_data -> arg_types [i ]);
869
+ }
870
+ }
871
+ if (callback_data -> ret_type -> type == FFI_TYPE_STRUCT ) {
872
+ efree (callback_data -> ret_type );
873
+ }
866
874
efree (callback_data );
867
875
}
868
876
/* }}} */
@@ -916,6 +924,8 @@ static void zend_ffi_callback_trampoline(ffi_cif* cif, void* ret, void** args, v
916
924
if (ret_type -> kind != ZEND_FFI_TYPE_VOID ) {
917
925
zend_ffi_zval_to_cdata (ret , ret_type , & retval );
918
926
}
927
+
928
+ zval_ptr_dtor (& retval );
919
929
}
920
930
/* }}} */
921
931
@@ -966,6 +976,11 @@ static void *zend_ffi_create_callback(zend_ffi_type *type, zval *value) /* {{{ *
966
976
callback_data -> arg_types [n ] = zend_ffi_get_type (arg_type );
967
977
if (!callback_data -> arg_types [n ]) {
968
978
zend_ffi_pass_unsupported (arg_type );
979
+ for (int i = 0 ; i < n ; ++ i ) {
980
+ if (callback_data -> arg_types [i ]-> type == FFI_TYPE_STRUCT ) {
981
+ efree (callback_data -> arg_types [i ]);
982
+ }
983
+ }
969
984
efree (callback_data );
970
985
ffi_closure_free (callback );
971
986
return NULL ;
@@ -976,20 +991,32 @@ static void *zend_ffi_create_callback(zend_ffi_type *type, zval *value) /* {{{ *
976
991
callback_data -> ret_type = zend_ffi_get_type (ZEND_FFI_TYPE (type -> func .ret_type ));
977
992
if (!callback_data -> ret_type ) {
978
993
zend_ffi_return_unsupported (type -> func .ret_type );
994
+ for (int i = 0 ; i < callback_data -> arg_count ; ++ i ) {
995
+ if (callback_data -> arg_types [i ]-> type == FFI_TYPE_STRUCT ) {
996
+ efree (callback_data -> arg_types [i ]);
997
+ }
998
+ }
979
999
efree (callback_data );
980
1000
ffi_closure_free (callback );
981
1001
return NULL ;
982
1002
}
983
1003
984
1004
if (ffi_prep_cif (& callback_data -> cif , type -> func .abi , callback_data -> arg_count , callback_data -> ret_type , callback_data -> arg_types ) != FFI_OK ) {
985
1005
zend_throw_error (zend_ffi_exception_ce , "Cannot prepare callback CIF" );
986
- efree (callback_data );
987
- ffi_closure_free (callback );
988
- return NULL ;
1006
+ goto free_on_failure ;
989
1007
}
990
1008
991
1009
if (ffi_prep_closure_loc (callback , & callback_data -> cif , zend_ffi_callback_trampoline , callback_data , code ) != FFI_OK ) {
992
1010
zend_throw_error (zend_ffi_exception_ce , "Cannot prepare callback" );
1011
+ free_on_failure : ;
1012
+ for (int i = 0 ; i < callback_data -> arg_count ; ++ i ) {
1013
+ if (callback_data -> arg_types [i ]-> type == FFI_TYPE_STRUCT ) {
1014
+ efree (callback_data -> arg_types [i ]);
1015
+ }
1016
+ }
1017
+ if (callback_data -> ret_type -> type == FFI_TYPE_STRUCT ) {
1018
+ efree (callback_data -> ret_type );
1019
+ }
993
1020
efree (callback_data );
994
1021
ffi_closure_free (callback );
995
1022
return NULL ;
0 commit comments