aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHimbeer <himbeer@disroot.org>2024-06-21 11:16:46 +0200
committerHimbeer <himbeer@disroot.org>2024-06-21 11:16:46 +0200
commit88ee047a24518161478dc1f79fb95f3343bc642a (patch)
tree08d983c0f43ac9ebcb8fd04a8c9de785c23af388 /src
parent0c0ca6e0344c4566fe21263160ed9fda197d4ea3 (diff)
mem: Fix resizing not accounting for alignment padding between Chunk header and data buffer
Fixes #32.
Diffstat (limited to 'src')
-rw-r--r--src/lib/mem.zig16
1 files changed, 11 insertions, 5 deletions
diff --git a/src/lib/mem.zig b/src/lib/mem.zig
index a9addf6..9e77add 100644
--- a/src/lib/mem.zig
+++ b/src/lib/mem.zig
@@ -72,6 +72,8 @@ pub fn ChunkAllocator(comptime config: ChunkAllocatorConfig) type {
pub fn alloc(ctx: *anyopaque, len: usize, log2_ptr_align: u8, ret_addr: usize) ?[*]u8 {
_ = ret_addr;
+ if (len == 0) return null;
+
const self: *Self = @ptrCast(@alignCast(ctx));
const ptr_align = @as(usize, 1) << @as(std.mem.Allocator.Log2Align, @intCast(log2_ptr_align));
@@ -110,18 +112,22 @@ pub fn ChunkAllocator(comptime config: ChunkAllocatorConfig) type {
pub fn resize(ctx: *anyopaque, buf: []u8, log2_buf_align: u8, new_len: usize, ret_addr: usize) bool {
_ = ret_addr;
+ if (new_len == 0) return false;
+
const self: *Self = @ptrCast(@alignCast(ctx));
const ptr_align = @as(usize, 1) << @as(std.mem.Allocator.Log2Align, @intCast(log2_buf_align));
+ const adjust_off = std.mem.alignPointerOffset(buf.ptr, ptr_align) orelse return false;
+ const aligned_new_len = new_len + adjust_off;
+
+ const len_ptr: [*]const u8 = @ptrFromInt(buf.len);
+ const padding_len = std.mem.alignPointerOffset(len_ptr, ptr_align) orelse return false;
+
const head = self.head orelse return false;
const bound = @intFromPtr(head) + (self.pages * paging.page_size);
- // fixme: Doesn't account for alignment between header and data.
- const chunk = @as(*align(1) Chunk, @ptrCast(buf.ptr - @sizeOf(Chunk)));
-
- const adjust_off = std.mem.alignPointerOffset(buf.ptr, ptr_align) orelse return false;
- const aligned_new_len = new_len + adjust_off;
+ const chunk = @as(*align(1) Chunk, @ptrCast(buf.ptr - padding_len - @sizeOf(Chunk)));
if (aligned_new_len < chunk.len) {
const regained = chunk.len - aligned_new_len;