Fix a variety of memory leaks
authorMatthew Jordan <mjordan@digium.com>
Fri, 18 May 2012 14:43:44 +0000 (14:43 +0000)
committerMatthew Jordan <mjordan@digium.com>
Fri, 18 May 2012 14:43:44 +0000 (14:43 +0000)
This patch addresses a number of memory leaks in a variety of modules that were
found by a static analysis tool.  A brief summary of the changes:

* app_minivm:       free ast_str objects on off nominal paths
* app_page:         free the ast_dial object if the requested channel technology
                    cannot be appended to the dialing structure
* app_queue:        if a penalty rule failed to match any existing rule list
                    names, the created rule would not be inserted and its memory
                    would be leaked
* app_read:         dispose of the created silence detector in the presence of
                    off nominal circumstances
* app_voicemail:    dispose of an allocated unique ID field for MWI event
                    un-subscribe requests in off nominal paths; dispose of
                    configuration objects when using the secret.conf option
* chan_dahdi:       dispose of the allocated frame produced by ast_dsp_process
* chan_iax2:        properly unref peer in CLI command "iax2 unregister"
* chan_sip:         dispose of the allocated frame produced by sip_rtp_read's
                    call of ast_dsp_process; free memory in parse unit tests
* func_dialgroup:   properly deref ao2 object grhead in nominal path of
                    dialgroup_read
* func_odbc:        free resultset in off nominal paths of odbc_read
* cli:              free match_list in off nominal paths of CLI match completion
* config:           free comment_buffer/list_buffer when configuration file load
                    is unchanged; free the same buffers any time they were
                    created and config files were processed
* data:             free XML nodes in various places
* enum:             free context buffer in off nominal paths
* features:         free ast_call_feature in off nominal paths of applicationmap
                    config processing
* netsock2:         users of ast_sockaddr_resolve pass in an ast_sockaddr struct
                    that is allocated by the method.  Failures in
                    ast_sockaddr_resolve could result in the users of the method
                    not knowing whether or not the buffer was allocated.  The
                    method will now not allocate the ast_sockaddr struct if it
                    will return failure.
* pbx:              cleanup hash table traversals in off nominal paths; free
                    ignore pattern buffer if it already exists for the specified
                    context
* xmldoc:           cleanup various nodes when we no longer need them
* main/editline:    various cleanup of pointers not being freed before being
                    assigned to other memory, cleanup along off nominal paths
* menuselect/mxml:  cleanup of value buffer for an attribute when that attribute
                    did not specify a value
* res_calendar*:    responses are allocated via the various *_request method
                    returns and should not be allocated in the various
                    write_event methods; ensure attendee buffer is freed if no
                    data exists in the parsed node; ensure that calendar objects
                    are de-ref'd appropriately
* res_jabber:       free buffer in off nominal path
* res_musiconhold:  close the DIR* object in off nominal paths
* res_rtp_asterisk: if we run out of ports, close the rtp socket object and free
                    the rtp object
* res_srtp:         if we fail to create the session in libsrtp, destroy the
                    temporary ast_srtp object

(issue ASTERISK-19665)
Reported by: Matt Jordan

Review: https://reviewboard.asterisk.org/r/1922
........

Merged revisions 366880 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........

Merged revisions 366881 from http://svn.asterisk.org/svn/asterisk/branches/10

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@366917 65c4cc65-6c06-0410-ace0-fbb531ad65f3

29 files changed:
apps/app_minivm.c
apps/app_page.c
apps/app_queue.c
apps/app_record.c
apps/app_voicemail.c
channels/chan_dahdi.c
channels/chan_iax2.c
channels/chan_sip.c
channels/sip/config_parser.c
funcs/func_dialgroup.c
funcs/func_odbc.c
main/cli.c
main/config.c
main/data.c
main/editline/readline.c
main/editline/term.c
main/editline/tokenizer.c
main/enum.c
main/features.c
main/netsock2.c
main/pbx.c
main/xmldoc.c
res/res_calendar.c
res/res_calendar_caldav.c
res/res_calendar_exchange.c
res/res_calendar_icalendar.c
res/res_jabber.c
res/res_rtp_asterisk.c
res/res_srtp.c

index eca7f30..0b46311 100644 (file)
@@ -1255,6 +1255,8 @@ static int sendmail(struct minivm_template *template, struct minivm_account *vmu
 
        if (ast_strlen_zero(email)) {
                ast_log(LOG_WARNING, "No address to send message to.\n");
+               ast_free(str1);
+               ast_free(str2);
                return -1;      
        }
 
@@ -1309,11 +1311,15 @@ static int sendmail(struct minivm_template *template, struct minivm_account *vmu
        }
        if (!p) {
                ast_log(LOG_WARNING, "Unable to open temporary file '%s'\n", tmp);
+               ast_free(str1);
+               ast_free(str2);
                return -1;
        }
        /* Allocate channel used for chanvar substitution */
        ast = ast_dummy_channel_alloc();
        if (!ast) {
+               ast_free(str1);
+               ast_free(str2);
                return -1;
        }
 
index 61172fc..8c56948 100644 (file)
@@ -270,6 +270,7 @@ static int page_exec(struct ast_channel *chan, const char *data)
                /* Append technology and resource */
                if (ast_dial_append(dial, tech, resource) == -1) {
                        ast_log(LOG_ERROR, "Failed to add %s to outbound dial\n", tech);
+                       ast_dial_destroy(dial);
                        continue;
                }
 
index 151f03c..a566c9a 100644 (file)
@@ -1973,9 +1973,17 @@ static int insert_penaltychange(const char *list_name, const char *content, cons
        
                if (!inserted) {
                        AST_LIST_INSERT_TAIL(&rl_iter->rules, rule, list);
+                       inserted = 1;
                }
+
+               break;
        }
 
+       if (!inserted) {
+               ast_log(LOG_WARNING, "Unknown rule list name %s; ignoring.\n", list_name);
+               ast_free(rule);
+               return -1;
+       }
        return 0;
 }
 
@@ -4538,6 +4546,7 @@ static struct ast_datastore *setup_transfer_datastore(struct queue_ent *qe, stru
        ast_channel_lock(qe->chan);
        if (!(ds = ast_datastore_alloc(&queue_transfer_info, NULL))) {
                ast_channel_unlock(qe->chan);
+               ast_free(qtds);
                ast_log(LOG_WARNING, "Unable to create transfer datastore. queue_log will not show attended transfer\n");
                return NULL;
        }
index 3499cb1..ff233d6 100644 (file)
@@ -415,12 +415,14 @@ static int record_exec(struct ast_channel *chan, const char *data)
 out:
        if ((silence > 0) && rfmt.id) {
                res = ast_set_read_format(chan, &rfmt);
-               if (res)
+               if (res) {
                        ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", ast_channel_name(chan));
-               if (sildet)
-                       ast_dsp_free(sildet);
+               }
        }
 
+       if (sildet) {
+               ast_dsp_free(sildet);
+       }
        return res;
 }
 
index 7e75ea9..eec08a4 100644 (file)
@@ -11728,16 +11728,22 @@ static int handle_subscribe(void *datap)
 static void mwi_unsub_event_cb(const struct ast_event *event, void *userdata)
 {
        uint32_t u, *uniqueid = ast_calloc(1, sizeof(*uniqueid));
-       if (ast_event_get_type(event) != AST_EVENT_UNSUB)
+
+       if (!uniqueid) {
+               ast_log(LOG_ERROR, "Unable to allocate memory for uniqueid\n");
                return;
+       }
 
-       if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI)
+       if (ast_event_get_type(event) != AST_EVENT_UNSUB) {
+               ast_free(uniqueid);
                return;
+       }
 
-       if (!uniqueid) {
-               ast_log(LOG_ERROR, "Unable to allocate memory for uniqueid\n");
+       if (ast_event_get_ie_uint(event, AST_EVENT_IE_EVENTTYPE) != AST_EVENT_MWI) {
+               ast_free(uniqueid);
                return;
        }
+
        u = ast_event_get_ie_uint(event, AST_EVENT_IE_UNIQUEID);
        *uniqueid = u;
        if (ast_taskprocessor_push(mwi_subscription_tps, handle_unsubscribe, uniqueid) < 0) {
@@ -12728,8 +12734,10 @@ static void read_password_from_file(const char *secretfn, char *password, int pa
                const char *val = ast_variable_retrieve(pwconf, "general", "password");
                if (val) {
                        ast_copy_string(password, val, passwordlen);
-                       return;
+                       ast_config_destroy(pwconf);
+                       return;
                }
+               ast_config_destroy(pwconf);
        }
        ast_log(LOG_NOTICE, "Failed reading voicemail password from %s, using secret from config file\n", secretfn);
 }
@@ -12738,26 +12746,33 @@ static int write_password_to_file(const char *secretfn, const char *password) {
        struct ast_config *conf;
        struct ast_category *cat;
        struct ast_variable *var;
+       int res = -1;
 
-       if (!(conf=ast_config_new())) {
+       if (!(conf = ast_config_new())) {
                ast_log(LOG_ERROR, "Error creating new config structure\n");
-               return -1;
+               return res;
        }
-       if (!(cat=ast_category_new("general","",1))) {
+       if (!(cat = ast_category_new("general", "", 1))) {
                ast_log(LOG_ERROR, "Error creating new category structure\n");
-               return -1;
+               ast_config_destroy(conf);
+               return res;
        }
-       if (!(var=ast_variable_new("password",password,""))) {
+       if (!(var = ast_variable_new("password", password, ""))) {
                ast_log(LOG_ERROR, "Error creating new variable structure\n");
-               return -1;
+               ast_config_destroy(conf);
+               ast_category_destroy(cat);
+               return res;
        }
-       ast_category_append(conf,cat);
-       ast_variable_append(cat,var);
-       if (ast_config_text_file_save(secretfn, conf, "app_voicemail")) {
+       ast_category_append(conf, cat);
+       ast_variable_append(cat, var);
+       if (!ast_config_text_file_save(secretfn, conf, "app_voicemail")) {
+               res = 0;
+       } else {
                ast_log(LOG_ERROR, "Error writing voicemail password to %s\n", secretfn);
-               return -1;
        }
-       return 0;
+
+       ast_config_destroy(conf);
+       return res;
 }
 
 static int vmsayname_exec(struct ast_channel *chan, const char *data)
index 8f4da6f..77b2eb8 100644 (file)
@@ -9315,6 +9315,7 @@ static struct ast_frame *dahdi_read(struct ast_channel *ast)
                                         * Treat this as a "hangup" instead of a "busy" on the
                                         * assumption that a busy means the incoming call went away.
                                         */
+                                       ast_frfree(f);
                                        f = NULL;
                                }
                        } else if (p->dialtone_detect && !p->outgoing && f->frametype == AST_FRAME_VOICE) {
@@ -9345,7 +9346,8 @@ static struct ast_frame *dahdi_read(struct ast_channel *ast)
                                if (ast_tvdiff_ms(ast_tvnow(), p->waitingfordt) >= p->waitfordialtone ) {
                                        p->waitingfordt.tv_sec = 0;
                                        ast_log(LOG_WARNING, "Never saw dialtone on channel %d\n", p->channel);
-                                       f=NULL;
+                                       ast_frfree(f);
+                                       f = NULL;
                                } else if (f->frametype == AST_FRAME_VOICE) {
                                        f->frametype = AST_FRAME_NULL;
                                        f->subclass.integer = 0;
@@ -9360,6 +9362,7 @@ static struct ast_frame *dahdi_read(struct ast_channel *ast)
                                                                ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d\n", p->channel);
                                                                p->dop.dialstr[0] = '\0';
                                                                ast_mutex_unlock(&p->lock);
+                                                               ast_frfree(f);
                                                                return NULL;
                                                        } else {
                                                                ast_debug(1, "Sent deferred digit string: %s\n", p->dop.dialstr);
index 0d9af69..3b2d8cc 100644 (file)
@@ -6899,6 +6899,7 @@ static char *handle_cli_iax2_unregister(struct ast_cli_entry *e, int cmd, struct
                } else {
                        ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
                }
+               peer_unref(p);
        } else {
                ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]);
        }
@@ -9847,6 +9848,7 @@ static int acf_iaxvar_write(struct ast_channel *chan, const char *cmd, char *dat
                }
                varlist = ast_calloc(1, sizeof(*varlist));
                if (!varlist) {
+                       ast_datastore_free(variablestore);
                        ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
                        return -1;
                }
index 5d0cf0b..a21ebf3 100644 (file)
@@ -7657,6 +7657,7 @@ static struct ast_frame *sip_read(struct ast_channel *ast)
                                if (ast_async_goto(ast, target_context, "fax", 1)) {
                                        ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", ast_channel_name(ast), target_context);
                                }
+                               ast_frfree(fr);
                                fr = &ast_null_frame;
                        } else {
                                ast_channel_lock(ast);
@@ -7668,6 +7669,7 @@ static struct ast_frame *sip_read(struct ast_channel *ast)
 
        /* Only allow audio through if they sent progress with SDP, or if the channel is actually answered */
        if (fr && fr->frametype == AST_FRAME_VOICE && p->invitestate != INV_EARLY_MEDIA && ast_channel_state(ast) != AST_STATE_UP) {
+               ast_frfree(fr);
                fr = &ast_null_frame;
        }
 
index 98b42d5..ba6880d 100644 (file)
@@ -597,6 +597,8 @@ AST_TEST_DEFINE(sip_parse_register_line_test)
                ast_test_status_update(test, "Test 13, add domain port failed.\n");
                res = AST_TEST_FAIL;
        }
+       ast_string_field_free_memory(reg);
+       ast_free(reg);
 
        /* ---Test reg14, domain port without secret --- */
        if (!(reg = ast_calloc_with_stringfields(1, struct sip_registry, 256))) {
@@ -623,7 +625,9 @@ AST_TEST_DEFINE(sip_parse_register_line_test)
 
                ast_test_status_update(test, "Test 14, domain port without secret failed.\n");
                res = AST_TEST_FAIL;
-}
+       }
+       ast_string_field_free_memory(reg);
+       ast_free(reg);
 
 
        return res;
index c3322e3..0e078cd 100644 (file)
@@ -165,6 +165,7 @@ static int dialgroup_read(struct ast_channel *chan, const char *cmd, char *data,
                ao2_ref(entry, -1);
        }
        ao2_iterator_destroy(&i);
+       ao2_ref(grhead, -1);
 
        return res;
 }
index 1ee9771..72a87cc 100644 (file)
@@ -539,6 +539,7 @@ static int acf_odbc_read(struct ast_channel *chan, const char *cmd, char *s, cha
                        pbx_builtin_setvar_helper(chan, "ODBCROWS", rowcount);
                        ast_autoservice_stop(chan);
                }
+               ast_free(resultset);
                return -1;
        }
 
@@ -553,6 +554,7 @@ static int acf_odbc_read(struct ast_channel *chan, const char *cmd, char *s, cha
                        pbx_builtin_setvar_helper(chan, "ODBCROWS", rowcount);
                        ast_autoservice_stop(chan);
                }
+               ast_free(resultset);
                return -1;
        }
 
@@ -578,6 +580,7 @@ static int acf_odbc_read(struct ast_channel *chan, const char *cmd, char *s, cha
                        pbx_builtin_setvar_helper(chan, "ODBCSTATUS", status);
                        ast_autoservice_stop(chan);
                }
+               ast_free(resultset);
                return res1;
        }
 
index 6c79c7b..c54d89e 100644 (file)
@@ -2350,8 +2350,10 @@ char **ast_cli_completion_matches(const char *text, const char *word)
                max_equal = i;
        }
 
-       if (!(retstr = ast_malloc(max_equal + 1)))
+       if (!(retstr = ast_malloc(max_equal + 1))) {
+               ast_free(match_list);
                return NULL;
+       }
 
        ast_copy_string(retstr, match_list[1], max_equal + 1);
        match_list[0] = retstr;
index 249cf04..7f7f355 100644 (file)
@@ -1491,6 +1491,8 @@ static struct ast_config *config_text_file_load(const char *database, const char
 
                        if (unchanged) {
                                AST_LIST_UNLOCK(&cfmtime_head);
+                               ast_free(comment_buffer);
+                               ast_free(lline_buffer);
                                return CONFIG_STATUS_FILEUNCHANGED;
                        }
                }
@@ -1643,7 +1645,7 @@ static struct ast_config *config_text_file_load(const char *database, const char
                }
 #endif
 
-       if (cfg && cfg != CONFIG_STATUS_FILEUNCHANGED && cfg != CONFIG_STATUS_FILEINVALID && cfg->include_level == 1 && ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) {
+       if (ast_test_flag(&flags, CONFIG_FLAG_WITHCOMMENTS)) {
                ast_free(comment_buffer);
                ast_free(lline_buffer);
                comment_buffer = NULL;
index 146b154..3a7d5e9 100644 (file)
@@ -1042,6 +1042,7 @@ static int data_search_cmp_ptr(const struct ast_data_search *root, const char *n
        cmp_type = child->cmp_type;
 
        if (sscanf(child->value, "%p", &node_ptr) <= 0) {
+               ao2_ref(child, -1);
                return 1;
        }
 
@@ -2186,6 +2187,7 @@ struct ast_xml_doc *ast_data_get_xml(const struct ast_data_query *query)
 
        doc = ast_xml_new();
        if (!doc) {
+               ast_data_free(res);
                return NULL;
        }
 
index 4729fa9..77827c3 100644 (file)
@@ -549,6 +549,7 @@ _history_expand_command(const char *command, size_t cmdlen, char **result)
                                                from = strdup(search);
                                        else {
                                                from = NULL;
+                                               free(line);
                                                return (-1);
                                        }
                                }
@@ -609,8 +610,13 @@ _history_expand_command(const char *command, size_t cmdlen, char **result)
                end = max - ((end < -1) ? 1 : 0);
 
        /* check boundaries ... */
-       if (start > max || end > max || start > end)
+       if (start > max || end > max || start > end) {
+               for (i = 0; i <= max; i++) {
+                       free(arr[i]);
+               }
+               free(arr), arr = (char **) NULL;
                return (-1);
+       }
 
        for (i = 0; i <= max; i++) {
                char *temp;
index fb627ca..63cec6e 100644 (file)
@@ -472,7 +472,7 @@ term_rebuffer_display(EditLine *el)
 private int
 term_alloc_display(EditLine *el)
 {
-       int i;
+       int i, j;
        char **b;
        coord_t *c = &el->el_term.t_size;
 
@@ -481,8 +481,13 @@ term_alloc_display(EditLine *el)
                return (-1);
        for (i = 0; i < c->v; i++) {
                b[i] = (char *) el_malloc((size_t) (sizeof(char) * (c->h + 1)));
-               if (b[i] == NULL)
+               if (b[i] == NULL) {
+                       for (j = 0; j < i; j++) {
+                               el_free(b[j]);
+                       }
+                       el_free(b);
                        return (-1);
+               }
        }
        b[c->v] = NULL;
        el->el_display = b;
@@ -492,8 +497,13 @@ term_alloc_display(EditLine *el)
                return (-1);
        for (i = 0; i < c->v; i++) {
                b[i] = (char *) el_malloc((size_t) (sizeof(char) * (c->h + 1)));
-               if (b[i] == NULL)
+               if (b[i] == NULL) {
+                       for (j = 0; j < i; j++) {
+                               el_free(b[j]);
+                       }
+                       el_free(b);
                        return (-1);
+               }
        }
        b[c->v] = NULL;
        el->el_vdisplay = b;
index f0de39b..67398c6 100644 (file)
@@ -113,12 +113,17 @@ tok_init(const char *ifs)
        tok->argc = 0;
        tok->amax = AINCR;
        tok->argv = (char **) tok_malloc(sizeof(char *) * tok->amax);
-       if (tok->argv == NULL)
+       if (tok->argv == NULL) {
+               tok_free(tok);
                return (NULL);
+       }
        tok->argv[0] = NULL;
        tok->wspace = (char *) tok_malloc(WINCR);
-       if (tok->wspace == NULL)
+       if (tok->wspace == NULL) {
+               tok_free(tok->argv);
+               tok_free(tok);
                return (NULL);
+       }
        tok->wmax = tok->wspace + WINCR;
        tok->wstart = tok->wspace;
        tok->wptr = tok->wspace;
index 413085e..9c31c93 100644 (file)
@@ -790,6 +790,7 @@ int ast_get_enum(struct ast_channel *chan, const char *number, char *dst, int ds
 
                if (sdl > strlen(number)) {     /* Number too short for this sdl? */
                        ast_log(LOG_WARNING, "I-ENUM: subdomain location %d behind number %s\n", sdl, number);
+                       ast_free(context);
                        return 0;
                }
                ast_copy_string(left, number + sdl, sizeof(left));
@@ -802,6 +803,7 @@ int ast_get_enum(struct ast_channel *chan, const char *number, char *dst, int ds
                /* check the space we need for middle */
                if ((sdl * 2 + strlen(middle) + 2) > sizeof(middle)) {
                        ast_log(LOG_WARNING, "ast_get_enum: not enough space for I-ENUM rewrite.\n");
+                       ast_free(context);
                        return -1;
                }
 
@@ -819,6 +821,7 @@ int ast_get_enum(struct ast_channel *chan, const char *number, char *dst, int ds
 
        if (strlen(left) * 2 + 2 > sizeof(domain)) {
                ast_log(LOG_WARNING, "string to long in ast_get_enum\n");
+               ast_free(context);
                return -1;
        }
 
index 433c1a6..964e536 100644 (file)
@@ -6044,6 +6044,7 @@ static void process_applicationmap_line(struct ast_variable *var)
        } else {
                ast_log(LOG_NOTICE, "Invalid 'ActivateOn' specification for feature '%s',"
                        " must be 'self', or 'peer'\n", var->name);
+               ast_free(feature);
                return;
        }
 
@@ -6058,6 +6059,7 @@ static void process_applicationmap_line(struct ast_variable *var)
        } else {
                ast_log(LOG_NOTICE, "Invalid 'ActivatedBy' specification for feature '%s',"
                        " must be 'caller', or 'callee', or 'both'\n", var->name);
+               ast_free(feature);
                return;
        }
 
index 1922ac3..5ae4ceb 100644 (file)
@@ -270,6 +270,10 @@ int ast_sockaddr_resolve(struct ast_sockaddr **addrs, const char *str,
                res_cnt++;
        }
 
+       if (res_cnt == 0) {
+               goto cleanup;
+       }
+
        if ((*addrs = ast_malloc(res_cnt * sizeof(struct ast_sockaddr))) == NULL) {
                res_cnt = 0;
                goto cleanup;
index 2860218..250737b 100644 (file)
@@ -7511,6 +7511,8 @@ static void context_merge(struct ast_context **extcontexts, struct ast_hashtab *
 
                                if (!new) {
                                        ast_log(LOG_ERROR,"Could not allocate a new context for %s in merge_and_delete! Danger!\n", context->name);
+                                       ast_hashtab_end_traversal(prio_iter);
+                                       ast_hashtab_end_traversal(exten_iter);
                                        return; /* no sense continuing. */
                                }
                                /* we will not replace existing entries in the new context with stuff from the old context.
@@ -8236,6 +8238,7 @@ int ast_context_add_ignorepat2(struct ast_context *con, const char *value, const
                if (!strcasecmp(ignorepatc->pattern, value)) {
                        /* Already there */
                        ast_unlock_context(con);
+                       ast_free(ignorepat);
                        errno = EEXIST;
                        return -1;
                }
index 2735583..fad10e0 100644 (file)
@@ -1666,6 +1666,7 @@ static void xmldoc_parse_optionlist(struct ast_xml_node *fixnode, const char *ta
                ast_str_append(buffer, 0, "\n");
                ast_xml_free_attr(optname);
                ast_xml_free_attr(hasparams);
+               ast_free(optionsyntax);
        }
 }
 
@@ -1740,12 +1741,14 @@ char *ast_xmldoc_build_arguments(const char *type, const char *name, const char
        char *retstr = NULL;
 
        if (ast_strlen_zero(type) || ast_strlen_zero(name)) {
+               ast_free(ret);
                return NULL;
        }
 
        node = xmldoc_get_node(type, name, module, documentation_language);
 
        if (!node || !ast_xml_node_get_children(node)) {
+               ast_free(ret);
                return NULL;
        }
 
@@ -1758,6 +1761,7 @@ char *ast_xmldoc_build_arguments(const char *type, const char *name, const char
 
        if (!node || !ast_xml_node_get_children(node)) {
                /* We couldn't find the syntax node. */
+               ast_free(ret);
                return NULL;
        }
 
index 5ddcaae..8c34994 100644 (file)
@@ -374,6 +374,7 @@ static int calendar_is_busy(struct ast_calendar *cal)
 
 static enum ast_device_state calendarstate(const char *data)
 {
+       enum ast_device_state state;
        struct ast_calendar *cal;
 
        if (ast_strlen_zero(data) || (!(cal = find_calendar(data)))) {
@@ -381,10 +382,13 @@ static enum ast_device_state calendarstate(const char *data)
        }
 
        if (cal->tech->is_busy) {
-               return cal->tech->is_busy(cal) ? AST_DEVICE_INUSE : AST_DEVICE_NOT_INUSE;
+               state = cal->tech->is_busy(cal) ? AST_DEVICE_INUSE : AST_DEVICE_NOT_INUSE;
+       } else {
+               state = calendar_is_busy(cal) ? AST_DEVICE_INUSE : AST_DEVICE_NOT_INUSE;
        }
 
-       return calendar_is_busy(cal) ? AST_DEVICE_INUSE : AST_DEVICE_NOT_INUSE;
+       cal = unref_calendar(cal);
+       return state;
 }
 
 static struct ast_calendar *build_calendar(struct ast_config *cfg, const char *cat, const struct ast_calendar_tech *tech)
@@ -1060,6 +1064,7 @@ static int calendar_busy_exec(struct ast_channel *chan, const char *cmd, char *d
        }
 
        strcpy(buf, calendar_is_busy(cal) ? "1" : "0");
+       cal = unref_calendar(cal);
 
        return 0;
 }
@@ -1214,6 +1219,8 @@ static int calendar_query_exec(struct ast_channel *chan, const char *cmd, char *
                        ast_debug(10, "%s (%ld - %ld) overlapped with (%ld - %ld)\n", event->summary, (long) event->start, (long) event->end, (long) start, (long) end);
                        if (add_event_to_list(events, event, start, end) < 0) {
                                event = ast_calendar_unref_event(event);
+                               cal = unref_calendar(cal);
+                               ao2_ref(events, -1);
                                ao2_iterator_destroy(&i);
                                return -1;
                        }
@@ -1231,6 +1238,8 @@ static int calendar_query_exec(struct ast_channel *chan, const char *cmd, char *
 
        if (!(eventlist_datastore = ast_datastore_alloc(&eventlist_datastore_info, buf))) {
                ast_log(LOG_ERROR, "Could not allocate datastore!\n");
+               cal = unref_calendar(cal);
+               ao2_ref(events, -1);
                return -1;
        }
 
@@ -1241,6 +1250,7 @@ static int calendar_query_exec(struct ast_channel *chan, const char *cmd, char *
        ast_channel_datastore_add(chan, eventlist_datastore);
        ast_channel_unlock(chan);
 
+       cal = unref_calendar(cal);
        return 0;
 }
 
index 88b0432..b1dd628 100644 (file)
@@ -188,9 +188,8 @@ static int caldav_write_event(struct ast_calendar_event *event)
                return -1;
        }
        if (!(body = ast_str_create(512)) ||
-               !(subdir = ast_str_create(32)) ||
-               !(response = ast_str_create(512))) {
-               ast_log(LOG_ERROR, "Could not allocate memory for request and response!\n");
+               !(subdir = ast_str_create(32))) {
+               ast_log(LOG_ERROR, "Could not allocate memory for request!\n");
                goto write_cleanup;
        }
 
@@ -417,10 +416,12 @@ static void caldav_add_event(icalcomponent *comp, struct icaltime_span *span, vo
                        return;
                }
                data = icalproperty_get_attendee(prop);
-               if (!ast_strlen_zero(data)) {
-                       attendee->data = ast_strdup(data);;
-                       AST_LIST_INSERT_TAIL(&event->attendees, attendee, next);
+               if (ast_strlen_zero(data)) {
+                       ast_free(attendee);
+                       continue;
                }
+               attendee->data = ast_strdup(data);
+               AST_LIST_INSERT_TAIL(&event->attendees, attendee, next);
        }
 
 
index 6c0982a..e7beeaf 100644 (file)
@@ -433,9 +433,8 @@ static int exchangecal_write_event(struct ast_calendar_event *event)
                return -1;
        }
        if (!(body = ast_str_create(512)) ||
-               !(subdir = ast_str_create(32)) ||
-               !(response = ast_str_create(512))) {
-               ast_log(LOG_ERROR, "Could not allocate memory for request and response!\n");
+               !(subdir = ast_str_create(32))) {
+               ast_log(LOG_ERROR, "Could not allocate memory for request!\n");
                goto write_cleanup;
        }
 
index b177b49..dc7b5f3 100644 (file)
@@ -261,10 +261,12 @@ static void icalendar_add_event(icalcomponent *comp, struct icaltime_span *span,
                        return;
                }
                data = icalproperty_get_attendee(prop);
-               if (!ast_strlen_zero(data)) {
-                       attendee->data = ast_strdup(data);;
-                       AST_LIST_INSERT_TAIL(&event->attendees, attendee, next);
+               if (ast_strlen_zero(data)) {
+                       ast_free(attendee);
+                       continue;
                }
+               attendee->data = ast_strdup(data);;
+               AST_LIST_INSERT_TAIL(&event->attendees, attendee, next);
        }
 
 
index a68864f..384b12c 100644 (file)
@@ -2292,6 +2292,7 @@ static void aji_handle_message(struct aji_client *client, ikspak *pak)
                /* insert will furtherly be added to message list */
                insert->from = ast_strdup(pak->from->full);
                if (!insert->from) {
+                       ast_free(insert);
                        ast_log(LOG_ERROR, "Memory allocation failure\n");
                        return;
                }
index 62a3211..32b762e 100644 (file)
@@ -566,6 +566,8 @@ static int ast_rtp_new(struct ast_rtp_instance *instance,
                /* See if we ran out of ports or if the bind actually failed because of something other than the address being in use */
                if (x == startplace || errno != EADDRINUSE) {
                        ast_log(LOG_ERROR, "Oh dear... we couldn't allocate a port for RTP instance '%p'\n", instance);
+                       close(rtp->s);
+                       ast_free(rtp);
                        return -1;
                }
        }
index 756c62e..f651c40 100644 (file)
@@ -433,12 +433,14 @@ static int ast_srtp_create(struct ast_srtp **srtp, struct ast_rtp_instance *rtp,
        if (!(temp = res_srtp_new())) {
                return -1;
        }
+       ast_module_ref(ast_module_info->self);
 
+       /* Any failures after this point can use ast_srtp_destroy to destroy the instance */
        if (srtp_create(&temp->session, &policy->sp) != err_status_ok) {
+               ast_srtp_destroy(temp);
                return -1;
        }
 
-       ast_module_ref(ast_module_info->self);
        temp->rtp = rtp;
        *srtp = temp;