diff options
author | Richard Mudgett <rmudgett@digium.com> | 2014-04-30 21:03:29 +0000 |
---|---|---|
committer | Richard Mudgett <rmudgett@digium.com> | 2014-04-30 21:03:29 +0000 |
commit | 20750e261b3cc1cd954ac3de839afadcc4817d8d (patch) | |
tree | 6d0f7ff8367b5ce0d7a2930bc219c9b058942ed6 /main/message.c | |
parent | f2a060f5027367de68fb298c31bb661e45cf7f7a (diff) |
chan_sip.c: Fixed off-nominal message iterator ref count and alloc fail issues.
* Fixed early exit in sip_msg_send() not destroying the message iterator.
* Made ast_msg_var_iterator_next() and ast_msg_var_iterator_destroy()
tolerant of a NULL iter parameter in case ast_msg_var_iterator_init()
fails.
* Made ast_msg_var_iterator_destroy() clean up any current message data
ref.
* Made struct ast_msg_var_iterator, ast_msg_var_iterator_init(),
ast_msg_var_iterator_next(), ast_msg_var_unref_current(), and
ast_msg_var_iterator_destroy() use iter instead of i.
* Eliminated RAII_VAR usage in res_pjsip_messaging.c:vars_to_headers().
........
Merged revisions 413139 from http://svn.asterisk.org/svn/asterisk/branches/11
........
Merged revisions 413142 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@413144 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/message.c')
-rw-r--r-- | main/message.c | 40 |
1 files changed, 24 insertions, 16 deletions
diff --git a/main/message.c b/main/message.c index bd706e363..39166e0ff 100644 --- a/main/message.c +++ b/main/message.c @@ -610,28 +610,34 @@ const char *ast_msg_get_var(struct ast_msg *msg, const char *name) } struct ast_msg_var_iterator { - struct ao2_iterator i; + struct ao2_iterator iter; struct msg_data *current_used; }; struct ast_msg_var_iterator *ast_msg_var_iterator_init(const struct ast_msg *msg) { - struct ast_msg_var_iterator *i; - if (!(i = ast_calloc(1, sizeof(*i)))) { + struct ast_msg_var_iterator *iter; + + iter = ast_calloc(1, sizeof(*iter)); + if (!iter) { return NULL; } - i->i = ao2_iterator_init(msg->vars, 0); + iter->iter = ao2_iterator_init(msg->vars, 0); - return i; + return iter; } -int ast_msg_var_iterator_next(const struct ast_msg *msg, struct ast_msg_var_iterator *i, const char **name, const char **value) +int ast_msg_var_iterator_next(const struct ast_msg *msg, struct ast_msg_var_iterator *iter, const char **name, const char **value) { struct msg_data *data; + if (!iter) { + return 0; + } + /* Skip any that aren't marked for sending out */ - while ((data = ao2_iterator_next(&i->i)) && !data->send) { + while ((data = ao2_iterator_next(&iter->iter)) && !data->send) { ao2_ref(data, -1); } @@ -646,22 +652,24 @@ int ast_msg_var_iterator_next(const struct ast_msg *msg, struct ast_msg_var_iter /* Leave the refcount to be cleaned up by the caller with * ast_msg_var_unref_current after they finish with the pointers to the data */ - i->current_used = data; + iter->current_used = data; return 1; } -void ast_msg_var_unref_current(struct ast_msg_var_iterator *i) { - if (i->current_used) { - ao2_ref(i->current_used, -1); - } - i->current_used = NULL; +void ast_msg_var_unref_current(struct ast_msg_var_iterator *iter) +{ + ao2_cleanup(iter->current_used); + iter->current_used = NULL; } -void ast_msg_var_iterator_destroy(struct ast_msg_var_iterator *i) +void ast_msg_var_iterator_destroy(struct ast_msg_var_iterator *iter) { - ao2_iterator_destroy(&i->i); - ast_free(i); + if (iter) { + ao2_iterator_destroy(&iter->iter); + ast_msg_var_unref_current(iter); + ast_free(iter); + } } static struct ast_channel *create_msg_q_chan(void) |