diff --git a/lib/std/heap.zig b/lib/std/heap.zig index 50fb23fa7f..ba4abc9ffe 100644 --- a/lib/std/heap.zig +++ b/lib/std/heap.zig @@ -260,6 +260,9 @@ const PageAllocator = struct { fn alloc(_: *anyopaque, n: usize, alignment: u29, len_align: u29, ra: usize) error{OutOfMemory}![]u8 { _ = ra; assert(n > 0); + if (n > maxInt(usize) - (mem.page_size - 1)) { + return error.OutOfMemory; + } const aligned_len = mem.alignForward(n, mem.page_size); if (builtin.os.tag == .windows) { diff --git a/lib/std/heap/general_purpose_allocator.zig b/lib/std/heap/general_purpose_allocator.zig index 490d352da2..2180b87942 100644 --- a/lib/std/heap/general_purpose_allocator.zig +++ b/lib/std/heap/general_purpose_allocator.zig @@ -971,6 +971,14 @@ test "large allocations" { allocator.free(ptr2); } +test "very large allocation" { + var gpa = GeneralPurposeAllocator(test_config){}; + defer std.testing.expect(!gpa.deinit()) catch @panic("leak"); + const allocator = gpa.allocator(); + + try std.testing.expectError(error.OutOfMemory, allocator.alloc(u8, math.maxInt(usize))); +} + test "realloc" { var gpa = GeneralPurposeAllocator(test_config){}; defer std.testing.expect(!gpa.deinit()) catch @panic("leak"); diff --git a/lib/std/mem.zig b/lib/std/mem.zig index 93dd54bdb5..3e6a3cdeb6 100644 --- a/lib/std/mem.zig +++ b/lib/std/mem.zig @@ -3551,12 +3551,14 @@ test "sliceAsBytes preserves pointer attributes" { /// Round an address up to the next (or current) aligned address. /// The alignment must be a power of 2 and greater than 0. +/// Asserts that rounding up the address does not cause integer overflow. pub fn alignForward(addr: usize, alignment: usize) usize { return alignForwardGeneric(usize, addr, alignment); } /// Round an address up to the next (or current) aligned address. /// The alignment must be a power of 2 and greater than 0. +/// Asserts that rounding up the address does not cause integer overflow. pub fn alignForwardGeneric(comptime T: type, addr: T, alignment: T) T { return alignBackwardGeneric(T, addr + (alignment - 1), alignment); }