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