Skip to content

Fix cross-realm TypedArray and ArrayBuffer detection#20

Open
ItsChrisHickman wants to merge 1 commit intogreggman:mainfrom
ItsChrisHickman:fix/cross-realm-typedarray
Open

Fix cross-realm TypedArray and ArrayBuffer detection#20
ItsChrisHickman wants to merge 1 commit intogreggman:mainfrom
ItsChrisHickman:fix/cross-realm-typedarray

Conversation

@ItsChrisHickman
Copy link

@ItsChrisHickman ItsChrisHickman commented Mar 17, 2026

Problem

isTypedArray and isBufferSource use instanceof ArrayBuffer checks that silently fail when values cross JavaScript realm boundaries. This happens whenever WebGL content runs inside an iframe and receives buffers from the parent page (or vice versa) — each realm has its own ArrayBuffer constructor, so instanceof returns false for objects created in the other realm. This has as real world application for THREE.js applications with javascript SDKs that provide the ability add THREE based enhancements.

The result is that bufferData calls reject perfectly valid TypedArray and ArrayBuffer inputs with an "unsupported src type" error, even though the data is correct.

Fix

  • isTypedArray: Replace v && v.buffer && v.buffer instanceof ArrayBuffer with ArrayBuffer.isView(v). This is the spec-recommended way to check for TypedArrays and DataViews — it works across realms by design and is supported in all browsers since IE10.

  • isBufferSource: Add an Object.prototype.toString.call(v) === '[object ArrayBuffer]' fallback alongside the existing instanceof check. The instanceof fast path still covers same-realm buffers with zero overhead; the fallback only activates for cross-realm cases.

Why this is safe

Both replacement APIs are strictly more correct than instanceof:

  • ArrayBuffer.isView returns true for the exact same set of types (all TypedArray variants + DataView) that the original duck-typing check targeted, but without the realm limitation.
  • The Object.prototype.toString fallback is the standard pattern for cross-realm type detection used throughout the JS ecosystem (e.g. lodash, Node.js internals).
  • No new dependencies, no behavioral change for same-realm usage — existing consumers see identical results.

isTypedArray used `v.buffer instanceof ArrayBuffer` which fails when
the value originates from a different JavaScript realm (e.g. an iframe).
Each realm has its own built-in constructors, so instanceof returns
false for objects created in another realm.

Replace with `ArrayBuffer.isView(v)` which is specified to work across
realms. Apply the same cross-realm fix to isBufferSource using an
Object.prototype.toString fallback for ArrayBuffer.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant