dashboard / erock/vaxis / fix(vxfw/list): check if index is out of bounds #95 rss

open · opened on 2025-12-16T16:06:41Z by erock
Help
checkout latest patchset:
ssh pr.pico.sh print pr-95 | git am -3
checkout any patchset in a patch request:
ssh pr.pico.sh print ps-X | git am -3
add changes to patch request:
git format-patch main --stdout | ssh pr.pico.sh pr add 95
add review to patch request:
git format-patch main --stdout | ssh pr.pico.sh pr add --review 95
accept PR:
ssh pr.pico.sh pr accept 95
close PR:
ssh pr.pico.sh pr close 95

Logs

erock created pr with ps-172 on 2025-12-16T16:06:41Z
erock added ps-173 on 2025-12-16T16:07:53Z

Patchsets

ps-172 by erock on 2025-12-16T16:06:41Z
Range Diff ↕ rd-173
1: 37f44c1 ! 1: 7a2f7ff fix(vxfw/list): check if index is out of bounds
ps-173 by erock on 2025-12-16T16:07:53Z

Patchset ps-173

Back to top
```
panic: runtime error: index out of range [64976] with length 64792

goroutine 53 [running]:
git.sr.ht/~rockorager/vaxis/vxfw.(*Surface).WriteCell(...)
     /go/pkg/mod/git.sr.ht/~rockorager/vaxis@v0.14.1-0.20250527151737-5530f9f4bcf6/vxfw/vxfw.go:158
git.sr.ht/~rockorager/vaxis/vxfw/list.(*Dynamic).Draw(0x40005c9f08, {{0xb?, 0x0?}, {0x0?, 0x0?}, 0x40000309a0?})
     /go/pkg/mod/git.sr.ht/~rockorager/vaxis@v0.14.1-0.20250527151737-5530f9f4bcf6/vxfw/list/list.go:210 +0xca8
```
+37 -0 vxfw/surface_test.go link
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
diff --git a/vxfw/surface_test.go b/vxfw/surface_test.go
new file mode 100644
index 0000000..6400880
--- /dev/null
+++ b/vxfw/surface_test.go
@@ -0,0 +1,37 @@
+package vxfw_test
+
+import (
+	"testing"
+
+	"git.sr.ht/~rockorager/vaxis"
+	"git.sr.ht/~rockorager/vaxis/vxfw"
+)
+
+func TestWriteCellBoundsCheck(t *testing.T) {
+	// Create a surface where Size claims more cells than Buffer actually has.
+	// This simulates the bug where Size and Buffer get out of sync.
+	s := vxfw.Surface{
+		Size: vxfw.Size{
+			Width:  100,
+			Height: 100,
+		},
+		Buffer: make([]vaxis.Cell, 50), // Only 50 cells, but Size claims 10000
+	}
+
+	cell := vaxis.Cell{
+		Character: vaxis.Character{
+			Grapheme: "x",
+			Width:    1,
+		},
+	}
+
+	// This should not panic even though the index would be out of bounds
+	// if we only checked against Size.
+	s.WriteCell(99, 99, cell) // Would calculate index 9999, but Buffer only has 50 cells
+
+	// Also test that valid writes still work
+	s.WriteCell(0, 0, cell)
+	if s.Buffer[0].Character.Grapheme != "x" {
+		t.Errorf("expected cell at (0,0) to be written, got %q", s.Buffer[0].Character.Grapheme)
+	}
+}
+3 -0 vxfw/vxfw.go link
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
diff --git a/vxfw/vxfw.go b/vxfw/vxfw.go
index 9f1ae13..5ac9252 100644
--- a/vxfw/vxfw.go
+++ b/vxfw/vxfw.go
@@ -155,6 +155,9 @@ func (s *Surface) WriteCell(col uint16, row uint16, cell vaxis.Cell) {
 		return
 	}
 	i := (row * s.Size.Width) + col
+	if int(i) >= len(s.Buffer) {
+		return
+	}
 	s.Buffer[i] = cell
 }