aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2023-09-19 18:16:51 -0700
committerGravatar GitHub <noreply@github.com> 2023-09-19 18:16:51 -0700
commit5defdf3e28249b34772864a50273a390d345b2df (patch)
tree499f8138fae7309a4ba1ce00041604a96ab04deb
parentf8d7f50cdbee67e938205afbb71b3e13cfddeba3 (diff)
downloadbun-5defdf3e28249b34772864a50273a390d345b2df.tar.gz
bun-5defdf3e28249b34772864a50273a390d345b2df.tar.zst
bun-5defdf3e28249b34772864a50273a390d345b2df.zip
Fixes #5769 (#5775)
Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
-rwxr-xr-xbun.lockbbin73707 -> 74396 bytes
-rw-r--r--src/bun.js/node/types.zig17
-rw-r--r--src/resolver/resolve_path.zig20
-rw-r--r--test/js/node/path/path.test.js13
4 files changed, 46 insertions, 4 deletions
diff --git a/bun.lockb b/bun.lockb
index 635178a9c..fc33e014b 100755
--- a/bun.lockb
+++ b/bun.lockb
Binary files differ
diff --git a/src/bun.js/node/types.zig b/src/bun.js/node/types.zig
index 72f1dff7e..7e9cdcd2d 100644
--- a/src/bun.js/node/types.zig
+++ b/src/bun.js/node/types.zig
@@ -2192,6 +2192,8 @@ pub const Path = struct {
if (comptime is_bindgen) return JSC.JSValue.jsUndefined();
if (args_len == 0) return JSC.ZigString.init("").toValue(globalThis);
var arena = @import("root").bun.ArenaAllocator.init(heap_allocator);
+ defer arena.deinit();
+
var arena_allocator = arena.allocator();
var stack_fallback_allocator = std.heap.stackFallback(
((32 * @sizeOf(string)) + 1024),
@@ -2199,18 +2201,27 @@ pub const Path = struct {
);
var allocator = stack_fallback_allocator.get();
- defer arena.deinit();
var buf: [bun.MAX_PATH_BYTES]u8 = undefined;
+ var count: usize = 0;
var to_join = allocator.alloc(string, args_len) catch unreachable;
for (args_ptr[0..args_len], 0..) |arg, i| {
const zig_str: JSC.ZigString = arg.getZigString(globalThis);
to_join[i] = zig_str.toSlice(allocator).slice();
+ count += to_join[i].len;
+ }
+
+ var buf_to_use: []u8 = &buf;
+ if (count * 2 >= buf.len) {
+ buf_to_use = allocator.alloc(u8, count * 2) catch {
+ globalThis.throwOutOfMemory();
+ return .zero;
+ };
}
const out = if (!isWindows)
- PathHandler.joinStringBuf(&buf, to_join, .posix)
+ PathHandler.joinStringBuf(buf_to_use, to_join, .posix)
else
- PathHandler.joinStringBuf(&buf, to_join, .windows);
+ PathHandler.joinStringBuf(buf_to_use, to_join, .windows);
var str = bun.String.create(out);
defer str.deref();
diff --git a/src/resolver/resolve_path.zig b/src/resolver/resolve_path.zig
index f74211709..381abc648 100644
--- a/src/resolver/resolve_path.zig
+++ b/src/resolver/resolve_path.zig
@@ -829,7 +829,25 @@ pub fn joinStringBuf(buf: []u8, _parts: anytype, comptime _platform: Platform) [
var written: usize = 0;
const platform = comptime _platform.resolve();
- var temp_buf: [4096]u8 = undefined;
+ var temp_buf_: [4096]u8 = undefined;
+ var temp_buf: []u8 = &temp_buf_;
+ var free_temp_buf = false;
+ defer {
+ if (free_temp_buf) {
+ bun.default_allocator.free(temp_buf);
+ }
+ }
+
+ var count: usize = 0;
+ for (_parts) |part| {
+ count += if (part.len > 0) part.len + 1 else 0;
+ }
+
+ if (count * 2 > temp_buf.len) {
+ temp_buf = bun.default_allocator.alloc(u8, count * 2) catch @panic("Out of memory");
+ free_temp_buf = true;
+ }
+
temp_buf[0] = 0;
for (_parts) |part| {
diff --git a/test/js/node/path/path.test.js b/test/js/node/path/path.test.js
index 26b6a3b6d..1d14e1d9e 100644
--- a/test/js/node/path/path.test.js
+++ b/test/js/node/path/path.test.js
@@ -271,6 +271,19 @@ it("path.basename", () => {
strictEqual(path.posix.basename(`/a/b/${controlCharFilename}`), controlCharFilename);
});
+describe("path.join #5769", () => {
+ for (let length of [4096, 4095, 4097, 65_432, 65_431, 65_433]) {
+ it("length " + length, () => {
+ const tooLengthyFolderName = Array.from({ length }).fill("b").join("");
+ expect(path.join(tooLengthyFolderName)).toEqual("b".repeat(length));
+ });
+ it("length " + length + "joined", () => {
+ const tooLengthyFolderName = Array.from({ length }).fill("b");
+ expect(path.join(...tooLengthyFolderName)).toEqual("b/".repeat(length).substring(0, 2 * length - 1));
+ });
+ }
+});
+
it("path.join", () => {
const failures = [];
const backslashRE = /\\/g;