--- dovecot-2.0-pure/src/lib-mail/message-parser.c	2010-08-08 10:05:30.000000000 +0200
+++ dovecot-2.0/src/lib-mail/message-parser.c	2010-08-26 10:01:57.000000000 +0200
@@ -81,26 +81,40 @@
 {
 	unsigned int missing_cr_count = 0;
 	const unsigned char *data = block->data;
-	size_t i;
+	unsigned char *last, *curr;
 
 	block->hdr = NULL;
 
-	for (i = 0; i < block->size; i++) {
-		if (data[i] <= '\n') {
-			if (data[i] == '\n') {
-				ctx->part->body_size.lines++;
-				if ((i > 0 && data[i-1] != '\r') ||
-				    (i == 0 && ctx->last_chr != '\r'))
-					missing_cr_count++;
-			} else if (data[i] == '\0')
-				ctx->part->flags |= MESSAGE_PART_FLAG_HAS_NULS;
-		}
+	/* check nuls */
+	if (memchr(data, 0, block->size) != NULL) {
+		ctx->part->flags |= MESSAGE_PART_FLAG_HAS_NULS;
+	}
+
+	/* count lines and missing cr (from begining + 1) */
+	last = (unsigned char *)data + 1;
+	while (TRUE) {
+		curr = memchr(last, '\n', block->size - (last - data));
+		if (curr == NULL)
+			break;
+
+		ctx->part->body_size.lines++;
+
+		if (*(curr - 1) != '\r')
+			missing_cr_count++;
+
+		last = curr + 1;
+	}
+
+	/* exceptional condition (test begining) */
+	if (*data == '\n' && ctx->last_chr != '\r') {
+		ctx->part->body_size.lines++;
+		missing_cr_count++;
 	}
 
 	ctx->part->body_size.physical_size += block->size;
 	ctx->part->body_size.virtual_size += block->size + missing_cr_count;
 
-	ctx->last_chr = data[i-1];
+	ctx->last_chr = *(data + block->size - 1);
 	ctx->skip += block->size;
 }
 
@@ -196,6 +210,7 @@
 		   const unsigned char *data, size_t size, bool full,
 		   struct message_boundary **boundary_r)
 {
+	unsigned char *ptr;
 	size_t i;
 
 	*boundary_r = NULL;
@@ -215,10 +230,9 @@
 	}
 
 	/* need to find the end of line */
-	for (i = 2; i < size; i++) {
-		if (data[i] == '\n')
-			break;
-	}
+	ptr = (unsigned char *)memchr(data + 2, '\n', size - 2);
+	i = (ptr != NULL) ? ptr - data : size;
+
 	if (i == size && i < BOUNDARY_END_MAX_LEN &&
 	    !ctx->input->eof && !full) {
 		/* no LF found */
@@ -251,6 +265,7 @@
 static int parse_next_body_skip_boundary_line(struct message_parser_ctx *ctx,
 					      struct message_block *block_r)
 {
+	unsigned char *ptr;
 	size_t i;
 	int ret;
 	bool full;
@@ -258,10 +273,8 @@
 	if ((ret = message_parser_read_more(ctx, block_r, &full)) <= 0)
 		return ret;
 
-	for (i = 0; i < block_r->size; i++) {
-		if (block_r->data[i] == '\n')
-			break;
-	}
+	ptr = (unsigned char *)memchr(block_r->data, '\n', block_r->size);
+	i = (ptr != NULL) ? ptr - block_r->data : block_r->size;
 
 	if (i == block_r->size) {
 		parse_body_add_block(ctx, block_r);
@@ -323,6 +336,7 @@
 {
 	struct message_boundary *boundary = NULL;
 	const unsigned char *data;
+	unsigned char *last, *curr;
 	size_t i, boundary_start;
 	int ret;
 	bool full;
@@ -343,20 +357,26 @@
 	}
 
 	i_assert(block_r->size > 0);
-	for (i = boundary_start = 0; i < block_r->size; i++) {
+	boundary_start = 0;
+	last = data;
+	while (TRUE) {
 		/* skip to beginning of the next line. the first line was
 		   handled already. */
 		size_t next_line_idx = block_r->size;
 
-		for (; i < block_r->size; i++) {
-			if (data[i] == '\n') {
-				boundary_start = i;
-				if (i > 0 && data[i-1] == '\r')
-					boundary_start--;
-				next_line_idx = i + 1;
-				break;
-			}
-		}
+		curr = (unsigned char *)memchr(last, '\n',
+				block_r->size - (last - data));
+		if (curr == NULL)
+			break;
+
+		last = curr + 1;
+		i = (curr - data);
+
+		boundary_start = i;
+		if (curr > data && *(curr - 1) == '\r')
+			boundary_start--;
+		next_line_idx = i + 1;
+
 		if (boundary_start != 0) {
 			/* we can skip the first lines. input buffer can't be
 			   full anymore. */
@@ -378,7 +398,7 @@
 		}
 	}
 
-	if (i >= block_r->size) {
+	if (curr == NULL) {
 		/* the boundary wasn't found from this data block,
 		   we'll need more data. */
 		ret = 0;