mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-07-12 12:19:47 +00:00
terminal: preserve tabstops on resize failure
Terminal.resize deinitialized the current tab stops before allocating their replacement. If a resize beyond the inline tab-stop capacity ran out of memory, the terminal retained an undefined tab-stop value and normal deinitialization dereferenced a poisoned pointer. Allocate and initialize the replacement first, then release the old tab stops only after allocation succeeds. A failed resize now retains the original tab stops and remains safe to destroy.
This commit is contained in:
@@ -3518,8 +3518,13 @@ pub fn resize(
|
||||
|
||||
// Resize our tabstops
|
||||
if (self.cols != cols) {
|
||||
const tabstops: Tabstops = try .init(
|
||||
alloc,
|
||||
cols,
|
||||
TABSTOP_INTERVAL,
|
||||
);
|
||||
self.tabstops.deinit(alloc);
|
||||
self.tabstops = try .init(alloc, cols, 8);
|
||||
self.tabstops = tabstops;
|
||||
}
|
||||
|
||||
// Resize primary screen, which supports reflow
|
||||
@@ -3554,6 +3559,19 @@ pub fn resize(
|
||||
};
|
||||
}
|
||||
|
||||
test "Terminal: resize preserves tabstops on allocation failure" {
|
||||
var failing = testing.FailingAllocator.init(testing.allocator, .{});
|
||||
const alloc = failing.allocator();
|
||||
var t = try init(alloc, .{ .cols = 10, .rows = 1 });
|
||||
defer t.deinit(alloc);
|
||||
|
||||
failing.fail_index = failing.alloc_index;
|
||||
try testing.expectError(error.OutOfMemory, t.resize(alloc, 513, 1));
|
||||
|
||||
try testing.expectEqual(@as(size.CellCountInt, 10), t.cols);
|
||||
try testing.expect(t.tabstops.get(8));
|
||||
}
|
||||
|
||||
/// Set the pwd for the terminal.
|
||||
pub fn setPwd(self: *Terminal, pwd: []const u8) !void {
|
||||
if (pwd.len == 0) {
|
||||
|
||||
Reference in New Issue
Block a user