terminal: fix out-of-bounds access in CSI W handler with no params (#11110)

CSI ? W (cursor tabulation control) accessed input.params[0] without
first checking that params.len > 0, causing an index out-of-bounds panic
when the sequence had an intermediate but no parameters.

Add a params.len == 1 guard before accessing params[0].

Found by AFL++ fuzzing #11109
This commit is contained in:
Mitchell Hashimoto
2026-03-01 14:30:42 -08:00
committed by GitHub
2 changed files with 20 additions and 1 deletions

View File

@@ -1188,7 +1188,10 @@ pub fn Stream(comptime Handler: type) type {
return;
},
1 => if (input.intermediates[0] == '?' and input.params[0] == 5) {
1 => if (input.intermediates[0] == '?' and
input.params.len == 1 and
input.params[0] == 5)
{
try self.handler.vt(.tab_reset, {});
} else log.warn("invalid cursor tabulation control: {f}", .{input}),

View File

@@ -988,3 +988,19 @@ test "semantic prompt end_prompt_start_input_terminate_eol clears on linefeed" {
try s.nextSlice("\n");
try testing.expectEqual(.output, t.screens.active.cursor.semantic_content);
}
test "stream: CSI W with intermediate but no params" {
// Regression test from AFL++ crash. CSI ? W without
// parameters caused an out-of-bounds access on input.params[0].
var t: Terminal = try .init(testing.allocator, .{
.cols = 80,
.rows = 24,
.max_scrollback = 100,
});
defer t.deinit(testing.allocator);
var s: Stream = .initAlloc(testing.allocator, .init(&t));
defer s.deinit();
try s.nextSlice("\x1b[?W");
}