diff --git a/src/terminal/kitty/graphics_image.zig b/src/terminal/kitty/graphics_image.zig index 4eb0d2f9d..8a6ecacd5 100644 --- a/src/terminal/kitty/graphics_image.zig +++ b/src/terminal/kitty/graphics_image.zig @@ -123,6 +123,16 @@ pub const LoadingImage = struct { else => @compileError("readFile only supports file and temporary_file"), } + // Verify file seems "safe". This is logic copied directly from Kitty, + // mostly. This is really rough but it will catch obvious bad actors. + if (std.mem.startsWith(u8, path, "/proc/") or + std.mem.startsWith(u8, path, "/sys/") or + (std.mem.startsWith(u8, path, "/dev/") and + !std.mem.startsWith(u8, path, "/dev/shm/"))) + { + return error.InvalidData; + } + // Temporary file logic if (medium == .temporary_file) { if (!isPathInTempDir(path)) return error.TemporaryFileNotInTempDir; @@ -139,6 +149,17 @@ pub const LoadingImage = struct { }; defer file.close(); + // File must be a regular file + if (file.stat()) |stat| { + if (stat.kind != .file) { + log.warn("file is not a regular file kind={}", .{stat.kind}); + return error.InvalidData; + } + } else |err| { + log.warn("failed to stat file: {}", .{err}); + return error.InvalidData; + } + if (t.offset > 0) { file.seekTo(@intCast(t.offset)) catch |err| { log.warn("failed to seek to offset {}: {}", .{ t.offset, err });