dovecot-2.2: lib-storage: Catch input stream errors when parsing...

dovecot at dovecot.org dovecot at dovecot.org
Sat Feb 16 18:57:45 EET 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/2b76d357a56a
changeset: 15791:2b76d357a56a
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Jan 22 16:31:17 2013 +0200
description:
lib-storage: Catch input stream errors when parsing mail.

diffstat:

 src/lib-storage/index/index-mail-headers.c |   6 ++++-
 src/lib-storage/index/index-mail.c         |  34 ++++++++++++++++++++++++++---
 src/lib-storage/index/index-mail.h         |   1 +
 3 files changed, 36 insertions(+), 5 deletions(-)

diffs (91 lines):

diff -r c762a9af72c1 -r 2b76d357a56a src/lib-storage/index/index-mail-headers.c
--- a/src/lib-storage/index/index-mail-headers.c	Tue Jan 15 08:30:03 2013 +0200
+++ b/src/lib-storage/index/index-mail-headers.c	Tue Jan 22 16:31:17 2013 +0200
@@ -374,6 +374,7 @@
 	input2 = tee_i_stream_create_child(mail->data.tee_stream);
 
 	index_mail_parse_header_init(mail, NULL);
+	mail->data.parser_input = input;
 	mail->data.parser_ctx =
 		message_parser_init(mail->data_pool, input,
 				    hdr_parser_flags, msg_parser_flags);
@@ -386,10 +387,13 @@
 	struct index_mail_data *data = &mail->data;
 	struct message_part *parts;
 
-	if (data->parser_ctx != NULL)
+	if (data->parser_ctx != NULL) {
+		data->parser_input = NULL;
 		(void)message_parser_deinit(&data->parser_ctx, &parts);
+	}
 
 	if (data->parts == NULL) {
+		data->parser_input = data->stream;
 		data->parser_ctx = message_parser_init(mail->data_pool,
 						       data->stream,
 						       hdr_parser_flags,
diff -r c762a9af72c1 -r 2b76d357a56a src/lib-storage/index/index-mail.c
--- a/src/lib-storage/index/index-mail.c	Tue Jan 15 08:30:03 2013 +0200
+++ b/src/lib-storage/index/index-mail.c	Tue Jan 22 16:31:17 2013 +0200
@@ -751,13 +751,38 @@
 static int index_mail_parse_body_finish(struct index_mail *mail,
 					enum index_cache_field field)
 {
-	if (message_parser_deinit(&mail->data.parser_ctx,
-				  &mail->data.parts) < 0) {
-		mail_set_cache_corrupted(&mail->mail.mail,
-					 MAIL_FETCH_MESSAGE_PARTS);
+	struct istream *parser_input = mail->data.parser_input;
+	int ret;
+
+	if (parser_input == NULL) {
+		ret = message_parser_deinit(&mail->data.parser_ctx,
+					    &mail->data.parts) < 0 ? 0 : 1;
+	} else {
+		mail->data.parser_input = NULL;
+		i_stream_ref(parser_input);
+		ret = message_parser_deinit(&mail->data.parser_ctx,
+					    &mail->data.parts) < 0 ? 0 : 1;
+		if (parser_input->stream_errno != 0) {
+			errno = parser_input->stream_errno;
+			mail_storage_set_critical(mail->mail.mail.box->storage,
+					"read(%s) failed: %m",
+					i_stream_get_name(parser_input));
+			ret = -1;
+		}
+		i_assert(i_stream_read(parser_input) == -1 &&
+			 !i_stream_have_bytes_left(parser_input));
+		i_stream_unref(&parser_input);
+	}
+	if (ret <= 0) {
+		if (ret == 0) {
+			mail_set_cache_corrupted(&mail->mail.mail,
+						 MAIL_FETCH_MESSAGE_PARTS);
+		}
+		mail->data.parts = NULL;
 		mail->data.parsed_bodystructure = FALSE;
 		return -1;
 	}
+
 	if (mail->data.no_caching) {
 		/* if we're here because we aborted parsing, don't get any
 		   further or we may crash while generating output from
@@ -1150,6 +1175,7 @@
 			mail_set_cache_corrupted(&mail->mail.mail,
 						 MAIL_FETCH_MESSAGE_PARTS);
 		}
+		mail->data.parser_input = NULL;
 	}
 	if (data->filter_stream != NULL)
 		i_stream_unref(&data->filter_stream);
diff -r c762a9af72c1 -r 2b76d357a56a src/lib-storage/index/index-mail.h
--- a/src/lib-storage/index/index-mail.h	Tue Jan 15 08:30:03 2013 +0200
+++ b/src/lib-storage/index/index-mail.h	Tue Jan 22 16:31:17 2013 +0200
@@ -96,6 +96,7 @@
 	struct istream *stream, *filter_stream;
 	struct tee_istream *tee_stream;
 	struct message_size hdr_size, body_size;
+	struct istream *parser_input;
 	struct message_parser_ctx *parser_ctx;
 	int parsing_count;
 	ARRAY_TYPE(keywords) keywords;


More information about the dovecot-cvs mailing list