Allow Gosub to recognize quote delimiters without consuming them.
authorTilghman Lesher <tilghman@meg.abyt.es>
Thu, 6 Aug 2009 21:29:26 +0000 (21:29 +0000)
committerTilghman Lesher <tilghman@meg.abyt.es>
Thu, 6 Aug 2009 21:29:26 +0000 (21:29 +0000)
(closes issue #15557)
 Reported by: rain
 Patches:
       20090723__issue15557.diff.txt uploaded by tilghman (license 14)
 Tested by: rain

Review: https://reviewboard.asterisk.org/r/316/

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

apps/app_stack.c
include/asterisk/app.h
main/app.c

index 84be40b..1a25231 100644 (file)
@@ -380,7 +380,7 @@ static int gosub_exec(struct ast_channel *chan, const char *data)
                        *endparen = '\0';
                else
                        ast_log(LOG_WARNING, "Ouch.  No closing paren: '%s'?\n", (char *)data);
                        *endparen = '\0';
                else
                        ast_log(LOG_WARNING, "Ouch.  No closing paren: '%s'?\n", (char *)data);
-               AST_STANDARD_APP_ARGS(args2, tmp);
+               AST_STANDARD_RAW_ARGS(args2, tmp);
        } else
                args2.argc = 0;
 
        } else
                args2.argc = 0;
 
@@ -444,13 +444,13 @@ static int gosubif_exec(struct ast_channel *chan, const char *data)
        }
 
        args = ast_strdupa(data);
        }
 
        args = ast_strdupa(data);
-       AST_NONSTANDARD_APP_ARGS(cond, args, '?');
+       AST_NONSTANDARD_RAW_ARGS(cond, args, '?');
        if (cond.argc != 2) {
                ast_log(LOG_WARNING, "GosubIf requires an argument: GosubIf(cond?label1(args):label2(args)\n");
                return 0;
        }
 
        if (cond.argc != 2) {
                ast_log(LOG_WARNING, "GosubIf requires an argument: GosubIf(cond?label1(args):label2(args)\n");
                return 0;
        }
 
-       AST_NONSTANDARD_APP_ARGS(label, cond.labels, ':');
+       AST_NONSTANDARD_RAW_ARGS(label, cond.labels, ':');
 
        if (pbx_checkcondition(cond.ition)) {
                if (!ast_strlen_zero(label.iftrue))
 
        if (pbx_checkcondition(cond.ition)) {
                if (!ast_strlen_zero(label.iftrue))
@@ -532,7 +532,7 @@ static int peek_read(struct ast_channel *chan, const char *cmd, char *data, char
                return -1;
        }
 
                return -1;
        }
 
-       AST_STANDARD_APP_ARGS(args, data);
+       AST_STANDARD_RAW_ARGS(args, data);
        n = atoi(args.n);
        *buf = '\0';
 
        n = atoi(args.n);
        *buf = '\0';
 
index 3bf7800..6d73b77 100644 (file)
@@ -380,7 +380,9 @@ int ast_app_group_list_unlock(void);
   the argc argument counter field.
  */
 #define AST_STANDARD_APP_ARGS(args, parse) \
   the argc argument counter field.
  */
 #define AST_STANDARD_APP_ARGS(args, parse) \
-       args.argc = ast_app_separate_args(parse, ',', args.argv, ((sizeof(args) - offsetof(typeof(args), argv)) / sizeof(args.argv[0])))
+       args.argc = __ast_app_separate_args(parse, ',', 1, args.argv, ((sizeof(args) - offsetof(typeof(args), argv)) / sizeof(args.argv[0])))
+#define AST_STANDARD_RAW_ARGS(args, parse) \
+       args.argc = __ast_app_separate_args(parse, ',', 0, args.argv, ((sizeof(args) - offsetof(typeof(args), argv)) / sizeof(args.argv[0])))
 
 /*!
   \brief Performs the 'nonstandard' argument separation process for an application.
 
 /*!
   \brief Performs the 'nonstandard' argument separation process for an application.
@@ -393,12 +395,15 @@ int ast_app_group_list_unlock(void);
   the argc argument counter field.
  */
 #define AST_NONSTANDARD_APP_ARGS(args, parse, sep) \
   the argc argument counter field.
  */
 #define AST_NONSTANDARD_APP_ARGS(args, parse, sep) \
-       args.argc = ast_app_separate_args(parse, sep, args.argv, ((sizeof(args) - offsetof(typeof(args), argv)) / sizeof(args.argv[0])))
+       args.argc = __ast_app_separate_args(parse, sep, 1, args.argv, ((sizeof(args) - offsetof(typeof(args), argv)) / sizeof(args.argv[0])))
+#define AST_NONSTANDARD_RAW_ARGS(args, parse, sep) \
+       args.argc = __ast_app_separate_args(parse, sep, 0, args.argv, ((sizeof(args) - offsetof(typeof(args), argv)) / sizeof(args.argv[0])))
 
 /*!
   \brief Separate a string into arguments in an array
   \param buf The string to be parsed (this must be a writable copy, as it will be modified)
   \param delim The character to be used to delimit arguments
 
 /*!
   \brief Separate a string into arguments in an array
   \param buf The string to be parsed (this must be a writable copy, as it will be modified)
   \param delim The character to be used to delimit arguments
+  \param remove_chars Remove backslashes and quote characters, while parsing
   \param array An array of 'char *' to be filled in with pointers to the found arguments
   \param arraylen The number of elements in the array (i.e. the number of arguments you will accept)
 
   \param array An array of 'char *' to be filled in with pointers to the found arguments
   \param arraylen The number of elements in the array (i.e. the number of arguments you will accept)
 
@@ -409,7 +414,8 @@ int ast_app_group_list_unlock(void);
 
   \return The number of arguments found, or zero if the function arguments are not valid.
 */
 
   \return The number of arguments found, or zero if the function arguments are not valid.
 */
-unsigned int ast_app_separate_args(char *buf, char delim, char **array, int arraylen);
+unsigned int __ast_app_separate_args(char *buf, char delim, int remove_chars, char **array, int arraylen);
+#define ast_app_separate_args(a,b,c,d) __ast_app_separate_args(a,b,1,c,d)
 
 /*!
   \brief A structure to hold the description of an application 'option'.
 
 /*!
   \brief A structure to hold the description of an application 'option'.
index f1357de..f868858 100644 (file)
@@ -1174,7 +1174,10 @@ int ast_app_group_list_unlock(void)
        return AST_RWLIST_UNLOCK(&groups);
 }
 
        return AST_RWLIST_UNLOCK(&groups);
 }
 
-unsigned int ast_app_separate_args(char *buf, char delim, char **array, int arraylen)
+#undef ast_app_separate_args
+unsigned int ast_app_separate_args(char *buf, char delim, char **array, int arraylen);
+
+unsigned int __ast_app_separate_args(char *buf, char delim, int remove_chars, char **array, int arraylen)
 {
        int argc;
        char *scan, *wasdelim = NULL;
 {
        int argc;
        char *scan, *wasdelim = NULL;
@@ -1199,12 +1202,18 @@ unsigned int ast_app_separate_args(char *buf, char delim, char **array, int arra
                                }
                        } else if (*scan == '"' && delim != '"') {
                                quote = quote ? 0 : 1;
                                }
                        } else if (*scan == '"' && delim != '"') {
                                quote = quote ? 0 : 1;
-                               /* Remove quote character from argument */
-                               memmove(scan, scan + 1, strlen(scan));
-                               scan--;
+                               if (remove_chars) {
+                                       /* Remove quote character from argument */
+                                       memmove(scan, scan + 1, strlen(scan));
+                                       scan--;
+                               }
                        } else if (*scan == '\\') {
                        } else if (*scan == '\\') {
-                               /* Literal character, don't parse */
-                               memmove(scan, scan + 1, strlen(scan));
+                               if (remove_chars) {
+                                       /* Literal character, don't parse */
+                                       memmove(scan, scan + 1, strlen(scan));
+                               } else {
+                                       scan++;
+                               }
                        } else if ((*scan == delim) && !paren && !quote) {
                                wasdelim = scan;
                                *scan++ = '\0';
                        } else if ((*scan == delim) && !paren && !quote) {
                                wasdelim = scan;
                                *scan++ = '\0';
@@ -1222,6 +1231,12 @@ unsigned int ast_app_separate_args(char *buf, char delim, char **array, int arra
        return argc;
 }
 
        return argc;
 }
 
+/* ABI compatible function */
+unsigned int ast_app_separate_args(char *buf, char delim, char **array, int arraylen)
+{
+       return __ast_app_separate_args(buf, delim, 1, array, arraylen);
+}
+
 static enum AST_LOCK_RESULT ast_lock_path_lockfile(const char *path)
 {
        char *s;
 static enum AST_LOCK_RESULT ast_lock_path_lockfile(const char *path)
 {
        char *s;