diff options
author | 2022-09-09 19:26:02 -0700 | |
---|---|---|
committer | 2022-09-09 19:26:02 -0700 | |
commit | c600196b1a566b575d32bbdc4229f78c7dc3eb81 (patch) | |
tree | e700116cb61d93df970c6b77f6cb1080334cfe86 | |
parent | 3d8edcb77b7579090ebf370f12ce6107f3b3fb04 (diff) | |
download | bun-c600196b1a566b575d32bbdc4229f78c7dc3eb81.tar.gz bun-c600196b1a566b575d32bbdc4229f78c7dc3eb81.tar.zst bun-c600196b1a566b575d32bbdc4229f78c7dc3eb81.zip |
[node:fs] Fix readFileSync on non-regular files
Fixes https://github.com/oven-sh/bun/issues/1220
-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 = [ |