main()'s script-file failure paths return directly, bypassing the JABCPolUninstall/JSClose/JABCioUninstall/u8bUnMap teardown the success path runs — so the entire JS context built by JSInit/JABCInstallModules leaks (LSan: 95 objects / 2358 B from JSC bmalloc). Sibling of JS-007, which fixed the read's correctness but not the leak on its failure paths. Method: Issues.
js/main.cpp:184-208: fopen/ftell/malloc failures each return 1
AFTER JSInit, skipping the bottom cleanup block (:217-223).
js/lsan.supp (leak:libjavascriptcoregtk) HIDES it underctest — the 2358 B are JSC's. Only an unsuppressed run shows it.
jabc /no/such/file → LSan fires; jabc --eval 0 (success) isleak-clean, proving the teardown is the only difference.
script-file open frees the context (LSan-clean); exit code + stderr stay.
js/main.cpp only; output-equivalent. Verify under the existing ASANdebug build. New repro is red-before/green-after WITHOUT the JSC suppression.
JABCRunFile(path) → b8 worker (symmetric with
JABCRun); every failure returns NO → main sets rc=1 and falls through to the shared teardown. Mirrors the abc wrapper/worker idiom (CLAUDE.md §5).
run-054.sh (ctest JABCleakExit, no JSC suppression,
self-calibrated vs the clean --eval exit): missing-file run must not leak.
JABCRunFile; the three return 1 become return NO; main
funnels to cleanup. js/INDEX.md unchanged (main.cpp not documented there).
the missing-file exit is LSan-clean; stderr + exit code unchanged. ctest JABCleakExit red-before/green-after; full JABC suite 28/28.
ab4519af — main.cpp JABCRunFile worker + JABCleakExit ctest reg.b10b311c — js/test/run-054.sh repro script (staged first, harmless alone).