From 511a7ccd55cea57c9d953920b7d651720128ada9 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Tue, 16 Apr 2013 20:08:18 +0300 Subject: [PATCH] mbox: Handle broken Status: and X-Status: headers without sync errors. --- src/lib-storage/index/mbox/mbox-sync-parse.c | 18 +++++++++++++----- src/lib-storage/index/mbox/mbox-sync-private.h | 2 ++ src/lib-storage/index/mbox/mbox-sync-update.c | 6 ++++-- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/lib-storage/index/mbox/mbox-sync-parse.c b/src/lib-storage/index/mbox/mbox-sync-parse.c index ad93978bd2..d4b1aac19c 100644 --- a/src/lib-storage/index/mbox/mbox-sync-parse.c +++ b/src/lib-storage/index/mbox/mbox-sync-parse.c @@ -79,24 +79,31 @@ static enum mail_flags mbox_flag_find(struct mbox_flag_type *flags, char chr) return 0; } -static void parse_status_flags(struct mbox_sync_mail_context *ctx, +static bool parse_status_flags(struct mbox_sync_mail_context *ctx, struct message_header_line *hdr, struct mbox_flag_type *flags_list) { + enum mail_flags flag; size_t i; + bool duplicates = FALSE; ctx->mail.flags ^= MBOX_NONRECENT_KLUDGE; for (i = 0; i < hdr->full_value_len; i++) { - ctx->mail.flags |= - mbox_flag_find(flags_list, hdr->full_value[i]); + flag = mbox_flag_find(flags_list, hdr->full_value[i]); + if ((ctx->mail.flags & flag) != 0) + duplicates = TRUE; + else + ctx->mail.flags |= flag; } ctx->mail.flags ^= MBOX_NONRECENT_KLUDGE; + return duplicates; } static bool parse_status(struct mbox_sync_mail_context *ctx, struct message_header_line *hdr) { - parse_status_flags(ctx, hdr, mbox_status_flags); + if (parse_status_flags(ctx, hdr, mbox_status_flags)) + ctx->mail.status_broken = TRUE; ctx->hdr_pos[MBOX_HDR_STATUS] = str_len(ctx->header); return TRUE; } @@ -104,7 +111,8 @@ static bool parse_status(struct mbox_sync_mail_context *ctx, static bool parse_x_status(struct mbox_sync_mail_context *ctx, struct message_header_line *hdr) { - parse_status_flags(ctx, hdr, mbox_xstatus_flags); + if (parse_status_flags(ctx, hdr, mbox_xstatus_flags)) + ctx->mail.xstatus_broken = TRUE; ctx->hdr_pos[MBOX_HDR_X_STATUS] = str_len(ctx->header); return TRUE; } diff --git a/src/lib-storage/index/mbox/mbox-sync-private.h b/src/lib-storage/index/mbox/mbox-sync-private.h index 7624c14dfb..4c56c9038e 100644 --- a/src/lib-storage/index/mbox/mbox-sync-private.h +++ b/src/lib-storage/index/mbox/mbox-sync-private.h @@ -52,6 +52,8 @@ struct mbox_sync_mail { unsigned int uid_broken:1; unsigned int expunged:1; unsigned int pseudo:1; + unsigned int status_broken:1; + unsigned int xstatus_broken:1; uoff_t from_offset; uoff_t body_size; diff --git a/src/lib-storage/index/mbox/mbox-sync-update.c b/src/lib-storage/index/mbox/mbox-sync-update.c index 988c406330..e68650359f 100644 --- a/src/lib-storage/index/mbox/mbox-sync-update.c +++ b/src/lib-storage/index/mbox/mbox-sync-update.c @@ -409,7 +409,8 @@ static void mbox_sync_update_header_from_real(struct mbox_sync_mail_context *ctx, const struct mbox_sync_mail *mail) { - if ((ctx->mail.flags & STATUS_FLAGS_MASK) != + if (mail->status_broken || + (ctx->mail.flags & STATUS_FLAGS_MASK) != (mail->flags & STATUS_FLAGS_MASK) || (ctx->mail.flags & MAIL_RECENT) != 0) { ctx->mail.flags = (ctx->mail.flags & ~STATUS_FLAGS_MASK) | @@ -418,7 +419,8 @@ mbox_sync_update_header_from_real(struct mbox_sync_mail_context *ctx, ctx->mail.flags &= ~MAIL_RECENT; mbox_sync_update_status(ctx); } - if ((ctx->mail.flags & XSTATUS_FLAGS_MASK) != + if (mail->xstatus_broken || + (ctx->mail.flags & XSTATUS_FLAGS_MASK) != (mail->flags & XSTATUS_FLAGS_MASK)) { ctx->mail.flags = (ctx->mail.flags & ~XSTATUS_FLAGS_MASK) | (mail->flags & XSTATUS_FLAGS_MASK); -- 2.47.3