diff options
author | 2022-04-02 05:11:57 -0700 | |
---|---|---|
committer | 2022-04-02 05:11:57 -0700 | |
commit | 614f64ba82947f7c2d3bf2dcc4e4993f6446e9b9 (patch) | |
tree | e58fa827ef5503baaab87fc62dff3fb7fd00ab8b /src/javascript/jsc/base.zig | |
parent | b8263d097527efb64119a86b82c1e9dcabf40273 (diff) | |
download | bun-614f64ba82947f7c2d3bf2dcc4e4993f6446e9b9.tar.gz bun-614f64ba82947f7c2d3bf2dcc4e4993f6446e9b9.tar.zst bun-614f64ba82947f7c2d3bf2dcc4e4993f6446e9b9.zip |
Fix GC bug when reading TypedArray from user input
Diffstat (limited to '')
-rw-r--r-- | src/javascript/jsc/base.zig | 42 |
1 files changed, 36 insertions, 6 deletions
diff --git a/src/javascript/jsc/base.zig b/src/javascript/jsc/base.zig index c6a861e17..afc911140 100644 --- a/src/javascript/jsc/base.zig +++ b/src/javascript/jsc/base.zig @@ -2228,6 +2228,7 @@ pub const ArrayBuffer = extern struct { len: u32, byte_len: u32, typed_array_type: JSC.JSValue.JSType, + value: JSC.JSValue = JSC.JSValue.zero, pub const name = "Bun__ArrayBuffer"; pub const Stream = std.io.FixedBufferStream([]u8); @@ -2239,6 +2240,7 @@ pub const ArrayBuffer = extern struct { pub fn fromTypedArray(ctx: JSC.C.JSContextRef, value: JSC.JSValue, _: JSC.C.ExceptionRef) ArrayBuffer { var out = std.mem.zeroes(ArrayBuffer); std.debug.assert(value.asArrayBuffer_(ctx.ptr(), &out)); + out.value = value; return out; } @@ -2247,6 +2249,33 @@ pub const ArrayBuffer = extern struct { } pub fn toJS(this: ArrayBuffer, ctx: JSC.C.JSContextRef, exception: JSC.C.ExceptionRef) JSC.JSValue { + return this.value; + } + + // If it's not a mimalloc heap buffer, we're not going to call a deallocator + if (!bun.Global.Mimalloc.mi_is_in_heap_region(this.ptr)) { + if (this.typed_array_type == .ArrayBuffer) { + return JSC.JSValue.fromRef(JSC.C.JSObjectMakeArrayBufferWithBytesNoCopy( + ctx, + this.ptr, + this.byte_len, + null, + null, + exception, + )); + } + + return JSC.JSValue.fromRef(JSC.C.JSObjectMakeTypedArrayWithBytesNoCopy( + ctx, + this.typed_array_type.toC(), + this.ptr, + this.byte_len, + null, + null, + exception, + )); + } + if (this.typed_array_type == .ArrayBuffer) { return JSC.JSValue.fromRef(JSC.C.JSObjectMakeArrayBufferWithBytesNoCopy( ctx, @@ -2276,6 +2305,10 @@ pub const ArrayBuffer = extern struct { callback: JSC.C.JSTypedArrayBytesDeallocator, exception: JSC.C.ExceptionRef, ) JSC.JSValue { + if (!this.value.isEmpty()) { + return this.value; + } + if (this.typed_array_type == .ArrayBuffer) { return JSC.JSValue.fromRef(JSC.C.JSObjectMakeArrayBufferWithBytesNoCopy( ctx, @@ -2349,12 +2382,9 @@ pub const MarkedArrayBuffer = struct { return MarkedArrayBuffer.fromBytes(buf, allocator, JSC.JSValue.JSType.Uint8Array); } - pub fn fromJS(global: *JSC.JSGlobalObject, value: JSC.JSValue, exception: JSC.C.ExceptionRef) ?MarkedArrayBuffer { - return switch (value.jsType()) { - JSC.JSValue.JSType.Uint16Array, JSC.JSValue.JSType.Uint32Array, JSC.JSValue.JSType.Uint8Array, JSC.JSValue.JSType.DataView => fromTypedArray(global.ref(), value, exception), - JSC.JSValue.JSType.ArrayBuffer => fromArrayBuffer(global.ref(), value, exception), - else => null, - }; + pub fn fromJS(global: *JSC.JSGlobalObject, value: JSC.JSValue, _: JSC.C.ExceptionRef) ?MarkedArrayBuffer { + const array_buffer = value.asArrayBuffer(global) orelse return null; + return MarkedArrayBuffer{ .buffer = array_buffer, .allocator = null }; } pub fn fromBytes(bytes: []u8, allocator: std.mem.Allocator, typed_array_type: JSC.JSValue.JSType) MarkedArrayBuffer { |