mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-07-11 03:39:36 +00:00
terminal: reserve pwd terminator atomically
setPwd appended the path bytes and terminating NUL with separate fallible operations. If only the terminator allocation failed, the function returned OutOfMemory but left a nonempty unterminated buffer that made getPwd panic on its sentinel check. Reserve checked capacity for the complete sentinel-terminated value before clearing the old state, then use infallible appends. Allocation failure now leaves a valid prior value instead of exposing partial data.
This commit is contained in:
@@ -3556,11 +3556,18 @@ pub fn resize(
|
||||
|
||||
/// Set the pwd for the terminal.
|
||||
pub fn setPwd(self: *Terminal, pwd: []const u8) !void {
|
||||
self.pwd.clearRetainingCapacity();
|
||||
if (pwd.len > 0) {
|
||||
try self.pwd.appendSlice(self.gpa(), pwd);
|
||||
try self.pwd.append(self.gpa(), 0);
|
||||
if (pwd.len == 0) {
|
||||
self.pwd.clearRetainingCapacity();
|
||||
return;
|
||||
}
|
||||
|
||||
const capacity = std.math.add(usize, pwd.len, 1) catch
|
||||
return error.OutOfMemory;
|
||||
try self.pwd.ensureTotalCapacity(self.gpa(), capacity);
|
||||
|
||||
self.pwd.clearRetainingCapacity();
|
||||
self.pwd.appendSliceAssumeCapacity(pwd);
|
||||
self.pwd.appendAssumeCapacity(0);
|
||||
}
|
||||
|
||||
/// Returns the pwd for the terminal, if any. The memory is owned by the
|
||||
@@ -3570,6 +3577,18 @@ pub fn getPwd(self: *const Terminal) ?[:0]const u8 {
|
||||
return self.pwd.items[0 .. self.pwd.items.len - 1 :0];
|
||||
}
|
||||
|
||||
test "Terminal: setPwd preserves a sentinel on allocation failure" {
|
||||
var failing = testing.FailingAllocator.init(testing.allocator, .{});
|
||||
const alloc = failing.allocator();
|
||||
var t = try init(alloc, .{ .cols = 5, .rows = 1 });
|
||||
defer t.deinit(alloc);
|
||||
|
||||
try t.pwd.ensureTotalCapacityPrecise(alloc, 3);
|
||||
failing.fail_index = failing.alloc_index;
|
||||
try testing.expectError(error.OutOfMemory, t.setPwd("pwd"));
|
||||
try testing.expect(t.getPwd() == null);
|
||||
}
|
||||
|
||||
/// Set the title for the terminal, as set by escape sequences (e.g. OSC 0/2).
|
||||
pub fn setTitle(self: *Terminal, t: []const u8) !void {
|
||||
self.title.clearRetainingCapacity();
|
||||
|
||||
Reference in New Issue
Block a user