`Blob::new(&[u8])` fails when wasm memory is backed by `SharedArrayBuffer`
Describe the Bug
I've just stumbled upon an issue with my changes in #152, which is that new Blob() doesn't allow passing Uint8Arrays backed by SharedArrayBuffer. This is problematic because SharedArrayBuffer is sometimes used to back wasm memory, which will then cause Blob::new(&[u8]) to fail.
This isn't an issue for Blob::new(ArrayBuffer), since SharedArrayBuffer isn't actually a subclass of ArrayBuffer.
Blob::new will have to fall back to copying the buffer when wasm memory is backed by a SharedArrayBuffer, or just do it unconditionally.
Steps to Reproduce
- Clone https://github.com/Liamolucko/gloo-sab-repro
- Build and bindgen it:
cargo build --release
wasm-bindgen target/wasm32-unknown-unknown/release/gloo-sab-repro.wasm --out-dir dist --target web
- Run the resulting wasm in a web browser or Deno
Expected Behavior
It should run successfully.
Actual Behavior
new Blob() throws an error, which causes a panic since it's not expected to fail.
Additional Context
This is actually the case (according to the spec, at least) for basically everything accepting a buffer source, because WebIDL doesn't consider SharedArrayBuffer a real buffer source unless the type has the [AllowShared] attribute. Based on a quick grep of web-sys's WebIDL definitions, only WebGPU is using that right now.
I found out about this from getrandom's similar issue: rust-random/getrandom#164.
Do you know of a fix for this?
Yes; if the wasm memory is backed by a SharedArrayBuffer, the bytes will have to be copied into a regular ArrayBuffer before passing to new Blob() (probably via. Uint8Array::from). It's a bit annoying having to re-introduce an intermediate copy, but it's more important that it works.
Can we expose a separate API for handling this? We document that Blob cannot be used with SharedArrayBuffer, there will be a new type introduced to handle that.
I would really like to avoid copying memory. If we have to do it, it must be explicitly done