]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
mbox: Handle broken Status: and X-Status: headers without sync errors.
authorTimo Sirainen <tss@iki.fi>
Tue, 16 Apr 2013 17:08:18 +0000 (20:08 +0300)
committerTimo Sirainen <tss@iki.fi>
Tue, 16 Apr 2013 17:08:18 +0000 (20:08 +0300)
src/lib-storage/index/mbox/mbox-sync-parse.c
src/lib-storage/index/mbox/mbox-sync-private.h
src/lib-storage/index/mbox/mbox-sync-update.c

index ad93978bd2b077bcfde1b842c13eb23123e9784c..d4b1aac19cb40de769e1b4c55bc1bf9e8981d246 100644 (file)
@@ -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;
 }
index 7624c14dfb10d2252284293f6b606a6b82ebd499..4c56c9038ea1f3a8b0e2330c506a351e50f276b1 100644 (file)
@@ -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;
index 988c4063308ef87177154288b5fe42fe6576673a..e68650359f064e51818dd2663c83bd37f6fe0e46 100644 (file)
@@ -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);