Skip to content

Commit b711996

Browse files
committed
Account for Firefox SharedArrayBuffer bug in shared workers
1 parent d0b6d66 commit b711996

File tree

1 file changed

+22
-3
lines changed

1 file changed

+22
-3
lines changed

src/backends/wasm_js.rs

+22-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ pub use crate::util::{inner_u32, inner_u64};
1616
#[cfg(not(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none"))))]
1717
compile_error!("`wasm_js` backend can be enabled only for OS-less WASM targets!");
1818

19-
use js_sys::{SharedArrayBuffer, Uint8Array, WebAssembly::Memory};
19+
use js_sys::{JsString, Object, SharedArrayBuffer, Uint8Array, WebAssembly::Memory};
2020
use wasm_bindgen::{prelude::wasm_bindgen, JsCast, JsValue};
2121

2222
// Size of our temporary Uint8Array buffer used with WebCrypto methods
@@ -38,8 +38,21 @@ pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
3838
MEMORY_KIND_NOT_SHARED => false,
3939
MEMORY_KIND_SHARED => true,
4040
MEMORY_KIND_UNINIT => {
41-
let memory: Memory = wasm_bindgen::memory().unchecked_into();
42-
let val = if memory.buffer().is_instance_of::<SharedArrayBuffer>() {
41+
let buffer = wasm_bindgen::memory().unchecked_into::<Memory>().buffer();
42+
43+
// `SharedArrayBuffer` is only available with `crossOriginIsolated`. But even
44+
// without its possible to create a shared `WebAssembly.Memory`, so we check
45+
// for that via the constructor name.
46+
//
47+
// Keep in mind that `crossOriginIsolated` is not available on Node.js.
48+
let shared = if let Some(true) = CROSS_ORIGIN_ISOLATED.with(Option::clone) {
49+
buffer.is_instance_of::<SharedArrayBuffer>()
50+
} else {
51+
let constructor_name = Object::from(buffer).constructor().name();
52+
SHARED_ARRAY_BUFFER_NAME.with(|name| &constructor_name == name)
53+
};
54+
55+
let val = if shared {
4356
MEMORY_KIND_SHARED
4457
} else {
4558
MEMORY_KIND_NOT_SHARED
@@ -87,6 +100,7 @@ pub fn fill_inner(dest: &mut [MaybeUninit<u8>]) -> Result<(), Error> {
87100
}
88101

89102
#[wasm_bindgen]
103+
#[rustfmt::skip]
90104
extern "C" {
91105
// Web Crypto API: Crypto interface (https://www.w3.org/TR/WebCryptoAPI/)
92106
type Crypto;
@@ -98,4 +112,9 @@ extern "C" {
98112
fn get_random_values(this: &Crypto, buf: &Uint8Array) -> Result<(), JsValue>;
99113
#[wasm_bindgen(method, js_name = getRandomValues, catch)]
100114
fn get_random_values_ref(this: &Crypto, buf: &mut [u8]) -> Result<(), JsValue>;
115+
/// Returns the [`crossOriginIsolated`](https://developer.mozilla.org/en-US/docs/Web/API/crossOriginIsolated) global property.
116+
#[wasm_bindgen(thread_local_v2, js_namespace = globalThis, js_name = crossOriginIsolated)]
117+
static CROSS_ORIGIN_ISOLATED: Option<bool>;
118+
#[wasm_bindgen(thread_local_v2, static_string)]
119+
static SHARED_ARRAY_BUFFER_NAME: JsString = "SharedArrayBuffer";
101120
}

0 commit comments

Comments
 (0)