EigenScript's name is expr updates an existing OUTER binding when one exists. The engine's internal functions (lib/regex_parse.eigs, lib/regex_compile.eigs, lib/regex_vm.eigs, and the older API functions in lib/regex.eigs) assign working variables without local — c, pos, n, ranges, parts, branches, results, out, i, j, …
A user script that has a module-level variable with any of those names and then calls re_compile / re_search gets it silently overwritten. Example shape:
load_file of "lib/regex.eigs"
pos is 42
prog is re_compile of "[a-z]+"
r is re_find_all of [prog, "abc"]
print of pos # no longer 42
The new code from #4 (re_replace, lib/regex_compat.eigs) already uses local throughout; this issue is the mechanical pass over the pre-existing functions. for-loop variables are already safe (loop scope); loop while counters and accumulators are not.
Fix: add local to the first assignment of every function-internal variable across the four lib files; suite must stay 347/347.
EigenScript's
name is exprupdates an existing OUTER binding when one exists. The engine's internal functions (lib/regex_parse.eigs,lib/regex_compile.eigs,lib/regex_vm.eigs, and the older API functions inlib/regex.eigs) assign working variables withoutlocal—c,pos,n,ranges,parts,branches,results,out,i,j, …A user script that has a module-level variable with any of those names and then calls
re_compile/re_searchgets it silently overwritten. Example shape:The new code from #4 (
re_replace,lib/regex_compat.eigs) already useslocalthroughout; this issue is the mechanical pass over the pre-existing functions.for-loop variables are already safe (loop scope);loop whilecounters and accumulators are not.Fix: add
localto the first assignment of every function-internal variable across the four lib files; suite must stay 347/347.