Skip to content

Runtime split()/parseFloat() read past exact-sized slice allocations -> intermittent AV (c0000005) on hot paths #6085

Description

@proggeramlug

Symptom

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

  1. Any FFI (or plain TS source) producing a multi-line 1.23|4.56\n blob.
  2. Per frame: for (const line of blob.split('\n')) { const parts = line.split('|'); parseFloat(parts[0]); ... }
  3. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions