dovecot-2.2: lib-imap: Changed public IS_ATOM*() macros to match...

dovecot at dovecot.org dovecot at dovecot.org
Wed Oct 24 10:14:29 EEST 2012


details:   http://hg.dovecot.org/dovecot-2.2/rev/42f99a4fc763
changeset: 15245:42f99a4fc763
user:      Timo Sirainen <tss at iki.fi>
date:      Wed Oct 24 10:05:37 2012 +0300
description:
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.

diffstat:

 src/lib-imap/imap-arg.h            |  33 +++++++++++++++++++++++----------
 src/lib-imap/imap-parser.c         |  12 +++++++++++-
 src/lib-storage/mailbox-keywords.c |  11 +++++------
 3 files changed, 39 insertions(+), 17 deletions(-)

diffs (96 lines):

diff -r ff86acd4eef5 -r 42f99a4fc763 src/lib-imap/imap-arg.h
--- 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:
 
-   ']' 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)
+   CHAR           =  %x01-7F
+   CTL            =  %x00-1F / %x7F
+   SP             =  %x20
+   DQUOTE         =  %x22 */
 
+/* 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) \
-	(IS_ATOM_SPECIAL_INPUT(c) || \
-	 (c) == ']' || (c) == '%' || (c) == '*' || (c) == '\\')
+	((unsigned char)(c) <= 0x20 || (unsigned char)(c) >= 0x7f || \
+	 (c) == '(' || (c) == ')' || (c) == '{' || IS_LIST_WILDCARD(c) || \
+	 IS_QUOTED_SPECIAL(c) || IS_RESP_SPECIAL(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,
diff -r ff86acd4eef5 -r 42f99a4fc763 src/lib-imap/imap-parser.c
--- 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";
diff -r ff86acd4eef5 -r 42f99a4fc763 src/lib-storage/mailbox-keywords.c
--- 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;
 		}
 	}


More information about the dovecot-cvs mailing list