mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-17 09:16:11 +03:00
Merge pull request #1499 from marler8997/fixWindowsTmpDir
os: remove UB, tmpDir is returning stack memory on Windows
This commit is contained in:
@ -31,7 +31,8 @@ pub fn init() !TempDir {
|
|||||||
|
|
||||||
const dir = dir: {
|
const dir = dir: {
|
||||||
const cwd = std.fs.cwd();
|
const cwd = std.fs.cwd();
|
||||||
const tmp_dir = internal_os.tmpDir() orelse break :dir cwd;
|
const tmp_dir = internal_os.allocTmpDir(std.heap.page_allocator) orelse break :dir cwd;
|
||||||
|
defer internal_os.freeTmpDir(std.heap.page_allocator, tmp_dir);
|
||||||
break :dir try cwd.openDir(tmp_dir, .{});
|
break :dir try cwd.openDir(tmp_dir, .{});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -44,22 +44,26 @@ pub fn fixMaxFiles() void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Return the recommended path for temporary files.
|
/// Return the recommended path for temporary files.
|
||||||
pub fn tmpDir() ?[]const u8 {
|
/// This may not actually allocate memory, use freeTmpDir to properly
|
||||||
|
/// free the memory when applicable.
|
||||||
|
pub fn allocTmpDir(allocator: std.mem.Allocator) ?[]const u8 {
|
||||||
if (builtin.os.tag == .windows) {
|
if (builtin.os.tag == .windows) {
|
||||||
// TODO: what is a good fallback path on windows?
|
// TODO: what is a good fallback path on windows?
|
||||||
const v = std.os.getenvW(std.unicode.utf8ToUtf16LeStringLiteral("TMP")) orelse return null;
|
const v = std.os.getenvW(std.unicode.utf8ToUtf16LeStringLiteral("TMP")) orelse return null;
|
||||||
// MAX_PATH is very likely sufficient, but it's theoretically possible for someone to
|
return std.unicode.utf16leToUtf8Alloc(allocator, v) catch |e| {
|
||||||
// configure their os to allow paths as big as std.os.windows.PATH_MAX_WIDE, which is MUCH
|
|
||||||
// larger. Even if they did that, though, it's very unlikey that their Temp dir will use
|
|
||||||
// such a long path. We can switch if we see any issues, though it seems fairly unlikely.
|
|
||||||
var buf = [_]u8{0} ** std.os.windows.MAX_PATH;
|
|
||||||
const len = std.unicode.utf16leToUtf8(buf[0..], v[0..v.len]) catch |e| {
|
|
||||||
log.warn("failed to convert temp dir path from windows string: {}", .{e});
|
log.warn("failed to convert temp dir path from windows string: {}", .{e});
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
return buf[0..len];
|
|
||||||
}
|
}
|
||||||
if (std.os.getenv("TMPDIR")) |v| return v;
|
if (std.os.getenv("TMPDIR")) |v| return v;
|
||||||
if (std.os.getenv("TMP")) |v| return v;
|
if (std.os.getenv("TMP")) |v| return v;
|
||||||
return "/tmp";
|
return "/tmp";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Free a path returned by tmpDir if it allocated memory.
|
||||||
|
/// This is a "no-op" for all platforms except windows.
|
||||||
|
pub fn freeTmpDir(allocator: std.mem.Allocator, dir: []const u8) void {
|
||||||
|
if (builtin.os.tag == .windows) {
|
||||||
|
allocator.free(dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -192,7 +192,8 @@ pub const LoadingImage = struct {
|
|||||||
fn isPathInTempDir(path: []const u8) bool {
|
fn isPathInTempDir(path: []const u8) bool {
|
||||||
if (std.mem.startsWith(u8, path, "/tmp")) return true;
|
if (std.mem.startsWith(u8, path, "/tmp")) return true;
|
||||||
if (std.mem.startsWith(u8, path, "/dev/shm")) return true;
|
if (std.mem.startsWith(u8, path, "/dev/shm")) return true;
|
||||||
if (internal_os.tmpDir()) |dir| {
|
if (internal_os.allocTmpDir(std.heap.page_allocator)) |dir| {
|
||||||
|
defer internal_os.freeTmpDir(std.heap.page_allocator, dir);
|
||||||
if (std.mem.startsWith(u8, path, dir)) return true;
|
if (std.mem.startsWith(u8, path, dir)) return true;
|
||||||
|
|
||||||
// The temporary dir is sometimes a symlink. On macOS for
|
// The temporary dir is sometimes a symlink. On macOS for
|
||||||
|
Reference in New Issue
Block a user