improve and document function get_in_brackets(), introducing
authorLuigi Rizzo <rizzo@icir.org>
Sat, 7 Oct 2006 09:36:09 +0000 (09:36 +0000)
committerLuigi Rizzo <rizzo@icir.org>
Sat, 7 Oct 2006 09:36:09 +0000 (09:36 +0000)
a helper function find_closing_quote() of more general use.

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

channels/chan_sip.c

index f013d74..d52221f 100644 (file)
@@ -2138,47 +2138,65 @@ static int send_request(struct sip_pvt *p, struct sip_request *req, enum xmittyp
        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;
+       /*
+        * 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;
                }
-               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;
-                       }
+               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;
        }
+       return tmp;
 }
 
 /*! \brief Send SIP MESSAGE text within a call