authorgravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2025-03-26 14:12:25+01:00
committergravatar for mail@isaacfreund.comIsaac Freund <mail@isaacfreund.com> 2026-03-25 10:50:24+01:00
log4848c3a1ad2bfd956419351afb60928e290f2be1
treed10252d9031e6082c6d1004ee0cf665507c5f42b
parent3d16c1eb7609fc3793f549e5396fa4da9c2042e9
signaturelock-open Commit is signed but in an unrecognized format.

std: fix sentinel handling in Allocator interface

Currently the only function that handles sentinel terminated slices properly is free. All uses of mem.sliceAsBytes() in the allocator interface lack proper handling of a possible sentinel. This commit changes the Allocator interface to use @ptrCast() plus the new mem.absorbSentinel() instead. Reported-by: David Vanderson <david.vanderson@gmail.com> References: https://github.com/ziglang/zig/pull/19984 References: https://github.com/ziglang/zig/pull/23020

1 files changed, 4 insertions(+), 5 deletions(-)

lib/std/mem/Allocator.zig+4-5
...@@ -322,7 +322,7 @@ pub fn resize(self: Allocator, allocation: anytype, new_len: usize) bool {...@@ -322,7 +322,7 @@ pub fn resize(self: Allocator, allocation: anytype, new_len: usize) bool {
322 if (allocation.len == 0) {322 if (allocation.len == 0) {
323 return false;323 return false;
324 }324 }
325 const old_memory = mem.sliceAsBytes(allocation);325 const old_memory: []u8 = @ptrCast(@constCast(mem.absorbSentinel(allocation)));
326 // I would like to use saturating multiplication here, but LLVM cannot lower it326 // I would like to use saturating multiplication here, but LLVM cannot lower it
327 // on WebAssembly: https://github.com/ziglang/zig/issues/9660327 // on WebAssembly: https://github.com/ziglang/zig/issues/9660
328 //const new_len_bytes = new_len *| @sizeOf(T);328 //const new_len_bytes = new_len *| @sizeOf(T);
...@@ -368,7 +368,7 @@ pub fn remap(self: Allocator, allocation: anytype, new_len: usize) ?@TypeOf(allo...@@ -368,7 +368,7 @@ pub fn remap(self: Allocator, allocation: anytype, new_len: usize) ?@TypeOf(allo
368 new_memory.len = new_len;368 new_memory.len = new_len;
369 return new_memory;369 return new_memory;
370 }370 }
371 const old_memory = mem.sliceAsBytes(allocation);371 const old_memory: []u8 = @ptrCast(@constCast(mem.absorbSentinel(allocation)));
372 // I would like to use saturating multiplication here, but LLVM cannot lower it372 // I would like to use saturating multiplication here, but LLVM cannot lower it
373 // on WebAssembly: https://github.com/ziglang/zig/issues/9660373 // on WebAssembly: https://github.com/ziglang/zig/issues/9660
374 //const new_len_bytes = new_len *| @sizeOf(T);374 //const new_len_bytes = new_len *| @sizeOf(T);
...@@ -420,7 +420,7 @@ pub fn reallocAdvanced(...@@ -420,7 +420,7 @@ pub fn reallocAdvanced(
420 return ptr;420 return ptr;
421 }421 }
422422
423 const old_byte_slice = mem.sliceAsBytes(old_mem);423 const old_byte_slice: []u8 = @ptrCast(@constCast(mem.absorbSentinel(old_mem)));
424 const byte_count = math.mul(usize, @sizeOf(T), new_n) catch return error.OutOfMemory;424 const byte_count = math.mul(usize, @sizeOf(T), new_n) catch return error.OutOfMemory;
425 // Note: can't set shrunk memory to undefined as memory shouldn't be modified on realloc failure425 // Note: can't set shrunk memory to undefined as memory shouldn't be modified on realloc failure
426 if (self.rawRemap(old_byte_slice, .fromByteUnits(slice_info.alignment orelse @alignOf(T)), byte_count, return_address)) |p| {426 if (self.rawRemap(old_byte_slice, .fromByteUnits(slice_info.alignment orelse @alignOf(T)), byte_count, return_address)) |p| {
...@@ -443,8 +443,7 @@ pub fn reallocAdvanced(...@@ -443,8 +443,7 @@ pub fn reallocAdvanced(
443pub fn free(self: Allocator, memory: anytype) void {443pub fn free(self: Allocator, memory: anytype) void {
444 const slice_info = @typeInfo(@TypeOf(memory)).pointer;444 const slice_info = @typeInfo(@TypeOf(memory)).pointer;
445 comptime assert(slice_info.size == .slice);445 comptime assert(slice_info.size == .slice);
446 const mem_with_sent = memory[0 .. memory.len + @intFromBool(slice_info.sentinel() != null)];446 const bytes: []u8 = @ptrCast(@constCast(mem.absorbSentinel(memory)));
447 const bytes: []u8 = @ptrCast(@constCast(mem_with_sent));
448 if (bytes.len == 0) return;447 if (bytes.len == 0) return;
449 @memset(bytes, undefined);448 @memset(bytes, undefined);
450 self.rawFree(bytes, .fromByteUnits(slice_info.alignment orelse @alignOf(slice_info.child)), @returnAddress());449 self.rawFree(bytes, .fromByteUnits(slice_info.alignment orelse @alignOf(slice_info.child)), @returnAddress());