gloo icon indicating copy to clipboard operation
gloo copied to clipboard

`Blob::new(&[u8])` fails when wasm memory is backed by `SharedArrayBuffer`

Open Liamolucko opened this issue 3 years ago • 3 comments

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

  1. Clone https://github.com/Liamolucko/gloo-sab-repro
  2. Build and bindgen it:
cargo build --release
wasm-bindgen target/wasm32-unknown-unknown/release/gloo-sab-repro.wasm --out-dir dist --target web
  1. 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.

Liamolucko avatar Apr 07 '22 09:04 Liamolucko

Do you know of a fix for this?

ranile avatar Apr 07 '22 10:04 ranile

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.

Liamolucko avatar Apr 07 '22 11:04 Liamolucko

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

ranile avatar Apr 07 '22 15:04 ranile