changeset 14601:c34d4e3ff342

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.
author Timo Sirainen <tss@iki.fi>
date Wed, 20 Jun 2012 00:48:08 +0300
parents 27f769be0f85
children 8a4e5e5d82b5
files src/lib-mail/message-parser.c
diffstat 1 files changed, 19 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- 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,