summaryrefslogtreecommitdiff
path: root/main/message.c
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2014-04-30 21:03:29 +0000
committerRichard Mudgett <rmudgett@digium.com>2014-04-30 21:03:29 +0000
commit20750e261b3cc1cd954ac3de839afadcc4817d8d (patch)
tree6d0f7ff8367b5ce0d7a2930bc219c9b058942ed6 /main/message.c
parentf2a060f5027367de68fb298c31bb661e45cf7f7a (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.c40
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)