* Fix error path resouce leak in local_request().
authorRichard Mudgett <rmudgett@digium.com>
Tue, 1 May 2012 22:00:11 +0000 (22:00 +0000)
committerRichard Mudgett <rmudgett@digium.com>
Tue, 1 May 2012 22:00:11 +0000 (22:00 +0000)
* Restructure local_request() to reduce indentation.
........

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

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

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

channels/chan_local.c

index 069f44a..1a8ea17 100644 (file)
@@ -1176,20 +1176,26 @@ static struct ast_channel *local_new(struct local_pvt *p, int state, const char
 /*! \brief Part of PBX interface */
 static struct ast_channel *local_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
 {
-       struct local_pvt *p = NULL;
-       struct ast_channel *chan = NULL;
+       struct local_pvt *p;
+       struct ast_channel *chan;
 
        /* Allocate a new private structure and then Asterisk channel */
-       if ((p = local_alloc(data, cap))) {
-               if (!(chan = local_new(p, AST_STATE_DOWN, requestor ? ast_channel_linkedid(requestor) : NULL))) {
-                       ao2_unlink(locals, p);
-               }
-               if (chan && ast_channel_cc_params_init(chan, requestor ? ast_channel_get_cc_config_params((struct ast_channel *)requestor) : NULL)) {
-                       chan = ast_channel_release(chan);
-                       ao2_unlink(locals, p);
-               }
-               ao2_ref(p, -1); /* kill the ref from the alloc */
+       p = local_alloc(data, cap);
+       if (!p) {
+               return NULL;
+       }
+       chan = local_new(p, AST_STATE_DOWN, requestor ? ast_channel_linkedid(requestor) : NULL);
+       if (!chan) {
+               ao2_unlink(locals, p);
+       } else if (ast_channel_cc_params_init(chan, requestor ? ast_channel_get_cc_config_params((struct ast_channel *)requestor) : NULL)) {
+               ao2_unlink(locals, p);
+               p->owner = ast_channel_release(p->owner);
+               ast_module_user_remove(p->u_owner);
+               p->chan = ast_channel_release(p->chan);
+               ast_module_user_remove(p->u_chan);
+               chan = NULL;
        }
+       ao2_ref(p, -1); /* kill the ref from the alloc */
 
        return chan;
 }