diff --git a/check-linuxcnc-wasm-shims-source-map.sh b/check-linuxcnc-wasm-shims-source-map.sh index 93b1a4e..1154969 100755 --- a/check-linuxcnc-wasm-shims-source-map.sh +++ b/check-linuxcnc-wasm-shims-source-map.sh @@ -49,8 +49,17 @@ grep -F 'RCS_STAT_MSG::RCS_STAT_MSG' "$linuxcnc_root/src/libnml/nml/stat_msg.cc" grep -F 'print_rcs_error_new' "$linuxcnc_root/src/libnml/rcs/rcs_print.cc" >/dev/null grep -F 'rtapi_snprintf' "$linuxcnc_root/src/rtapi/uspace_common.h" >/dev/null grep -F 'class PythonPlugin' "$linuxcnc_root/src/emc/pythonplugin/python_plugin.hh" >/dev/null +grep -F 'PLUGIN_PYTHON_NOT_INITIALIZED = -12,' "$linuxcnc_root/src/emc/pythonplugin/python_plugin.hh" >/dev/null +grep -F 'PLUGIN_NO_CALLABLE = 1,' "$linuxcnc_root/src/emc/pythonplugin/python_plugin.hh" >/dev/null +grep -F 'PLUGIN_EXCEPTION = 2' "$linuxcnc_root/src/emc/pythonplugin/python_plugin.hh" >/dev/null grep -F 'PythonPlugin::instantiate' "$linuxcnc_root/src/emc/pythonplugin/python_plugin.cc" >/dev/null grep -F 'if (status < PLUGIN_OK)' "$linuxcnc_root/src/emc/pythonplugin/python_plugin.cc" >/dev/null +grep -F 'retval = bp::exec_file(cmd, main_namespace, main_namespace);' \ + "$linuxcnc_root/src/emc/pythonplugin/python_plugin.cc" >/dev/null +grep -F 'retval = bp::exec(cmd, main_namespace, main_namespace);' \ + "$linuxcnc_root/src/emc/pythonplugin/python_plugin.cc" >/dev/null +grep -F 'PyObject *rv = PyObject_Call(function.ptr(), tupleargs.ptr(), kwargs.ptr());' \ + "$linuxcnc_root/src/emc/pythonplugin/python_plugin.cc" >/dev/null grep -F '#define TOOL_MMAP_FILENAME ".tool.mmap"' "$linuxcnc_root/src/emc/tooldata/tooldata_mmap.cc" >/dev/null grep -F 'int tool_nml_register(CANON_TOOL_TABLE *tblptr)' "$linuxcnc_root/src/emc/tooldata/tooldata_nml.cc" >/dev/null grep -F 'int tooldata_db_init(char progname_plus_args[]' "$linuxcnc_root/src/emc/tooldata/tooldata_db.cc" >/dev/null @@ -153,6 +162,45 @@ for needle in [ if needle not in runtime_probe: raise SystemExit(f"runtime probe missing HAL unavailable assertion: {needle}") +python_plugin_shim = Path("core/wasm_shims/pythonplugin/python_plugin.cc").read_text(encoding="utf-8") +python_plugin_probe = Path("core/wasm_shims/pythonplugin/python_plugin_probe_main.cc").read_text(encoding="utf-8") +python_c_api_shim = Path("core/wasm_shims/python_c_api_shim.cc").read_text(encoding="utf-8") +for forbidden in [ + "bp::exec(", + "bp::exec_file(", + "PyObject_Call(", +]: + if forbidden in python_plugin_shim: + raise SystemExit(f"PythonPlugin wasm shim must not execute Python: {forbidden}") +for needle in [ + "python disabled in wasm-safe probe", + "status = PLUGIN_PYTHON_NOT_INITIALIZED;", + "return PLUGIN_NO_CALLABLE;", + "status = PLUGIN_EXCEPTION;", + "if (status < PLUGIN_OK)", +]: + if needle not in python_plugin_shim: + raise SystemExit(f"PythonPlugin wasm shim missing disabled-python boundary: {needle}") +for needle in [ + "PLUGIN_NO_SECTION", + "PLUGIN_BAD_INIFILE", + "PLUGIN_PYTHON_NOT_INITIALIZED", + "PLUGIN_NO_CALLABLE", + "PLUGIN_EXCEPTION", + "handle_pyerror().empty()", +]: + if needle not in python_plugin_probe: + raise SystemExit(f"PythonPlugin probe missing disabled-python status assertion: {needle}") +for needle in [ + "Py_IsInitialized", + "PyObject_CallMethod", + "Py_BuildValue", + "PyModule_Create", + "PyType_Ready", +]: + if needle not in python_c_api_shim: + raise SystemExit(f"Python C API shim missing symbol boundary: {needle}") + for phrase in [ "must not add CNC behavior", "must not expand the temporary smoke parser", @@ -164,6 +212,9 @@ for phrase in [ "must leave HAL values unavailable", "must not switch browser-safe probes into task mode", "must not become a shell expansion feature", + "must not become Python execution", + "keeping Python execution disabled", + "must not execute `bp::exec`, `bp::exec_file`, or", "inactive-DB return values", "negative-status short-circuit behavior", "./check-linuxcnc-wasm-shims-source-map.sh", diff --git a/docs/linuxcnc-wasm-shims-source-map.md b/docs/linuxcnc-wasm-shims-source-map.md index a7e4b56..dc74061 100644 --- a/docs/linuxcnc-wasm-shims-source-map.md +++ b/docs/linuxcnc-wasm-shims-source-map.md @@ -38,6 +38,18 @@ only; it must not add CNC behavior and must not expand the temporary smoke parse - `wordexp()` support is limited to the browser-safe path expansion needed by `src/emc/rs274ngc/rs274ngc_pre.cc`; it must not become a shell expansion feature. +## Python Shim Boundaries + +- `core/wasm_shims/python_c_api_shim.cc` satisfies Python C API symbols used by + LinuxCNC RS274/remap sources; it must not become Python execution. +- `core/wasm_shims/pythonplugin/python_plugin.cc` must preserve LinuxCNC + `PythonPlugin` status edges for `PLUGIN_NO_SECTION`, `PLUGIN_BAD_INIFILE`, + `PLUGIN_PYTHON_NOT_INITIALIZED`, `PLUGIN_NO_CALLABLE`, and + `PLUGIN_EXCEPTION` while keeping Python execution disabled. +- The PythonPlugin shim must not execute `bp::exec`, `bp::exec_file`, or + `PyObject_Call`; those remain browser blockers until implemented as a + source-backed browser-safe LinuxCNC adaptation. + ## Boundaries - The CMake `linuxcnc_wasm_safe_probe_shims` set and `list-linuxcnc-wasm-safe-shims.sh` must stay synchronized.