fix leaks
authorMichael Wallner <mike@php.net>
Fri, 12 Feb 2016 14:07:07 +0000 (15:07 +0100)
committerMichael Wallner <mike@php.net>
Fri, 12 Feb 2016 14:07:07 +0000 (15:07 +0100)
src/context_validate.c
src/engine.c
src/libffi.c

index 87aba784064c7d3f1fd2a907940d6a482d9bdb49..435dc2d0e4b2bf80f5d753dec4808b069259952f 100644 (file)
@@ -531,9 +531,6 @@ static inline int validate_decl_func(PSI_Data *data, void *dl, decl *decl, decl_
                return 0;
        }
 
-       if (!validate_decl_arg(data, func)) {
-               return 0;
-       }
        for (redir = &psi_func_redirs[0]; redir->name; ++redir) {
                if (!strcmp(func->var->name, redir->name)) {
                        decl->call.sym = redir->func;
@@ -552,14 +549,13 @@ static inline int validate_decl_func(PSI_Data *data, void *dl, decl *decl, decl_
        }
        return 1;
 }
-
-static inline int validate_decl(PSI_Data *data, void *dl, decl *decl) {
+static inline int validate_decl_nodl(PSI_Data *data, decl *decl) {
        if (!validate_decl_abi(data, decl->abi)) {
                data->error(data, decl->abi->token, PSI_WARNING,
                                "Invalid calling convention: '%s'", decl->abi->token->text);
                return 0;
        }
-       if (!validate_decl_func(data, dl, decl, decl->func)) {
+       if (!validate_decl_arg(data, decl->func)) {
                return 0;
        }
        if (decl->args) {
@@ -573,6 +569,15 @@ static inline int validate_decl(PSI_Data *data, void *dl, decl *decl) {
        }
        return 1;
 }
+static inline int validate_decl(PSI_Data *data, void *dl, decl *decl) {
+       if (!validate_decl_nodl(data, decl)) {
+               return 0;
+       }
+       if (!validate_decl_func(data, dl, decl, decl->func)) {
+               return 0;
+       }
+       return 1;
+}
 static inline decl_arg *locate_decl_var_arg(decl_var *var, decl_args *args, decl_arg *func) {
        size_t i;
 
@@ -963,7 +968,7 @@ static inline int validate_let_callback(PSI_Data *data, decl_var *cb_var, let_ca
                }
        }
 
-       if (!validate_decl(data, NULL, cb_func)) {
+       if (!validate_decl_nodl(data, cb_func)) {
                return 0;
        }
 
index 0c170cb63f5e4839e5cde371752bd8726bd7b4ab..4415e4b093dc4c656f491d19798fa40754074e1f 100644 (file)
@@ -201,7 +201,7 @@ static inline ZEND_RESULT_CODE psi_parse_args(zend_execute_data *execute_data, i
                        Z_PARAM_FUNC_EX(fci, fcc, 1, 0);
 
                        if (fci.size) {
-                               iarg->val.zend.cb = calloc(1, sizeof(zend_fcall));
+                               iarg->val.zend.cb = ecalloc(1, sizeof(zend_fcall));
                                iarg->val.zend.cb->fci = fci;
                                iarg->val.zend.cb->fcc = fcc;
                        }
@@ -372,6 +372,14 @@ static inline void psi_do_clean(impl *impl)
                                zend_string_release(iarg->val.zend.str);
                        }
                        break;
+               case PSI_T_CALLABLE:
+                       if (iarg->val.zend.cb) {
+                               if (iarg->val.zend.cb->fci.size) {
+                                       zend_fcall_info_args_clear(&iarg->val.zend.cb->fci, 1);
+                               }
+                               efree(iarg->val.zend.cb);
+                       }
+                       break;
                }
        }
 
index 0e948a85257739e376f10ad28e3f0bb32d48ff1c..514394f4047f506650473e367a724a7c729d4d8b 100644 (file)
@@ -116,6 +116,12 @@ static void psi_ffi_callback(ffi_cif *_sig, void *_result, void **_args, void *_
        if (result != _result) {
                *(void **)_result = result;
        }
+
+       zend_fcall_info_args_clear(&iarg->val.zend.cb->fci, 0);
+       for (i = 0; i < cb->args->count; ++i) {
+               zval_ptr_dtor(&zargv[i]);
+       }
+       free(zargv);
 }
 
 static inline ffi_type *psi_ffi_decl_arg_type(decl_arg *darg);
@@ -373,6 +379,26 @@ static void psi_ffi_dtor(PSI_Context *C)
                                PSI_LibffiCallFree(decl->call.info);
                        }
                }
+
+       }
+       if (C->impls) {
+               size_t i, j;
+
+               for (i = 0; i < C->impls->count; ++i) {
+                       impl *impl = C->impls->list[i];
+
+                       for (j = 0; j < impl->stmts->let.count; ++j) {
+                               let_stmt *let = impl->stmts->let.list[j];
+
+                               if (let->val && let->val->kind == PSI_LET_CALLBACK) {
+                                       let_callback *cb = let->val->data.callback;
+
+                                       if (cb->decl && cb->decl->call.info) {
+                                               PSI_LibffiCallFree(cb->decl->call.info);
+                                       }
+                               }
+                       }
+               }
        }
        free(C->context);
 }