imap: avoid crash when replying to unread message

When running `:reply -q` on an unread message, aerc crashes after
opening the editor:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x5d1019]

goroutine 63 [running]:
bufio.(*Reader).fill(0xc000086ef8)
	/usr/lib/golang/src/bufio/bufio.go:106 +0xd9
bufio.(*Reader).Peek(0xc00020bef8, 0x1)
	/usr/lib/golang/src/bufio/bufio.go:144 +0x5d
github.com/emersion/go-message/textproto.ReadHeader(0xc00004a700?)
	emersion/go-message@v0.15.0/textproto/header.go:525 +0x5f
git.sr.ht/~rjarry/aerc/worker/imap.(*IMAPWorker).handleFetchMessageBodyPart.func1(0xc00056e280)
	worker/imap/fetch.go:99 +0x1ab
git.sr.ht/~rjarry/aerc/worker/imap.(*IMAPWorker).handleFetchMessages.func1()
	worker/imap/fetch.go:178 +0xd7
created by git.sr.ht/~rjarry/aerc/worker/imap.(*IMAPWorker).handleFetchMessages
	worker/imap/fetch.go:172 +0x12b

This happens because the flags are updated in the callback that receives
the message itself. It causes the flag update to arrive in the same
channel/request. Ignore the messages that have an empty body (i.e. only
containing flag updates). This is inherently racy but there seems no way
to get rid of these extra messages.

Signed-off-by: Robin Jarry <robin@jarry.cc>
Tested-by: Connor Kuehl <cipkuehl@gmail.com>
This commit is contained in:
Robin Jarry 2022-04-28 09:39:47 +02:00
parent 57699b1fa6
commit 8ed95b0d2a

View file

@ -95,8 +95,15 @@ func (imapw *IMAPWorker) handleFetchMessageBodyPart(
} }
imapw.handleFetchMessages(msg, []uint32{msg.Uid}, items, imapw.handleFetchMessages(msg, []uint32{msg.Uid}, items,
func(_msg *imap.Message) error { func(_msg *imap.Message) error {
headerReader := bufio.NewReader(_msg.GetBody(&partHeaderSection)) if len(_msg.Body) == 0 {
h, err := textproto.ReadHeader(headerReader) // ignore duplicate messages with only flag updates
return nil
}
body := _msg.GetBody(&partHeaderSection)
if body == nil {
return fmt.Errorf("failed to find part: %v", partHeaderSection)
}
h, err := textproto.ReadHeader(bufio.NewReader(body))
if err != nil { if err != nil {
return fmt.Errorf("failed to read part header: %v", err) return fmt.Errorf("failed to read part header: %v", err)
} }