From: Timo Sirainen Date: Wed, 18 Aug 2021 12:04:53 +0000 (+0200) Subject: lib-storage: Fix assert-crash in special partial mail parsing failures X-Git-Tag: 2.3.17~166 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8e592661d5eae2417087328f699ff941d61187af;p=thirdparty%2Fdovecot%2Fcore.git lib-storage: Fix assert-crash in special partial mail parsing failures This happened for example if: - mail_precache() started parsing mail - header was parsed, but mail body parsing failed due to mail size mismatch - vsize parsing doesn't restart header parsing, because header size is already known - body parsing assert-crashes because there is no messsage parser initialized Fixes: Panic: file index-mail.c: line 1290 (index_mail_parse_body): assertion failed: (data->parser_ctx != NULL) --- diff --git a/src/lib-storage/index/index-mail.c b/src/lib-storage/index/index-mail.c index 37abde321b..f21c155d6e 100644 --- a/src/lib-storage/index/index-mail.c +++ b/src/lib-storage/index/index-mail.c @@ -1367,9 +1367,13 @@ int index_mail_init_stream(struct index_mail *mail, if (hdr_size != NULL || body_size != NULL) (void)get_cached_msgpart_sizes(mail); - if (hdr_size != NULL || body_size != NULL || want_attachment_kw) { + bool want_body_parsing = want_attachment_kw || + (body_size != NULL && !data->body_size_set && + (data->access_part & PARSE_BODY) != 0); + + if (hdr_size != NULL || body_size != NULL || want_body_parsing) { i_stream_seek(data->stream, 0); - if (!data->hdr_size_set || want_attachment_kw) { + if (!data->hdr_size_set || want_body_parsing) { if ((data->access_part & (PARSE_HDR | PARSE_BODY)) != 0) { (void)get_cached_parts(mail); if (index_mail_parse_headers_internal(mail, NULL) < 0) @@ -1389,10 +1393,10 @@ int index_mail_init_stream(struct index_mail *mail, *hdr_size = data->hdr_size; } - if (body_size != NULL || want_attachment_kw) { + if (body_size != NULL || want_body_parsing) { if (!data->body_size_set && body_size != NULL) index_mail_get_cached_body_size(mail); - if (!data->body_size_set || want_attachment_kw) { + if (!data->body_size_set || want_body_parsing) { i_stream_seek(data->stream, data->hdr_size.physical_size); if ((data->access_part & PARSE_BODY) != 0) {