From 4d43a49e865563357cae3de0b03c981848b79162 Mon Sep 17 00:00:00 2001 From: Bron Gondwana Date: Mon, 10 Aug 2009 10:49:02 +1000 Subject: [PATCH] Don't process "expunged" if uidvalidity changed We had a process crash during index_check, and further examination showed that "oldexists" was -1 due to a UID validity change (the user had been deleted and then another user renamed into place within about 30 seconds, while an authenticated imap connection was held open) This patch skips the "expunged" check if the uidvalidity has changed, since expunged doesn't make sense if you don't have the same uidvalidity. --- imap/index.c | 54 ++++++++++++++++++++++++++++-------------------------- 1 files changed, 28 insertions(+), 26 deletions(-) diff --git a/imap/index.c b/imap/index.c index e9f90d7..63338c7 100644 --- a/imap/index.c +++ b/imap/index.c @@ -296,36 +296,38 @@ void index_check(struct mailbox *mailbox, int usinguid, int checkseen) fatal("failed to reopen index file", EC_IOERR); } - if (olduidvalidity != mailbox->uidvalidity) { - /* Force a * OK [UIDVALIDITY n] message */ - oldexists = -1; - } + if (olduidvalidity == mailbox->uidvalidity) { + /* See if any messages have been expunged */ + for (oldmsgno = msgno = 1; oldmsgno <= imapd_exists; + oldmsgno++, msgno++) { + if ((unsigned) msgno <= mailbox->exists) { + mailbox_read_index_record(mailbox, msgno, &record); + } + else { + record.uid = mailbox->last_uid+1; + } - for (oldmsgno = msgno = 1; oldmsgno <= imapd_exists; - oldmsgno++, msgno++) { - if ((unsigned) msgno <= mailbox->exists) { - mailbox_read_index_record(mailbox, msgno, &record); - } - else { - record.uid = mailbox->last_uid+1; - } - - nexpunge = 0; - while (oldmsgno<=imapd_exists && UID(oldmsgno) < record.uid) { - nexpunge++; - oldmsgno++; - } - if (nexpunge) { - memmove(flagreport+msgno, flagreport+msgno+nexpunge, - (oldexists-msgno-nexpunge+1)*sizeof(*flagreport)); - memmove(seenflag+msgno, seenflag+msgno+nexpunge, - (oldexists-msgno-nexpunge+1)*sizeof(*seenflag)); - oldexists -= nexpunge; - while (nexpunge--) { - prot_printf(imapd_out, "* %u EXPUNGE\r\n", msgno); + nexpunge = 0; + while (oldmsgno<=imapd_exists && UID(oldmsgno) < record.uid) { + nexpunge++; + oldmsgno++; + } + if (nexpunge) { + memmove(flagreport+msgno, flagreport+msgno+nexpunge, + (oldexists-msgno-nexpunge+1)*sizeof(*flagreport)); + memmove(seenflag+msgno, seenflag+msgno+nexpunge, + (oldexists-msgno-nexpunge+1)*sizeof(*seenflag)); + oldexists -= nexpunge; + while (nexpunge--) { + prot_printf(imapd_out, "* %u EXPUNGE\r\n", msgno); + } } } } + else { + /* Force a * OK [UIDVALIDITY n] message */ + oldexists = -1; + } /* Force re-map of index/cache files */ map_free(&index_base, &index_len); -- 1.5.6.5