mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-04-06 07:38:21 +00:00
terminal: handle trailing colon in SGR underline parsing (#11113)
A trailing colon with no following sub-parameter (e.g. "ESC[58:4:m") leaves the colon separator bit set on the last param without adding another entry to the params array. When the SGR parser later iterates to that param (4 = underline) and sees the colon bit, it entered the colon path which asserted slice.len >= 2, but the slice only had one element. Replace the assert with a bounds check that treats the malformed sequence as a default single underline. Add a regression test reproducing the crash from AFL++ fuzzing (afl-out/stream/default/crashes/id:000021). #11109
This commit is contained in:
@@ -249,7 +249,16 @@ pub const Parser = struct {
|
||||
// Colons are fairly rare in the wild.
|
||||
@branchHint(.unlikely);
|
||||
|
||||
assert(slice.len >= 2);
|
||||
// A trailing colon with no following sub-param
|
||||
// (e.g. "ESC[58:4:m") leaves the colon separator
|
||||
// bit set on the last param without adding another
|
||||
// entry, so we can see param 4 with a colon but
|
||||
// nothing after it.
|
||||
if (slice.len < 2) {
|
||||
@branchHint(.cold);
|
||||
break :underline;
|
||||
}
|
||||
|
||||
if (self.isColon()) {
|
||||
// Invalid/unknown SGRs are just not very likely.
|
||||
@branchHint(.cold);
|
||||
@@ -1068,3 +1077,30 @@ test "sgr: kakoune input issue underline, fg, and bg" {
|
||||
|
||||
try testing.expect(p.next() == null);
|
||||
}
|
||||
|
||||
// Fuzz crash: afl-out/stream/default/crashes/id:000021
|
||||
// Input "ESC [ 5 8 : 4 : m" produces params [58, 4] with colon
|
||||
// separator bits set at indices 0 and 1. The trailing colon causes
|
||||
// the second iteration to see param 4 (underline) with a colon,
|
||||
// triggering assert(slice.len >= 2) with slice.len == 1.
|
||||
test "sgr: underline colon with trailing separator and short slice" {
|
||||
var p: Parser = .{
|
||||
.params = &[_]u16{ 58, 4 },
|
||||
.params_sep = sep: {
|
||||
var list = SepList.initEmpty();
|
||||
list.set(0);
|
||||
list.set(1);
|
||||
break :sep list;
|
||||
},
|
||||
};
|
||||
|
||||
// 58:4 is not a valid underline color (sub-param 4 is not 2 or 5),
|
||||
// so it falls through as unknown.
|
||||
try testing.expect(p.next().? == .unknown);
|
||||
|
||||
// Param 4 with a trailing colon but no sub-param is malformed,
|
||||
// so it also falls through as unknown rather than panicking.
|
||||
try testing.expect(p.next().? == .unknown);
|
||||
|
||||
try testing.expect(p.next() == null);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user