]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Make sure ENVELOPE parsing isn't done twice concurrently
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Mon, 9 Sep 2019 16:16:19 +0000 (19:16 +0300)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Fri, 31 Jan 2020 11:58:41 +0000 (11:58 +0000)
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.

src/lib-storage/index/index-mail-headers.c

index ed3ba87c5ba72319b81976e11f0cd7fbf1c0511f..9d001886dab773a4b73e4010f236e1aba0f0d812 100644 (file)
@@ -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)