core_local: Fix local channel parsing with slashes.

Currently, trying to call a Local channel with a slash
in the extension will fail due to the parsing of characters
after such a slash as being dial modifiers. Additionally,
core_local is inconsistent and incomplete with
its parsing of Local dial strings in that sometimes it
uses the first slash and at other times it uses the last.

For instance, something like DAHDI/5 or PJSIP/device
is a perfectly usable extension in the dialplan, but Local
channels in particular prevent these from being called.

This creates inconsistent behavior for users, since using
a slash in an extension is perfectly acceptable, and using
a Goto to accomplish this works fine, but if specified
through a Local channel, the parsing prevents this.

This fixes this by explicitly parsing options from the
last slash in the extension, rather than the first one,
which doesn't cause an issue for extensions with slashes.

ASTERISK-30013 #close

Resolves: #248
This commit is contained in:
Naveen Albert 2023-08-09 22:57:41 +00:00 committed by asterisk-org-access-app[bot]
parent fcb9feddfd
commit 82086545cc
1 changed files with 13 additions and 8 deletions

View File

@ -315,12 +315,6 @@ static int local_devicestate(const char *data)
struct local_pvt *lp;
struct ao2_iterator it;
/* Strip options if they exist */
opts = strchr(exten, '/');
if (opts) {
*opts = '\0';
}
context = strchr(exten, '@');
if (!context) {
ast_log(LOG_WARNING,
@ -329,6 +323,16 @@ static int local_devicestate(const char *data)
}
*context++ = '\0';
/* Strip options if they exist.
* However, don't strip '/' before an '@' (exten could contain slashes).
* So only start looking for '/' in context, because options would be past
* this point if they exist, but anything before would be a '/' in the exten,
* not options. */
opts = strchr(context, '/');
if (opts) {
*opts = '\0';
}
it = ao2_iterator_init(locals, 0);
for (; (lp = ao2_iterator_next(&it)); ao2_ref(lp, -1)) {
ao2_lock(lp);
@ -884,8 +888,9 @@ static struct local_pvt *local_alloc(const char *data, struct ast_stream_topolog
*/
ast_set_flag(&pvt->base, AST_UNREAL_MOH_INTERCEPT);
/* Look for options */
if ((opts = strchr(parse, '/'))) {
/* Look for options.
* Slashes can appear in channel names, so options are after the last match. */
if ((opts = strrchr(parse, '/'))) {
*opts++ = '\0';
if (strchr(opts, 'n')) {
ast_set_flag(&pvt->base, AST_UNREAL_NO_OPTIMIZATION);