changeset 22262:8b3a5ee25b13

lib-mail: message_header_hash_more() - add v3 that strips spaces This helps with Zimbra, which strips away trailing whitespaces in BODY[HEADER].
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Fri, 23 Jun 2017 11:00:37 +0300
parents 052275fa15ab
children 096f0c8b9cb1
files src/lib-mail/message-header-hash.c src/lib-mail/message-header-hash.h src/lib-mail/test-message-header-hash.c
diffstat 3 files changed, 32 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-mail/message-header-hash.c	Fri Jun 23 09:24:40 2017 +0300
+++ b/src/lib-mail/message-header-hash.c	Fri Jun 23 11:00:37 2017 +0300
@@ -11,7 +11,7 @@
 {
 	size_t i, start;
 
-	i_assert(version == 1 || version == 2);
+	i_assert(version >= 1 && version <= MESSAGE_HEADER_HASH_MAX_VERSION);
 
 	if (version == 1) {
 		method->loop(context, data, size);
@@ -28,24 +28,39 @@
 
 	   So we'll just replace all control and 8bit chars with '?' and
 	   remove any repeated '?', which hopefully will satisfy everybody.
+
+	   Also:
+	   - Zimbra removes trailing spaces from IMAP BODY[HEADER], but not
+	   IMAP BODY[] or POP3 TOP. Just strip away all spaces with version 3.
+
 	*/
 	for (i = start = 0; i < size; i++) {
+		bool cur_is_questionmark = FALSE;
+
 		switch (data[i]) {
+		case ' ':
+			if (version == 3) {
+				/* strip away spaces */
+				method->loop(context, data + start, i-start);
+				start = i+1;
+			}
+			break;
 		case '\t':
 		case '\n':
 			break;
 		default:
 			if (data[i] < 0x20 || data[i] >= 0x7f || data[i] == '?') {
 				/* remove repeated '?' */
-				if (start < i || (i == 0 && !ctx->prev_was_questionmark)) {
+				if (start < i || !ctx->prev_was_questionmark) {
 					method->loop(context, data + start, i-start);
 					method->loop(context, "?", 1);
 				}
 				start = i+1;
+				cur_is_questionmark = TRUE;
 			}
 			break;
 		}
+		ctx->prev_was_questionmark = cur_is_questionmark;
 	}
-	ctx->prev_was_questionmark = start == i;
 	method->loop(context, data + start, i-start);
 }
--- a/src/lib-mail/message-header-hash.h	Fri Jun 23 09:24:40 2017 +0300
+++ b/src/lib-mail/message-header-hash.h	Fri Jun 23 11:00:37 2017 +0300
@@ -1,6 +1,8 @@
 #ifndef MESSAGE_HEADER_HASH_H
 #define MESSAGE_HEADER_HASH_H
 
+#define MESSAGE_HEADER_HASH_MAX_VERSION 3
+
 struct hash_method;
 
 struct message_header_hash_context {
--- a/src/lib-mail/test-message-header-hash.c	Fri Jun 23 09:24:40 2017 +0300
+++ b/src/lib-mail/test-message-header-hash.c	Fri Jun 23 11:00:37 2017 +0300
@@ -25,6 +25,18 @@
 	{ "\x01?hi??\x01", 2, "?hi?" },
 	{ "?\t?hi?\t?", 2, "?\t?hi?\t?" },
 	{ "\n\nhi\n\n", 2, "\n\nhi\n\n" },
+	{ "", 2, "" },
+	{ " ", 2, " " },
+	{ "   ", 2, "   " },
+	{ "? ? ? hi \x01\x02   \x03   ", 2, "? ? ? hi ?   ?   " },
+
+	{ test_input_with_nuls, 3, "?\t\n?!?x?yz?-plop?" },
+	{ "\n\nhi\n\n", 2, "\n\nhi\n\n" },
+	{ "", 3, "" },
+	{ " ", 3, "" },
+	{ "   ", 3, "" },
+	{ " ? ", 3, "?" },
+	{ "? ? ? hi \x01\x02   \x03   ", 3, "???hi??" },
 };
 
 static void test_message_header_hash_more(void)