changeset 19623:7e08d7ae86be

pop3-migration: Convert all non-ASCII in headers to '?'
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Sun, 24 Jan 2016 19:23:59 +0200
parents 8368689f036b
children 259d971afa5a
files src/plugins/pop3-migration/pop3-migration-plugin.c
diffstat 1 files changed, 20 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/src/plugins/pop3-migration/pop3-migration-plugin.c	Sun Jan 24 18:15:53 2016 +0200
+++ b/src/plugins/pop3-migration/pop3-migration-plugin.c	Sun Jan 24 19:23:59 2016 +0200
@@ -154,8 +154,8 @@
 				bool *have_eoh_r)
 {
 	struct istream *input2;
-	const unsigned char *data, *p;
-	size_t size, idx;
+	const unsigned char *data;
+	size_t i, start, size;
 	struct sha1_ctxt sha1_ctx;
 	struct pop3_hdr_context hdr_ctx;
 
@@ -171,18 +171,25 @@
 
 	sha1_init(&sha1_ctx);
 	while (i_stream_read_data(input, &data, &size, 0) > 0) {
-		/* if there are NULs in header, replace them with 0x80
-		   character. This is done by at least Dovecot IMAP and also
-		   POP3 with outlook-no-nuls workaround. */
-		while ((p = memchr(data, '\0', size)) != NULL) {
-			idx = p - data;
-			sha1_loop(&sha1_ctx, data, idx);
-			sha1_loop(&sha1_ctx, "\x80", 1);
-			i_assert(size > idx);
-			data += idx + 1;
-			size -= idx + 1;
+		/* - Dovecot IMAP replaces NULs with 0x80 character.
+		   - Dovecot POP3 with outlook-no-nuls workaround replaces NULs
+		   with 0x80 character.
+		   - Zimbra replaces 8bit chars with '?' in header fetches,
+		   but not body fetches.
+		   - Yahoo replaces 8bit chars with '?' in partial header
+		   fetches, but not POP3 TOP.
+
+		   So we'll just replace all control and 8bit chars with '?',
+		   which hopefully will satisfy everybody.
+		*/
+		for (i = start = 0; i < size; i++) {
+			if (data[i] < 0x20 || data[i] >= 0x80) {
+				sha1_loop(&sha1_ctx, data + start, i-start);
+				sha1_loop(&sha1_ctx, "?", 1);
+				start = i+1;
+			}
 		}
-		sha1_loop(&sha1_ctx, data, size);
+		sha1_loop(&sha1_ctx, data + start, i-start);
 		i_stream_skip(input, size);
 	}
 	if (input->stream_errno != 0) {