fix(p2-shim): coerce browser file read bounds to numbers#1574
fix(p2-shim): coerce browser file read bounds to numbers#1574zacharywhitley wants to merge 1 commit into
Conversation
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>
…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>
vados-cosmonic
left a comment
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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).
Fixes #1573
wasi-filesystem
readtakesfilesize(u64) arguments, which the canonical-ABI binding passes asBigInt.Uint8Array.slicerejectsBigIntand throwsCannot convert a BigInt value to a numberon the first read against any file in the browser implementation.Coerce both arguments to
Numberon entry. Safe up toNumber.MAX_SAFE_INTEGERbytes.Reproducer and before/after evidence are in #1573.