[asterisk-commits] rizzo: branch 1.4 r44650 - /branches/1.4/channels/chan_sip.c

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Sat Oct 7 02:36:02 MST 2006


Author: rizzo
Date: Sat Oct  7 04:36:00 2006
New Revision: 44650

URL: http://svn.digium.com/view/asterisk?rev=44650&view=rev
Log:
improve and document function get_in_brackets(), introducing
a helper function find_closing_quote() of more general use.


Modified:
    branches/1.4/channels/chan_sip.c

Modified: branches/1.4/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/channels/chan_sip.c?rev=44650&r1=44649&r2=44650&view=diff
==============================================================================
--- branches/1.4/channels/chan_sip.c (original)
+++ branches/1.4/channels/chan_sip.c Sat Oct  7 04:36:00 2006
@@ -2142,47 +2142,65 @@
 	return res;
 }
 
+/*! \brief Locate closing quote in a string, skipping escaped quotes.
+ * optionally with a limit on the search.
+ * start must be past the first quote.
+ */
+static const char *find_closing_quote(const char *start, const char *lim)
+{
+        char last_char = '\0';
+        const char *s;
+        for (s = start; *s && s != lim; last_char = *s++) {
+                if (*s == '"' && last_char != '\\')
+                        break;
+        }
+        return s;
+}
+
 /*! \brief Pick out text in brackets from character string
 	\return pointer to terminated stripped string
-	\param tmp input string that will be modified */
+	\param tmp input string that will be modified
+	Examples:
+
+	"foo" <bar>	valid input, returns bar
+	foo		returns the whole string
+	< "foo ... >	returns the string between brackets
+	< "foo...	bogus (missing closing bracket), returns the whole string
+			XXX maybe should still skip the opening bracket
+ */
 static char *get_in_brackets(char *tmp)
 {
-	char *parse;
-	char *first_quote;
+	const char *parse = tmp;
 	char *first_bracket;
-	char *second_bracket;
-	char last_char;
-
-	parse = tmp;
-	for (;;) {
-		first_quote = strchr(parse, '"');
-		first_bracket = strchr(parse, '<');
-		if (first_quote && first_bracket && (first_quote < first_bracket)) {
-			last_char = '\0';
-			for (parse = first_quote + 1; *parse; parse++) {
-				if ((*parse == '"') && (last_char != '\\'))
-					break;
-				last_char = *parse;
-			}
-			if (!*parse) {
-				ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp);
-				return tmp;
-			}
-			parse++;
-			continue;
-		}
-		if (first_bracket) {
-			second_bracket = strchr(first_bracket + 1, '>');
-			if (second_bracket) {
-				*second_bracket = '\0';
-				return first_bracket + 1;
-			} else {
-				ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp);
-				return tmp;
-			}
-		}
-		return tmp;
-	}
+
+	/*
+	 * Skip any quoted text until we find the part in brackets.
+         * On any error give up and return the full string.
+         */
+        while ( (first_bracket = strchr(parse, '<')) ) {
+                char *first_quote = strchr(parse, '"');
+
+		if (!first_quote || first_quote > first_bracket)
+			break; /* no need to look at quoted part */
+		/* the bracket is within quotes, so ignore it */
+		parse = find_closing_quote(first_quote + 1, NULL);
+		if (!*parse) { /* not found, return full string ? */
+			/* XXX or be robust and return in-bracket part ? */
+			ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp);
+			break;
+		}
+		parse++;
+	}
+	if (first_bracket) {
+		char *second_bracket = strchr(first_bracket + 1, '>');
+		if (second_bracket) {
+			*second_bracket = '\0';
+			tmp = first_bracket + 1;
+		} else {
+			ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp);
+		}
+	}
+	return tmp;
 }
 
 /*! \brief Send SIP MESSAGE text within a call



More information about the asterisk-commits mailing list