add message size consistency check

the bulk of a message is stored on disk. a message prefix is stored in the
database (for prefixed headers like "Received:"). this adds a check to ensure
Size = prefix length + on-disk file size.

verifydata also checks for this now.

and one older and one new (since yesterday) bug was found. the first when
appending a message without a header/body section (uncommon). the second when
sending messages from webmail with localserve (uncommon).
This commit is contained in:
Mechiel Lukkien
2023-08-08 22:10:53 +02:00
parent 49cf16d3f2
commit 8c3c12d96a
9 changed files with 259 additions and 17 deletions

32
main.go
View File

@ -143,6 +143,7 @@ var commands = []struct {
{"reassignuids", cmdReassignUIDs},
{"fixuidmeta", cmdFixUIDMeta},
{"dmarcdb addreport", cmdDMARCDBAddReport},
{"fixmsgsize", cmdFixmsgsize},
{"reparse", cmdReparse},
{"ensureparsed", cmdEnsureParsed},
{"message parse", cmdMessageParse},
@ -1988,6 +1989,37 @@ func cmdVersion(c *cmd) {
fmt.Println(moxvar.Version)
}
func cmdFixmsgsize(c *cmd) {
c.unlisted = true
c.params = "[account]"
c.help = `Ensure message sizes in the database matching the sum of the message prefix length and on-disk file size.
Messages with an inconsistent size are also parsed again.
If an inconsistency is found, you should probably also run "mox
bumpuidvalidity" on the mailboxes or entire account to force IMAP clients to
refetch messages.
`
args := c.Parse()
if len(args) > 1 {
c.Usage()
}
mustLoadConfig()
var account string
if len(args) == 1 {
account = args[0]
}
ctlcmdFixmsgsize(xctl(), account)
}
func ctlcmdFixmsgsize(ctl *ctl, account string) {
ctl.xwrite("fixmsgsize")
ctl.xwrite(account)
ctl.xreadok()
ctl.xstreamto(os.Stdout)
}
func cmdReparse(c *cmd) {
c.unlisted = true
c.params = "[account]"