imap: fix segfault when disconnecting

Do not set client = nil, it breaks almost all message handlers:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x8c7e51]
goroutine 25 [running]:
  git.sr.ht/~rjarry/aerc/worker/imap.(*IMAPWorker).handleListDirectories
    worker/imap/list.go:32
  git.sr.ht/~rjarry/aerc/worker/imap.(*IMAPWorker).handleMessage
    worker/imap/worker.go:174
  git.sr.ht/~rjarry/aerc/worker/imap.(*IMAPWorker).Run
    worker/imap/worker.go:264
  created by git.sr.ht/~rjarry/aerc/widgets.NewAccountView
    widgets/account.go:85 +0x518

Simply leave the disconnected client object, it already returns explicit
error messages.

Fixes: e41ed82cf3 ("imap: add manual {dis,}connect support")
Signed-off-by: Robin Jarry <robin@jarry.cc>
This commit is contained in:
Robin Jarry 2021-11-22 21:31:42 +01:00
parent ec58090474
commit 6ddfc23e61

View file

@ -111,7 +111,7 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error {
c *client.Client c *client.Client
err error err error
) )
if w.client != nil { if w.client != nil && w.client.State() == imap.SelectedState {
return fmt.Errorf("Already connected") return fmt.Errorf("Already connected")
} }
switch w.config.scheme { switch w.config.scheme {
@ -162,13 +162,12 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error {
w.client = &imapClient{c, sortthread.NewThreadClient(c), sortthread.NewSortClient(c)} w.client = &imapClient{c, sortthread.NewThreadClient(c), sortthread.NewSortClient(c)}
w.worker.PostMessage(&types.Done{types.RespondTo(msg)}, nil) w.worker.PostMessage(&types.Done{types.RespondTo(msg)}, nil)
case *types.Disconnect: case *types.Disconnect:
if w.client == nil { if w.client == nil || w.client.State() != imap.SelectedState {
return fmt.Errorf("Not connected") return fmt.Errorf("Not connected")
} }
if err := w.client.Logout(); err != nil { if err := w.client.Logout(); err != nil {
return err return err
} }
w.client = nil
w.worker.PostMessage(&types.Done{types.RespondTo(msg)}, nil) w.worker.PostMessage(&types.Done{types.RespondTo(msg)}, nil)
case *types.ListDirectories: case *types.ListDirectories:
w.handleListDirectories(msg) w.handleListDirectories(msg)