fix(terminal): improve CSI parameter parsing

Make `MAX_PARAMS` public and increase CSI parameter limit from 16 to 24.
Fix potential out-of-bounds read in SGR partial sequence extraction.
pull/8417/head
Adrià Arrufat 2025-08-27 12:18:03 +09:00 committed by Mitchell Hashimoto
parent 58e85bf133
commit 56d3fd872e
3 changed files with 4 additions and 4 deletions

View File

@ -206,7 +206,7 @@ const MAX_INTERMEDIATE = 4;
/// number. I implore TUI authors to not use more than this number of CSI /// number. I implore TUI authors to not use more than this number of CSI
/// params, but I suspect we'll introduce a slow path with heap allocation /// params, but I suspect we'll introduce a slow path with heap allocation
/// one day. /// one day.
const MAX_PARAMS = 24; pub const MAX_PARAMS = 24;
/// Current state of the state machine /// Current state of the state machine
state: State, state: State,

View File

@ -134,7 +134,7 @@ pub const Parser = struct {
self.idx += 1; self.idx += 1;
return .{ .unknown = .{ return .{ .unknown = .{
.full = self.params, .full = self.params,
.partial = slice[0 .. self.idx - start + 1], .partial = slice[0..@min(self.idx - start + 1, slice.len)],
} }; } };
}, },
}; };

View File

@ -249,7 +249,7 @@ pub fn Stream(comptime Handler: type) type {
// the parser state to ground. // the parser state to ground.
0x18, 0x1A => self.parser.state = .ground, 0x18, 0x1A => self.parser.state = .ground,
// A parameter digit: // A parameter digit:
'0'...'9' => if (self.parser.params_idx < 16) { '0'...'9' => if (self.parser.params_idx < Parser.MAX_PARAMS) {
self.parser.param_acc *|= 10; self.parser.param_acc *|= 10;
self.parser.param_acc +|= c - '0'; self.parser.param_acc +|= c - '0';
// The parser's CSI param action uses param_acc_idx // The parser's CSI param action uses param_acc_idx
@ -259,7 +259,7 @@ pub fn Stream(comptime Handler: type) type {
self.parser.param_acc_idx |= 1; self.parser.param_acc_idx |= 1;
}, },
// A parameter separator: // A parameter separator:
':', ';' => if (self.parser.params_idx < 16) { ':', ';' => if (self.parser.params_idx < Parser.MAX_PARAMS) {
self.parser.params[self.parser.params_idx] = self.parser.param_acc; self.parser.params[self.parser.params_idx] = self.parser.param_acc;
if (c == ':') self.parser.params_sep.set(self.parser.params_idx); if (c == ':') self.parser.params_sep.set(self.parser.params_idx);
self.parser.params_idx += 1; self.parser.params_idx += 1;