Skip to content

Blob/URL: identify Blobs by our own constructor; make URL's static methods writable (WebIDL) - #251

Open
matthargett wants to merge 6 commits into
BabylonJS:mainfrom
rebeckerspecialties:blob-identity-url-writable-statics
Open

matthargett wants to merge 6 commits into
BabylonJS:mainfrom
rebeckerspecialties:blob-identity-url-writable-statics

Conversation

@matthargett

@matthargett matthargett commented Sep 17, 2026 •

Copy link
Copy Markdown

Problem

  • Blob::TryGetData (behind URL.createObjectURL) identified our Blobs by walking the prototype chain against the current global Blob. A page that installs its own Blob class (BabylonNative's validation harness does, for image loading) made every instance of that class pass the check: ObjectWrap::Unwrap threw a bare Error: Invalid argument, and a genuine native Blob was rejected as "not a Blob".
  • The same harness assigns its own URL.createObjectURL. Node-API's napi_default makes static methods read-only, so the assignment failed silently; WebIDL static operations are writable, enumerable and configurable.
  • Symptom: the SOG Gaussian-splat scenes failing with Failed to parse SOG zip data, cause Invalid argument.

Change

  • Pin the Blob constructor under a hidden, non-configurable global at Initialize and identify instances against that, not against the global binding and not on the JsRuntime native object (worker realms have none, Add a browser-compatible Worker polyfill (dedicated workers, structured clone, transfer lists, focused WPT regressions) #258). A null Unwrap yields nullopt, so the existing TypeError: … argument is not a Blob applies.
  • Declare the URL statics (canParse, parse, createObjectURL, revokeObjectURL) with napi_writable | napi_enumerable | napi_configurable.
  • Node-API-JSI honours napi_writable for method properties (it ignored the attribute).
  • Two regression tests in the URL.createObjectURL suite; both fail on main.

Current with main @ b2b51ca (#257's per-feature test layout).

…thods writable

Blob::TryGetData compared an object's prototype chain against whatever
the global `Blob` binding held at call time. A script that replaces the
global Blob with its own class (BabylonNative's validation harness does,
for image loading) made every instance of that class look like one of
ours, and Unwrap on an object that wraps nothing threw a bare "Invalid
argument" out of URL.createObjectURL -- while a real Blob was rejected
as "not a Blob". The constructor is now kept on the runtime's native
object at Initialize and identity is checked against that; a null
Unwrap yields "not a Blob" like any other foreign object.

The same harness assigns its own URL.createObjectURL. napi_default
makes static methods read-only, so that assignment failed silently and
the native method kept receiving the foreign Blob. WebIDL static
operations are writable, enumerable and configurable; declare the URL
statics that way.

Found by the SOG Gaussian-splat scenes of BabylonNative's Dawn
validation catalog ("Failed to parse SOG zip data", cause "Invalid
argument"); they pass again with this change. Regression tests cover
both halves.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

matthargett added a commit to rebeckerspecialties/JsRuntimeHost that referenced this pull request Sep 17, 2026
@matthargett

matthargett commented Sep 17, 2026 •

Copy link
Copy Markdown
Author

Twin caught a test-only issue on Win32_x86_Chakra: ChakraCore has no globalThis, so the look-alike test threw a ReferenceError before asserting anything. The test now reaches the global object via Function("return this")() (b374eb4); no polyfill change.

@matthargett

Copy link
Copy Markdown
Author

cc @CedricGuillemet since this is another issue blocking splats on WebGPU in BN

…abylonJS#257)

The Blob-identity and writable-URL-statics regression tests move from the monolithic tests.ts into
the URL.createObjectURL block of Source/Scripts/tests.url.ts.
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.

2 participants