hotfix(elc): bound token reads to Eof so malformed input errors instead of OOMing #65
Reference in New Issue
Block a user
Delete Branch "hotfix/elc-fixes"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Compiler hardening: bound token reads so malformed input errors instead of OOMing
Root cause
tok_kind/tok_value(parser.el:25-31) read the flat token list with nobounds check.
native_list_getout-of-range returns runtime null (0), NOT the"Eof"sentinel. The inner parse loops —parse_block(1191), call-args(1282), array literals (792), match arms (1104) — terminate only on their
closing delimiter or
k == "Eof", and (unlike the top-levelparse()loop at1937) have no
pos >= totalbound.expect()(39) advances the cursor even onmismatch, so one unclosed delimiter steps the cursor past the single trailing
Eof token. From there every
== "Eof"guard is blind,parse_primary'sfallback keeps advancing +1 and appending a Nil node, and
native_list_appendgrows the statement list forever → ~700GB → OOM (observed compiling
neuron/sessions.el; also reproduces on
fn f()->Int{ return g(1,2 }).Fix
Single choke-point change:
tok_kindreturns"Eof"andtok_valuereturns""for out-of-range positions, restoring the parser-wide contract that readsat/after the end yield Eof. Every overrun loop then terminates.
expect()nolonger steps past the Eof sentinel on mismatch. A malformed program now ends
the parse (best-effort recovery) instead of exhausting memory. Low risk:
in-range behavior is unchanged; the guards are purely additive.
Verification
ulimit -v): unfixed elc onfn f()->Int{ return g(1,2 }blew past 1.5GB in~1s and was killed (exit 137). Every run was bounded; the machine stayed
~5.7GB free.
because that requires a bootstrap rebuild of elc, which was deliberately out
of scope here (rebuilding the live compiler is memory-dangerous and needs
careful review).
DO NOT MERGE without a bootstrap rebuild
This edits the self-hosted parser. It only takes effect after elc is rebuilt
from this source (bootstrap) and the new binary is validated against the full
corpus. Please review + rebuild + regression-test before merging. The live elc
binary and soul were not touched.
The companion source-typo fixes that actually unblock compilation today
(no rebuild needed) are in neuron-technologies/neuron#<see hotfix/elc-source-typos>.
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.