mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 00:06:09 +03:00
osc: allow 0x20-0xFF in osc_put
The osc_string state of the parser limited accepted bytes to 0x7F. When parsing a utf-8 encoded string as part of an OSC string, the parser would encounter an error and abort the OSC parsing, allowing any remaining bytes to be leaked (possibly) as printable characters to the terminal window. Allow any byte in the range 0x20 - 0xFF to be accepted by osc_put. Add test cases which conflict with the 'anywhere' transitions (IE the utf8 sequence includes C1 control codes which might transition to another state).
This commit is contained in:
@ -584,6 +584,28 @@ test "OSC: change_window_title with 2" {
|
||||
try testing.expectEqualStrings("ab", cmd.change_window_title);
|
||||
}
|
||||
|
||||
test "OSC: change_window_title with utf8" {
|
||||
const testing = std.testing;
|
||||
|
||||
var p: Parser = .{};
|
||||
p.next('2');
|
||||
p.next(';');
|
||||
// '—' EM DASH U+2014 (E2 80 94)
|
||||
p.next(0xE2);
|
||||
p.next(0x80);
|
||||
p.next(0x94);
|
||||
|
||||
p.next(' ');
|
||||
// '‐' HYPHEN U+2010 (E2 80 90)
|
||||
// Intententionally chosen to conflict with the 0x90 C1 control
|
||||
p.next(0xE2);
|
||||
p.next(0x80);
|
||||
p.next(0x90);
|
||||
const cmd = p.end(null).?;
|
||||
try testing.expect(cmd == .change_window_title);
|
||||
try testing.expectEqualStrings("— ‐", cmd.change_window_title);
|
||||
}
|
||||
|
||||
test "OSC: prompt_start" {
|
||||
const testing = std.testing;
|
||||
|
||||
|
@ -345,7 +345,7 @@ fn genTable() Table {
|
||||
range(&result, 0, 0x06, source, source, .ignore);
|
||||
range(&result, 0x08, 0x17, source, source, .ignore);
|
||||
range(&result, 0x1C, 0x1F, source, source, .ignore);
|
||||
range(&result, 0x20, 0x7F, source, source, .osc_put);
|
||||
range(&result, 0x20, 0xFF, source, source, .osc_put);
|
||||
|
||||
// XTerm accepts either BEL or ST for terminating OSC
|
||||
// sequences, and when returning information, uses the same
|
||||
@ -381,7 +381,12 @@ fn single(t: *OptionalTable, c: u8, s0: State, s1: State, a: Action) void {
|
||||
|
||||
fn range(t: *OptionalTable, from: u8, to: u8, s0: State, s1: State, a: Action) void {
|
||||
var i = from;
|
||||
while (i <= to) : (i += 1) single(t, i, s0, s1, a);
|
||||
while (i <= to) : (i += 1) {
|
||||
single(t, i, s0, s1, a);
|
||||
// If 'to' is 0xFF, our next pass will overflow. Return early to prevent
|
||||
// the loop from executing it's continue expression
|
||||
if (i == to) break;
|
||||
}
|
||||
}
|
||||
|
||||
fn transition(state: State, action: Action) Transition {
|
||||
|
Reference in New Issue
Block a user