On Fri, 14 Dec 2012, david at tethera.net wrote: > From: David Bremner <bremner at debian.org> > > The query is split into tokens, with ' ' and ':' as delimiters. Any > token containing some hex-escaped character is quoted according to > Xapian rules. This maps id:foo%20%22bar to id:"foo ""bar". > This intentionally does not quote prefixes, so they still work as prefixes. > --- > tag-util.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 50 insertions(+) > > diff --git a/tag-util.c b/tag-util.c > index f89669a..e1181f8 100644 > --- a/tag-util.c > +++ b/tag-util.c > @@ -56,6 +56,56 @@ illegal_tag (const char *tag, notmuch_bool_t remove) > return NULL; > } > > +static tag_parse_status_t > +quote_and_decode_query (void *ctx, char *encoded, const char *line_for_error, > + char **query_string) > +{ > + char *tok = encoded; > + size_t tok_len = 0; > + char *buf = NULL; > + size_t buf_len = 0; > + tag_parse_status_t ret = TAG_PARSE_SUCCESS; > + > + *query_string = talloc_strdup (ctx, ""); > + > + while (*query_string && > + (tok = strtok_len (tok + tok_len, ": ", &tok_len)) != NULL) {
strtok_len() will eat all the leading delimiters at each call, and will not return a zero-length token if you have multiple consecutive delimiters. Which means you may end up losing stuff here. Whether that matters or not I'm too tired to tell... BR, Jani. > + char delim = tok[tok_len]; > + > + *(tok + tok_len++) = '\0'; > + > + if (strcspn (tok, "%") < tok_len - 1) { > + /* something to decode */ > + if (hex_decode_inplace (tok) != HEX_SUCCESS) { > + ret = line_error (TAG_PARSE_INVALID, line_for_error, > + "hex decoding of token '%s' failed", tok); > + goto DONE; > + } > + > + if (double_quote_str (ctx, tok, &buf, &buf_len)) { > + ret = line_error (TAG_PARSE_OUT_OF_MEMORY, > + line_for_error, "aborting"); > + goto DONE; > + } > + *query_string = talloc_asprintf_append_buffer ( > + *query_string, "%s%c", buf, delim); > + > + } else { > + /* This is not just an optimization, but used to preserve > + * prefixes like id:, which cannot be quoted. > + */ > + *query_string = talloc_asprintf_append_buffer ( > + *query_string, "%s%c", tok, delim); > + } > + > + } > + > + DONE: > + if (ret != TAG_PARSE_SUCCESS && *query_string) > + talloc_free (*query_string); > + return ret; > +} > + > tag_parse_status_t > parse_tag_line (void *ctx, char *line, > tag_op_flag_t flags, > -- > 1.7.10.4 > > _______________________________________________ > notmuch mailing list > notmuch at notmuchmail.org > http://notmuchmail.org/mailman/listinfo/notmuch