mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 15:56:13 +03:00
test: add failing test for Screen.cursorAbsolute
memory corruption
This commit is contained in:
@ -3764,6 +3764,81 @@ test "Screen: cursorAbsolute across pages preserves style" {
|
||||
}
|
||||
}
|
||||
|
||||
test "Screen: cursorAbsolute to page with insufficient capacity" {
|
||||
// This test checks for a very specific edge case
|
||||
// which previously resulted in memory corruption.
|
||||
//
|
||||
// The conditions for this edge case are as such:
|
||||
// - The cursor has an associated style or other managed memory.
|
||||
// - The cursor moves to a different page.
|
||||
// - The new page is at capacity and must have its capacity adjusted.
|
||||
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
var s = try init(alloc, 10, 3, 1);
|
||||
defer s.deinit();
|
||||
|
||||
// Scroll down enough to go to another page
|
||||
const start_page = &s.pages.pages.last.?.data;
|
||||
const rem = start_page.capacity.rows;
|
||||
start_page.pauseIntegrityChecks(true);
|
||||
for (0..rem) |_| try s.cursorDownOrScroll();
|
||||
start_page.pauseIntegrityChecks(false);
|
||||
|
||||
const new_page = &s.cursor.page_pin.node.data;
|
||||
|
||||
// We need our page to change for this test to make sense. If this
|
||||
// assertion fails then the bug is in the test: we should be scrolling
|
||||
// above enough for a new page to show up.
|
||||
try testing.expect(start_page != new_page);
|
||||
|
||||
// Add styles to the start page until it reaches capacity.
|
||||
{
|
||||
// Pause integrity checks because they're slow and
|
||||
// we're not testing this, this is just setup.
|
||||
start_page.pauseIntegrityChecks(true);
|
||||
defer start_page.pauseIntegrityChecks(false);
|
||||
defer start_page.assertIntegrity();
|
||||
|
||||
var n: u24 = 1;
|
||||
while (start_page.styles.add(
|
||||
start_page.memory,
|
||||
.{ .bg_color = .{ .rgb = @bitCast(n) } },
|
||||
)) |_| n += 1 else |_| {}
|
||||
}
|
||||
|
||||
// Set a style on the cursor.
|
||||
try s.setAttribute(.{ .bold = {} });
|
||||
{
|
||||
const styleval = new_page.styles.get(
|
||||
new_page.memory,
|
||||
s.cursor.style_id,
|
||||
);
|
||||
try testing.expect(styleval.flags.bold);
|
||||
}
|
||||
|
||||
// Go back up into the start page and we should still have that style.
|
||||
s.cursorAbsolute(1, 1);
|
||||
{
|
||||
const cur_page = &s.cursor.page_pin.node.data;
|
||||
// The page we're on now should NOT equal start_page, since its
|
||||
// capacity should have been adjusted, which invalidates our ptr.
|
||||
try testing.expect(start_page != cur_page);
|
||||
// To make sure we DID change pages we check we're not on new_page.
|
||||
try testing.expect(new_page != cur_page);
|
||||
|
||||
const styleval = cur_page.styles.get(
|
||||
cur_page.memory,
|
||||
s.cursor.style_id,
|
||||
);
|
||||
try testing.expect(styleval.flags.bold);
|
||||
}
|
||||
|
||||
s.cursor.page_pin.node.data.assertIntegrity();
|
||||
new_page.assertIntegrity();
|
||||
}
|
||||
|
||||
test "Screen: scrolling" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
Reference in New Issue
Block a user