dovecot-2.2: lib-storage: Bodystructure parsing flags weren't up...

dovecot at dovecot.org dovecot at dovecot.org
Fri Jul 4 11:17:42 UTC 2014


details:   http://hg.dovecot.org/dovecot-2.2/rev/cea7c4540ed0
changeset: 17600:cea7c4540ed0
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Jul 04 14:15:41 2014 +0300
description:
lib-storage: Bodystructure parsing flags weren't updated correctly on error conditions.
This fixes an assert-crash sometimes when mail parsing failed.

diffstat:

 src/lib-storage/index/index-mail-headers.c |   8 ++++++-
 src/lib-storage/index/index-mail.c         |  31 ++++++++++++++++++-----------
 2 files changed, 26 insertions(+), 13 deletions(-)

diffs (104 lines):

diff -r c95577fbbe5a -r cea7c4540ed0 src/lib-storage/index/index-mail-headers.c
--- a/src/lib-storage/index/index-mail-headers.c	Fri Jul 04 14:14:21 2014 +0300
+++ b/src/lib-storage/index/index-mail-headers.c	Fri Jul 04 14:15:41 2014 +0300
@@ -298,7 +298,11 @@
 		T_BEGIN {
 			index_mail_parse_header_finish(mail);
 		} T_END;
-                data->save_bodystructure_header = FALSE;
+		if (data->save_bodystructure_header) {
+			i_assert(!data->save_bodystructure_body ||
+				 data->parser_ctx != NULL);
+			data->save_bodystructure_header = FALSE;
+		}
 		return;
 	}
 
@@ -430,6 +434,8 @@
 					    mail);
 	} else {
 		/* just read the header */
+		i_assert(!data->save_bodystructure_body ||
+			 data->parser_ctx != NULL);
 		message_parse_header(data->stream, &data->hdr_size,
 				     hdr_parser_flags,
 				     index_mail_parse_header_cb, mail);
diff -r c95577fbbe5a -r cea7c4540ed0 src/lib-storage/index/index-mail.c
--- a/src/lib-storage/index/index-mail.c	Fri Jul 04 14:14:21 2014 +0300
+++ b/src/lib-storage/index/index-mail.c	Fri Jul 04 14:15:41 2014 +0300
@@ -850,7 +850,10 @@
 		if (parser_input->stream_errno == 0 ||
 		    parser_input->stream_errno == EPIPE) {
 			/* EPIPE = input already closed. allow the caller to
-			   decide if that is an error or not. */
+			   decide if that is an error or not. (for example we
+			   could be coming here from IMAP APPEND when IMAP
+			   client has closed the connection too early. we
+			   don't want to log an error in that case.) */
 			i_assert(!success ||
 				 (i_stream_read(parser_input) == -1 &&
 				  !i_stream_have_bytes_left(parser_input)));
@@ -867,8 +870,16 @@
 		}
 		mail->data.parts = NULL;
 		mail->data.parsed_bodystructure = FALSE;
+		if (mail->data.save_bodystructure_body)
+			mail->data.save_bodystructure_header = TRUE;
 		return -1;
 	}
+	if (mail->data.save_bodystructure_body) {
+		mail->data.parsed_bodystructure = TRUE;
+		mail->data.save_bodystructure_header = FALSE;
+		mail->data.save_bodystructure_body = FALSE;
+		i_assert(mail->data.parts != NULL);
+	}
 
 	if (mail->data.no_caching) {
 		/* if we're here because we aborted parsing, don't get any
@@ -954,11 +965,6 @@
 	ret = index_mail_stream_check_failure(mail);
 	if (index_mail_parse_body_finish(mail, field, TRUE) < 0)
 		ret = -1;
-	if (ret == 0 && data->save_bodystructure_body) {
-		data->save_bodystructure_body = FALSE;
-		data->parsed_bodystructure = TRUE;
-		i_assert(data->parts != NULL);
-	}
 
 	i_stream_seek(data->stream, old_offset);
 	return ret;
@@ -1090,8 +1096,11 @@
 			data->save_bodystructure_header = TRUE;
 			data->save_bodystructure_body = TRUE;
 			(void)get_cached_parts(mail);
-			if (index_mail_parse_headers(mail, NULL) < 0)
+			if (index_mail_parse_headers(mail, NULL) < 0) {
+				data->save_bodystructure_header = TRUE;
 				return -1;
+			}
+			i_assert(data->parser_ctx != NULL);
 		}
 
 		if (index_mail_parse_body(mail, field) < 0)
@@ -1309,6 +1318,8 @@
 						 MAIL_FETCH_MESSAGE_PARTS);
 		}
 		mail->data.parser_input = NULL;
+		if (mail->data.save_bodystructure_body)
+			mail->data.save_bodystructure_header = TRUE;
 	}
 	if (data->filter_stream != NULL)
 		i_stream_unref(&data->filter_stream);
@@ -1751,11 +1762,7 @@
 		mail->data.save_date = ioloop_time;
 	}
 
-	if (index_mail_parse_body_finish(mail, 0, success) == 0) {
-		mail->data.save_bodystructure_body = FALSE;
-		mail->data.parsed_bodystructure = TRUE;
-		i_assert(mail->data.parts != NULL);
-	}
+	(void)index_mail_parse_body_finish(mail, 0, success);
 }
 
 static void index_mail_drop_recent_flag(struct mail *mail)


More information about the dovecot-cvs mailing list