frostney / frostney/GocciaScript
Array copy-constructors preallocate guest-sized element capacity with no budget consult
Nobody has claimed this yet.
- Dominant language
- Pascal
- Stars
- 20
- Forks
- 3
- Avg merge
- 3d 4h
- Merged PRs (30d)
- 45
Description
Summary
Element-list capacity is guest-sizable with no budget consult at all on the array-copy constructors: Array.prototype.toSpliced.call({length: N}, 0, 0) allocates an N-slot element list (TGocciaArrayValue.Create(nil, NewLenInt) → FElements.Capacity := N) bounded only by CheckArrayCreateLenValue (≤ MaxInt), never by --max-memory.
Why
Runtime-confirmed during the #1157 rooting train's L3 review (2026-08-16): Array.prototype.toSpliced.call({length: 200000}, 0, 0) returns a 200,000-slot array with zero gate consultations. At the permitted ceiling that is a 2^31-1-pointer (~16 GiB on 64-bit) allocation request the budget never sees — the same uncharged-native-storage class ADR 0106 records for gated growth, except this path has no gate either. The growth gate (RequireNativeBytes via ExtendElementsWithHoles) bounds hole extension; capacity preallocation through the constructor bypasses it.
Current behavior
ArrayToSpliced (source/units/Goccia.Values.ArrayValue.pas ~:3645) and sibling copy-constructors (toReversed, toSorted — audit which share the constructor-capacity path) size FElements.Capacity directly from a guest-controlled length under a --max-memory ceiling that never sees the request.
Expected behavior
Constructor-capacity preallocation from guest-controlled lengths consults the element-storage gate (TGocciaElementList.RequireStorageBytes, in place since the rooting train's L3) or an equivalent budget check before Capacity := N, refusing with the uncatchable MemoryLimitError per the gate contract. Coverage: a test at a tight ceiling asserting the refusal, plus the existing suites green.
Scope notes
- Pre-existing on main; independent of the #1157 train (found by its L3 review, not introduced there).
- Related: ADR 0106 (uncharged gated storage posture), the #1157 train's L2/L3 gate-side rooting (the gate to reuse),
CheckArrayCreateLenValue. - The
new Array(n)constructor path IS gated (viaInitializeNativeFromArguments→ExtendElementsWithHoles); this issue is about the capacity-preallocation path that skips it.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in source/units/Goccia.Values.ArrayValue.pas around ArrayToSpliced (~:3645), then audit the toReversed and toSorted copy-constructor paths and the TGocciaElementList.RequireStorageBytes gate. Add coverage using a tight memory ceiling and verify guest-controlled capacity preallocation is refused with MemoryLimitError; run the existing suites afterward.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100