From d7005bf8ad0ac9aa95fc720c38136f20d105b198 Mon Sep 17 00:00:00 2001 From: Richard Mudgett <rmudgett@digium.com> Date: Fri, 6 Jan 2012 16:50:08 +0000 Subject: [PATCH] Fix memory leaks in app_followme find_realtime(). (closes issue ASTERISK-19055) Reported by: Matt Jordan ........ Merged revisions 349872 from http://svn.asterisk.org/svn/asterisk/branches/1.8 ........ Merged revisions 349873 from http://svn.asterisk.org/svn/asterisk/branches/10 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@349874 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- apps/app_followme.c | 51 ++++++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/apps/app_followme.c b/apps/app_followme.c index 9ee2e334e7..6d46a1fd55 100644 --- a/apps/app_followme.c +++ b/apps/app_followme.c @@ -952,62 +952,83 @@ static void findmeexec(struct fm_args *tpargs) static struct call_followme *find_realtime(const char *name) { - struct ast_variable *var = ast_load_realtime("followme", "name", name, SENTINEL), *v; + struct ast_variable *var; + struct ast_variable *v; struct ast_config *cfg; const char *catg; - struct call_followme *new; - struct ast_str *str = ast_str_create(16); + struct call_followme *new_follower; + struct ast_str *str; + str = ast_str_create(16); + if (!str) { + return NULL; + } + + var = ast_load_realtime("followme", "name", name, SENTINEL); if (!var) { + ast_free(str); return NULL; } - if (!(new = alloc_profile(name))) { + if (!(new_follower = alloc_profile(name))) { + ast_variables_destroy(var); + ast_free(str); return NULL; } for (v = var; v; v = v->next) { if (!strcasecmp(v->name, "active")) { if (ast_false(v->value)) { - ast_mutex_destroy(&new->lock); - ast_free(new); + ast_mutex_destroy(&new_follower->lock); + ast_free(new_follower); + ast_variables_destroy(var); + ast_free(str); return NULL; } } else { - profile_set_param(new, v->name, v->value, 0, 0); + profile_set_param(new_follower, v->name, v->value, 0, 0); } } ast_variables_destroy(var); - new->realtime = 1; + new_follower->realtime = 1; /* Load numbers */ - if (!(cfg = ast_load_realtime_multientry("followme_numbers", "ordinal LIKE", "%", "name", name, SENTINEL))) { - ast_mutex_destroy(&new->lock); - ast_free(new); + cfg = ast_load_realtime_multientry("followme_numbers", "ordinal LIKE", "%", "name", + name, SENTINEL); + if (!cfg) { + ast_mutex_destroy(&new_follower->lock); + ast_free(new_follower); + ast_free(str); return NULL; } for (catg = ast_category_browse(cfg, NULL); catg; catg = ast_category_browse(cfg, catg)) { - const char *numstr, *timeoutstr, *ordstr; + const char *numstr; + const char *timeoutstr; + const char *ordstr; int timeout; struct number *cur; + if (!(numstr = ast_variable_retrieve(cfg, catg, "phonenumber"))) { continue; } - if (!(timeoutstr = ast_variable_retrieve(cfg, catg, "timeout")) || sscanf(timeoutstr, "%30d", &timeout) != 1 || timeout < 1) { + if (!(timeoutstr = ast_variable_retrieve(cfg, catg, "timeout")) + || sscanf(timeoutstr, "%30d", &timeout) != 1 + || timeout < 1) { timeout = 25; } /* This one has to exist; it was part of the query */ ordstr = ast_variable_retrieve(cfg, catg, "ordinal"); ast_str_set(&str, 0, "%s", numstr); if ((cur = create_followme_number(ast_str_buffer(str), timeout, atoi(ordstr)))) { - AST_LIST_INSERT_TAIL(&new->numbers, cur, entry); + AST_LIST_INSERT_TAIL(&new_follower->numbers, cur, entry); } } ast_config_destroy(cfg); - return new; + ast_free(str); + return new_follower; } static void end_bridge_callback(void *data) -- GitLab