Skip to content

fix(p2-shim): coerce browser file read bounds to numbers#1574

Open
zacharywhitley wants to merge 1 commit into
bytecodealliance:mainfrom
zacharywhitley:fix-preview2-shim-browser-bigint-read
Open

fix(p2-shim): coerce browser file read bounds to numbers#1574
zacharywhitley wants to merge 1 commit into
bytecodealliance:mainfrom
zacharywhitley:fix-preview2-shim-browser-bigint-read

Conversation

@zacharywhitley
Copy link
Copy Markdown

Fixes #1573

wasi-filesystem read takes filesize (u64) arguments, which the canonical-ABI binding passes as BigInt. Uint8Array.slice rejects BigInt and throws Cannot convert a BigInt value to a number on the first read against any file in the browser implementation.

Coerce both arguments to Number on entry. Safe up to Number.MAX_SAFE_INTEGER bytes.

Reproducer and before/after evidence are in #1573.

wasi-filesystem read takes filesize (u64) arguments, which the
canonical-ABI binding passes as BigInt. Uint8Array.slice rejects
BigInt and throws "Cannot convert a BigInt value to a number" on
the first read against any file in the browser implementation:

    TypeError: Cannot convert a BigInt value to a number
        at Uint8Array.slice (<anonymous>)
        at Descriptor.read (preview2-shim/lib/browser/filesystem.js:191)

Coerce both arguments to Number on entry. Safe up to
Number.MAX_SAFE_INTEGER bytes (~9 PB), well above any practical
browser use.

Signed-off-by: Zachary Whitley <zachary.whitley@tegmentum.ai>
zacharywhitley pushed a commit to tegmentum/wasi-polyfill that referenced this pull request May 29, 2026
…cion

Establish patches/jco/ + docs/upstream-patches.md as the
register for compatibility patches carried locally against
published upstream WASI / browser runtime layers.

Adds the first entry:

  Patch:               bytecodealliance/jco#1574
  Reason:              browser p2-shim file read BigInt bounds incompatibility
                       (Uint8Array.slice rejects the canonical-ABI BigInt
                       offset and length arguments)
  Scope:               JCO preview2/browser shim only
                       (packages/preview2-shim/lib/browser/filesystem.js
                       Descriptor.read)
  Removal condition:   first jco release containing #1574 or equivalent
                       upstream fix (detected at apply time via
                       'typeof offset === "bigint"' against the browser
                       filesystem.js source)
  Substrate impact:    none — patch lives in the compatibility layer,
                       not in any consumer's substrate code

Carried so that any consumer of @tegmentum/wasi-polyfill picks
up the corrected browser compatibility behavior without having
to learn about JCO's browser BigInt bug or carry a private
workaround.

Patch file applies with:
    patch -p5 -d <shim-dir> < patches/jco/1574-coerce-browser-file-read-bounds-to-numbers.patch

against a copy of @bytecodealliance/preview2-shim's browser
build (verified on 0.18.0).

See docs/upstream-patches.md for the active/retired patch
register and the lifecycle of a carried patch.

Signed-off-by: Zachary Whitley <zachary.whitley@tegmentum.ai>
Copy link
Copy Markdown
Collaborator

@vados-cosmonic vados-cosmonic left a comment

Choose a reason for hiding this comment

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

LGTM 🚀

Thanks @zacharywhitley for getting this fixed -- would you mind sharing an outline of what the component was doing (or even code for the component itself?) would love to get it added to a regression test.

We're going to be expanding the coverage of our test suite (currently we only build Rust components for use in testing), but it would be nice to have JVM component code and some ooling to build and use during test.

read(length, offset) {
const source = getSource(this.#entry);
return [source.slice(offset, offset + length), offset + length >= source.byteLength];
const off = typeof offset === "bigint" ? Number(offset) : offset;
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The line after this is probably a good time to check and error loudly if we're over Number.MAX_SAFE_INTEGER.

Separately, rather than checking for bigint in particular we should check for number and do the conversion for non-number types (also happy with checking the cases systematically with a switch or if).

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.

Browser preview2-shim: Descriptor.read throws on canonical BigInt arguments

2 participants