You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Uint8Array<ArrayBuffer>-annotated receiver: indexOf / lastIndexOf silently return -1 (plain Uint8Array, any and Float32Array<ArrayBuffer> are correct) #10894
A receiver whose static type is written Uint8Array<ArrayBuffer> (the generic form TypeScript ≥ 5.7's lib types use, and what tsc infers for new Uint8Array(n)) gets the wrong indexOf / lastIndexOf: they return -1 for a value that is present. No error — a silent wrong value. The same call through Uint8Array, through any, or through Float32Array<ArrayBuffer> is correct, so this is the static dispatch chosen for that one annotation, not the runtime method.
length and indexed reads are right on the same receiver; only the search methods are wrong (includes not distinguishable in this fixture — the expected answer is false).
A binding whose type is only inferred through the generic is fine — inside for await (const m of gen()) with gen(): AsyncGenerator<Uint8Array<ArrayBuffer>>, m.indexOf(44, from) is correct, while passing that same m to a parameter annotated Uint8Array<ArrayBuffer> returns -1.
Impact
Found in a real program: the TypeScript Native Messaging host at https://github.com/guest271314/NativeMessagingHosts (nm_typescript.ts). sendMessage(message: Uint8Array<ArrayBuffer>) splits replies larger than 1 MiB at a comma found with message.indexOf(COMMA, searchStart). With -1 it never splits, so a 1,048,581-byte message goes out as one frame over the 1 MiB host→browser limit (node: 2 frames, max 1,048,571).
Fixed in v0.5.1633 (merge train 253, 0fa3915293) by #10912 — the generic spelling Uint8Array<ArrayBuffer> silently got the wrong indexOf / lastIndexOf / includes / join. Covered by buffer_backed_generic_tests.rs (perry-hir) and typed_array_receiver_tests.rs (perry-runtime), both inside suites run to completion on the landed tree: perry-hir 471/0 and perry-runtime 4233/0/0.
Severity bump: this is an out-of-bounds read, not just a wrong value — it SIGSEGVs. (Found while chasing the "64 MiB SIGSEGV" noted at the bottom of #10895; that crash is this bug.)
macOS crash report for the Native Messaging host (Uint8Array<ArrayBuffer>-annotated message, 64 MiB message, main 841b605c97):
So the generic annotation dispatches indexOf to the plain-Arrayjs_array_indexOf_jsvalue, which walks the typed array's byte storage as 8-byte JSValue slots: -1 when the garbage never equals the needle and the walk stays inside mapped memory, SIGSEGV when it runs off the end.
Six-line crash repro — rc=139 on Linux x86_64 main (v0.5.1632) at n = 2 MiB, 16 MiB and 64 MiB; the published 0.5.1520 returns -1 without crashing:
functiong(m: Uint8Array<ArrayBuffer>,from: number): number{returnm.indexOf(44,from);}constn=Number(process.argv[2]);constu=newUint8Array(n);u.fill(110);// no match anywhere -> scans to "length"console.log("generic",g(u,1048568));
With the receiver annotated plain Uint8Array the same host round-trips 64 MiB 100/100.
Activity
changelog: fragment for PerryTS#10912 (`Uint8Array<ArrayBuffer>` rece…
fix(hir,runtime): `Uint8Array<ArrayBuffer>`-annotated receivers no lo…
changelog: fragment for #10912 (`Uint8Array<ArrayBuffer>` receivers, #…
proggeramlug commentedon Sep 21, 2026
Fixed in v0.5.1633 (merge train 253,
0fa3915293) by #10912 — the generic spellingUint8Array<ArrayBuffer>silently got the wrongindexOf/lastIndexOf/includes/join. Covered bybuffer_backed_generic_tests.rs(perry-hir) andtyped_array_receiver_tests.rs(perry-runtime), both inside suites run to completion on the landed tree:perry-hir471/0 andperry-runtime4233/0/0.proggeramlug commentedon Sep 21, 2026
Severity bump: this is an out-of-bounds read, not just a wrong value — it SIGSEGVs. (Found while chasing the "64 MiB SIGSEGV" noted at the bottom of #10895; that crash is this bug.)
macOS crash report for the Native Messaging host (
Uint8Array<ArrayBuffer>-annotatedmessage, 64 MiB message, main841b605c97):So the generic annotation dispatches
indexOfto the plain-Arrayjs_array_indexOf_jsvalue, which walks the typed array's byte storage as 8-byte JSValue slots:-1when the garbage never equals the needle and the walk stays inside mapped memory, SIGSEGV when it runs off the end.Six-line crash repro —
rc=139on Linux x86_64 main (v0.5.1632) at n = 2 MiB, 16 MiB and 64 MiB; the published 0.5.1520 returns-1without crashing:With the receiver annotated plain
Uint8Arraythe same host round-trips 64 MiB 100/100.