Fix memory leaks in app_followme find_realtime().
authorRichard Mudgett <rmudgett@digium.com>
Fri, 6 Jan 2012 16:50:08 +0000 (16:50 +0000)
committerRichard Mudgett <rmudgett@digium.com>
Fri, 6 Jan 2012 16:50:08 +0000 (16:50 +0000)
(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

index 9ee2e33..6d46a1f 100644 (file)
@@ -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)