summaryrefslogtreecommitdiff
path: root/res/ael
diff options
context:
space:
mode:
authorTilghman Lesher <tilghman@meg.abyt.es>2009-10-06 19:17:11 +0000
committerTilghman Lesher <tilghman@meg.abyt.es>2009-10-06 19:17:11 +0000
commit78012e4f713fb76cea7cc55383fdab93479cc0ba (patch)
tree2629575d6ef7e2323649f46ae1cbaa62f0d42f5f /res/ael
parent0c3cd2ee458a347a9ff0a3ffb4366137b306b4a3 (diff)
When we call a gosub routine, the variables should be scoped to avoid contaminating the caller.
This affected the ~~EXTEN~~ hack, where a subroutine might have changed the value before it was used in the caller. Patch by myself, tested by ebroad on #asterisk git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@222273 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'res/ael')
-rw-r--r--res/ael/pval.c78
1 files changed, 50 insertions, 28 deletions
diff --git a/res/ael/pval.c b/res/ael/pval.c
index dc1678616..5865634d8 100644
--- a/res/ael/pval.c
+++ b/res/ael/pval.c
@@ -3361,38 +3361,60 @@ static void gen_prios(struct ael_extension *exten, char *label, pval *statement,
if (contains_switch(statement)) { /* only run contains_switch if you haven't checked before */
if (mother_exten) {
if (!mother_exten->has_switch) {
- switch_set = new_prio();
- switch_set->type = AEL_APPCALL;
- if (!ast_compat_app_set) {
- switch_set->app = strdup("MSet");
- } else {
- switch_set->app = strdup("Set");
- }
- switch_set->appargs = strdup("~~EXTEN~~=${EXTEN}");
- linkprio(exten, switch_set, mother_exten);
- mother_exten->has_switch = 1;
- mother_exten->checked_switch = 1;
- if (exten) {
- exten->has_switch = 1;
- exten->checked_switch = 1;
+ for (first = 1; first >= 0; first--) {
+ switch_set = new_prio();
+ switch_set->type = AEL_APPCALL;
+ if (!ast_compat_app_set) {
+ switch_set->app = strdup("MSet");
+ } else {
+ switch_set->app = strdup("Set");
+ }
+ /* Are we likely inside a gosub subroutine? */
+ if (!strcmp(mother_exten->name, "s") && first) {
+ /* If we're not actually within a gosub, this will fail, but the
+ * second time through, it will get set. If we are within gosub,
+ * the second time through is redundant, but acceptable. */
+ switch_set->appargs = strdup("LOCAL(~~EXTEN~~)=${EXTEN}");
+ } else {
+ switch_set->appargs = strdup("~~EXTEN~~=${EXTEN}");
+ first = 0;
+ }
+ linkprio(exten, switch_set, mother_exten);
+ mother_exten->has_switch = 1;
+ mother_exten->checked_switch = 1;
+ if (exten) {
+ exten->has_switch = 1;
+ exten->checked_switch = 1;
+ }
}
}
} else if (exten) {
if (!exten->has_switch) {
- switch_set = new_prio();
- switch_set->type = AEL_APPCALL;
- if (!ast_compat_app_set) {
- switch_set->app = strdup("MSet");
- } else {
- switch_set->app = strdup("Set");
- }
- switch_set->appargs = strdup("~~EXTEN~~=${EXTEN}");
- linkprio(exten, switch_set, mother_exten);
- exten->has_switch = 1;
- exten->checked_switch = 1;
- if (mother_exten) {
- mother_exten->has_switch = 1;
- mother_exten->checked_switch = 1;
+ for (first = 1; first >= 0; first--) {
+ switch_set = new_prio();
+ switch_set->type = AEL_APPCALL;
+ if (!ast_compat_app_set) {
+ switch_set->app = strdup("MSet");
+ } else {
+ switch_set->app = strdup("Set");
+ }
+ /* Are we likely inside a gosub subroutine? */
+ if (!strcmp(exten->name, "s")) {
+ /* If we're not actually within a gosub, this will fail, but the
+ * second time through, it will get set. If we are within gosub,
+ * the second time through is redundant, but acceptable. */
+ switch_set->appargs = strdup("LOCAL(~~EXTEN~~)=${EXTEN}");
+ } else {
+ switch_set->appargs = strdup("~~EXTEN~~=${EXTEN}");
+ first = 0;
+ }
+ linkprio(exten, switch_set, mother_exten);
+ exten->has_switch = 1;
+ exten->checked_switch = 1;
+ if (mother_exten) {
+ mother_exten->has_switch = 1;
+ mother_exten->checked_switch = 1;
+ }
}
}
}