]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Fix crash in mail_get_header_stream() when its previous stream wasn...
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Tue, 30 May 2017 15:25:50 +0000 (18:25 +0300)
committerVille Savolainen <ville.savolainen@dovecot.fi>
Wed, 14 Jun 2017 12:34:30 +0000 (15:34 +0300)
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

index e491172e14f5e6e6612bfe61903e6551eb0a87d6..e9e07a5eae8d716b08b80ef7bdb3f2950cd45e21 100644 (file)
@@ -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,