changeset 22211:e7239fd6301f

lib-storage: Fix crash in mail_get_header_stream() when its previous stream wasn't at EOF At least this could have happened when indexes were disabled and running: FETCH 1 (envelope body.peek[header.fields (foo)] bodystructure) Fixes: Panic: file index-mail-headers.c: line 198 (index_mail_parse_header_init): assertion failed: (!mail->data.header_parser_initialized)
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Tue, 30 May 2017 18:25:50 +0300
parents 0223995dd50a
children 8cc50c161f4a
files src/lib-storage/index/index-mail-headers.c
diffstat 1 files changed, 13 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/index/index-mail-headers.c	Wed May 31 14:32:30 2017 +0300
+++ b/src/lib-storage/index/index-mail-headers.c	Tue May 30 18:25:50 2017 +0300
@@ -875,6 +875,19 @@
 	struct istream *input;
 	string_t *dest;
 
+	if (mail->data.filter_stream != NULL) {
+		const unsigned char *data;
+		size_t size;
+
+		/* read through the previous filter_stream. this makes sure
+		   that the fields are added to cache, and most importantly it
+		   resets header_parser_initialized=FALSE so we don't assert
+		   on it. */
+		while (i_stream_read_more(mail->data.filter_stream, &data, &size) > 0)
+			i_stream_skip(mail->data.filter_stream, size);
+		i_stream_destroy(&mail->data.filter_stream);
+	}
+
 	if (mail->data.save_bodystructure_header) {
 		/* we have to parse the header. */
 		const char *reason =
@@ -889,8 +902,6 @@
 				      headers->count) > 0) {
 		str_append(dest, "\n");
 		_mail->transaction->stats.cache_hit_count++;
-		if (mail->data.filter_stream != NULL)
-			i_stream_destroy(&mail->data.filter_stream);
 		mail->data.filter_stream =
 			i_stream_create_from_data(str_data(dest),
 						  str_len(dest));
@@ -921,9 +932,6 @@
 	if (mail_get_hdr_stream_because(_mail, NULL, reason, &input) < 0)
 		return -1;
 
-	if (mail->data.filter_stream != NULL)
-		i_stream_destroy(&mail->data.filter_stream);
-
 	index_mail_parse_header_init(mail, headers);
 	mail->data.filter_stream =
 		i_stream_create_header_filter(mail->data.stream,