From 7c9dce2a39a34260c07dbef524b6129edfd59631 Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Tue, 21 Apr 2026 17:00:31 +0800 Subject: [PATCH] Add error-callback on shared buffer clone from v8 With our current "null" cullback, trying to clone a shared buffer crashes. The callback throws an error. Fixes a WPT crash: /html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/blob-data.https.html --- src/browser/js/Value.zig | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/browser/js/Value.zig b/src/browser/js/Value.zig index 3105b95e..a59701d7 100644 --- a/src/browser/js/Value.zig +++ b/src/browser/js/Value.zig @@ -328,12 +328,23 @@ pub fn structuredCloneTo(self: Value, target: *const js.Local) !Value { // Called by V8 to report serialization errors. The exception should already be thrown. fn throwDataCloneError(_: ?*anyopaque, _: ?*const v8.String) callconv(.c) void {} + + // Called when V8 encounters a SharedArrayBuffer. We don't support sharing them across + // contexts, so throw a DataCloneError and return false. V8's WriteJSArrayBuffer calls + // RETURN_VALUE_IF_EXCEPTION after this, so throwing prevents the fatal FromJust call. + fn getSharedArrayBufferId(_: ?*anyopaque, isolate: ?*v8.Isolate, _: ?*const v8.SharedArrayBuffer, _: ?*u32) callconv(.c) bool { + const iso = isolate orelse return false; + const message = v8.v8__String__NewFromUtf8(iso, "SharedArrayBuffer cannot be cloned.", v8.kNormal, -1); + const error_value = v8.v8__Exception__Error(message) orelse return false; + _ = v8.v8__Isolate__ThrowException(iso, error_value); + return false; + } }; const size, const data = blk: { const serializer = v8.v8__ValueSerializer__New(v8_isolate, &.{ .data = null, - .get_shared_array_buffer_id = null, + .get_shared_array_buffer_id = SerializerDelegate.getSharedArrayBufferId, .write_host_object = SerializerDelegate.writeHostObject, .throw_data_clone_error = SerializerDelegate.throwDataCloneError, }) orelse return error.JsException;