aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKoni Marti <koni.marti@gmail.com>2022-01-19 13:18:08 +0100
committerRobin Jarry <robin@jarry.cc>2022-01-19 17:34:41 +0100
commit022bf1a11fa65c81dd5c7ded2a205a94bb449a7a (patch)
tree64712ee178cd773ba654c92afb1d6f6254697fff
parentf81d8871c7007c7fa17f3779f711631d747f22df (diff)
downloadaerc-022bf1a11fa65c81dd5c7ded2a205a94bb449a7a.tar.gz
imap: fix panic when sending multiple connect cmds
fixes the panic when the user sends multiple connect commands and is already connected. The panic is caused by closing an already closed channel. This happens when the idle re-init code is not executed, e.g. when there's a return statement in the switch block. A defer func() before the switch block will prevent this. The existing behavior of only creating a new idleStop channel when properly connected is preseverd. Signed-off-by: Koni Marti <koni.marti@gmail.com>
-rw-r--r--worker/imap/worker.go41
1 files changed, 26 insertions, 15 deletions
diff --git a/worker/imap/worker.go b/worker/imap/worker.go
index 0f1c38d6..81d954fb 100644
--- a/worker/imap/worker.go
+++ b/worker/imap/worker.go
@@ -74,6 +74,14 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error {
w.worker.PostMessage(&types.Error{Error: err}, nil)
}
}
+ defer func() {
+ if w.client != nil && w.client.State() == imap.SelectedState {
+ w.idleStop = make(chan struct{})
+ go func() {
+ w.idleDone <- w.client.Idle(w.idleStop, &client.IdleOptions{0, 0})
+ }()
+ }
+ }()
var reterr error // will be returned at the end, needed to support idle
@@ -83,7 +91,8 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error {
case *types.Configure:
u, err := url.Parse(msg.Config.Source)
if err != nil {
- return err
+ reterr = err
+ break
}
w.config.scheme = u.Scheme
@@ -123,44 +132,50 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error {
case "connection-timeout":
val, err := time.ParseDuration(value)
if err != nil || val < 0 {
- return fmt.Errorf(
+ reterr = fmt.Errorf(
"invalid connection-timeout value %v: %v",
value, err)
+ break
}
w.config.connection_timeout = val
case "keepalive-period":
val, err := time.ParseDuration(value)
if err != nil || val < 0 {
- return fmt.Errorf(
+ reterr = fmt.Errorf(
"invalid keepalive-period value %v: %v",
value, err)
+ break
}
w.config.keepalive_period = val
case "keepalive-probes":
val, err := strconv.Atoi(value)
if err != nil || val < 0 {
- return fmt.Errorf(
+ reterr = fmt.Errorf(
"invalid keepalive-probes value %v: %v",
value, err)
+ break
}
w.config.keepalive_probes = val
case "keepalive-interval":
val, err := time.ParseDuration(value)
if err != nil || val < 0 {
- return fmt.Errorf(
+ reterr = fmt.Errorf(
"invalid keepalive-interval value %v: %v",
value, err)
+ break
}
w.config.keepalive_interval = int(val.Seconds())
}
}
case *types.Connect:
if w.client != nil && w.client.State() == imap.SelectedState {
- return fmt.Errorf("Already connected")
+ reterr = fmt.Errorf("Already connected")
+ break
}
c, err := w.connect()
if err != nil {
- return err
+ reterr = err
+ break
}
c.Updates = w.updates
@@ -168,10 +183,12 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error {
w.worker.PostMessage(&types.Done{types.RespondTo(msg)}, nil)
case *types.Disconnect:
if w.client == nil || w.client.State() != imap.SelectedState {
- return fmt.Errorf("Not connected")
+ reterr = fmt.Errorf("Not connected")
+ break
}
if err := w.client.Logout(); err != nil {
- return err
+ reterr = err
+ break
}
w.worker.PostMessage(&types.Done{types.RespondTo(msg)}, nil)
case *types.ListDirectories:
@@ -208,12 +225,6 @@ func (w *IMAPWorker) handleMessage(msg types.WorkerMessage) error {
reterr = errUnsupported
}
- if w.client != nil && w.client.State() == imap.SelectedState {
- w.idleStop = make(chan struct{})
- go func() {
- w.idleDone <- w.client.Idle(w.idleStop, &client.IdleOptions{0, 0})
- }()
- }
return reterr
}