From f029db3f47b0783ec5b387cb49c4dbf8356f4f37 Mon Sep 17 00:00:00 2001 From: Mechiel Lukkien Date: Wed, 23 Aug 2023 16:13:39 +0200 Subject: [PATCH] imapserver bugfix: fix expunging for messages marked junk/nonjunk such messages would be marked expunged in the database, then the junkfilter would be retrained for the removal of the message. but during retraining, the expunged flag would be cleared again. the on-disk message file would still be removed. so when opening the mailbox, the message would appear to still exist, but cannot be retrieved from disk. if you run "mox fixmsgsize", and you get warnings about missing message files, you could create empty files (with "touch"), run "mox fixsmsgsize" again, followed by "mox recalculatemailboxcounts " and run "mox bumpuidvalidity ". "mox backup" would probably also complain, as would "mox verifydata". this may have caused the "wrong mailbox counts" error i got from "mox verifydata" on a backup. --- imapserver/server.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/imapserver/server.go b/imapserver/server.go index b15b634..f6a34c8 100644 --- a/imapserver/server.go +++ b/imapserver/server.go @@ -2915,6 +2915,9 @@ func (c *conn) xexpunge(uidSet *numSet, missingMailboxOK bool) (remove []store.M removeIDs[i] = m.ID anyIDs[i] = m.ID mb.Sub(m.MailboxCounts()) + // Update "remove", because RetrainMessage below will save the message. + remove[i].Expunged = true + remove[i].ModSeq = modseq } qmr := bstore.QueryTx[store.Recipient](tx) qmr.FilterEqual("MessageID", anyIDs...) @@ -2923,7 +2926,10 @@ func (c *conn) xexpunge(uidSet *numSet, missingMailboxOK bool) (remove []store.M qm = bstore.QueryTx[store.Message](tx) qm.FilterIDs(removeIDs) - _, err = qm.UpdateNonzero(store.Message{Expunged: true, ModSeq: modseq}) + n, err := qm.UpdateNonzero(store.Message{Expunged: true, ModSeq: modseq}) + if err == nil && n != len(removeIDs) { + err = fmt.Errorf("only %d messages set to expunged, expected %d", n, len(removeIDs)) + } xcheckf(err, "marking messages marked for deleted as expunged") err = tx.Update(&mb)