diff options
-rw-r--r-- | src/bun.js/node/node_fs.zig | 42 | ||||
-rw-r--r-- | test/bun.js/fs.test.js | 12 |
2 files changed, 54 insertions, 0 deletions
diff --git a/src/bun.js/node/node_fs.zig b/src/bun.js/node/node_fs.zig index 29464b3a2..8374e1c77 100644 --- a/src/bun.js/node/node_fs.zig +++ b/src/bun.js/node/node_fs.zig @@ -3334,11 +3334,14 @@ pub const NodeFS = struct { .result => |stat_| stat_, }; + // For certain files, the size might be 0 but the file might still have contents. const size = @intCast(u64, @maximum(stat_.size, 0)); + var buf = std.ArrayList(u8).init(bun.default_allocator); buf.ensureTotalCapacityPrecise(size + 16) catch unreachable; buf.expandToCapacity(); var total: usize = 0; + while (total < size) { switch (Syscall.read(fd, buf.items.ptr[total..buf.capacity])) { .err => |err| return .{ @@ -3358,8 +3361,47 @@ pub const NodeFS = struct { } }, } + } else { + // https://github.com/oven-sh/bun/issues/1220 + while (true) { + switch (Syscall.read(fd, buf.items.ptr[total..buf.capacity])) { + .err => |err| return .{ + .err = err, + }, + .result => |amt| { + total += amt; + // There are cases where stat()'s size is wrong or out of date + if (total > size and amt != 0) { + buf.ensureUnusedCapacity(8096) catch unreachable; + buf.expandToCapacity(); + continue; + } + + if (amt == 0) { + break; + } + }, + } + } } + buf.items.len = total; + if (total == 0) { + buf.deinit(); + return switch (args.encoding) { + .buffer => .{ + .result = .{ + .buffer = Buffer.empty, + }, + }, + else => .{ + .result = .{ + .string = "", + }, + }, + }; + } + return switch (args.encoding) { .buffer => .{ .result = .{ diff --git a/test/bun.js/fs.test.js b/test/bun.js/fs.test.js index 80622f895..304232954 100644 --- a/test/bun.js/fs.test.js +++ b/test/bun.js/fs.test.js @@ -231,6 +231,18 @@ describe("readFileSync", () => { expect(text).toBe("File read successfully"); }); + it("works with special files in the filesystem", () => { + { + const text = readFileSync("/dev/null", "utf8"); + expect(text).toBe(""); + } + + if (process.platform === "linux") { + const text = readFileSync("/proc/filesystems"); + expect(text.length > 0).toBe(true); + } + }); + it("returning Buffer works", () => { const text = readFileSync(import.meta.dir + "/readFileSync.txt"); const encoded = [ |