fix: crash when copying/moving all messages

This prevents dereferencing nil when updating RUE counts. This seems to
happen for messages that were not yet loaded, but were selected for
copy operation. This can happen when using `mark -a` command and then
initiating copy operation.

When such message is encountered during RUE counting, it is stopped
and full recount is triggered.

**Original backtrace:**
Error: runtime error: invalid memory address or nil pointer dereference

goroutine 1 [running]:
runtime/debug.Stack()
	runtime/debug/stack.go:24 +0x65
git.sr.ht/~rjarry/aerc/logging.PanicHandler()
	git.sr.ht/~rjarry/aerc/logging/panic-logger.go:45 +0x64b
panic({0x9e5f80, 0xecc360})
	runtime/panic.go:844 +0x258
git.sr.ht/~rjarry/aerc/widgets.(*AccountView).onMessage(0xc0001be870, {0xb7f860?, 0xc00073b4c0?})
	git.sr.ht/~rjarry/aerc/widgets/account.go:353 +0xecc
git.sr.ht/~rjarry/aerc/widgets.(*AccountView).Tick(0xc0001be870)
	git.sr.ht/~rjarry/aerc/widgets/account.go:116 +0x6c
git.sr.ht/~rjarry/aerc/widgets.(*Aerc).Tick(0xc0003ba000)
	git.sr.ht/~rjarry/aerc/widgets/aerc.go:144 +0x7a
main.main()
	git.sr.ht/~rjarry/aerc/aerc.go:225 +0xbb8

Signed-off-by: Ensar Sarajčić <dev@ensarsarajcic.com>
Acked-by: Robin Jarry <robin@jarry.cc>
This commit is contained in:
Ensar Sarajčić 2022-07-22 08:39:39 +02:00 committed by Robin Jarry
parent ab941ebc6a
commit 3b90b3b0dd
1 changed files with 19 additions and 7 deletions

View File

@ -334,12 +334,18 @@ func (acct *AccountView) onMessage(msg types.WorkerMessage) {
// Only update the destination destStore if it is initialized // Only update the destination destStore if it is initialized
if destStore, ok := acct.dirlist.MsgStore(msg.Destination); ok { if destStore, ok := acct.dirlist.MsgStore(msg.Destination); ok {
var recent, unseen int var recent, unseen int
var accurate bool = true
for _, uid := range msg.Uids { for _, uid := range msg.Uids {
// Get the message from the originating store // Get the message from the originating store
msg, ok := acct.Store().Messages[uid] msg, ok := acct.Store().Messages[uid]
if !ok { if !ok {
continue continue
} }
// If message that was not yet loaded is copied
if msg == nil {
accurate = false
break
}
seen := false seen := false
for _, flag := range msg.Flags { for _, flag := range msg.Flags {
if flag == models.SeenFlag { if flag == models.SeenFlag {
@ -353,13 +359,19 @@ func (acct *AccountView) onMessage(msg types.WorkerMessage) {
unseen = unseen + 1 unseen = unseen + 1
} }
} }
destStore.DirInfo.Recent += recent if accurate {
destStore.DirInfo.Unseen += unseen destStore.DirInfo.Recent += recent
destStore.DirInfo.Exists += len(msg.Uids) destStore.DirInfo.Unseen += unseen
// True. For imap, we don't have the message in the store until we destStore.DirInfo.Exists += len(msg.Uids)
// Select so we need to rely on the math we just did for accurate // True. For imap, we don't have the message in the store until we
// counts // Select so we need to rely on the math we just did for accurate
destStore.DirInfo.AccurateCounts = true // counts
destStore.DirInfo.AccurateCounts = true
} else {
destStore.DirInfo.Exists += len(msg.Uids)
// False to trigger recount of recent/unseen
destStore.DirInfo.AccurateCounts = false
}
} }
case *types.LabelList: case *types.LabelList:
acct.labels = msg.Labels acct.labels = msg.Labels