diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/bun.js/javascript.zig | 4 | ||||
-rw-r--r-- | src/bun.js/node/node_fs.zig | 6 | ||||
-rw-r--r-- | src/bun.js/node/types.zig | 42 | ||||
-rw-r--r-- | src/bun.js/webcore/response.zig | 119 | ||||
-rw-r--r-- | src/bun.js/webcore/streams.zig | 10 |
5 files changed, 100 insertions, 81 deletions
diff --git a/src/bun.js/javascript.zig b/src/bun.js/javascript.zig index 4068e9cfe..bbc10291c 100644 --- a/src/bun.js/javascript.zig +++ b/src/bun.js/javascript.zig @@ -1220,7 +1220,7 @@ pub const VirtualMachine = struct { return promise; } - promise = JSModuleLoader.loadAndEvaluateModule(this.global, &ZigString.init(std.mem.span(main_file_name))); + promise = JSModuleLoader.loadAndEvaluateModule(this.global, ZigString.static(main_file_name)); this.pending_internal_promise = promise; } else { promise = JSModuleLoader.loadAndEvaluateModule(this.global, &ZigString.init(this.main)); @@ -1704,7 +1704,7 @@ pub const VirtualMachine = struct { "pkg", }; - if (error_instance.isCell()) { + if (error_instance != .zero and error_instance.isCell() and error_instance.jsType().canGet()) { inline for (extra_fields) |field| { if (error_instance.get(this.global, field)) |value| { if (!value.isEmptyOrUndefinedOrNull()) { diff --git a/src/bun.js/node/node_fs.zig b/src/bun.js/node/node_fs.zig index 6862b53de..23596d7b5 100644 --- a/src/bun.js/node/node_fs.zig +++ b/src/bun.js/node/node_fs.zig @@ -101,7 +101,7 @@ const Arguments = struct { len: JSC.WebCore.Blob.SizeType = 0, pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?Truncate { - const path = PathOrFileDescriptor.fromJS(ctx, arguments, exception) orelse { + const path = PathOrFileDescriptor.fromJS(ctx, arguments, arguments.arena.allocator(), exception) orelse { if (exception.* == null) { JSC.throwInvalidArguments( "path must be a string or TypedArray", @@ -1448,7 +1448,7 @@ const Arguments = struct { flag: FileSystemFlags = FileSystemFlags.@"r", pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?ReadFile { - const path = PathOrFileDescriptor.fromJS(ctx, arguments, exception) orelse { + const path = PathOrFileDescriptor.fromJS(ctx, arguments, arguments.arena.allocator(), exception) orelse { if (exception.* == null) { JSC.throwInvalidArguments( "path must be a string or a file descriptor", @@ -1529,7 +1529,7 @@ const Arguments = struct { data: StringOrBuffer, pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?WriteFile { - const file = PathOrFileDescriptor.fromJS(ctx, arguments, exception) orelse { + const file = PathOrFileDescriptor.fromJS(ctx, arguments, arguments.arena.allocator(), exception) orelse { if (exception.* == null) { JSC.throwInvalidArguments( "path must be a string or a file descriptor", diff --git a/src/bun.js/node/types.zig b/src/bun.js/node/types.zig index 144274b9b..df676a551 100644 --- a/src/bun.js/node/types.zig +++ b/src/bun.js/node/types.zig @@ -524,6 +524,9 @@ pub const PathLike = union(Tag) { } pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?PathLike { + return fromJSWithAllocator(ctx, arguments, arguments.arena.allocator(), exception); + } + pub fn fromJSWithAllocator(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, allocator: std.mem.Allocator, exception: JSC.C.ExceptionRef) ?PathLike { const arg = arguments.next() orelse return null; switch (arg.jsType()) { JSC.JSValue.JSType.Uint8Array, @@ -551,19 +554,16 @@ pub const PathLike = union(Tag) { JSC.JSValue.JSType.StringObject, JSC.JSValue.JSType.DerivedStringObject, => { - var zig_str = JSC.ZigString.init(""); - arg.toZigString(&zig_str, ctx.ptr()); + var zig_str = arg.toSlice(ctx, allocator); - if (!Valid.pathString(zig_str, ctx, exception)) return null; + if (!Valid.pathSlice(zig_str, ctx, exception)) { + zig_str.deinit(); + return null; + } arguments.eat(); arg.ensureStillAlive(); - if (zig_str.is16Bit()) { - var printed = std.mem.span(std.fmt.allocPrintZ(arguments.arena.allocator(), "{}", .{zig_str}) catch unreachable); - return PathLike{ .string = PathString.init(printed.ptr[0 .. printed.len + 1]) }; - } - return PathLike{ .string = PathString.init(zig_str.slice()) }; }, else => { @@ -597,6 +597,28 @@ pub const Valid = struct { return true; } + pub fn pathSlice(zig_str: JSC.ZigString.Slice, ctx: JSC.C.JSContextRef, exception: JSC.C.ExceptionRef) bool { + switch (zig_str.len) { + 0 => { + JSC.throwInvalidArguments("Invalid path string: can't be empty", .{}, ctx, exception); + return false; + }, + 1...bun.MAX_PATH_BYTES => return true, + else => { + // TODO: should this be an EINVAL? + JSC.throwInvalidArguments( + comptime std.fmt.comptimePrint("Invalid path string: path is too long (max: {d})", .{bun.MAX_PATH_BYTES}), + .{}, + ctx, + exception, + ); + return false; + }, + } + + unreachable; + } + pub fn pathString(zig_str: JSC.ZigString, ctx: JSC.C.JSContextRef, exception: JSC.C.ExceptionRef) bool { switch (zig_str.len) { 0 => { @@ -811,7 +833,7 @@ pub const PathOrFileDescriptor = union(Tag) { } } - pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, exception: JSC.C.ExceptionRef) ?PathOrFileDescriptor { + pub fn fromJS(ctx: JSC.C.JSContextRef, arguments: *ArgumentsSlice, allocator: std.mem.Allocator, exception: JSC.C.ExceptionRef) ?PathOrFileDescriptor { const first = arguments.next() orelse return null; if (fileDescriptorFromJS(ctx, first, exception)) |fd| { @@ -821,7 +843,7 @@ pub const PathOrFileDescriptor = union(Tag) { if (exception.* != null) return null; - return PathOrFileDescriptor{ .path = PathLike.fromJS(ctx, arguments, exception) orelse return null }; + return PathOrFileDescriptor{ .path = PathLike.fromJSWithAllocator(ctx, arguments, allocator, exception) orelse return null }; } pub fn toJS(this: PathOrFileDescriptor, ctx: JSC.C.JSContextRef, exception: JSC.C.ExceptionRef) JSC.C.JSValueRef { diff --git a/src/bun.js/webcore/response.zig b/src/bun.js/webcore/response.zig index db8531253..d77a5714b 100644 --- a/src/bun.js/webcore/response.zig +++ b/src/bun.js/webcore/response.zig @@ -952,26 +952,8 @@ const PathOrBlob = union(enum) { path: JSC.Node.PathOrFileDescriptor, blob: Blob, - pub fn fromJS(ctx: js.JSContextRef, args: *JSC.Node.ArgumentsSlice, exception: js.ExceptionRef) ?PathOrBlob { - if (JSC.Node.PathOrFileDescriptor.fromJS(ctx, args, exception)) |path| { - return PathOrBlob{ - .path = path, - }; - } - - const arg = args.nextEat() orelse return null; - - if (arg.as(Blob)) |blob| { - return PathOrBlob{ - .blob = blob.dupe(), - }; - } - - return null; - } - pub fn fromJSNoCopy(ctx: js.JSContextRef, args: *JSC.Node.ArgumentsSlice, exception: js.ExceptionRef) ?PathOrBlob { - if (JSC.Node.PathOrFileDescriptor.fromJS(ctx, args, exception)) |path| { + if (JSC.Node.PathOrFileDescriptor.fromJS(ctx, args, args.arena.allocator(), exception)) |path| { return PathOrBlob{ .path = path, }; @@ -1687,58 +1669,66 @@ pub const Blob = struct { arguments: []const js.JSValueRef, exception: js.ExceptionRef, ) js.JSObjectRef { - var args = JSC.Node.ArgumentsSlice.from(ctx.bunVM(), arguments); + var vm = ctx.bunVM(); + var args = JSC.Node.ArgumentsSlice.from(vm, arguments); defer args.deinit(); - var path = JSC.Node.PathOrFileDescriptor.fromJS(ctx, &args, exception) orelse { + const path = JSC.Node.PathOrFileDescriptor.fromJS(ctx, &args, args.arena.allocator(), exception) orelse { exception.* = JSC.toInvalidArguments("Expected file path string or file descriptor", .{}, ctx).asObjectRef(); return js.JSValueMakeUndefined(ctx); }; const blob = Blob.findOrCreateFileFromPath(path, ctx.ptr()); - var ptr = bun.default_allocator.create(Blob) catch unreachable; + var ptr = vm.allocator.create(Blob) catch unreachable; ptr.* = blob; - ptr.allocator = bun.default_allocator; + ptr.allocator = vm.allocator; return ptr.toJS(ctx).asObjectRef(); } pub fn findOrCreateFileFromPath(path_: JSC.Node.PathOrFileDescriptor, globalThis: *JSGlobalObject) Blob { - var path = path_; var vm = globalThis.bunVM(); - if (vm.getFileBlob(path)) |blob| { + if (vm.getFileBlob(path_)) |blob| { blob.ref(); return Blob.initWithStore(blob, globalThis); } - switch (path) { - .path => { - path.path = .{ - .string = bun.PathString.init( - (bun.default_allocator.dupeZ(u8, path.path.slice()) catch unreachable)[0..path.path.slice().len], - ), - }; - }, - .fd => { - switch (path.fd) { - std.os.STDIN_FILENO => return Blob.initWithStore( - vm.rareData().stdin(), - globalThis, - ), - std.os.STDERR_FILENO => return Blob.initWithStore( - vm.rareData().stderr(), - globalThis, - ), - std.os.STDOUT_FILENO => return Blob.initWithStore( - vm.rareData().stdout(), - globalThis, - ), - else => {}, - } - }, - } + var allocator = globalThis.bunVM().allocator; + + const path: JSC.Node.PathOrFileDescriptor = brk: { + switch (path_) { + .path => { + const slice = path_.path.slice(); + var cloned = (allocator.dupeZ(u8, slice) catch unreachable)[0..slice.len]; - const result = Blob.initWithStore(Blob.Store.initFile(path, null, bun.default_allocator) catch unreachable, globalThis); + break :brk .{ + .path = .{ + .string = bun.PathString.init(cloned), + }, + }; + }, + .fd => { + switch (path_.fd) { + std.os.STDIN_FILENO => return Blob.initWithStore( + vm.rareData().stdin(), + globalThis, + ), + std.os.STDERR_FILENO => return Blob.initWithStore( + vm.rareData().stderr(), + globalThis, + ), + std.os.STDOUT_FILENO => return Blob.initWithStore( + vm.rareData().stdout(), + globalThis, + ), + else => {}, + } + break :brk path_; + }, + } + }; + + const result = Blob.initWithStore(Blob.Store.initFile(path, null, allocator) catch unreachable, globalThis); vm.putFileBlob(path, result.store.?) catch unreachable; return result; } @@ -3098,14 +3088,20 @@ pub const Blob = struct { return JSValue.jsUndefined(); }; - var input_path: JSC.WebCore.PathOrFileDescriptor = undefined; - if (store.data.file.pathlike == .fd) { - input_path = .{ .fd = store.data.file.pathlike.fd }; - } else { - input_path = .{ - .path = ZigString.Slice.fromUTF8NeverFree(store.data.file.pathlike.path.slice()), - }; - } + const input_path: JSC.WebCore.PathOrFileDescriptor = brk: { + if (store.data.file.pathlike == .fd) { + break :brk .{ .fd = store.data.file.pathlike.fd }; + } else { + break :brk .{ + .path = ZigString.Slice.fromUTF8NeverFree( + store.data.file.pathlike.path.slice(), + ).clone( + globalThis.allocator(), + ) catch unreachable, + }; + } + }; + defer input_path.deinit(); var stream_start: JSC.WebCore.StreamStart = .{ .FileSink = .{ @@ -3122,7 +3118,8 @@ pub const Blob = struct { .err => |err| { globalThis.vm().throwError(globalThis, err.toJSC(globalThis)); sink.finalize(); - return JSC.JSValue.jsUndefined(); + + return JSC.JSValue.zero; }, else => {}, } diff --git a/src/bun.js/webcore/streams.zig b/src/bun.js/webcore/streams.zig index 827bc25bf..2d7a3badd 100644 --- a/src/bun.js/webcore/streams.zig +++ b/src/bun.js/webcore/streams.zig @@ -999,6 +999,10 @@ pub const Sink = struct { pub const PathOrFileDescriptor = union(enum) { path: ZigString.Slice, fd: JSC.Node.FileDescriptor, + + pub fn deinit(this: *const PathOrFileDescriptor) void { + if (this.* == .path) this.path.deinit(); + } }; pub const FileSink = struct { @@ -1045,9 +1049,7 @@ pub const FileSink = struct { if (auto_close) { _ = JSC.Node.Syscall.close(fd); } - if (input_path == .path) - return .{ .err = err.withPath(input_path.path.slice()) }; - return .{ .err = err }; + return .{ .err = err.withPathLike(input_path) }; }, }; @@ -1084,8 +1086,6 @@ pub const FileSink = struct { this.auto_close = config.close or config.input_path == .path; this.auto_truncate = config.truncate; - defer if (config.input_path == .path) config.input_path.path.deinit(); - switch (this.prepare(config.input_path, config.mode)) { .err => |err| { return .{ .err = err }; |