Skip to content

Commit

Permalink
fix(node:fs): set allow above root (#16814)
Browse files Browse the repository at this point in the history
Co-authored-by: Dylan Conway <[email protected]>
  • Loading branch information
paperclover and dylan-conway authored Jan 28, 2025
1 parent ce53290 commit c08f4ab
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 6 deletions.
10 changes: 5 additions & 5 deletions src/bun.js/node/types.zig
Original file line number Diff line number Diff line change
Expand Up @@ -932,23 +932,23 @@ pub const PathLike = union(enum) {
return buf[0..sliced.len :0];
}

pub inline fn sliceZ(this: PathLike, buf: *bun.PathBuffer) [:0]const u8 {
pub fn sliceZ(this: PathLike, buf: *bun.PathBuffer) callconv(bun.callconv_inline) [:0]const u8 {
return sliceZWithForceCopy(this, buf, false);
}

pub inline fn sliceW(this: PathLike, buf: *bun.WPathBuffer) [:0]const u16 {
pub fn sliceW(this: PathLike, buf: *bun.WPathBuffer) callconv(bun.callconv_inline) [:0]const u16 {
return strings.toWPath(buf, this.slice());
}

pub inline fn osPath(this: PathLike, buf: *bun.OSPathBuffer) bun.OSPathSliceZ {
pub fn osPath(this: PathLike, buf: *bun.OSPathBuffer) callconv(bun.callconv_inline) bun.OSPathSliceZ {
if (comptime Environment.isWindows) {
return sliceW(this, buf);
}

return sliceZWithForceCopy(this, buf, false);
}

pub inline fn osPathKernel32(this: PathLike, buf: *bun.PathBuffer) bun.OSPathSliceZ {
pub fn osPathKernel32(this: PathLike, buf: *bun.PathBuffer) callconv(bun.callconv_inline) bun.OSPathSliceZ {
if (comptime Environment.isWindows) {
const s = this.slice();
const b = bun.PathBufferPool.get();
Expand All @@ -958,7 +958,7 @@ pub const PathLike = union(enum) {
const normal = path_handler.normalizeBuf(resolve, b, .windows);
return strings.toKernel32Path(@alignCast(std.mem.bytesAsSlice(u16, buf)), normal);
}
const normal = path_handler.normalizeBuf(s, b, .windows);
const normal = path_handler.normalizeStringBuf(s, b, true, .windows, false);
return strings.toKernel32Path(@alignCast(std.mem.bytesAsSlice(u16, buf)), normal);
}

Expand Down
45 changes: 44 additions & 1 deletion test/js/node/fs/fs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import fs, {
writevSync,
} from "node:fs";
import * as os from "node:os";
import { dirname, relative, resolve } from "node:path";
import path, { dirname, relative, resolve } from "node:path";
import { promisify } from "node:util";

import _promises, { type FileHandle } from "node:fs/promises";
Expand Down Expand Up @@ -3603,3 +3603,46 @@ it("fs.Stat.atime reflects date matching Node.js behavior", () => {
expect(stats.atime).toEqual(new Date(0));
}
});

describe('kernel32 long path conversion does not mangle "../../path" into "path"', () => {
const tmp1 = tempDirWithFiles("longpath", {
"a/b/config": "true",
});
const tmp2 = tempDirWithFiles("longpath", {
"a/b/hello": "true",
"config": "true",
});
const workingDir1 = path.join(tmp1, "a/b");
const workingDir2 = path.join(tmp2, "a/b");
const nonExistTests = [
["existsSync", 'assert.strictEqual(fs.existsSync("../../config"), false)'],
["accessSync", 'assert.throws(() => fs.accessSync("../../config"), { code: "ENOENT" })'],
];
const existTests = [
["existsSync", 'assert.strictEqual(fs.existsSync("../../config"), true)'],
["accessSync", 'assert.strictEqual(fs.accessSync("../../config"), null)'],
];

for (const [name, code] of nonExistTests) {
it(`${name} (not existing)`, () => {
const { success } = spawnSync({
cmd: [bunExe(), "-e", code],
cwd: workingDir1,
stdio: ["ignore", "inherit", "inherit"],
env: bunEnv,
});
expect(success).toBeTrue();
});
}
for (const [name, code] of existTests) {
it(`${name} (existing)`, () => {
const { success } = spawnSync({
cmd: [bunExe(), "-e", code],
cwd: workingDir2,
stdio: ["ignore", "inherit", "inherit"],
env: bunEnv,
});
expect(success).toBeTrue();
});
}
});

0 comments on commit c08f4ab

Please sign in to comment.