diff options
author | 2023-08-19 18:17:16 -0700 | |
---|---|---|
committer | 2023-08-19 18:17:16 -0700 | |
commit | 507761b4637a83d10e2f8b64ff870881bba7c14b (patch) | |
tree | cb3a2920ed18832df3c7075bd8e21b15b1184a3d /src | |
parent | 196620183fd20ca42b363c5f947af1dc979f888f (diff) | |
download | bun-507761b4637a83d10e2f8b64ff870881bba7c14b.tar.gz bun-507761b4637a83d10e2f8b64ff870881bba7c14b.tar.zst bun-507761b4637a83d10e2f8b64ff870881bba7c14b.zip |
Fix crash impacting sharp & resvg (#4221)
Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/bun.js/base.zig | 38 | ||||
-rw-r--r-- | src/bun.js/bindings/JSBuffer.cpp | 2 | ||||
-rw-r--r-- | src/bun.js/bindings/napi.cpp | 49 | ||||
-rw-r--r-- | src/napi/napi.zig | 26 |
4 files changed, 53 insertions, 62 deletions
diff --git a/src/bun.js/base.zig b/src/bun.js/base.zig index dbb208284..b08b82c40 100644 --- a/src/bun.js/base.zig +++ b/src/bun.js/base.zig @@ -771,44 +771,6 @@ comptime { std.testing.refAllDecls(RefString); } -// TODO: remove this abstraction and make it work directly with -pub const ExternalBuffer = struct { - global: *JSC.JSGlobalObject, - ctx: ?*anyopaque = null, - function: JSC.napi.napi_finalize = null, - allocator: std.mem.Allocator, - buf: []u8 = &[_]u8{}, - - pub fn create(ctx: ?*anyopaque, buf: []u8, global: *JSC.JSGlobalObject, function: JSC.napi.napi_finalize, allocator: std.mem.Allocator) !*ExternalBuffer { - var container = try allocator.create(ExternalBuffer); - container.* = .{ - .ctx = ctx, - .global = global, - .allocator = allocator, - .function = function, - .buf = buf, - }; - return container; - } - - pub fn toJS(this: *ExternalBuffer, ctx: *JSC.JSGlobalObject) JSC.JSValue { - return JSC.JSValue.createBufferWithCtx(ctx, this.buf, this, ExternalBuffer_deallocator); - } - - pub fn toArrayBuffer(this: *ExternalBuffer, ctx: *JSC.JSGlobalObject) JSC.JSValue { - return JSValue.c(JSC.C.JSObjectMakeArrayBufferWithBytesNoCopy(ctx.ref(), this.buf.ptr, this.buf.len, ExternalBuffer_deallocator, this, null)); - } -}; -pub export fn ExternalBuffer_deallocator(bytes_: *anyopaque, ctx: *anyopaque) callconv(.C) void { - var external: *ExternalBuffer = bun.cast(*ExternalBuffer, ctx); - if (external.function) |function| { - function(external.global, external.ctx, bytes_); - } - - const allocator = external.allocator; - allocator.destroy(external); -} - pub export fn MarkedArrayBuffer_deallocator(bytes_: *anyopaque, _: *anyopaque) void { const mimalloc = @import("../allocators/mimalloc.zig"); // zig's memory allocator interface won't work here diff --git a/src/bun.js/bindings/JSBuffer.cpp b/src/bun.js/bindings/JSBuffer.cpp index 16c0e64b6..934fc9b6c 100644 --- a/src/bun.js/bindings/JSBuffer.cpp +++ b/src/bun.js/bindings/JSBuffer.cpp @@ -202,7 +202,7 @@ JSC::EncodedJSValue JSBuffer__bufferFromPointerAndLengthAndDeinit(JSC::JSGlobalO auto* subclassStructure = globalObject->JSBufferSubclassStructure(); if (LIKELY(length > 0)) { - auto buffer = ArrayBuffer::createFromBytes(ptr, length, createSharedTask<void(void*)>([=](void* p) { + auto buffer = ArrayBuffer::createFromBytes(ptr, length, createSharedTask<void(void*)>([ctx, bytesDeallocator](void* p) { if (bytesDeallocator) bytesDeallocator(p, ctx); })); diff --git a/src/bun.js/bindings/napi.cpp b/src/bun.js/bindings/napi.cpp index 237f3d554..393c133e1 100644 --- a/src/bun.js/bindings/napi.cpp +++ b/src/bun.js/bindings/napi.cpp @@ -1551,6 +1551,55 @@ extern "C" napi_status napi_get_property_names(napi_env env, napi_value object, return napi_ok; } +extern "C" napi_status napi_create_external_buffer(napi_env env, size_t length, + void* data, + napi_finalize finalize_cb, + void* finalize_hint, + napi_value* result) +{ + if (UNLIKELY(result == nullptr)) { + return napi_invalid_arg; + } + + Zig::GlobalObject* globalObject = toJS(env); + JSC::VM& vm = globalObject->vm(); + + auto arrayBuffer = ArrayBuffer::createFromBytes(data, length, createSharedTask<void(void*)>([globalObject, finalize_hint, finalize_cb](void* p) { + if (finalize_cb != nullptr) { + finalize_cb(toNapi(globalObject), p, finalize_hint); + } + })); + auto* subclassStructure = globalObject->JSBufferSubclassStructure(); + + auto* buffer = JSC::JSUint8Array::create(globalObject, subclassStructure, WTFMove(arrayBuffer), 0, length); + + *result = toNapi(buffer); + return napi_ok; +} + +extern "C" napi_status napi_create_external_arraybuffer(napi_env env, void* external_data, size_t byte_length, + napi_finalize finalize_cb, void* finalize_hint, napi_value* result) +{ + if (UNLIKELY(result == nullptr)) { + return napi_invalid_arg; + } + + Zig::GlobalObject* globalObject = toJS(env); + JSC::VM& vm = globalObject->vm(); + + auto arrayBuffer = ArrayBuffer::createFromBytes(external_data, byte_length, createSharedTask<void(void*)>([globalObject, finalize_hint, finalize_cb](void* p) { + if (finalize_cb != nullptr) { + finalize_cb(toNapi(globalObject), p, finalize_hint); + } + })); + + auto* buffer = JSC::JSArrayBuffer::create(vm, globalObject->arrayBufferStructure(ArrayBufferSharingMode::Shared), WTFMove(arrayBuffer)); + + *result = toNapi(buffer); + + return napi_ok; +} + extern "C" napi_status napi_get_value_string_utf8(napi_env env, napi_value napiValue, char* buf, size_t bufsize, diff --git a/src/napi/napi.zig b/src/napi/napi.zig index 9d361a14e..ac428028b 100644 --- a/src/napi/napi.zig +++ b/src/napi/napi.zig @@ -707,20 +707,8 @@ pub export fn napi_create_arraybuffer(env: napi_env, byte_length: usize, data: [ return .ok; } -pub export fn napi_create_external_arraybuffer(env: napi_env, external_data: ?*anyopaque, byte_length: usize, finalize_cb: napi_finalize, finalize_hint: ?*anyopaque, result: *napi_value) napi_status { - log("napi_create_external_arraybuffer", .{}); - var external = JSC.ExternalBuffer.create( - finalize_hint, - @as([*]u8, @ptrCast(external_data.?))[0..byte_length], - env, - finalize_cb, - env.bunVM().allocator, - ) catch { - return genericFailure(); - }; - result.* = external.toArrayBuffer(env); - return .ok; -} +pub extern fn napi_create_external_arraybuffer(env: napi_env, external_data: ?*anyopaque, byte_length: usize, finalize_cb: napi_finalize, finalize_hint: ?*anyopaque, result: *napi_value) napi_status; + pub export fn napi_get_arraybuffer_info(env: napi_env, arraybuffer: napi_value, data: ?*[*]u8, byte_length: ?*usize) napi_status { log("napi_get_arraybuffer_info", .{}); const array_buffer = arraybuffer.asArrayBuffer(env) orelse return .arraybuffer_expected; @@ -1072,15 +1060,7 @@ pub export fn napi_create_buffer(env: napi_env, length: usize, data: ?**anyopaqu result.* = buffer; return .ok; } -pub export fn napi_create_external_buffer(env: napi_env, length: usize, data: ?*anyopaque, finalize_cb: napi_finalize, finalize_hint: ?*anyopaque, result: *napi_value) napi_status { - log("napi_create_external_buffer: {d}", .{length}); - var buf = JSC.ExternalBuffer.create(finalize_hint, @as([*]u8, @ptrCast(data.?))[0..length], env, finalize_cb, bun.default_allocator) catch { - return genericFailure(); - }; - - result.* = buf.toJS(env); - return .ok; -} +pub extern fn napi_create_external_buffer(env: napi_env, length: usize, data: ?*anyopaque, finalize_cb: napi_finalize, finalize_hint: ?*anyopaque, result: *napi_value) napi_status; pub export fn napi_create_buffer_copy(env: napi_env, length: usize, data: [*]u8, result_data: ?*?*anyopaque, result: *napi_value) napi_status { log("napi_create_buffer_copy: {d}", .{length}); var buffer = JSC.JSValue.createBufferFromLength(env, length); |