From 70f215a31fab4be1fe3e80125eb401e11eb02b9f Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Fri, 12 Feb 2016 15:07:07 +0100 Subject: [PATCH] fix leaks --- src/context_validate.c | 19 ++++++++++++------- src/engine.c | 10 +++++++++- src/libffi.c | 26 ++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 8 deletions(-) diff --git a/src/context_validate.c b/src/context_validate.c index 87aba78..435dc2d 100644 --- a/src/context_validate.c +++ b/src/context_validate.c @@ -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; } diff --git a/src/engine.c b/src/engine.c index 0c170cb..4415e4b 100644 --- a/src/engine.c +++ b/src/engine.c @@ -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; } } diff --git a/src/libffi.c b/src/libffi.c index 0e948a8..514394f 100644 --- a/src/libffi.c +++ b/src/libffi.c @@ -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); } -- 2.30.2