aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-09-09 19:26:02 -0700
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-09-09 19:26:02 -0700
commitc600196b1a566b575d32bbdc4229f78c7dc3eb81 (patch)
treee700116cb61d93df970c6b77f6cb1080334cfe86
parent3d8edcb77b7579090ebf370f12ce6107f3b3fb04 (diff)
downloadbun-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.zig42
-rw-r--r--test/bun.js/fs.test.js12
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 = [