From 5dee7e1430c186ba72d1fa8610a9711601b86b61 Mon Sep 17 00:00:00 2001 From: Qwerasd Date: Sun, 31 Mar 2024 19:29:56 -0400 Subject: [PATCH 1/4] terminal/kitty_graphics: update outdated comments --- src/terminal/kitty/graphics_command.zig | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/terminal/kitty/graphics_command.zig b/src/terminal/kitty/graphics_command.zig index ca7a4d674..9f321c447 100644 --- a/src/terminal/kitty/graphics_command.zig +++ b/src/terminal/kitty/graphics_command.zig @@ -27,8 +27,11 @@ pub const CommandParser = struct { kv_temp_len: u4 = 0, kv_current: u8 = 0, // Current kv key - /// This is the list of bytes that contains both KV data and final - /// data. You shouldn't access this directly. + /// This is the list we use to collect the bytes from the data payload. + /// The Kitty Graphics protocol specification seems to imply that the + /// payload content of a single command should never exceed 4096 bytes, + /// but Kitty itself supports larger payloads, so we use an ArrayList + /// here instead of a fixed buffer so that we can too. data: std.ArrayList(u8), /// Internal state for parsing. @@ -42,7 +45,7 @@ pub const CommandParser = struct { control_value, control_value_ignore, - /// We're parsing the data blob. + /// Collecting the data payload blob. data, }; @@ -106,9 +109,6 @@ pub const CommandParser = struct { .data => try self.data.append(c), } - - // We always add to our data list because this is our stable - // array of bytes that we'll reference everywhere else. } /// Complete the parsing. This must be called after all the From ca4b55b486779c7523d1478a93de953b110b90ec Mon Sep 17 00:00:00 2001 From: Qwerasd Date: Sun, 31 Mar 2024 21:09:37 -0400 Subject: [PATCH 2/4] terminal/kitty_graphics: ignore base64 padding Also move all base64 decoding to inside of the command parser. --- src/terminal/kitty/graphics_command.zig | 41 ++++++++++++++++-- src/terminal/kitty/graphics_image.zig | 56 ++++++------------------- 2 files changed, 51 insertions(+), 46 deletions(-) diff --git a/src/terminal/kitty/graphics_command.zig b/src/terminal/kitty/graphics_command.zig index 9f321c447..fe8149d9a 100644 --- a/src/terminal/kitty/graphics_command.zig +++ b/src/terminal/kitty/graphics_command.zig @@ -3,6 +3,8 @@ const assert = std.debug.assert; const Allocator = std.mem.Allocator; const ArenaAllocator = std.heap.ArenaAllocator; +const log = std.log.scoped(.kitty_gfx); + /// The key-value pairs for the control information for a command. The /// keys are always single characters and the values are either single /// characters or 32-bit unsigned integers. @@ -165,12 +167,45 @@ pub const CommandParser = struct { return .{ .control = control, .quiet = quiet, - .data = if (self.data.items.len == 0) "" else data: { - break :data try self.data.toOwnedSlice(); - }, + .data = try self.decodeData(), }; } + /// Decodes the payload data from base64 and returns it as a slice. + /// This function will destroy the contents of self.data, it should + /// only be used once we are done collecting payload bytes. + fn decodeData(self: *CommandParser) ![]const u8 { + if (self.data.items.len == 0) { + return ""; + } + + const Base64Decoder = std.base64.standard_no_pad.Decoder; + + // We remove any padding, since it's optional, and decode without it. + while (self.data.items[self.data.items.len - 1] == '=') { + self.data.items.len -= 1; + } + + const size = Base64Decoder.calcSizeForSlice(self.data.items) catch |err| { + log.warn("failed to calculate base64 size for payload: {}", .{err}); + return error.InvalidData; + }; + + // This is kinda cursed, but we can decode the base64 on top of + // itself, since it's guaranteed that the encoded size is larger, + // and any bytes in areas that are written to will have already + // been used (assuming scalar decoding). + Base64Decoder.decode(self.data.items[0..size], self.data.items) catch |err| { + log.warn("failed to decode base64 payload data: {}", .{err}); + return error.InvalidData; + }; + + // Remove the extra bytes. + self.data.items.len = size; + + return try self.data.toOwnedSlice(); + } + fn accumulateValue(self: *CommandParser, c: u8, overflow_state: State) !void { const idx = self.kv_temp_len; self.kv_temp_len += 1; diff --git a/src/terminal/kitty/graphics_image.zig b/src/terminal/kitty/graphics_image.zig index 4f3e3e48f..c661a8a24 100644 --- a/src/terminal/kitty/graphics_image.zig +++ b/src/terminal/kitty/graphics_image.zig @@ -5,6 +5,7 @@ const Allocator = std.mem.Allocator; const ArenaAllocator = std.heap.ArenaAllocator; const posix = std.posix; +const fastmem = @import("../../fastmem.zig"); const command = @import("graphics_command.zig"); const point = @import("../point.zig"); const PageList = @import("../PageList.zig"); @@ -56,30 +57,16 @@ pub const LoadingImage = struct { .display = cmd.display(), }; - // Special case for the direct medium, we just add it directly - // which will handle copying the data, base64 decoding, etc. + // Special case for the direct medium, we just add the chunk directly. if (t.medium == .direct) { try result.addData(alloc, cmd.data); return result; } - // For every other medium, we'll need to at least base64 decode - // the data to make it useful so let's do that. Also, all the data - // has to be path data so we can put it in a stack-allocated buffer. - var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined; - const Base64Decoder = std.base64.standard.Decoder; - const size = Base64Decoder.calcSizeForSlice(cmd.data) catch |err| { - log.warn("failed to calculate base64 size for file path: {}", .{err}); - return error.InvalidData; - }; - if (size > buf.len) return error.FilePathTooLong; - Base64Decoder.decode(&buf, cmd.data) catch |err| { - log.warn("failed to decode base64 data: {}", .{err}); - return error.InvalidData; - }; + // Otherwise, the payload data is guaranteed to be a path. if (comptime builtin.os.tag != .windows) { - if (std.mem.indexOfScalar(u8, buf[0..size], 0) != null) { + if (std.mem.indexOfScalar(u8, cmd.data, 0) != null) { // posix.realpath *asserts* that the path does not have // internal nulls instead of erroring. log.warn("failed to get absolute path: BadPathName", .{}); @@ -88,7 +75,7 @@ pub const LoadingImage = struct { } var abs_buf: [std.fs.MAX_PATH_BYTES]u8 = undefined; - const path = posix.realpath(buf[0..size], &abs_buf) catch |err| { + const path = posix.realpath(cmd.data, &abs_buf) catch |err| { log.warn("failed to get absolute path: {}", .{err}); return error.InvalidData; }; @@ -229,42 +216,25 @@ pub const LoadingImage = struct { alloc.destroy(self); } - /// Adds a chunk of base64-encoded data to the image. Use this if the - /// image is coming in chunks (the "m" parameter in the protocol). + /// Adds a chunk of data to the image. Use this if the image + /// is coming in chunks (the "m" parameter in the protocol). pub fn addData(self: *LoadingImage, alloc: Allocator, data: []const u8) !void { // If no data, skip if (data.len == 0) return; - // Grow our array list by size capacity if it needs it - const Base64Decoder = std.base64.standard.Decoder; - const size = Base64Decoder.calcSizeForSlice(data) catch |err| { - log.warn("failed to calculate size for base64 data: {}", .{err}); - return error.InvalidData; - }; - // If our data would get too big, return an error - if (self.data.items.len + size > max_size) { + if (self.data.items.len + data.len > max_size) { log.warn("image data too large max_size={}", .{max_size}); return error.InvalidData; } - try self.data.ensureUnusedCapacity(alloc, size); + // Ensure we have enough room to add the data + // to the end of the ArrayList before doing so. + try self.data.ensureUnusedCapacity(alloc, data.len); - // We decode directly into the arraylist const start_i = self.data.items.len; - self.data.items.len = start_i + size; - const buf = self.data.items[start_i..]; - Base64Decoder.decode(buf, data) catch |err| switch (err) { - // We have to ignore invalid padding because lots of encoders - // add the wrong padding. Since we validate image data later - // (PNG decode or simple dimensions check), we can ignore this. - error.InvalidPadding => {}, - - else => { - log.warn("failed to decode base64 data: {}", .{err}); - return error.InvalidData; - }, - }; + self.data.items.len = start_i + data.len; + fastmem.copy(u8, self.data.items[start_i..], data); } /// Complete the chunked image, returning a completed image. From 51d3c2cf351cbf378269f89561f3d412d90a387c Mon Sep 17 00:00:00 2001 From: Qwerasd Date: Sun, 31 Mar 2024 21:49:28 -0400 Subject: [PATCH 3/4] fix(kitty_graphics): set dirty state on various scroll operations --- src/terminal/Screen.zig | 3 +++ src/terminal/Terminal.zig | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/src/terminal/Screen.zig b/src/terminal/Screen.zig index 96c84ce9b..a295f0ce5 100644 --- a/src/terminal/Screen.zig +++ b/src/terminal/Screen.zig @@ -540,6 +540,9 @@ pub fn cursorDownScroll(self: *Screen) !void { assert(self.cursor.y == self.pages.rows - 1); defer self.assertIntegrity(); + // Scrolling dirties the images because it updates their placements pins. + self.kitty_images.dirty = true; + // If we have no scrollback, then we shift all our rows instead. if (self.no_scrollback) { // If we have a single-row screen, we have no rows to shift diff --git a/src/terminal/Terminal.zig b/src/terminal/Terminal.zig index 70bf9cfcc..d002b47ec 100644 --- a/src/terminal/Terminal.zig +++ b/src/terminal/Terminal.zig @@ -1075,6 +1075,9 @@ pub fn index(self: *Terminal) !void { self.screen.cursor.x >= self.scrolling_region.left and self.screen.cursor.x <= self.scrolling_region.right) { + // Scrolling dirties the images because it updates their placements pins. + self.screen.kitty_images.dirty = true; + // If our scrolling region is the full screen, we create scrollback. // Otherwise, we simply scroll the region. if (self.scrolling_region.top == 0 and @@ -1391,6 +1394,9 @@ pub fn insertLines(self: *Terminal, count: usize) void { self.screen.cursor.x < self.scrolling_region.left or self.screen.cursor.x > self.scrolling_region.right) return; + // Scrolling dirties the images because it updates their placements pins. + self.screen.kitty_images.dirty = true; + // Remaining rows from our cursor to the bottom of the scroll region. const rem = self.scrolling_region.bottom - self.screen.cursor.y + 1; @@ -1534,6 +1540,9 @@ pub fn deleteLines(self: *Terminal, count_req: usize) void { self.screen.cursor.x < self.scrolling_region.left or self.screen.cursor.x > self.scrolling_region.right) return; + // Scrolling dirties the images because it updates their placements pins. + self.screen.kitty_images.dirty = true; + // top is just the cursor position. insertLines starts at the cursor // so this is our top. We want to shift lines down, down to the bottom // of the scroll region. From 04ec8599251db4dcb23b3e5070d60a378cbdb4fd Mon Sep 17 00:00:00 2001 From: Qwerasd Date: Sun, 31 Mar 2024 22:28:53 -0400 Subject: [PATCH 4/4] terminal/kitty_graphics: update tests Kitty Graphics command structures have been changed to hold decoded payloads not base64 strings. --- src/terminal/kitty/graphics_command.zig | 2 +- src/terminal/kitty/graphics_image.zig | 43 ++++-------------- .../image-rgb-none-20x15-2147483647-raw.data | Bin 0 -> 900 bytes .../image-rgb-none-20x15-2147483647.data | 1 - ...gb-zlib_deflate-128x96-2147483647-raw.data | Bin 0 -> 30455 bytes ...ge-rgb-zlib_deflate-128x96-2147483647.data | 1 - 6 files changed, 10 insertions(+), 37 deletions(-) create mode 100644 src/terminal/kitty/testdata/image-rgb-none-20x15-2147483647-raw.data delete mode 100644 src/terminal/kitty/testdata/image-rgb-none-20x15-2147483647.data create mode 100644 src/terminal/kitty/testdata/image-rgb-zlib_deflate-128x96-2147483647-raw.data delete mode 100644 src/terminal/kitty/testdata/image-rgb-zlib_deflate-128x96-2147483647.data diff --git a/src/terminal/kitty/graphics_command.zig b/src/terminal/kitty/graphics_command.zig index fe8149d9a..b8d0b0b7d 100644 --- a/src/terminal/kitty/graphics_command.zig +++ b/src/terminal/kitty/graphics_command.zig @@ -890,7 +890,7 @@ test "query command" { var p = CommandParser.init(alloc); defer p.deinit(); - const input = "i=31,s=1,v=1,a=q,t=d,f=24;AAAA"; + const input = "i=31,s=1,v=1,a=q,t=d,f=24;QUFBQQ"; for (input) |c| try p.feed(c); const command = try p.complete(); defer command.deinit(alloc); diff --git a/src/terminal/kitty/graphics_image.zig b/src/terminal/kitty/graphics_image.zig index c661a8a24..09e9376e2 100644 --- a/src/terminal/kitty/graphics_image.zig +++ b/src/terminal/kitty/graphics_image.zig @@ -427,23 +427,6 @@ pub const Rect = struct { bottom_right: PageList.Pin, }; -/// Easy base64 encoding function. -fn testB64(alloc: Allocator, data: []const u8) ![]const u8 { - const B64Encoder = std.base64.standard.Encoder; - const b64 = try alloc.alloc(u8, B64Encoder.calcSize(data.len)); - errdefer alloc.free(b64); - return B64Encoder.encode(b64, data); -} - -/// Easy base64 decoding function. -fn testB64Decode(alloc: Allocator, data: []const u8) ![]const u8 { - const B64Decoder = std.base64.standard.Decoder; - const result = try alloc.alloc(u8, try B64Decoder.calcSizeForSlice(data)); - errdefer alloc.free(result); - try B64Decoder.decode(result, data); - return result; -} - // This specifically tests we ALLOW invalid RGB data because Kitty // documents that this should work. test "image load with invalid RGB data" { @@ -518,7 +501,7 @@ test "image load: rgb, zlib compressed, direct" { } }, .data = try alloc.dupe( u8, - @embedFile("testdata/image-rgb-zlib_deflate-128x96-2147483647.data"), + @embedFile("testdata/image-rgb-zlib_deflate-128x96-2147483647-raw.data"), ), }; defer cmd.deinit(alloc); @@ -546,7 +529,7 @@ test "image load: rgb, not compressed, direct" { } }, .data = try alloc.dupe( u8, - @embedFile("testdata/image-rgb-none-20x15-2147483647.data"), + @embedFile("testdata/image-rgb-none-20x15-2147483647-raw.data"), ), }; defer cmd.deinit(alloc); @@ -563,7 +546,7 @@ test "image load: rgb, zlib compressed, direct, chunked" { const testing = std.testing; const alloc = testing.allocator; - const data = @embedFile("testdata/image-rgb-zlib_deflate-128x96-2147483647.data"); + const data = @embedFile("testdata/image-rgb-zlib_deflate-128x96-2147483647-raw.data"); // Setup our initial chunk var cmd: command.Command = .{ @@ -600,7 +583,7 @@ test "image load: rgb, zlib compressed, direct, chunked with zero initial chunk" const testing = std.testing; const alloc = testing.allocator; - const data = @embedFile("testdata/image-rgb-zlib_deflate-128x96-2147483647.data"); + const data = @embedFile("testdata/image-rgb-zlib_deflate-128x96-2147483647-raw.data"); // Setup our initial chunk var cmd: command.Command = .{ @@ -638,11 +621,7 @@ test "image load: rgb, not compressed, temporary file" { var tmp_dir = try internal_os.TempDir.init(); defer tmp_dir.deinit(); - const data = try testB64Decode( - alloc, - @embedFile("testdata/image-rgb-none-20x15-2147483647.data"), - ); - defer alloc.free(data); + const data = @embedFile("testdata/image-rgb-none-20x15-2147483647-raw.data"); try tmp_dir.dir.writeFile("image.data", data); var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined; @@ -657,7 +636,7 @@ test "image load: rgb, not compressed, temporary file" { .height = 15, .image_id = 31, } }, - .data = try testB64(alloc, path), + .data = try alloc.dupe(u8, path), }; defer cmd.deinit(alloc); var loading = try LoadingImage.init(alloc, &cmd); @@ -676,11 +655,7 @@ test "image load: rgb, not compressed, regular file" { var tmp_dir = try internal_os.TempDir.init(); defer tmp_dir.deinit(); - const data = try testB64Decode( - alloc, - @embedFile("testdata/image-rgb-none-20x15-2147483647.data"), - ); - defer alloc.free(data); + const data = @embedFile("testdata/image-rgb-none-20x15-2147483647-raw.data"); try tmp_dir.dir.writeFile("image.data", data); var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined; @@ -695,7 +670,7 @@ test "image load: rgb, not compressed, regular file" { .height = 15, .image_id = 31, } }, - .data = try testB64(alloc, path), + .data = try alloc.dupe(u8, path), }; defer cmd.deinit(alloc); var loading = try LoadingImage.init(alloc, &cmd); @@ -727,7 +702,7 @@ test "image load: png, not compressed, regular file" { .height = 0, .image_id = 31, } }, - .data = try testB64(alloc, path), + .data = try alloc.dupe(u8, path), }; defer cmd.deinit(alloc); var loading = try LoadingImage.init(alloc, &cmd); diff --git a/src/terminal/kitty/testdata/image-rgb-none-20x15-2147483647-raw.data b/src/terminal/kitty/testdata/image-rgb-none-20x15-2147483647-raw.data new file mode 100644 index 0000000000000000000000000000000000000000..2c070cb2a1a30ef256c40d5909376e1d049a40a6 GIT binary patch literal 900 zcmV-~1AF`p8XgN6919mC5*{iH7$gf9BMKHG3l}2^7bOJ~AqNr{A1g0SQ&DVkaB*;U zE-f<%78esCA`2NB3>q5>7aIr_84nvL1P~k$94HDFA`2HI3>YL194ZGDBMcWDo2IJE z(a+S{*v`$=u&=fvFfj-g7YG&?2Nf0+8X6B36(A-mBPlHr7a0!~7Y`K`5*Qc`6%z{* z5E>sBy1=;1&c(dGwX3J4nU#}GTU-np8x0#A3mFbj6 z1P~I$z`?e%v#O@2p`D(Mhl_Y|c6o7chJJjWmyflsrk9Y4fqHaXSWjtYU1eudVq{Mi zCIAf`02Cwu6C(h(v$T|uk$-!9cyx7UUu0ukVPRTWY-D12a%y;SX?1OAb8BXBZDe0u zQ*CcrjgNYco_Ud>e2}1fk)eFBuB&o!ZC_nnTv}OMT2@$BQ(an9URzXXVqjxkTVq{a zYh`6?Ze40^TyT3+o~ePNwQZ-ma-_F!p|os=hJt8kV^~&ITv}OSU|eTrVrXSvWMNuk zU0Y&YT31m~XJKJU5NjG$YZsB4+0 zYLK2`i(7m_1r*Um;URqg) aj$)~>gqW#inW|=*scN3BZk?=cps#SQ#E#qm literal 0 HcmV?d00001 diff --git a/src/terminal/kitty/testdata/image-rgb-none-20x15-2147483647.data b/src/terminal/kitty/testdata/image-rgb-none-20x15-2147483647.data deleted file mode 100644 index f65d40ce8..000000000 --- a/src/terminal/kitty/testdata/image-rgb-none-20x15-2147483647.data +++ /dev/null @@ -1 +0,0 @@ -DRoeCxgcCxcjEh4qDBgkCxcjChYiCxcjCRclBRMhBxIXHysvTVNRbHJwcXB2Li0zCBYXEyEiCxkaDBobChcbCBUZDxsnBBAcEBwoChYiCxcjDBgkDhwqBxUjDBccm6aqy9HP1NrYzs3UsK+2IjAxCBYXCBYXBxUWFBoaDxUVICYqIyktERcZDxUXDxUVEhgYDhUTCxIQGh8XusC4zM7FvL61q6elmZWTTVtcDBobDRscCxkaKS8vaW9vxMnOur/EiY+RaW5wICYmW2FhfYOBQEZEnqSc4ebeqauilZaOsa2rm5eVcH5/GigpChgZCBYX0NHP3d7c3tzbx8XExsTEvry8wL241dLN0tDF0tDF29nM4d/StbKpzMrAUk5DZmJXeYSGKTU3ER0fDRkb1tfVysvJ0tDPsa+tr6ytop+gmZaRqaahuritw8G2urirqKaZiYZ9paKZZmJXamZbOkZIDhocBxMVBBASxMDBtrKzqqanoZ2ejYeLeHF2eXFvhn58npePta6ml5CKgXp0W1hPaWZdZWdSYmRPFiYADR0AFCQAEyMAt7O0lJCRf3t8eHR1Zl9kY1xhYVpYbGRieXJqeHFpdW1oc2tmcG1kX1xTbW9ajY96jp55kaF8kKB7kaF8sK6rcnFtX11cXFpZW1pWWFdTXVpTXltUaGJgY11bY11da2Vla25dam1ccHtTnqmBorVtp7pypLdvobRsh4aCaGdjWFZVXFpZYWBcZ2ZiaGVeZGFaY11bYlxaV1FRZ2FhdHdmbG9egItjo66GpLdvq752rL93rsF5kpKIZ2ddWFxTW19WbnZdipJ6cnhaaW9RaGhgV1ZPY2Jga2poanFQd35dk6Vpn7B0oLFvorNxm6xqmKlnv760enpwVlpRW19Wc3til5+Hl55/k5p7iIiAcnJqd3Z0bm1rcHdWh45tipxgladrkaJglKVjkaJgkqNh09DJiYZ/YmZdY2deeYZYjJlrj51ijpxhztHClJaIdHNvdHNvanNHi5RpmaxnjKBbmqhrmadqkJ5hi5lcxsO8jImCaGtiYmZdg5Bikp9xjJpfjpxh1djJqq2eamllZ2Zid4BVmKF2kqZhh5tWlaNmlaNmjpxfjJpdw729rqiodnZ0cHBuiplij55nj6FVjJ5SzdC9t7qncW1sXlpZh45iqbCEmKllmapmmqlqnq1unaxtoK9w \ No newline at end of file diff --git a/src/terminal/kitty/testdata/image-rgb-zlib_deflate-128x96-2147483647-raw.data b/src/terminal/kitty/testdata/image-rgb-zlib_deflate-128x96-2147483647-raw.data new file mode 100644 index 0000000000000000000000000000000000000000..ea816083afba88810f195212d887aca26036e0f7 GIT binary patch literal 30455 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 y6J!6tUhayUF=e