From 49f1866f2820a3f1325a1e2d0c97da7c17f87d5c Mon Sep 17 00:00:00 2001 From: Nameless Date: Thu, 19 Oct 2023 16:38:52 -0500 Subject: [PATCH] add tests for fuzzed results, clean up unimplemented osc warning --- src/Command.zig | 3 ++ src/terminal/osc.zig | 8 ++--- src/terminal/stream.zig | 72 ++++++++++++++++++++++++++++++++--------- 3 files changed, 63 insertions(+), 20 deletions(-) diff --git a/src/Command.zig b/src/Command.zig index ce606f770..1f0e81bec 100644 --- a/src/Command.zig +++ b/src/Command.zig @@ -255,6 +255,9 @@ pub fn expandPath(alloc: Allocator, cmd: []const u8) !?[]u8 { path_buf[path_len] = 0; const full_path = path_buf[0..path_len :0]; + // Skip if this isn't an absolute path + if (!std.fs.path.isAbsolute(full_path)) continue; + // Stat it const f = std.fs.openFileAbsolute(full_path, .{}) catch |err| switch (err) { error.FileNotFound => continue, diff --git a/src/terminal/osc.zig b/src/terminal/osc.zig index fe5a72f2f..823f9ff67 100644 --- a/src/terminal/osc.zig +++ b/src/terminal/osc.zig @@ -284,7 +284,7 @@ pub const Parser = struct { .@"0" => switch (c) { ';' => { - self.command = .{ .change_window_title = &.{} }; + self.command = .{ .change_window_title = undefined }; self.state = .string; self.temp_state = .{ .str = &self.command.change_window_title }; @@ -328,7 +328,7 @@ pub const Parser = struct { .@"2" => switch (c) { '2' => self.state = .@"22", ';' => { - self.command = .{ .change_window_title = &.{} }; + self.command = .{ .change_window_title = undefined }; self.state = .string; self.temp_state = .{ .str = &self.command.change_window_title }; @@ -339,7 +339,7 @@ pub const Parser = struct { .@"22" => switch (c) { ';' => { - self.command = .{ .mouse_shape = .{ .value = &.{} } }; + self.command = .{ .mouse_shape = undefined }; self.state = .string; self.temp_state = .{ .str = &self.command.mouse_shape.value }; @@ -366,7 +366,7 @@ pub const Parser = struct { .@"52" => switch (c) { ';' => { - self.command = .{ .clipboard_contents = .{ .kind = undefined, .data = &.{} } }; + self.command = .{ .clipboard_contents = undefined }; self.state = .clipboard_kind; }, else => self.state = .invalid, diff --git a/src/terminal/stream.zig b/src/terminal/stream.zig index 1fda8c514..b2855797f 100644 --- a/src/terminal/stream.zig +++ b/src/terminal/stream.zig @@ -969,44 +969,53 @@ pub fn Stream(comptime Handler: type) type { .change_window_title => |title| { if (@hasDecl(T, "changeWindowTitle")) { try self.handler.changeWindowTitle(title); - } else log.warn("unimplemented OSC callback: {}", .{cmd}); + return; + } }, .clipboard_contents => |clip| { if (@hasDecl(T, "clipboardContents")) { try self.handler.clipboardContents(clip.kind, clip.data); - } else log.warn("unimplemented OSC callback: {}", .{cmd}); + return; + } }, .prompt_start => |v| { - if (@hasDecl(T, "promptStart")) switch (v.kind) { - .primary, .right => try self.handler.promptStart(v.aid, v.redraw), - .continuation => try self.handler.promptContinuation(v.aid), - } else log.warn("unimplemented OSC callback: {}", .{cmd}); + if (@hasDecl(T, "promptStart")) { + switch (v.kind) { + .primary, .right => try self.handler.promptStart(v.aid, v.redraw), + .continuation => try self.handler.promptContinuation(v.aid), + } + return; + } }, .prompt_end => { if (@hasDecl(T, "promptEnd")) { try self.handler.promptEnd(); - } else log.warn("unimplemented OSC callback: {}", .{cmd}); + return; + } }, .end_of_input => { if (@hasDecl(T, "endOfInput")) { try self.handler.endOfInput(); - } else log.warn("unimplemented OSC callback: {}", .{cmd}); + return; + } }, .end_of_command => |end| { if (@hasDecl(T, "endOfCommand")) { try self.handler.endOfCommand(end.exit_code); - } else log.warn("unimplemented OSC callback: {}", .{cmd}); + return; + } }, .report_pwd => |v| { if (@hasDecl(T, "reportPwd")) { try self.handler.reportPwd(v.value); - } else log.warn("unimplemented OSC callback: {}", .{cmd}); + return; + } }, .mouse_shape => |v| { @@ -1017,19 +1026,25 @@ pub fn Stream(comptime Handler: type) type { }; try self.handler.setMouseShape(shape); - } else log.warn("unimplemented OSC callback: {}", .{cmd}); + return; + } }, .report_default_color => |v| { if (@hasDecl(T, "reportDefaultColor")) { try self.handler.reportDefaultColor(v.kind, v.terminator); - } else log.warn("unimplemented OSC callback: {}", .{cmd}); + return; + } }, - else => if (@hasDecl(T, "oscUnimplemented")) - try self.handler.oscUnimplemented(cmd) - else - log.warn("unimplemented OSC command: {}", .{cmd}), + else => {}, + } + + // Fall through for when we don't have a handler. + if (@hasDecl(T, "oscUnimplemented")) { + try self.handler.oscUnimplemented(cmd); + } else { + log.warn("unimplemented OSC command: {s}", .{@tagName(cmd)}); } } @@ -1598,3 +1613,28 @@ test "stream: insert characters" { for ("\x1B[?42@") |c| try s.next(c); try testing.expect(!s.handler.called); } + +test "stream: too many csi params" { + const H = struct { + pub fn setCursorRight(self: *@This(), v: u16) !void { + _ = v; + _ = self; + unreachable; + } + }; + + var s: Stream(H) = .{ .handler = .{} }; + try s.nextSlice("\x1B[1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1C"); +} + +test "stream: csi param too long" { + const H = struct { + pub fn setCursorRight(self: *@This(), v: u16) !void { + _ = v; + _ = self; + } + }; + + var s: Stream(H) = .{ .handler = .{} }; + try s.nextSlice("\x1B[1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111C"); +}