fix(vt): reject invalid cursor styles
Apply CodeRabbit finding from the single review run against main: DECSCUSR values outside 0-6 are ignored and do not overwrite existing cursor style state.
- commit
- e672f742902217a671c056ab4bdd89eeea650e28
- author
- brice · · 2026-07-02 19:56 UTC
- parent
- 922d0fd
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
2 files · +15 -0
M pkg/vt/screen.go +3 -0
| @@ -806,6 +806,9 @@ func (s *Screen) applyCursorStyle(params string) { | |||
| 806 | 806 | } | |
| 807 | 807 | style = v | |
| 808 | 808 | } | |
| 809 | + | if style < 0 || style > 6 { | |
| 810 | + | return | |
| 811 | + | } | |
| 809 | 812 | s.cursorStyle = style | |
| 810 | 813 | s.cursorStyleSet = true | |
| 811 | 814 | } | |
| @@ -806,6 +806,9 @@ func (s *Screen) applyCursorStyle(params string) { | |||||
| 806 | } | 806 | } | ||
| 807 | style = v | 807 | style = v | ||
| 808 | } | 808 | } | ||
| 809 | + | if style < 0 || style > 6 { | |||
| 810 | + | return | |||
| 811 | + | } | |||
| 809 | s.cursorStyle = style | 812 | s.cursorStyle = style | ||
| 810 | s.cursorStyleSet = true | 813 | s.cursorStyleSet = true | ||
| 811 | } | 814 | } | ||
M pkg/vt/screen_test.go +12 -0
| @@ -2281,6 +2281,8 @@ func TestScreenCursorStyleDECSCUSR(t *testing.T) { | |||
| 2281 | 2281 | }{ | |
| 2282 | 2282 | {name: "explicit style", seq: "\x1b[5 q", wantStyle: 5, wantSet: true}, | |
| 2283 | 2283 | {name: "blank style parameter", seq: "\x1b[ q", wantStyle: 0, wantSet: true}, | |
| 2284 | + | {name: "invalid low style is ignored", seq: "\x1b[-1 q", wantStyle: 0, wantSet: false}, | |
| 2285 | + | {name: "invalid high style is ignored", seq: "\x1b[7 q", wantStyle: 0, wantSet: false}, | |
| 2284 | 2286 | {name: "XTVERSION is ignored", seq: "\x1b[>0q", wantStyle: 0, wantSet: false}, | |
| 2285 | 2287 | } | |
| 2286 | 2288 | for _, tt := range tests { | |
| @@ -2295,6 +2297,16 @@ func TestScreenCursorStyleDECSCUSR(t *testing.T) { | |||
| 2295 | 2297 | } | |
| 2296 | 2298 | } | |
| 2297 | 2299 | ||
| 2300 | + | func TestScreenInvalidCursorStyleDoesNotOverwriteCurrentStyle(t *testing.T) { | |
| 2301 | + | s := NewScreen(10, 2) | |
| 2302 | + | s.Write([]byte("\x1b[5 q")) | |
| 2303 | + | s.Write([]byte("\x1b[99 q")) | |
| 2304 | + | style, set := s.CursorStyle() | |
| 2305 | + | if style != 5 || !set { | |
| 2306 | + | t.Fatalf("CursorStyle() = (%d, %v), want (5, true)", style, set) | |
| 2307 | + | } | |
| 2308 | + | } | |
| 2309 | + | ||
| 2298 | 2310 | func TestScreenAltScreenActiveAccessor(t *testing.T) { | |
| 2299 | 2311 | s := NewScreen(10, 2) | |
| 2300 | 2312 | if s.AltScreenActive() { | |
| @@ -2281,6 +2281,8 @@ func TestScreenCursorStyleDECSCUSR(t *testing.T) { | |||||
| 2281 | }{ | 2281 | }{ | ||
| 2282 | {name: "explicit style", seq: "\x1b[5 q", wantStyle: 5, wantSet: true}, | 2282 | {name: "explicit style", seq: "\x1b[5 q", wantStyle: 5, wantSet: true}, | ||
| 2283 | {name: "blank style parameter", seq: "\x1b[ q", wantStyle: 0, wantSet: true}, | 2283 | {name: "blank style parameter", seq: "\x1b[ q", wantStyle: 0, wantSet: true}, | ||
| 2284 | + | {name: "invalid low style is ignored", seq: "\x1b[-1 q", wantStyle: 0, wantSet: false}, | |||
| 2285 | + | {name: "invalid high style is ignored", seq: "\x1b[7 q", wantStyle: 0, wantSet: false}, | |||
| 2284 | {name: "XTVERSION is ignored", seq: "\x1b[>0q", wantStyle: 0, wantSet: false}, | 2286 | {name: "XTVERSION is ignored", seq: "\x1b[>0q", wantStyle: 0, wantSet: false}, | ||
| 2285 | } | 2287 | } | ||
| 2286 | for _, tt := range tests { | 2288 | for _, tt := range tests { | ||
| @@ -2295,6 +2297,16 @@ func TestScreenCursorStyleDECSCUSR(t *testing.T) { | |||||
| 2295 | } | 2297 | } | ||
| 2296 | } | 2298 | } | ||
| 2297 | 2299 | ||||
| 2300 | + | func TestScreenInvalidCursorStyleDoesNotOverwriteCurrentStyle(t *testing.T) { | |||
| 2301 | + | s := NewScreen(10, 2) | |||
| 2302 | + | s.Write([]byte("\x1b[5 q")) | |||
| 2303 | + | s.Write([]byte("\x1b[99 q")) | |||
| 2304 | + | style, set := s.CursorStyle() | |||
| 2305 | + | if style != 5 || !set { | |||
| 2306 | + | t.Fatalf("CursorStyle() = (%d, %v), want (5, true)", style, set) | |||
| 2307 | + | } | |||
| 2308 | + | } | |||
| 2309 | + | ||||
| 2298 | func TestScreenAltScreenActiveAccessor(t *testing.T) { | 2310 | func TestScreenAltScreenActiveAccessor(t *testing.T) { | ||
| 2299 | s := NewScreen(10, 2) | 2311 | s := NewScreen(10, 2) | ||
| 2300 | if s.AltScreenActive() { | 2312 | if s.AltScreenActive() { | ||