[asterisk-commits] tilghman: branch 1.6.1 r257594 - in /branches/1.6.1: ./ include/asterisk/ main/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Apr 15 16:33:25 CDT 2010


Author: tilghman
Date: Thu Apr 15 16:33:23 2010
New Revision: 257594

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=257594
Log:
Merged revisions 257560 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/trunk

................
  r257560 | tilghman | 2010-04-15 16:26:19 -0500 (Thu, 15 Apr 2010) | 13 lines
  
  Merged revisions 257544 via svnmerge from 
  https://origsvn.digium.com/svn/asterisk/branches/1.4
  
  ........
    r257544 | tilghman | 2010-04-15 16:23:24 -0500 (Thu, 15 Apr 2010) | 6 lines
    
    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/
  ........
................

Modified:
    branches/1.6.1/   (props changed)
    branches/1.6.1/include/asterisk/app.h
    branches/1.6.1/main/app.c

Propchange: branches/1.6.1/
------------------------------------------------------------------------------
Binary property 'trunk-merged' - no diff available.

Modified: branches/1.6.1/include/asterisk/app.h
URL: http://svnview.digium.com/svn/asterisk/branches/1.6.1/include/asterisk/app.h?view=diff&rev=257594&r1=257593&r2=257594
==============================================================================
--- branches/1.6.1/include/asterisk/app.h (original)
+++ branches/1.6.1/include/asterisk/app.h Thu Apr 15 16:33:23 2010
@@ -481,8 +481,7 @@
 
   	... do any argument parsing here ...
 
-	if (ast_parseoptions(my_app_options, &opts, opt_args, options)) {
-		ast_module_user_remove(u);
+	if (ast_app_parse_options(my_app_options, &opts, opt_args, options)) {
 		return -1;
 	}
   }

Modified: branches/1.6.1/main/app.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.6.1/main/app.c?view=diff&rev=257594&r1=257593&r2=257594
==============================================================================
--- branches/1.6.1/main/app.c (original)
+++ branches/1.6.1/main/app.c Thu Apr 15 16:33:23 2010
@@ -1691,13 +1691,19 @@
 	return output;
 }
 
-int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
+static int parse_options(const struct ast_app_option *options, void *_flags, char **args, char *optstr, int flaglen)
 {
 	char *s, *arg;
 	int curarg, res = 0;
 	unsigned int argloc;
-
-	ast_clear_flag(flags, AST_FLAGS_ALL);
+	struct ast_flags *flags = _flags;
+	struct ast_flags64 *flags64 = _flags;
+
+	if (flaglen == 32) {
+		ast_clear_flag(flags, AST_FLAGS_ALL);
+	} else {
+		flags64->flags = 0;
+	}
 
 	if (!optstr)
 		return 0;
@@ -1707,8 +1713,40 @@
 		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;
@@ -1721,50 +1759,24 @@
 		} else if (argloc) {
 			args[argloc - 1] = "";
 		}
-		ast_set_flag(flags, options[curarg].flag);
+		if (flaglen == 32) {
+			ast_set_flag(flags, options[curarg].flag);
+		} else {
+			ast_set_flag64(flags64, options[curarg].flag);
+		}
 	}
 
 	return res;
 }
 
-/* the following function will probably only be used in app_dial, until app_dial is reorganized to
-   better handle the large number of options it provides. After it is, you need to get rid of this variant 
-   -- unless, of course, someone else digs up some use for large flag fields. */
+int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
+{
+	return parse_options(options, flags, args, optstr, 32);
+}
 
 int ast_app_parse_options64(const struct ast_app_option *options, struct ast_flags64 *flags, char **args, char *optstr)
 {
-	char *s, *arg;
-	int curarg, res = 0;
-	unsigned int argloc;
-
-	flags->flags = 0;
-	
-	if (!optstr)
-		return 0;
-
-	s = optstr;
-	while (*s) {
-		curarg = *s++ & 0x7f;	/* the array (in app.h) has 128 entries */
-		ast_set_flag64(flags, options[curarg].flag);
-		argloc = options[curarg].arg_index;
-		if (*s == '(') {
-			/* Has argument */
-			arg = ++s;
-			if ((s = strchr(s, ')'))) {
-				if (argloc)
-					args[argloc - 1] = arg;
-				*s++ = '\0';
-			} else {
-				ast_log(LOG_WARNING, "Missing closing parenthesis for argument '%c' in string '%s'\n", curarg, arg);
-				res = -1;
-				break;
-			}
-		} else if (argloc) {
-			args[argloc - 1] = NULL;
-		}
-	}
-
-	return res;
+	return parse_options(options, flags, args, optstr, 64);
 }
 
 void ast_app_options2str64(const struct ast_app_option *options, struct ast_flags64 *flags, char *buf, size_t len)




More information about the asterisk-commits mailing list