diff --git a/src/include/switch_channel.h b/src/include/switch_channel.h index d566434457..6b9d0e1697 100644 --- a/src/include/switch_channel.h +++ b/src/include/switch_channel.h @@ -273,6 +273,7 @@ SWITCH_DECLARE(const char *) switch_channel_get_hold_music_partner(switch_channe SWITCH_DECLARE(uint32_t) switch_channel_del_variable_prefix(switch_channel_t *channel, const char *prefix); +#define switch_channel_set_variable_safe(_channel, _var, _val) switch_channel_set_variable_var_check(_channel, _var, _val, SWITCH_FALSE) #define switch_channel_set_variable(_channel, _var, _val) switch_channel_set_variable_var_check(_channel, _var, _val, SWITCH_TRUE) #define switch_channel_set_variable_partner(_channel, _var, _val) switch_channel_set_variable_partner_var_check(_channel, _var, _val, SWITCH_TRUE) diff --git a/src/switch_channel.c b/src/switch_channel.c index b15b0948a7..0380f422db 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -3350,7 +3350,7 @@ SWITCH_DECLARE(char *) switch_channel_expand_variables_check(switch_channel_t *c char *p, *c = NULL; char *data, *indup, *endof_indup; size_t sp = 0, len = 0, olen = 0, vtype = 0, br = 0, cpos, block = 128; - char *cloned_sub_val = NULL, *sub_val = NULL; + char *cloned_sub_val = NULL, *sub_val = NULL, *expanded_sub_val = NULL; char *func_val = NULL, *sb = NULL; int nv = 0; @@ -3482,7 +3482,7 @@ SWITCH_DECLARE(char *) switch_channel_expand_variables_check(switch_channel_t *c int ooffset = 0; char *ptr; int idx = -1; - + if ((expanded = switch_channel_expand_variables_check(channel, (char *) vname, var_list, api_list)) == vname) { expanded = NULL; } else { @@ -3508,6 +3508,12 @@ SWITCH_DECLARE(char *) switch_channel_expand_variables_check(switch_channel_t *c sub_val = "INVALID"; } + if ((expanded_sub_val = switch_channel_expand_variables(channel, sub_val)) == sub_val) { + expanded_sub_val = NULL; + } else { + sub_val = expanded_sub_val; + } + if (offset || ooffset) { cloned_sub_val = strdup(sub_val); switch_assert(cloned_sub_val); @@ -3587,6 +3593,7 @@ SWITCH_DECLARE(char *) switch_channel_expand_variables_check(switch_channel_t *c switch_safe_free(func_val); switch_safe_free(cloned_sub_val); + switch_safe_free(expanded_sub_val); sub_val = NULL; vname = NULL; vtype = 0; diff --git a/src/switch_event.c b/src/switch_event.c index 25bab3185a..dc4168687e 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -1457,7 +1457,7 @@ SWITCH_DECLARE(switch_status_t) switch_event_create_brackets(char *data, char a, switch_event_t *e = *event; char *var_array[1024] = { 0 }; int var_count = 0; - char *next; + char *next = NULL, *vnext = NULL; if (dup) { vdatap = strdup(data); @@ -1479,6 +1479,7 @@ SWITCH_DECLARE(switch_status_t) switch_event_create_brackets(char *data, char a, if (check_a) end = check_a; if (end) { + next = end; vdata++; *end++ = '\0'; } else { @@ -1494,13 +1495,17 @@ SWITCH_DECLARE(switch_status_t) switch_event_create_brackets(char *data, char a, for (;;) { - if ((next = strchr(vdata, b))) { + if (next) { char *pnext; + *next++ = '\0'; if ((pnext = switch_strchr_strict(next, a, " "))) { next = pnext + 1; } + + vnext = switch_find_end_paren(next, a, b); + next = NULL; } @@ -1519,14 +1524,14 @@ SWITCH_DECLARE(switch_status_t) switch_event_create_brackets(char *data, char a, if ((inner_var_count = switch_separate_string(var_array[x], '=', inner_var_array, (sizeof(inner_var_array) / sizeof(inner_var_array[0])))) == 2) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Parsing variable [%s]=[%s]\n", inner_var_array[0], inner_var_array[1]); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Parsing variable [%s]=[%s]\n", inner_var_array[0], inner_var_array[1]); switch_event_add_header_string(e, SWITCH_STACK_BOTTOM, inner_var_array[0], inner_var_array[1]); } } } - if (next) { - vdata = next; + if (vnext) { + vdata = vnext; } else { break; } @@ -1993,7 +1998,7 @@ SWITCH_DECLARE(char *) switch_event_expand_headers_check(switch_event_t *event, char *data, *indup, *endof_indup; size_t sp = 0, len = 0, olen = 0, vtype = 0, br = 0, cpos, block = 128; const char *sub_val = NULL; - char *cloned_sub_val = NULL; + char *cloned_sub_val = NULL, *expanded_sub_val = NULL; char *func_val = NULL; int nv = 0; char *gvar = NULL, *sb = NULL; @@ -2156,23 +2161,30 @@ SWITCH_DECLARE(char *) switch_event_expand_headers_check(switch_event_t *event, sub_val = "INVALID"; } - } - if (offset || ooffset) { - cloned_sub_val = strdup(sub_val); - switch_assert(cloned_sub_val); - sub_val = cloned_sub_val; - } + if ((expanded_sub_val = switch_event_expand_headers(event, sub_val)) == sub_val) { + expanded_sub_val = NULL; + } else { + sub_val = expanded_sub_val; + } + - if (offset >= 0) { - sub_val += offset; - } else if ((size_t) abs(offset) <= strlen(sub_val)) { - sub_val = cloned_sub_val + (strlen(cloned_sub_val) + offset); - } + if (offset || ooffset) { + cloned_sub_val = strdup(sub_val); + switch_assert(cloned_sub_val); + sub_val = cloned_sub_val; + } + + if (offset >= 0) { + sub_val += offset; + } else if ((size_t) abs(offset) <= strlen(sub_val)) { + sub_val = cloned_sub_val + (strlen(cloned_sub_val) + offset); + } - if (ooffset > 0 && (size_t) ooffset < strlen(sub_val)) { - if ((ptr = (char *) sub_val + ooffset)) { - *ptr = '\0'; + if (ooffset > 0 && (size_t) ooffset < strlen(sub_val)) { + if ((ptr = (char *) sub_val + ooffset)) { + *ptr = '\0'; + } } } @@ -2232,6 +2244,7 @@ SWITCH_DECLARE(char *) switch_event_expand_headers_check(switch_event_t *event, switch_safe_free(func_val); switch_safe_free(cloned_sub_val); + switch_safe_free(expanded_sub_val); sub_val = NULL; vname = NULL; vtype = 0; diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 1528f6a9d5..825de90d32 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -122,6 +122,7 @@ typedef struct { int bridge_early_media; switch_thread_t *ethread; switch_caller_profile_t *caller_profile_override; + switch_bool_t check_vars; switch_memory_pool_t *pool; } originate_global_t; @@ -1764,6 +1765,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess caller_profile_override, ovars, flags, cancel_cause); } + oglobals.check_vars = SWITCH_TRUE; oglobals.ringback_ok = 1; oglobals.bridge_early_media = -1; oglobals.file = NULL; @@ -1882,6 +1884,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess data++; } + if ((ovars && switch_true(switch_event_get_header(ovars,"origination_nested_vars"))) || + (caller_channel && switch_true(switch_channel_get_variable(caller_channel, "origination_nested_vars"))) + || switch_true(switch_core_get_variable("origination_nested_vars")) || switch_stristr("origination_nested_vars=true", data)) { + oglobals.check_vars = SWITCH_FALSE; + } + /* extract channel variables, allowing multiple sets of braces */ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Parsing global variables\n"); while (*data == '{') { @@ -2510,7 +2518,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess switch_event_header_t *header; /* install the vars from the {} params */ for (header = var_event->headers; header; header = header->next) { - switch_channel_set_variable(originate_status[i].peer_channel, header->name, header->value); + switch_channel_set_variable_var_check(originate_status[i].peer_channel, header->name, header->value, oglobals.check_vars); } } } @@ -2519,7 +2527,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess if (local_var_event) { switch_event_header_t *header; for (header = local_var_event->headers; header; header = header->next) { - switch_channel_set_variable(originate_status[i].peer_channel, header->name, header->value); + switch_channel_set_variable_var_check(originate_status[i].peer_channel, header->name, header->value, oglobals.check_vars); } switch_event_destroy(&local_var_event); } @@ -2529,7 +2537,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess switch_event_header_t *header; /* install the vars from the {} params */ for (header = var_event->headers; header; header = header->next) { - switch_channel_set_variable(originate_status[i].peer_channel, header->name, header->value); + switch_channel_set_variable_var_check(originate_status[i].peer_channel, header->name, header->value, oglobals.check_vars); } } }