Add some safety measures when using gosub, especially when using the options
authorMark Michelson <mmichelson@digium.com>
Wed, 3 Dec 2008 18:37:46 +0000 (18:37 +0000)
committerMark Michelson <mmichelson@digium.com>
Wed, 3 Dec 2008 18:37:46 +0000 (18:37 +0000)
for app_dial and app_queue to run a gosub when the call is answered.

* Check for the existence of the gosub target in gosub_exec. If it is nonexistent,
  then this will cause errors when we attempt to actually run the gosub, including
  a definite memory leak and potential crashes. Return an error in this situation
* Check the return value of pbx_exec in app_dial and app_queue before attempting
  to actually run the gosub routine. If there was an error, we should not attempt
  to run the gosub.
* Change a '|' to a ',' in app_queue.
* Add some extra curly braces where they had been missing previously.

(closes issue #13548)
Reported by: fiddur

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

apps/app_dial.c
apps/app_queue.c
apps/app_stack.c

index 462b30e..08e8646 100644 (file)
@@ -2081,14 +2081,16 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
 
                                if (gosub_args) {
                                        res9 = pbx_exec(peer, theapp, gosub_args);
-                                       ast_pbx_run(peer);
+                                       if (!res9) {
+                                               ast_pbx_run(peer);
+                                       }
                                        ast_free(gosub_args);
                                        if (option_debug)
                                                ast_log(LOG_DEBUG, "Gosub exited with status %d\n", res9);
-                               } else
+                               } else {
                                        ast_log(LOG_ERROR, "Could not Allocate string for Gosub arguments -- Gosub Call Aborted!\n");
+                               }
 
-                               res9 = 0;
                        } else if (!res9) {
                                ast_log(LOG_ERROR, "Could not find application Gosub\n");
                                res9 = -1;
index 3937140..7f538d8 100644 (file)
@@ -3982,7 +3982,7 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce
                                                ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
                                                gosub_args = NULL;
                                        }
-                                       *gosub_argstart = '|';
+                                       *gosub_argstart = ',';
                                } else {
                                        if (asprintf(&gosub_args, "%s,s,1", gosubexec) < 0) {
                                                ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
@@ -3991,13 +3991,14 @@ static int try_calling(struct queue_ent *qe, const char *options, char *announce
                                }
                                if (gosub_args) {
                                        res = pbx_exec(peer, application, gosub_args);
-                                       ast_pbx_run(peer);
+                                       if (!res) {
+                                               ast_pbx_run(peer);
+                                       }
                                        free(gosub_args);
                                        ast_debug(1, "Gosub exited with status %d\n", res);
-                               } else
+                               } else {
                                        ast_log(LOG_ERROR, "Could not Allocate string for Gosub arguments -- Gosub Call Aborted!\n");
-                               
-                               res = 0;
+                               }
                        } else {
                                ast_log(LOG_ERROR, "Could not find application Gosub\n");
                                res = -1;
index 92a0e0d..eae4a1d 100644 (file)
@@ -373,8 +373,9 @@ static int gosub_exec(struct ast_channel *chan, void *data)
        /* Create the return address, but don't save it until we know that the Gosub destination exists */
        newframe = gosub_allocate_frame(chan->context, chan->exten, chan->priority + 1, args2.argc);
 
-       if (!newframe)
+       if (!newframe) {
                return -1;
+       }
 
        if (ast_parseable_goto(chan, label)) {
                ast_log(LOG_ERROR, "Gosub address is invalid: '%s'\n", (char *)data);
@@ -382,6 +383,16 @@ static int gosub_exec(struct ast_channel *chan, void *data)
                return -1;
        }
 
+       if (!ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num)) {
+               ast_log(LOG_ERROR, "Attempt to reach a non-existent destination for gosub: (Context:%s, Extension:%s, Priority:%d)\n",
+                               chan->context, chan->exten, chan->priority);
+               ast_copy_string(chan->context, newframe->context, sizeof(chan->context));
+               ast_copy_string(chan->exten, newframe->extension, sizeof(chan->exten));
+               chan->priority = newframe->priority;
+               ast_free(newframe);
+               return -1;
+       }
+
        /* Now that we know for certain that we're going to a new location, set our arguments */
        for (i = 0; i < args2.argc; i++) {
                snprintf(argname, sizeof(argname), "ARG%d", i + 1);