data->parser_input = NULL;
if (message_parser_deinit_from_parts(&data->parser_ctx, &parts, &error) < 0) {
index_mail_set_message_parts_corrupted(&mail->mail.mail, error);
- data->parts = NULL;
+ index_mail_parts_reset(mail);
}
if (data->parts == NULL || data->parts != parts) {
/* The previous parsing didn't finish, so we're
return ret;
}
+void index_mail_parts_reset(struct index_mail *mail)
+{
+ mail->data.parts = NULL;
+ mail->data.parsed_bodystructure_header = FALSE;
+ mail->data.parsed_bodystructure = FALSE;
+}
+
static int
index_mail_parse_body_finish(struct index_mail *mail,
enum index_cache_field field, bool success)
i_assert(error != NULL);
index_mail_set_message_parts_corrupted(&mail->mail.mail, error);
}
- mail->data.parts = NULL;
- mail->data.parsed_bodystructure = FALSE;
+ index_mail_parts_reset(mail);
if (mail->data.save_bodystructure_body)
mail->data.save_bodystructure_header = TRUE;
if (mail->data.header_parser_initialized)
field_name = "physical size";
imail->data.physical_size = UOFF_T_MAX;
imail->data.virtual_size = UOFF_T_MAX;
- imail->data.parts = NULL;
+ index_mail_parts_reset(imail);
index_mail_reset_vsize_ext(mail);
break;
case MAIL_FETCH_VIRTUAL_SIZE:
field_name = "virtual size";
imail->data.physical_size = UOFF_T_MAX;
imail->data.virtual_size = UOFF_T_MAX;
- imail->data.parts = NULL;
+ index_mail_parts_reset(imail);
index_mail_reset_vsize_ext(mail);
break;
case MAIL_FETCH_MESSAGE_PARTS:
field_name = "MIME parts";
- imail->data.parts = NULL;
+ index_mail_parts_reset(imail);
break;
case MAIL_FETCH_IMAP_BODY:
field_name = "IMAP BODY";
struct mailbox_header_lookup_ctx *headers)
ATTR_NULL(2);
int index_mail_headers_get_envelope(struct index_mail *mail);
+void index_mail_parts_reset(struct index_mail *mail);
int index_mail_get_first_header(struct mail *_mail, const char *field,
bool decode_to_utf8, const char **value_r);
test_end();
}
+static void test_bodystructure_corruption_reparsing(void)
+{
+ struct test_mail_storage_ctx *ctx;
+ struct test_mail_storage_settings set = {
+ .driver = "sdbox",
+ };
+ const char *value;
+
+ test_begin("bodystructure corruption reparsing");
+ ctx = test_mail_storage_init();
+ test_mail_storage_init_user(ctx, &set);
+
+ struct mailbox *box =
+ mailbox_alloc(ctx->user->namespaces->list, "INBOX", 0);
+ test_assert(mailbox_open(box) == 0);
+
+ test_mail_save(box,
+ "From: <test1@example.com>\r\n"
+ "\r\n"
+ "test body\n");
+
+ struct mailbox_transaction_context *trans =
+ mailbox_transaction_begin(box, 0, __func__);
+ struct mail *mail = mail_alloc(trans, 0, NULL);
+ mail_set_seq(mail, 1);
+
+ test_assert(mail_get_special(mail, MAIL_FETCH_IMAP_BODY, &value) == 0);
+ test_expect_error_string("Mailbox INBOX: Deleting corrupted cache record uid=1: UID 1: Broken MIME parts in mailbox INBOX: test");
+ mail_set_cache_corrupted(mail, MAIL_FETCH_MESSAGE_PARTS, "test");
+ test_expect_no_more_errors();
+ test_assert(mail_get_special(mail, MAIL_FETCH_IMAP_BODYSTRUCTURE, &value) == 0);
+
+ mail_free(&mail);
+ test_assert(mailbox_transaction_commit(&trans) == 0);
+ mailbox_free(&box);
+ test_mail_storage_deinit_user(ctx);
+ test_mail_storage_deinit(&ctx);
+ test_end();
+}
+
int main(int argc, char **argv)
{
void (*const tests[])(void) = {
test_mail_random_access,
test_attachment_flags_during_header_fetch,
test_bodystructure_reparsing,
+ test_bodystructure_corruption_reparsing,
NULL
};
int ret;