From: Timo Sirainen Date: Mon, 9 Sep 2019 16:16:19 +0000 (+0300) Subject: lib-storage: Make sure ENVELOPE parsing isn't done twice concurrently X-Git-Tag: 2.3.10~118 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d422cad5d5019db62cad5293e80b67e403ed05e8;p=thirdparty%2Fdovecot%2Fcore.git lib-storage: Make sure ENVELOPE parsing isn't done twice concurrently If save_envelope=TRUE and ENVELOPE headers aren't already in cache, header_cache_callback() starts parsing the ENVELOPE. But imap_envelope_parse_callback() does it as well, so the envelope parsing is done concurrently by the two callbacks. Also once the ENVELOPE parsing is done once, make sure it's not done again if the header is parsed again. This didn't cause any problems so far, but it fixes the following commit to work correctly. --- diff --git a/src/lib-storage/index/index-mail-headers.c b/src/lib-storage/index/index-mail-headers.c index ed3ba87c5b..9d001886da 100644 --- a/src/lib-storage/index/index-mail-headers.c +++ b/src/lib-storage/index/index-mail-headers.c @@ -269,6 +269,7 @@ static void index_mail_parse_finish_imap_envelope(struct index_mail *mail) str = str_new(mail->mail.data_pool, 256); imap_envelope_write(mail->data.envelope_data, str); mail->data.envelope = str_c(str); + mail->data.save_envelope = FALSE; if (mail_cache_field_can_add(_mail->transaction->cache_trans, _mail->seq, cache_field_envelope)) { @@ -509,7 +510,10 @@ int index_mail_headers_get_envelope(struct index_mail *mail) old_offset = mail->data.stream == NULL ? 0 : mail->data.stream->v_offset; - mail->data.save_envelope = TRUE; + /* Make sure header_cache_callback() isn't also parsing the ENVELOPE. + Otherwise two callbacks are doing it and mixing up results. */ + mail->data.save_envelope = FALSE; + header_ctx = mailbox_header_lookup_init(mail->mail.mail.box, message_part_envelope_headers); if (mail_get_header_stream(&mail->mail.mail, header_ctx, &stream) < 0) { @@ -518,7 +522,7 @@ int index_mail_headers_get_envelope(struct index_mail *mail) } mailbox_header_lookup_unref(&header_ctx); - if (mail->data.envelope == NULL && stream != NULL) { + if (mail->data.envelope == NULL) { /* we got the headers from cache - parse them to get the envelope */ message_parse_header(stream, NULL, hdr_parser_flags, @@ -527,7 +531,7 @@ int index_mail_headers_get_envelope(struct index_mail *mail) index_mail_stream_log_failure_for(mail, stream); return -1; } - mail->data.save_envelope = FALSE; + i_assert(mail->data.envelope != NULL); } if (mail->data.stream != NULL)