summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobin Jarry <robin@jarry.cc>2022-12-30 21:33:52 +0100
committerRobin Jarry <robin@jarry.cc>2023-01-02 21:58:59 +0100
commitd2edd71d0ce8119cf571bfff16b88208a32aeac3 (patch)
treec5512e24f930bdeb4a3d9b7b90566a0b77b37d3f
parent49d4e9d607006acd783d524feefef50e0ea27001 (diff)
downloadaerc-d2edd71d0ce8119cf571bfff16b88208a32aeac3.tar.gz
aerc-d2edd71d0ce8119cf571bfff16b88208a32aeac3.zip
textinput: fix crash when scrolling back in command history
Pressing up while in command mode, calls TextInput.Set() with the previous command in the history. If the command exceeds the current terminal width, there is a scroll mechanism that puts the cursor at the end of the text (see ensureScroll()). However, the offset used to perform the draw is not the current scroll value but the "previous" one. When the one before last command required a longer scroll offset than the current command length, this causes a crash: Error: runtime error: slice bounds out of range [348:5] git.sr.ht/~rjarry/aerc/lib/ui.(*TextInput).Draw(0xc0017ce000, 0xc005460570) git.sr.ht/~rjarry/aerc/lib/ui/textinput.go:111 +0x525 git.sr.ht/~rjarry/aerc/widgets.(*ExLine).Draw(0x30?, 0xc01de13b08?) git.sr.ht/~rjarry/aerc/widgets/exline.go:76 +0x1d git.sr.ht/~rjarry/aerc/lib/ui.(*Stack).Draw(0xc0003f0ff0?, 0x0?) git.sr.ht/~rjarry/aerc/lib/ui/stack.go:30 +0x49 git.sr.ht/~rjarry/aerc/lib/ui.(*Grid).Draw(0xc00038c240, 0xc0003f0ff0) git.sr.ht/~rjarry/aerc/lib/ui/grid.go:126 +0x225 git.sr.ht/~rjarry/aerc/widgets.(*Aerc).Draw(0xc0003f4000, 0xc0003f0ff0) git.sr.ht/~rjarry/aerc/widgets/aerc.go:176 +0x1d2 git.sr.ht/~rjarry/aerc/lib/ui.(*UI).Render(0xc0003a0000) git.sr.ht/~rjarry/aerc/lib/ui/ui.go:110 +0x63 main.main() git.sr.ht/~rjarry/aerc/aerc.go:255 +0x9c5 There are actually two distinct issues here: 1) The scroll offset used for drawing must be the current one, not the one from the previous ensureScoll() call. 2) The scroll offset must be reset when changing the text with TextInput.Set(). Other methods that change the text actually call ensureScroll but they make incremental changes to the text, since Set completely overwrites everything, it makes more sense to set the scroll offset to 0. Reported-by: Adam Cooper <adam@theadamcooper.com> Signed-off-by: Robin Jarry <robin@jarry.cc> Acked-by: Tim Culverhouse <tim@timculverhouse.com>
-rw-r--r--lib/ui/textinput.go8
1 files changed, 4 insertions, 4 deletions
diff --git a/lib/ui/textinput.go b/lib/ui/textinput.go
index bcfe4a83..2b23f15d 100644
--- a/lib/ui/textinput.go
+++ b/lib/ui/textinput.go
@@ -89,6 +89,7 @@ func (ti *TextInput) StringRight() string {
func (ti *TextInput) Set(value string) *TextInput {
ti.text = []rune(value)
ti.index = len(ti.text)
+ ti.scroll = 0
return ti
}
@@ -97,11 +98,10 @@ func (ti *TextInput) Invalidate() {
}
func (ti *TextInput) Draw(ctx *Context) {
- scroll := ti.scroll
- if !ti.focus {
- scroll = 0
- } else {
+ scroll := 0
+ if ti.focus {
ti.ensureScroll()
+ scroll = ti.scroll
}
ti.ctx = ctx // gross