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
Runtime split()/parseFloat() read past exact-sized slice allocations -> intermittent AV (c0000005) on hot paths #6085
Access violation (c0000005) with empty stderr — the compiled game dies silently or freezes (last presented frame stays on screen, input appears dead). Faulting reads land just past the end of a heap page (0x...FFF8-style addresses). The crash is layout-sensitive: a relink can hide or resurface it, which makes it look unreproducible.
Trigger
Running a string through split() + parseFloat() on a hot path (every frame). Perry's runtime string scanners appear to read one word past the end of their own exact-sized slice allocations; with enough fresh allocations per second, one eventually lands flush against an unmapped page and faults.
We hit this parsing a label|1.23|4.56\n...-style blob returned from a native FFI every frame: 6/6 crashes within 7-29 seconds, reproduced across two different link layouts. One-shot parses carry the same risk per call, just with much lower odds.
Minimal repro sketch
Any FFI (or plain TS source) producing a multi-line 1.23|4.56\n blob.
Per frame: for (const line of blob.split('\n')) { const parts = line.split('|'); parseFloat(parts[0]); ... }
On Windows x64 this AVs within a minute on an affected build.
Workaround we shipped
Replaced the delimited-text ABI with a numeric one (one FFI call per scalar, f64 across the boundary; strings cross whole and are only drawn, never parsed). Also tail-padded engine-allocated FFI strings by 16 zero bytes — note this cannot protect Perry-internal slice allocations, which is why the ABI change was required.
Environment
perry 0.5.1208 (also reproduced on the 0.5.11xx line)
Windows 11 Pro 26200, x64, lld-link
Crash addresses consistently at end-of-heap-page boundaries; minidumps available on request
Activity
fix(runtime): bound WTF-8 decode against truncated trailing lead bytes (
fix(runtime): root split parts across allocations; don't trim truncat…
fix(runtime): string scanners must not read past exact-sized slice al…
fix(runtime): derive each split part's metadata from its own bytes (#…
perf(string): ASCII fast path for UTF-16 code-unit comparison (#7229)
fix(runtime): multiline ^/$ hold at every LineTerminator, and split("…
perf(runtime): stop double-scanning ASCII-ness and buffering the conc…
perf(runtime): stop double-scanning ASCII-ness and buffering the conc…
fix(string): make codePointAt linear on non-ASCII strings (#10656)
fix(runtime): guard normalize/localeCompare against WTF-8 payloads (#…