diff --git a/src/resolver/resolve_path.zig b/src/resolver/resolve_path.zig index a8077aecf6d..270628bc989 100644 --- a/src/resolver/resolve_path.zig +++ b/src/resolver/resolve_path.zig @@ -2048,13 +2048,18 @@ export fn ResolvePath__joinAbsStringBufCurrentPlatformBunString( const str = in.toUTF8WithoutRef(bun.default_allocator); defer str.deinit(); - const out_slice = joinAbsStringBuf( - globalObject.bunVM().transpiler.fs.top_level_dir, - &join_buf, - &.{str.slice()}, - .auto, - ); + const cwd = globalObject.bunVM().transpiler.fs.top_level_dir; + const input = str.slice(); + const total = cwd.len + input.len + 2; + + if (total <= join_buf.len) { + const out_slice = joinAbsStringBuf(cwd, &join_buf, &.{input}, .auto); + return bun.String.cloneUTF8(out_slice); + } + const buf = bun.handleOom(bun.default_allocator.alloc(u8, total)); + defer bun.default_allocator.free(buf); + const out_slice = joinAbsStringBuf(cwd, buf, &.{input}, .auto); return bun.String.cloneUTF8(out_slice); } diff --git a/test/js/node/url/pathToFileURL.test.ts b/test/js/node/url/pathToFileURL.test.ts index 23c76155ef9..4190a81cee4 100644 --- a/test/js/node/url/pathToFileURL.test.ts +++ b/test/js/node/url/pathToFileURL.test.ts @@ -5,6 +5,13 @@ test("pathToFileURL doesn't leak memory", () => { expect([path.join(import.meta.dir, "pathToFileURL-leak-fixture.js")]).toRun(); }); +test("pathToFileURL handles relative paths longer than 4096 bytes", () => { + expect([ + "-e", + 'const p = Buffer.alloc(200000, "a").toString(); const u = Bun.pathToFileURL(p); if (!u.href.endsWith("/" + p)) throw new Error(u.href)', + ]).toRun(); +}); + test("pathToFileURL escapes special characters", () => { const cases = [ ["\0", "%00"], // '\0' == 0x00