Mercurial > dovecot > core-2.2
changeset 15245:42f99a4fc763
lib-imap: Changed public IS_ATOM*() macros to match RFC 3501 exactly.
Move the imap-parser specific "atom plus some more" parsing macro inside
imap-parser.c so it's not used by anyone else.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 24 Oct 2012 10:05:37 +0300 |
parents | ff86acd4eef5 |
children | d9c44aafd163 |
files | src/lib-imap/imap-arg.h src/lib-imap/imap-parser.c src/lib-storage/mailbox-keywords.c |
diffstat | 3 files changed, 40 insertions(+), 18 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-imap/imap-arg.h Wed Oct 24 09:39:52 2012 +0300 +++ b/src/lib-imap/imap-arg.h Wed Oct 24 10:05:37 2012 +0300 @@ -3,19 +3,32 @@ #include "array.h" -/* We use this macro to read atoms from input. It should probably contain - everything some day, but for now we can't handle some input otherwise: +/* ABNF: + + CHAR = %x01-7F + CTL = %x00-1F / %x7F + SP = %x20 + DQUOTE = %x22 */ - ']' is required for parsing section (FETCH BODY[]) - '%', '*' and ']' are valid list-chars for LIST patterns - '\' is used in flags */ -#define IS_ATOM_SPECIAL_INPUT(c) \ - ((c) == '(' || (c) == ')' || (c) == '{' || \ - (c) == '"' || (c) <= 32 || (c) == 0x7f) +/* ASTRING-CHAR = ATOM-CHAR / resp-specials */ +#define IS_ASTRING_CHAR(c) (IS_ATOM_CHAR(c) || IS_RESP_SPECIAL(c)) +/* ATOM-CHAR = <any CHAR except atom-specials> */ +#define IS_ATOM_CHAR(c) (!IS_ATOM_SPECIAL(c)) +/* atom-specials = "(" / ")" / "{" / SP / CTL / list-wildcards / + quoted-specials / resp-specials + Since atoms are only 7bit, we'll also optimize a bit by assuming 8bit chars + are also atom-specials. */ +#define IS_ATOM_SPECIAL(c) \ + ((unsigned char)(c) <= 0x20 || (unsigned char)(c) >= 0x7f || \ + (c) == '(' || (c) == ')' || (c) == '{' || IS_LIST_WILDCARD(c) || \ + IS_QUOTED_SPECIAL(c) || IS_RESP_SPECIAL(c)) -#define IS_ATOM_SPECIAL(c) \ - (IS_ATOM_SPECIAL_INPUT(c) || \ - (c) == ']' || (c) == '%' || (c) == '*' || (c) == '\\') +/* list-wildcards = "%" / "*" */ +#define IS_LIST_WILDCARD(c) ((c) == '%' || (c) == '*') +/* quoted-specials = DQUOTE / "\" */ +#define IS_QUOTED_SPECIAL(c) ((c) == '\"' || (c) == '\\') +/* resp-specials = "]" */ +#define IS_RESP_SPECIAL(c) ((c) == ']') enum imap_arg_type { IMAP_ARG_NIL = 0,
--- a/src/lib-imap/imap-parser.c Wed Oct 24 09:39:52 2012 +0300 +++ b/src/lib-imap/imap-parser.c Wed Oct 24 10:05:37 2012 +0300 @@ -6,6 +6,16 @@ #include "strescape.h" #include "imap-parser.h" +/* We use this macro to read atoms from input. It should probably contain + everything some day, but for now we can't handle some input otherwise: + + ']' is required for parsing section (FETCH BODY[]) + '%', '*' and ']' are valid list-chars for LIST patterns + '\' is used in flags */ +#define IS_ATOM_PARSER_INPUT(c) \ + ((c) == '(' || (c) == ')' || (c) == '{' || \ + (c) == '"' || (c) <= 32 || (c) == 0x7f) + #define is_linebreak(c) \ ((c) == '\r' || (c) == '\n') @@ -280,7 +290,7 @@ { const char *error; - if (IS_ATOM_SPECIAL_INPUT((unsigned char)chr)) + if (IS_ATOM_PARSER_INPUT((unsigned char)chr)) error = "Invalid characters in atom"; else if ((chr & 0x80) != 0) error = "8bit data in atom";
--- a/src/lib-storage/mailbox-keywords.c Wed Oct 24 09:39:52 2012 +0300 +++ b/src/lib-storage/mailbox-keywords.c Wed Oct 24 10:05:37 2012 +0300 @@ -117,12 +117,11 @@ /* these are IMAP-specific restrictions, but for now IMAP is all we care about */ for (i = 0; keyword[i] != '\0'; i++) { - if (IS_ATOM_SPECIAL((unsigned char)keyword[i])) { - *error_r = "Invalid characters in keyword"; - return FALSE; - } - if ((unsigned char)keyword[i] >= 0x80) { - *error_r = "8bit characters in keyword"; + if (!IS_ATOM_CHAR(keyword[i])) { + if ((unsigned char)keyword[i] < 0x80) + *error_r = "Invalid characters in keyword"; + else + *error_r = "8bit characters in keyword"; return FALSE; } }