dovecot-2.2: message parser: Fixes to handling CRLF linefeeds.

dovecot at dovecot.org dovecot at dovecot.org
Wed Jun 20 00:48:20 EEST 2012


details:   http://hg.dovecot.org/dovecot-2.2/rev/c34d4e3ff342
changeset: 14601:c34d4e3ff342
user:      Timo Sirainen <tss at iki.fi>
date:      Wed Jun 20 00:48:08 2012 +0300
description:
message parser: Fixes to handling CRLF linefeeds.
An extra CR could have been left to the end of a MIME part that belonged to
its --boundary.

diffstat:

 src/lib-mail/message-parser.c |  24 +++++++++++++++++++-----
 1 files changed, 19 insertions(+), 5 deletions(-)

diffs (49 lines):

diff -r 27f769be0f85 -r c34d4e3ff342 src/lib-mail/message-parser.c
--- a/src/lib-mail/message-parser.c	Sat Jun 16 02:06:16 2012 +0300
+++ b/src/lib-mail/message-parser.c	Wed Jun 20 00:48:08 2012 +0300
@@ -291,6 +291,7 @@
 			     struct message_block *block_r, bool first_line)
 {
 	struct message_part *part;
+	size_t line_size;
 
 	/* get back to parent MIME part, summing the child MIME part sizes
 	   into parent's body sizes */
@@ -310,12 +311,21 @@
 
 	/* the boundary itself should already be in buffer. add that. */
 	block_r->data = i_stream_get_data(ctx->input, &block_r->size);
-	i_assert(block_r->size >= ctx->skip + 2 + boundary->len +
-		 (first_line ? 0 : 1));
+	i_assert(block_r->size >= ctx->skip);
 	block_r->data += ctx->skip;
-	/* [\n]--<boundary>[--] */
-	block_r->size = (first_line ? 0 : 1) + 2 + boundary->len +
-		(boundary->epilogue_found ? 2 : 0);
+	/* [[\r]\n]--<boundary>[--] */
+	if (first_line)
+		line_size = 0;
+	else if (block_r->data[0] == '\r') {
+		i_assert(block_r->data[1] == '\n');
+		line_size = 2;
+	} else {
+		i_assert(block_r->data[0] == '\n');
+		line_size = 1;
+	}
+	line_size += 2 + boundary->len + (boundary->epilogue_found ? 2 : 0);
+	i_assert(block_r->size >= ctx->skip + line_size);
+	block_r->size = line_size;
 	parse_body_add_block(ctx, block_r);
 
 	ctx->parse_next_block = parse_next_body_skip_boundary_line;
@@ -382,6 +392,10 @@
 	} else if (boundary_start == 0) {
 		/* no linefeeds in this block. we can just skip it. */
 		ret = 0;
+		if (block_r->data[block_r->size-1] == '\r') {
+			/* this may be the beginning of the \r\n--boundary */
+			block_r->size--;
+		}
 		boundary_start = block_r->size;
 	} else {
 		/* the boundary wasn't found from this data block,


More information about the dovecot-cvs mailing list