about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorRobin Jarry <robin@jarry.cc>2021-11-22 21:31:42 +0100
committerRobin Jarry <robin@jarry.cc>2021-11-22 21:32:56 +0100
commit6ddfc23e617ad66bd98d980b22d01bf0fe20ec10 (patch)
treeca698b93636f204669a4ce1e252d44a1994e5873
parentec58090474b37cb46b332cb9bb90e2e33d4a0f67 (diff)
downloadaerc-6ddfc23e617ad66bd98d980b22d01bf0fe20ec10.tar.gz
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: e41ed82cf3db ("imap: add manual {dis,}connect support")
Signed-off-by: Robin Jarry <robin@jarry.cc>
-rw-r--r--worker/imap/worker.go5
1 files changed, 2 insertions, 3 deletions
diff --git a/worker/imap/worker.go b/worker/imap/worker.go
index 2c0e6a6..c427e60 100644
--- a/worker/imap/worker.go
+++ b/worker/imap/worker.go
@@ -111,7 +111,7 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error {
 			c   *client.Client
 			err error
 		)
-		if w.client != nil {
+		if w.client != nil && w.client.State() == imap.SelectedState {
 			return fmt.Errorf("Already connected")
 		}
 		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.worker.PostMessage(&types.Done{types.RespondTo(msg)}, nil)
 	case *types.Disconnect:
-		if w.client == nil {
+		if w.client == nil || w.client.State() != imap.SelectedState {
 			return fmt.Errorf("Not connected")
 		}
 		if err := w.client.Logout(); err != nil {
 			return err
 		}
-		w.client = nil
 		w.worker.PostMessage(&types.Done{types.RespondTo(msg)}, nil)
 	case *types.ListDirectories:
 		w.handleListDirectories(msg)