summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuigi Rizzo <rizzo@icir.org>2006-10-07 09:36:09 +0000
committerLuigi Rizzo <rizzo@icir.org>2006-10-07 09:36:09 +0000
commite691246b6eac8860b3734a9f99d0282bb2e7d879 (patch)
tree70eedd97a36f84a908968472a3869d9c34820e86
parent6466c2ebf903662b09ef916658da432da0b233ff (diff)
improve and document function get_in_brackets(), introducing
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
-rw-r--r--channels/chan_sip.c82
1 files changed, 50 insertions, 32 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index f013d7406..d52221f0e 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -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