terminal: reserve title terminator atomically

setTitle appended the title bytes and terminating NUL with separate fallible operations. If only the terminator allocation failed, it returned OutOfMemory but left a nonempty unterminated buffer that made getTitle panic on its sentinel check.

Reserve checked capacity before clearing the existing title, then append both the title and terminator without further allocation. Allocation failure now leaves the prior valid title intact.
This commit is contained in:
Mitchell Hashimoto
2026-07-09 21:41:22 -07:00
parent 1d5b6f90e5
commit fdd255c782

View File

@@ -3591,11 +3591,18 @@ test "Terminal: setPwd preserves a sentinel on allocation failure" {
/// 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();
if (t.len > 0) {
try self.title.appendSlice(self.gpa(), t);
try self.title.append(self.gpa(), 0);
if (t.len == 0) {
self.title.clearRetainingCapacity();
return;
}
const capacity = std.math.add(usize, t.len, 1) catch
return error.OutOfMemory;
try self.title.ensureTotalCapacity(self.gpa(), capacity);
self.title.clearRetainingCapacity();
self.title.appendSliceAssumeCapacity(t);
self.title.appendAssumeCapacity(0);
}
/// Returns the title for the terminal, if any. The memory is owned by the
@@ -3605,6 +3612,18 @@ pub fn getTitle(self: *const Terminal) ?[:0]const u8 {
return self.title.items[0 .. self.title.items.len - 1 :0];
}
test "Terminal: setTitle 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.title.ensureTotalCapacityPrecise(alloc, 5);
failing.fail_index = failing.alloc_index;
try testing.expectError(error.OutOfMemory, t.setTitle("title"));
try testing.expect(t.getTitle() == null);
}
/// Switch to the given screen type (alternate or primary).
///
/// This does NOT handle behaviors such as clearing the screen,