From: Tilghman Lesher Date: Thu, 15 Apr 2010 21:23:24 +0000 (+0000) Subject: Allow application options with arguments to contain parentheses, through a variety... X-Git-Tag: 1.4.32-rc1~36 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2b74f9be7b732bebe48708bb0e69376f8751687e;p=thirdparty%2Fasterisk.git Allow application options with arguments to contain parentheses, through a variety of escaping techniques. Fixes SWP-1194 (ABE-2143). Review: https://reviewboard.asterisk.org/r/604/ git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@257544 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- diff --git a/include/asterisk/app.h b/include/asterisk/app.h index e23b3b4771..ff6a7254ac 100644 --- a/include/asterisk/app.h +++ b/include/asterisk/app.h @@ -370,7 +370,7 @@ struct ast_app_option { ... do any argument parsing here ... - if (ast_parseoptions(my_app_options, &opts, opt_args, options)) { + if (ast_app_parse_options(my_app_options, &opts, opt_args, options)) { LOCAL_USER_REMOVE(u); return -1; } diff --git a/main/app.c b/main/app.c index 2beee00a36..abf0529009 100644 --- a/main/app.c +++ b/main/app.c @@ -1438,8 +1438,40 @@ int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags curarg = *s++ & 0x7f; /* the array (in app.h) has 128 entries */ argloc = options[curarg].arg_index; if (*s == '(') { + int paren = 1, quote = 0; + int parsequotes = (s[1] == '"') ? 1 : 0; + /* Has argument */ arg = ++s; + for (; *s; s++) { + if (*s == '(' && !quote) { + paren++; + } else if (*s == ')' && !quote) { + /* Count parentheses, unless they're within quotes (or backslashed, below) */ + paren--; + } else if (*s == '"' && parsequotes) { + /* Leave embedded quotes alone, unless they are the first character */ + quote = quote ? 0 : 1; + ast_copy_string(s, s + 1, INT_MAX); + s--; + } else if (*s == '\\') { + if (!quote) { + /* If a backslash is found outside of quotes, remove it */ + ast_copy_string(s, s + 1, INT_MAX); + } else if (quote && s[1] == '"') { + /* Backslash for a quote character within quotes, remove the backslash */ + ast_copy_string(s, s + 1, INT_MAX); + } else { + /* Backslash within quotes, keep both characters */ + s++; + } + } + + if (paren == 0) { + break; + } + } + /* This will find the closing paren we found above, or none, if the string ended before we found one. */ if ((s = strchr(s, ')'))) { if (argloc) args[argloc - 1] = arg;