From f89b6433c2470f363609ffbf3fbc4fbd2dd99c58 Mon Sep 17 00:00:00 2001 From: Qwerasd Date: Fri, 16 Jan 2026 16:26:54 -0500 Subject: [PATCH 1/3] osc: add failing test for osc 133 parsing trailing ; This actually causes a crash lol, bad indexing of a slice with `1..0` because it's `key.len + 1 ..` and the length is `0`. --- src/terminal/osc/parsers/semantic_prompt.zig | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/terminal/osc/parsers/semantic_prompt.zig b/src/terminal/osc/parsers/semantic_prompt.zig index 510fe3447..811b6d055 100644 --- a/src/terminal/osc/parsers/semantic_prompt.zig +++ b/src/terminal/osc/parsers/semantic_prompt.zig @@ -348,6 +348,18 @@ test "OSC 133: prompt_start with special_key empty" { try testing.expect(cmd.prompt_start.special_key == false); } +test "OSC 133: prompt_start with trailing ;" { + const testing = std.testing; + + var p: Parser = .init(null); + + const input = "133;A;"; + for (input) |ch| p.next(ch); + + const cmd = p.end(null).?.*; + try testing.expect(cmd == .prompt_start); +} + test "OSC 133: prompt_start with click_events true" { const testing = std.testing; From 4e5c1dcdc17d67757d32faeb2bffe0e27376db00 Mon Sep 17 00:00:00 2001 From: Qwerasd Date: Fri, 16 Jan 2026 16:29:39 -0500 Subject: [PATCH 2/3] osc: fix bad indexing for empty kv in semantic prompt --- src/terminal/osc/parsers/semantic_prompt.zig | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/terminal/osc/parsers/semantic_prompt.zig b/src/terminal/osc/parsers/semantic_prompt.zig index 811b6d055..ac7298267 100644 --- a/src/terminal/osc/parsers/semantic_prompt.zig +++ b/src/terminal/osc/parsers/semantic_prompt.zig @@ -186,6 +186,15 @@ const SemanticPromptKVIterator = struct { break :kv kv; }; + // If we have an empty item, we return an empty key and value. + // + // This allows for trailing semicolons, but also lets us parse + // (or rather, ignore) empty fields; for example `a=b;;e=f`. + if (kv.len < 1) return .{ + .key = kv, + .value = kv, + }; + const key = key: { const index = std.mem.indexOfScalar(u8, kv, '=') orelse break :key kv; kv[index] = 0; From 69066200ef24985f4f5214f0adc38ce6c40cb975 Mon Sep 17 00:00:00 2001 From: Qwerasd Date: Fri, 16 Jan 2026 16:58:58 -0500 Subject: [PATCH 3/3] fix: handle double tmux control mode exit command --- src/termio/stream_handler.zig | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/termio/stream_handler.zig b/src/termio/stream_handler.zig index c647e3ba2..082a0fa10 100644 --- a/src/termio/stream_handler.zig +++ b/src/termio/stream_handler.zig @@ -398,11 +398,16 @@ pub const StreamHandler = struct { break :tmux; }, - .exit => if (self.tmux_viewer) |viewer| { - // Free our viewer state - viewer.deinit(); - self.alloc.destroy(viewer); - self.tmux_viewer = null; + .exit => { + // Free our viewer state if we have one + if (self.tmux_viewer) |viewer| { + viewer.deinit(); + self.alloc.destroy(viewer); + self.tmux_viewer = null; + } + + // And always break since we assert below + // that we're not handling an exit command. break :tmux; },