diff --git a/src/bun.js/webcore/blob/read_file.zig b/src/bun.js/webcore/blob/read_file.zig index db36497de4a..05c07df4885 100644 --- a/src/bun.js/webcore/blob/read_file.zig +++ b/src/bun.js/webcore/blob/read_file.zig @@ -384,8 +384,9 @@ pub const ReadFile = struct { // add an extra 16 bytes to the buffer to avoid having to resize it for trailing extra data if (!this.could_block or (this.size > 0 and this.size != Blob.max_size)) - this.buffer = std.ArrayListUnmanaged(u8).initCapacity(bun.default_allocator, this.size + 16) catch |err| { + this.buffer = std.ArrayListUnmanaged(u8).initCapacity(bun.default_allocator, this.size +| 16) catch |err| { this.errno = err; + this.system_error = bun.sys.Error.fromCode(bun.sys.E.NOMEM, .read).toSystemError(); this.onFinish(); return; }; diff --git a/test/js/bun/util/bun-file-read.test.ts b/test/js/bun/util/bun-file-read.test.ts index fd8bca82ac3..e3a4cc7747f 100644 --- a/test/js/bun/util/bun-file-read.test.ts +++ b/test/js/bun/util/bun-file-read.test.ts @@ -1,4 +1,5 @@ import { expect, it } from "bun:test"; +import { isPosix } from "harness"; import { tmpdir } from "node:os"; it("offset should work in Bun.file() #4963", async () => { @@ -9,3 +10,13 @@ it("offset should work in Bun.file() #4963", async () => { const contents = await slice.text(); expect(contents).toBe("ntents"); }); + +it.skipIf(!isPosix)("slicing Bun.file() by a non-zero offset rejects rather than overflowing", async () => { + // Regression: ReadFile.runAsyncWithFD computed buffer capacity as + // `this.size + 16`, which overflowed u52 when `this.size` approached + // Blob.max_size (2^52 - 1). The fix uses saturating addition and + // propagates the OOM via system_error so the promise rejects with ENOMEM. + const file = Bun.file("/dev/zero"); + const sliced = file.slice(1); + await expect(sliced.text()).rejects.toMatchObject({ code: "ENOMEM" }); +});