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