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:
Tim Culverhouse
2023-09-21 01:58:19 -05:00
parent bf6ff079d4
commit 5e800df277
2 changed files with 29 additions and 2 deletions

View File

@ -584,6 +584,28 @@ test "OSC: change_window_title with 2" {
try testing.expectEqualStrings("ab", cmd.change_window_title); 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" { test "OSC: prompt_start" {
const testing = std.testing; const testing = std.testing;

View File

@ -345,7 +345,7 @@ fn genTable() Table {
range(&result, 0, 0x06, source, source, .ignore); range(&result, 0, 0x06, source, source, .ignore);
range(&result, 0x08, 0x17, source, source, .ignore); range(&result, 0x08, 0x17, source, source, .ignore);
range(&result, 0x1C, 0x1F, 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 // XTerm accepts either BEL or ST for terminating OSC
// sequences, and when returning information, uses the same // 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 { fn range(t: *OptionalTable, from: u8, to: u8, s0: State, s1: State, a: Action) void {
var i = from; 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 { fn transition(state: State, action: Action) Transition {