aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-11-19 04:59:17 -0800
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-11-19 04:59:17 -0800
commit17e8181b4ec760bea8acdd2f25c3dec3c693be50 (patch)
treeeec07374e4739123736a1b6bffad917f16c96e37 /src
parentee939f7a6dbe3571cf17b4b8135edff5f2497b48 (diff)
downloadbun-17e8181b4ec760bea8acdd2f25c3dec3c693be50.tar.gz
bun-17e8181b4ec760bea8acdd2f25c3dec3c693be50.tar.zst
bun-17e8181b4ec760bea8acdd2f25c3dec3c693be50.zip
Fix GC crash in `Bun.file(string).text()`, `Bun.file(string).arrayBuffer()`, `Bun.file(string).json()` uncovered via `BUN_GARBAGE_COLLECTOR_LEVEL`
Diffstat (limited to 'src')
-rw-r--r--src/bun.js/webcore/response.zig31
1 files changed, 16 insertions, 15 deletions
diff --git a/src/bun.js/webcore/response.zig b/src/bun.js/webcore/response.zig
index 80ffc62ec..0d01a218f 100644
--- a/src/bun.js/webcore/response.zig
+++ b/src/bun.js/webcore/response.zig
@@ -31,7 +31,6 @@ const GetJSPrivateData = @import("../base.zig").GetJSPrivateData;
const Environment = @import("../../env.zig");
const ZigString = JSC.ZigString;
const IdentityContext = @import("../../identity_context.zig").IdentityContext;
-const JSInternalPromise = JSC.JSInternalPromise;
const JSPromise = JSC.JSPromise;
const JSValue = JSC.JSValue;
const JSError = JSC.JSError;
@@ -1213,11 +1212,13 @@ pub const Blob = struct {
if (destination_type == .file and source_type == .bytes) {
var write_file_promise = bun.default_allocator.create(WriteFilePromise) catch unreachable;
+ var promise = JSC.JSPromise.create(ctx.ptr());
+ const promise_value = promise.asValue(ctx);
write_file_promise.* = .{
- .promise = JSC.JSPromise.create(ctx.ptr()),
.globalThis = ctx.ptr(),
};
- JSC.C.JSValueProtect(ctx, write_file_promise.promise.asValue(ctx.ptr()).asObjectRef());
+ write_file_promise.promise.strong.set(ctx, promise_value);
+ promise_value.ensureStillAlive();
var file_copier = Store.WriteFile.create(
bun.default_allocator,
@@ -1229,7 +1230,7 @@ pub const Blob = struct {
) catch unreachable;
var task = Store.WriteFile.WriteFileTask.createOnJSThread(bun.default_allocator, ctx.ptr(), file_copier) catch unreachable;
task.schedule();
- return write_file_promise.promise.asValue(ctx.ptr()).asObjectRef();
+ return promise_value.asObjectRef();
}
// If this is file <> file, we can just copy the file
else if (destination_type == .file and source_type == .file) {
@@ -1243,7 +1244,7 @@ pub const Blob = struct {
ctx.ptr(),
) catch unreachable;
file_copier.schedule();
- return file_copier.promise.asObjectRef();
+ return file_copier.promise.value().asObjectRef();
} else if (destination_type == .bytes and source_type == .bytes) {
// If this is bytes <> bytes, we can just duplicate it
// this is an edgecase
@@ -2529,7 +2530,7 @@ pub const Blob = struct {
bun.default_allocator.destroy(this);
}
- pub fn reject(this: *CopyFile, promise: *JSC.JSInternalPromise) void {
+ pub fn reject(this: *CopyFile, promise: *JSC.JSPromise) void {
var globalThis = this.globalThis;
var system_error: SystemError = this.system_error orelse SystemError{};
if (this.source_file_store.pathlike == .path and system_error.path.len == 0) {
@@ -2548,7 +2549,7 @@ pub const Blob = struct {
promise.reject(globalThis, instance);
}
- pub fn then(this: *CopyFile, promise: *JSC.JSInternalPromise) void {
+ pub fn then(this: *CopyFile, promise: *JSC.JSPromise) void {
this.source_store.?.deref();
if (this.system_error != null) {
@@ -3460,10 +3461,10 @@ pub const Blob = struct {
pub fn NewReadFileHandler(comptime Function: anytype, comptime lifetime: Lifetime) type {
return struct {
context: Blob,
- promise: *JSPromise,
+ promise: JSPromise.Strong = .{},
globalThis: *JSGlobalObject,
pub fn run(handler: *@This(), bytes_: Blob.Store.ReadFile.ResultType) void {
- var promise = handler.promise;
+ var promise = handler.promise.swap();
var blob = handler.context;
blob.allocator = null;
var globalThis = handler.globalThis;
@@ -3489,21 +3490,19 @@ pub const Blob = struct {
}
pub const WriteFilePromise = struct {
- promise: *JSPromise,
+ promise: JSPromise.Strong = .{},
globalThis: *JSGlobalObject,
pub fn run(handler: *@This(), count: Blob.Store.WriteFile.ResultType) void {
- var promise = handler.promise;
+ var promise = handler.promise.swap();
var globalThis = handler.globalThis;
bun.default_allocator.destroy(handler);
const value = promise.asValue(globalThis);
value.ensureStillAlive();
switch (count) {
.err => |err| {
- value.unprotect();
promise.reject(globalThis, err.toErrorInstance(globalThis));
},
.result => |wrote| {
- value.unprotect();
promise.resolve(globalThis, JSC.JSValue.jsNumberFromUint64(wrote));
},
}
@@ -3537,9 +3536,11 @@ pub const Blob = struct {
var handler = Handler{
.context = this.*,
- .promise = promise,
.globalThis = global,
};
+ const promise_value = promise.asValue(global);
+ promise_value.ensureStillAlive();
+ handler.promise.strong.set(global, promise_value);
var ptr = bun.default_allocator.create(Handler) catch unreachable;
ptr.* = handler;
@@ -3554,7 +3555,7 @@ pub const Blob = struct {
) catch unreachable;
var read_file_task = Store.ReadFile.ReadFileTask.createOnJSThread(bun.default_allocator, global, file_read) catch unreachable;
read_file_task.schedule();
- return promise.asValue(global);
+ return promise_value;
}
pub fn needsToReadFile(this: *const Blob) bool {