mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
kittygfx: Ensure temporary files are named per spec (#4451)
Temporary files used with Kitty graphics must have "tty-graphics-protocol" somewhere in their full path. https://sw.kovidgoyal.net/kitty/graphics-protocol/#the-transmission-medium
This commit is contained in:
@ -382,6 +382,7 @@ fn encodeError(r: *Response, err: EncodeableError) void {
|
|||||||
error.DecompressionFailed => r.message = "EINVAL: decompression failed",
|
error.DecompressionFailed => r.message = "EINVAL: decompression failed",
|
||||||
error.FilePathTooLong => r.message = "EINVAL: file path too long",
|
error.FilePathTooLong => r.message = "EINVAL: file path too long",
|
||||||
error.TemporaryFileNotInTempDir => r.message = "EINVAL: temporary file not in temp dir",
|
error.TemporaryFileNotInTempDir => r.message = "EINVAL: temporary file not in temp dir",
|
||||||
|
error.TemporaryFileNotNamedCorrectly => r.message = "EINVAL: temporary file not named correctly",
|
||||||
error.UnsupportedFormat => r.message = "EINVAL: unsupported format",
|
error.UnsupportedFormat => r.message = "EINVAL: unsupported format",
|
||||||
error.UnsupportedMedium => r.message = "EINVAL: unsupported medium",
|
error.UnsupportedMedium => r.message = "EINVAL: unsupported medium",
|
||||||
error.UnsupportedDepth => r.message = "EINVAL: unsupported pixel depth",
|
error.UnsupportedDepth => r.message = "EINVAL: unsupported pixel depth",
|
||||||
|
@ -220,6 +220,9 @@ pub const LoadingImage = struct {
|
|||||||
// Temporary file logic
|
// Temporary file logic
|
||||||
if (medium == .temporary_file) {
|
if (medium == .temporary_file) {
|
||||||
if (!isPathInTempDir(path)) return error.TemporaryFileNotInTempDir;
|
if (!isPathInTempDir(path)) return error.TemporaryFileNotInTempDir;
|
||||||
|
if (std.mem.indexOf(u8, path, "tty-graphics-protocol") == null) {
|
||||||
|
return error.TemporaryFileNotNamedCorrectly;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
defer if (medium == .temporary_file) {
|
defer if (medium == .temporary_file) {
|
||||||
posix.unlink(path) catch |err| {
|
posix.unlink(path) catch |err| {
|
||||||
@ -469,6 +472,7 @@ pub const Image = struct {
|
|||||||
DimensionsTooLarge,
|
DimensionsTooLarge,
|
||||||
FilePathTooLong,
|
FilePathTooLong,
|
||||||
TemporaryFileNotInTempDir,
|
TemporaryFileNotInTempDir,
|
||||||
|
TemporaryFileNotNamedCorrectly,
|
||||||
UnsupportedFormat,
|
UnsupportedFormat,
|
||||||
UnsupportedMedium,
|
UnsupportedMedium,
|
||||||
UnsupportedDepth,
|
UnsupportedDepth,
|
||||||
@ -682,7 +686,7 @@ test "image load: rgb, zlib compressed, direct, chunked with zero initial chunk"
|
|||||||
try testing.expect(img.compression == .none);
|
try testing.expect(img.compression == .none);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "image load: rgb, not compressed, temporary file" {
|
test "image load: temporary file without correct path" {
|
||||||
const testing = std.testing;
|
const testing = std.testing;
|
||||||
const alloc = testing.allocator;
|
const alloc = testing.allocator;
|
||||||
|
|
||||||
@ -697,6 +701,39 @@ test "image load: rgb, not compressed, temporary file" {
|
|||||||
var buf: [std.fs.max_path_bytes]u8 = undefined;
|
var buf: [std.fs.max_path_bytes]u8 = undefined;
|
||||||
const path = try tmp_dir.dir.realpath("image.data", &buf);
|
const path = try tmp_dir.dir.realpath("image.data", &buf);
|
||||||
|
|
||||||
|
var cmd: command.Command = .{
|
||||||
|
.control = .{ .transmit = .{
|
||||||
|
.format = .rgb,
|
||||||
|
.medium = .temporary_file,
|
||||||
|
.compression = .none,
|
||||||
|
.width = 20,
|
||||||
|
.height = 15,
|
||||||
|
.image_id = 31,
|
||||||
|
} },
|
||||||
|
.data = try alloc.dupe(u8, path),
|
||||||
|
};
|
||||||
|
defer cmd.deinit(alloc);
|
||||||
|
try testing.expectError(error.TemporaryFileNotNamedCorrectly, LoadingImage.init(alloc, &cmd));
|
||||||
|
|
||||||
|
// Temporary file should still be there
|
||||||
|
try tmp_dir.dir.access(path, .{});
|
||||||
|
}
|
||||||
|
|
||||||
|
test "image load: rgb, not compressed, temporary file" {
|
||||||
|
const testing = std.testing;
|
||||||
|
const alloc = testing.allocator;
|
||||||
|
|
||||||
|
var tmp_dir = try internal_os.TempDir.init();
|
||||||
|
defer tmp_dir.deinit();
|
||||||
|
const data = @embedFile("testdata/image-rgb-none-20x15-2147483647-raw.data");
|
||||||
|
try tmp_dir.dir.writeFile(.{
|
||||||
|
.sub_path = "tty-graphics-protocol-image.data",
|
||||||
|
.data = data,
|
||||||
|
});
|
||||||
|
|
||||||
|
var buf: [std.fs.max_path_bytes]u8 = undefined;
|
||||||
|
const path = try tmp_dir.dir.realpath("tty-graphics-protocol-image.data", &buf);
|
||||||
|
|
||||||
var cmd: command.Command = .{
|
var cmd: command.Command = .{
|
||||||
.control = .{ .transmit = .{
|
.control = .{ .transmit = .{
|
||||||
.format = .rgb,
|
.format = .rgb,
|
||||||
@ -762,12 +799,12 @@ test "image load: png, not compressed, regular file" {
|
|||||||
defer tmp_dir.deinit();
|
defer tmp_dir.deinit();
|
||||||
const data = @embedFile("testdata/image-png-none-50x76-2147483647-raw.data");
|
const data = @embedFile("testdata/image-png-none-50x76-2147483647-raw.data");
|
||||||
try tmp_dir.dir.writeFile(.{
|
try tmp_dir.dir.writeFile(.{
|
||||||
.sub_path = "image.data",
|
.sub_path = "tty-graphics-protocol-image.data",
|
||||||
.data = data,
|
.data = data,
|
||||||
});
|
});
|
||||||
|
|
||||||
var buf: [std.fs.max_path_bytes]u8 = undefined;
|
var buf: [std.fs.max_path_bytes]u8 = undefined;
|
||||||
const path = try tmp_dir.dir.realpath("image.data", &buf);
|
const path = try tmp_dir.dir.realpath("tty-graphics-protocol-image.data", &buf);
|
||||||
|
|
||||||
var cmd: command.Command = .{
|
var cmd: command.Command = .{
|
||||||
.control = .{ .transmit = .{
|
.control = .{ .transmit = .{
|
||||||
|
Reference in New Issue
Block a user