The script-file loader in main() slurps the file with no validation. long len = ftell(f) is unchecked: on a non-seekable file (pipe/FIFO/char device) ftell returns -1, so malloc(len+1) becomes malloc(0), fread is called with count (size_t)-1, and script[len]=='\0' writes script[-1] — a deterministic heap-underflow OOB write. The malloc return is unchecked (NULL write under OOM) and the fread count is ignored (uninitialized bytes before the NUL parsed by JABCExecute). It also fopens argv[1] instead of the parsed script_file. Local CLI utility (operator is the actor), but the underflow is trivially reachable. The goal is to validate ftell>=0, check malloc, and terminate at the actual fread count.
Three unchecked stdio results feed alloc/index/terminate.
js/main.cpp:218 long len=ftell(f) unchecked; non-seekable file → len==-1 feeds malloc/fread/index.js/main.cpp:220 malloc(len+1) return unchecked; with len==-1 → malloc(0); under OOM → NULL.js/main.cpp:221-222 fread return ignored; script[len]='\0' writes script[-1] (OOB underflow) or wild on NULL.js/main.cpp:212/214 fopen/error use argv[1] instead of the parsed script_file.None.
Validate sizes; terminate at the read count.
/dev/stdin from a pipe); run under ASan; assert no OOB write.ftell()>=0 and malloc()!=NULL; bail with an error on failure.fread count n (script[n]='\0'); use script_file (not argv[1]) in fopen.