From 3c93c5e736d409be46ba28be7ddb93c8852b947e Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Tue, 30 May 2017 18:25:50 +0300 Subject: [PATCH] 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) --- src/lib-storage/index/index-mail-headers.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/lib-storage/index/index-mail-headers.c b/src/lib-storage/index/index-mail-headers.c index e491172e14..e9e07a5eae 100644 --- a/src/lib-storage/index/index-mail-headers.c +++ b/src/lib-storage/index/index-mail-headers.c @@ -875,6 +875,19 @@ int index_mail_get_header_stream(struct mail *_mail, 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 @@ int index_mail_get_header_stream(struct mail *_mail, 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 @@ int index_mail_get_header_stream(struct mail *_mail, 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,