From d5f59ddbb5977719dec365445b7015e212d068f8 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Thu, 5 Dec 2024 02:13:50 +0100 Subject: [PATCH] Account for Firefox `SharedArrayBuffer` bug in shared workers --- src/backends/wasm_js.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/backends/wasm_js.rs b/src/backends/wasm_js.rs index 61198f53..687c00af 100644 --- a/src/backends/wasm_js.rs +++ b/src/backends/wasm_js.rs @@ -16,7 +16,7 @@ pub use crate::util::{inner_u32, inner_u64}; #[cfg(not(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none"))))] compile_error!("`wasm_js` backend can be enabled only for OS-less WASM targets!"); -use js_sys::{SharedArrayBuffer, Uint8Array, WebAssembly::Memory}; +use js_sys::{JsString, Object, Uint8Array, WebAssembly::Memory}; use wasm_bindgen::{prelude::wasm_bindgen, JsCast, JsValue}; // Size of our temporary Uint8Array buffer used with WebCrypto methods @@ -39,7 +39,10 @@ pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { MEMORY_KIND_SHARED => true, MEMORY_KIND_UNINIT => { let memory: Memory = wasm_bindgen::memory().unchecked_into(); - let val = if memory.buffer().is_instance_of::() { + // We can't use `instanceof` because of a bug in Firefox. + // Instead we compare the constructor name, which always works. + let constructor_name = Object::from(memory.buffer()).constructor().name(); + let val = if SHARED_ARRAY_BUFFER_NAME.with(|name| &constructor_name == name) { MEMORY_KIND_SHARED } else { MEMORY_KIND_NOT_SHARED @@ -87,6 +90,7 @@ pub fn fill_inner(dest: &mut [MaybeUninit]) -> Result<(), Error> { } #[wasm_bindgen] +#[rustfmt::skip] extern "C" { // Web Crypto API: Crypto interface (https://www.w3.org/TR/WebCryptoAPI/) type Crypto; @@ -98,4 +102,6 @@ extern "C" { fn get_random_values(this: &Crypto, buf: &Uint8Array) -> Result<(), JsValue>; #[wasm_bindgen(method, js_name = getRandomValues, catch)] fn get_random_values_ref(this: &Crypto, buf: &mut [u8]) -> Result<(), JsValue>; + #[wasm_bindgen(thread_local_v2, static_string)] + static SHARED_ARRAY_BUFFER_NAME: JsString = "SharedArrayBuffer"; }