diff --git a/core/src/linuxcnc_rs274_backend.cpp b/core/src/linuxcnc_rs274_backend.cpp index 54c911a..47fd35c 100644 --- a/core/src/linuxcnc_rs274_backend.cpp +++ b/core/src/linuxcnc_rs274_backend.cpp @@ -183,8 +183,14 @@ int parse_linuxcnc_rs274_backend(CanonEventSink &sink, return -1; } + // LinuxCNC source basis: rs274ngc_pre.cc uses + // RS274NGC_PARAMETER_FILE_NAME_DEFAULT when the external parameter file + // name is empty. Reset the bridge every parse so a prior native env + // override does not leak into later default parses. if (const char *parameter_file = std::getenv("CNC_SIM_RS274_VAR")) { SET_PARAMETER_FILE_NAME(parameter_file); + } else { + SET_PARAMETER_FILE_NAME("rs274ngc.var"); } cnc_sim_init_minimal_linuxcnc_tooldata(); sink.clear_callback_status(); diff --git a/core/tests/cnc_sim_api_smoke.cpp b/core/tests/cnc_sim_api_smoke.cpp index cf4b770..53c3d86 100644 --- a/core/tests/cnc_sim_api_smoke.cpp +++ b/core/tests/cnc_sim_api_smoke.cpp @@ -6163,6 +6163,48 @@ int main() { "expected LinuxCNC rotary/UVW persistent numbered parameters to reload from parameter file"); } + const std::string parameter_env_leak_guard_var_path = temp_dir.file("parameter_env_leak_guard.var"); + { + std::ofstream var_file(parameter_env_leak_guard_var_path); + var_file << "5001\t17.000000\n"; + } + { + ScopedEnv var_env("CNC_SIM_RS274_VAR", parameter_env_leak_guard_var_path.c_str()); + const char parameter_env_leak_guard_set_program[] = + "#5001 = 91\n" + "M30\n"; + events.clear(); + ok &= expect(cnc_sim_parse_program(sim, + parameter_env_leak_guard_set_program, + sizeof(parameter_env_leak_guard_set_program) - 1) == 0, + cnc_sim_last_error(sim)); + } + { + const char parameter_env_default_check_program[] = + "F100\n" + "O10 if [#5001 EQ 91]\n" + "G1 X1\n" + "O10 endif\n"; + events.clear(); + ok &= expect(cnc_sim_parse_program(sim, + parameter_env_default_check_program, + sizeof(parameter_env_default_check_program) - 1) == 0, + cnc_sim_last_error(sim)); + bool saw_stale_env_parameter = false; + for (const auto &event : events) { + saw_stale_env_parameter = saw_stale_env_parameter || + (event.type == CNC_SIM_EVENT_LINEAR_FEED && + event.line == 3 && + near(event.end.x, 1.0)); + } + // LinuxCNC source basis: rs274ngc_pre.cc rs274_ngc_init() falls back + // to RS274NGC_PARAMETER_FILE_NAME_DEFAULT when the external parameter + // file name is empty. The project env override must not persist after + // CNC_SIM_RS274_VAR is unset. + ok &= expect(!saw_stale_env_parameter, + "expected LinuxCNC parameter env override not to leak into default parses"); + } + const char volatile_global_set_program[] = "#31 = 7\n" "M30\n"; diff --git a/test-native.sh b/test-native.sh index f0668e1..8f2892d 100755 --- a/test-native.sh +++ b/test-native.sh @@ -79,6 +79,8 @@ grep -F 'metadata:src/emc/task/taskclass.cc:source basis for wasm-safe builtin P grep -F 'metadata:src/emc/task/emccanon.cc:source basis for wasm-safe tooldata API declaration shim' linuxcnc-rs274-wasm-source-files.txt >/dev/null grep -F 'metadata:src/emc/sai/dummyemcstat.cc:source basis for wasm-safe emcStatus singleton shim' linuxcnc-rs274-wasm-source-files.txt >/dev/null grep -F 'blocked:src/emc/rs274ngc/gcodemodule.cc:Python gcode module binding, tracked for full rs274ngc source coverage' linuxcnc-rs274-wasm-source-files.txt >/dev/null +grep -F 'expected LinuxCNC parameter env override not to leak into default parses' core/tests/cnc_sim_api_smoke.cpp >/dev/null +grep -F 'SET_PARAMETER_FILE_NAME("rs274ngc.var")' core/src/linuxcnc_rs274_backend.cpp >/dev/null grep -F 'metadata:src/emc/nml_intf/emcops.cc:source basis for native source-link EMC status constructor support object' linuxcnc-rs274-source-files.txt >/dev/null grep -F 'metadata:src/emc/sai/dummyemcstat.cc:source basis for native source-link emcStatus singleton support object' linuxcnc-rs274-source-files.txt >/dev/null grep -F 'metadata:src/emc/sai/Submakefile:LinuxCNC SAI build metadata defining dummyemcstat support object' linuxcnc-rs274-source-files.txt >/dev/null