diff options
author | Robin Jarry <robin@jarry.cc> | 2022-09-26 20:56:01 +0200 |
---|---|---|
committer | Robin Jarry <robin@jarry.cc> | 2022-09-29 16:52:27 +0200 |
commit | bf2bf8c242cbddce684acd55743caa9b749f6d46 (patch) | |
tree | 3db4b9d43ea1abeabde0cc3e20a3a218e3ed7c05 /widgets | |
parent | 0e50f29bf3e2cde36b2c345addbc51527b17e14b (diff) | |
download | aerc-bf2bf8c242cbddce684acd55743caa9b749f6d46.tar.gz |
compose: prevent out of bounds access
Fix the following panic, seen while switching accounts:
runtime error: index out of range [4] with length 4
goroutine 6 [running]:
git.sr.ht/~rjarry/aerc/widgets.(*Composer).Focus(0xc005cfbe30?, 0x40?)
git.sr.ht/~rjarry/aerc/widgets/compose.go:618 +0x51
git.sr.ht/~rjarry/aerc/widgets.(*Aerc).focus(0xc00034c000, {0x0?, 0x0})
git.sr.ht/~rjarry/aerc/widgets/aerc.go:568 +0xec
git.sr.ht/~rjarry/aerc/widgets.(*Aerc).BeginExCommand.func2()
git.sr.ht/~rjarry/aerc/widgets/aerc.go:590 +0x4c
git.sr.ht/~rjarry/aerc/widgets.(*ExLine).Event(0xc009453860, {0xbb6820?, 0xc009baa320?})
git.sr.ht/~rjarry/aerc/widgets/exline.go:81 +0xbc
git.sr.ht/~rjarry/aerc/widgets.(*Aerc).Event(0xc009ab1950?, {0xbb6820?, 0xc009baa320?})
git.sr.ht/~rjarry/aerc/widgets/aerc.go:285 +0x470
git.sr.ht/~rjarry/aerc/lib/ui.(*UI).ProcessEvents(0xc000327540)
git.sr.ht/~rjarry/aerc/lib/ui/ui.go:117 +0x202
created by main.main
git.sr.ht/~rjarry/aerc/aerc.go:244 +0x94c
Protect Composer.editable and Composer.focus with a mutex.
Reported-by: Bence Ferdinandy <bence@ferdinandy.com>
Signed-off-by: Robin Jarry <robin@jarry.cc>
Acked-by: Moritz Poldrack <moritz@poldrack.dev>
Diffstat (limited to 'widgets')
-rw-r--r-- | widgets/compose.go | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/widgets/compose.go b/widgets/compose.go index c0740d22..ee07d1cd 100644 --- a/widgets/compose.go +++ b/widgets/compose.go @@ -8,6 +8,7 @@ import ( "os" "os/exec" "strings" + "sync" "time" "github.com/emersion/go-message/mail" @@ -28,6 +29,7 @@ import ( ) type Composer struct { + sync.Mutex editors map[string]*headerEditor // indexes in lower case (from / cc / bcc) header *mail.Header parent models.OriginalMail // parent of current message, only set if reply @@ -131,6 +133,8 @@ func (c *Composer) SwitchAccount(newAcct *AccountView) error { } func (c *Composer) setupFor(acct *AccountView) error { + c.Lock() + defer c.Unlock() // set new account and accountConfig c.acct = acct c.acctConfig = acct.AccountConfig() @@ -524,6 +528,8 @@ func (c *Composer) readSignatureFromFile() []byte { } func (c *Composer) FocusTerminal() *Composer { + c.Lock() + defer c.Unlock() if c.editor == nil { return c } @@ -587,6 +593,8 @@ func (c *Composer) Close() { } func (c *Composer) Bindings() string { + c.Lock() + defer c.Unlock() switch c.editor { case nil: return "compose::review" @@ -598,6 +606,8 @@ func (c *Composer) Bindings() string { } func (c *Composer) Event(event tcell.Event) bool { + c.Lock() + defer c.Unlock() if c.editor != nil { return c.focusable[c.focused].Event(event) } @@ -605,6 +615,8 @@ func (c *Composer) Event(event tcell.Event) bool { } func (c *Composer) MouseEvent(localX int, localY int, event tcell.Event) { + c.Lock() + defer c.Unlock() c.grid.MouseEvent(localX, localY, event) for _, e := range c.focusable { he, ok := e.(*headerEditor) @@ -615,7 +627,9 @@ func (c *Composer) MouseEvent(localX int, localY int, event tcell.Event) { } func (c *Composer) Focus(focus bool) { + c.Lock() c.focusable[c.focused].Focus(focus) + c.Unlock() } func (c *Composer) Config() *config.AccountConfig { @@ -873,6 +887,8 @@ func (c *Composer) termEvent(event tcell.Event) bool { } func (c *Composer) termClosed(err error) { + c.Lock() + defer c.Unlock() if c.editor == nil { return } @@ -888,6 +904,8 @@ func (c *Composer) termClosed(err error) { } func (c *Composer) ShowTerminal() { + c.Lock() + defer c.Unlock() if c.editor != nil { return } @@ -910,6 +928,8 @@ func (c *Composer) ShowTerminal() { } func (c *Composer) PrevField() { + c.Lock() + defer c.Unlock() c.focusable[c.focused].Focus(false) c.focused-- if c.focused == -1 { @@ -919,12 +939,16 @@ func (c *Composer) PrevField() { } func (c *Composer) NextField() { + c.Lock() + defer c.Unlock() c.focusable[c.focused].Focus(false) c.focused = (c.focused + 1) % len(c.focusable) c.focusable[c.focused].Focus(true) } func (c *Composer) FocusEditor(editor string) { + c.Lock() + defer c.Unlock() editor = strings.ToLower(editor) c.focusable[c.focused].Focus(false) for i, f := range c.focusable { @@ -939,6 +963,8 @@ func (c *Composer) FocusEditor(editor string) { // AddEditor appends a new header editor to the compose window. func (c *Composer) AddEditor(header string, value string, appendHeader bool) { + c.Lock() + defer c.Unlock() var editor *headerEditor header = strings.ToLower(header) if e, ok := c.editors[header]; ok { |