mirror of
https://github.com/ziglang/zig.git
synced 2026-02-13 04:48:20 +00:00
arena_allocator/reset: fix use after free
Previously, when the last buffer in `buffer_list` was retained after deleting all other buffers, `buffer_list` wasn't updated and pointed to a deleted buffer.
This commit is contained in:
parent
41430a366f
commit
5d3c8f4913
@ -139,6 +139,7 @@ pub const ArenaAllocator = struct {
|
||||
// reset the state before we try resizing the buffers, so we definitely have reset the arena to 0.
|
||||
self.state.end_index = 0;
|
||||
if (maybe_first_node) |first_node| {
|
||||
self.state.buffer_list.first = first_node;
|
||||
// perfect, no need to invoke the child_allocator
|
||||
if (first_node.data == total_size)
|
||||
return true;
|
||||
@ -270,3 +271,19 @@ test "ArenaAllocator (reset with preheating)" {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
test "ArenaAllocator (reset while retaining a buffer)" {
|
||||
var arena_allocator = ArenaAllocator.init(std.testing.allocator);
|
||||
defer arena_allocator.deinit();
|
||||
const a = arena_allocator.allocator();
|
||||
|
||||
// Create two internal buffers
|
||||
_ = try a.alloc(u8, 1);
|
||||
_ = try a.alloc(u8, 1000);
|
||||
|
||||
// Check that we have at least two buffers
|
||||
try std.testing.expect(arena_allocator.state.buffer_list.first.?.next != null);
|
||||
|
||||
// This retains the first allocated buffer
|
||||
try std.testing.expect(arena_allocator.reset(.{ .retain_with_limit = 1 }));
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user