按规划继续工作
结论:补充 INI 派生机器文件名的 OPFS 路径拒绝回归测试,确认非法遍历和嵌套路径不会进入主机存储,并通过 host/WASM/browser 聚合验证。
This commit is contained in:
@@ -103,7 +103,9 @@ round-trip store plus pure-text machine file and G-code stores without
|
|||||||
defining CNC machine-state or file-format semantics. It now also validates the
|
defining CNC machine-state or file-format semantics. It now also validates the
|
||||||
OPFS-to-WASM parameter-file bridge with a mock interpreter SDK to ensure the
|
OPFS-to-WASM parameter-file bridge with a mock interpreter SDK to ensure the
|
||||||
host boundary copies text into and out of the WASM filesystem without defining
|
host boundary copies text into and out of the WASM filesystem without defining
|
||||||
parameter semantics.
|
parameter semantics, and that INI-derived machine file names are still
|
||||||
|
rejected by the OPFS path model when they contain traversal or nested path
|
||||||
|
segments.
|
||||||
|
|
||||||
The browser INI/OPFS smoke script serves `wasm-port/` over localhost and runs
|
The browser INI/OPFS smoke script serves `wasm-port/` over localhost and runs
|
||||||
Chromium headless against a test page that imports the JS SDK, loads the INI
|
Chromium headless against a test page that imports the JS SDK, loads the INI
|
||||||
@@ -257,9 +259,10 @@ SDK into vendored LinuxCNC file APIs, the Node machine-session bridge that
|
|||||||
groups INI, parameter, and tool-table loading, the random-toolchanger flag
|
groups INI, parameter, and tool-table loading, the random-toolchanger flag
|
||||||
derived from vendored LinuxCNC INI boolean parsing, INI-derived
|
derived from vendored LinuxCNC INI boolean parsing, INI-derived
|
||||||
`[RS274NGC]PARAMETER_FILE` and `[EMCIO]TOOL_TABLE` file names mapped to OPFS
|
`[RS274NGC]PARAMETER_FILE` and `[EMCIO]TOOL_TABLE` file names mapped to OPFS
|
||||||
machine files, and a browser interpreter smoke that uses the same session
|
machine files, OPFS path-model rejection of invalid INI-derived file names,
|
||||||
bridge before saving OPFS-backed parameter and tool-table text through
|
and a browser interpreter smoke that uses the same session bridge before
|
||||||
vendored LinuxCNC file APIs.
|
saving OPFS-backed parameter and tool-table text through vendored LinuxCNC
|
||||||
|
file APIs.
|
||||||
Full browser coverage, full SDK coverage, and richer machine-state validation
|
Full browser coverage, full SDK coverage, and richer machine-state validation
|
||||||
remain future work.
|
remain future work.
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ semantic rewrites:
|
|||||||
| Kinematics component lifecycle | Kinematics modules are initialized through LinuxCNC module entry points where native runtime probes exist, while HAL component init/ready/exit, HAL pin allocation, and RTAPI module metadata are handled by standalone shims. |
|
| Kinematics component lifecycle | Kinematics modules are initialized through LinuxCNC module entry points where native runtime probes exist, while HAL component init/ready/exit, HAL pin allocation, and RTAPI module metadata are handled by standalone shims. |
|
||||||
| Go math C/C++ linkage | `genserkins` runtime probing compiles vendored `gomath.c` through a narrow C++ wrapper so LinuxCNC `genserfuncs.c` can link to the upstream Go math symbols without editing vendored source. |
|
| Go math C/C++ linkage | `genserkins` runtime probing compiles vendored `gomath.c` through a narrow C++ wrapper so LinuxCNC `genserfuncs.c` can link to the upstream Go math symbols without editing vendored source. |
|
||||||
| Switchkins iterative forward | `genhexkins` runtime probing follows LinuxCNC switchkins iterative-forward behavior, including the first-call warmup path before asserting roundtrip convergence. |
|
| Switchkins iterative forward | `genhexkins` runtime probing follows LinuxCNC switchkins iterative-forward behavior, including the first-call warmup path before asserting roundtrip convergence. |
|
||||||
| Browser storage | OPFS remains outside the native core; `runtime/opfs/file-service.js` owns browser text-file persistence, `runtime/opfs/path-model.js` owns host-side storage paths for INI, tool table, parameter, G-code, preview-cache, and session-snapshot content, `runtime/opfs/snapshot-store.js` owns generic JSON session snapshot persistence, `runtime/opfs/machine-file-store.js` owns pure-text machine-file and G-code persistence, `runtime/opfs/linuxcnc-parameter-bridge.js` only copies parameter files between OPFS text storage and the LinuxCNC-backed WASM parameter-file ABI, `runtime/opfs/linuxcnc-tool-table-bridge.js` only copies tool tables between OPFS text storage and the LinuxCNC-backed WASM tool-table ABI, and `runtime/opfs/linuxcnc-machine-session-bridge.js` groups INI, parameter, and tool-table loading while using the LinuxCNC-backed INI SDK for `[EMCIO]RANDOM_TOOLCHANGER`, `[RS274NGC]PARAMETER_FILE`, and `[EMCIO]TOOL_TABLE` when available. |
|
| Browser storage | OPFS remains outside the native core; `runtime/opfs/file-service.js` owns browser text-file persistence, `runtime/opfs/path-model.js` owns host-side storage paths for INI, tool table, parameter, G-code, preview-cache, and session-snapshot content, `runtime/opfs/snapshot-store.js` owns generic JSON session snapshot persistence, `runtime/opfs/machine-file-store.js` owns pure-text machine-file and G-code persistence, `runtime/opfs/linuxcnc-parameter-bridge.js` only copies parameter files between OPFS text storage and the LinuxCNC-backed WASM parameter-file ABI, `runtime/opfs/linuxcnc-tool-table-bridge.js` only copies tool tables between OPFS text storage and the LinuxCNC-backed WASM tool-table ABI, and `runtime/opfs/linuxcnc-machine-session-bridge.js` groups INI, parameter, and tool-table loading while using the LinuxCNC-backed INI SDK for `[EMCIO]RANDOM_TOOLCHANGER`, `[RS274NGC]PARAMETER_FILE`, and `[EMCIO]TOOL_TABLE` when available; path validation remains owned by the OPFS path model, including rejection of traversal or nested path segments from INI-derived file names. |
|
||||||
|
|
||||||
## Enforced Non-Drift Rules
|
## Enforced Non-Drift Rules
|
||||||
|
|
||||||
@@ -69,8 +69,9 @@ semantic rewrites:
|
|||||||
- OPFS validation covers a Node mock of the file-service adapter, the
|
- OPFS validation covers a Node mock of the file-service adapter, the
|
||||||
host-side path model, generic session snapshot storage, pure-text machine
|
host-side path model, generic session snapshot storage, pure-text machine
|
||||||
file and G-code storage, parameter/tool-table bridge copying into the
|
file and G-code storage, parameter/tool-table bridge copying into the
|
||||||
interpreter SDK filesystem, grouped machine-session loading, and a Chromium
|
interpreter SDK filesystem, grouped machine-session loading, invalid
|
||||||
localhost round trip for those persistence paths.
|
INI-derived machine file names, and a Chromium localhost round trip for those
|
||||||
|
persistence paths.
|
||||||
- Host-side smoke validation is aggregated by
|
- Host-side smoke validation is aggregated by
|
||||||
`tests/host/verify_host_smokes.sh` so Node, WASM, OPFS, and browser checks
|
`tests/host/verify_host_smokes.sh` so Node, WASM, OPFS, and browser checks
|
||||||
run from one command.
|
run from one command.
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ Current validation is intentionally mechanical:
|
|||||||
|
|
||||||
| Dependency | LinuxCNC files that expose it | Standalone treatment |
|
| Dependency | LinuxCNC files that expose it | Standalone treatment |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| Native file IO | `inifile.cc`, `rs274ngc_pre.cc`, `tooldata_common.cc`, parameter file paths, tool table paths | Allowed in native probes; the interpreter WASM C ABI validates parameter-file restore/save by calling vendored `Interp::restore_parameters()` and `Interp::save_parameters()` and tool-table load/save by calling vendored `tooldata_load()` and `tooldata_save()` against Emscripten filesystem paths; browser OPFS remains a host-side adapter under `runtime/opfs/`, with path ownership in `runtime/opfs/path-model.js`, generic snapshot persistence in `runtime/opfs/snapshot-store.js`, pure-text machine-file persistence in `runtime/opfs/machine-file-store.js`, OPFS-to-WASM parameter-file copying in `runtime/opfs/linuxcnc-parameter-bridge.js`, OPFS-to-WASM tool-table copying in `runtime/opfs/linuxcnc-tool-table-bridge.js`, and grouped INI/parameter/tool-table session loading in `runtime/opfs/linuxcnc-machine-session-bridge.js`, including INI-derived `[RS274NGC]PARAMETER_FILE` and `[EMCIO]TOOL_TABLE` OPFS filename selection through the LinuxCNC-backed INI SDK |
|
| Native file IO | `inifile.cc`, `rs274ngc_pre.cc`, `tooldata_common.cc`, parameter file paths, tool table paths | Allowed in native probes; the interpreter WASM C ABI validates parameter-file restore/save by calling vendored `Interp::restore_parameters()` and `Interp::save_parameters()` and tool-table load/save by calling vendored `tooldata_load()` and `tooldata_save()` against Emscripten filesystem paths; browser OPFS remains a host-side adapter under `runtime/opfs/`, with path ownership in `runtime/opfs/path-model.js`, generic snapshot persistence in `runtime/opfs/snapshot-store.js`, pure-text machine-file persistence in `runtime/opfs/machine-file-store.js`, OPFS-to-WASM parameter-file copying in `runtime/opfs/linuxcnc-parameter-bridge.js`, OPFS-to-WASM tool-table copying in `runtime/opfs/linuxcnc-tool-table-bridge.js`, and grouped INI/parameter/tool-table session loading in `runtime/opfs/linuxcnc-machine-session-bridge.js`, including INI-derived `[RS274NGC]PARAMETER_FILE` and `[EMCIO]TOOL_TABLE` OPFS filename selection through the LinuxCNC-backed INI SDK; OPFS path validation rejects traversal and nested segments before host storage access |
|
||||||
| RTAPI | `rtapi_*.h`, TP, posemath, motion headers | Minimal standalone shim in `runtime/core/shims/rtapi.h` |
|
| RTAPI | `rtapi_*.h`, TP, posemath, motion headers | Minimal standalone shim in `runtime/core/shims/rtapi.h` |
|
||||||
| NML transport | `emc.hh`, motion/NML type headers | Transport is not ported; only the status/type edges needed by vendored compute code are exposed through standalone shims and probes |
|
| NML transport | `emc.hh`, motion/NML type headers | Transport is not ported; only the status/type edges needed by vendored compute code are exposed through standalone shims and probes |
|
||||||
| HAL runtime | named parameter lookup, kinematics component lifecycle, and runtime status edges | Standalone HAL adapter under `runtime/core/linuxcnc_wrap/` |
|
| HAL runtime | named parameter lookup, kinematics component lifecycle, and runtime status edges | Standalone HAL adapter under `runtime/core/linuxcnc_wrap/` |
|
||||||
@@ -95,6 +95,7 @@ Current validation is intentionally mechanical:
|
|||||||
tool-table loading into one host-side session load boundary and can derive
|
tool-table loading into one host-side session load boundary and can derive
|
||||||
the random-toolchanger tooldata mode from `[EMCIO]RANDOM_TOOLCHANGER` plus
|
the random-toolchanger tooldata mode from `[EMCIO]RANDOM_TOOLCHANGER` plus
|
||||||
parameter/tool-table OPFS file names from `[RS274NGC]PARAMETER_FILE` and
|
parameter/tool-table OPFS file names from `[RS274NGC]PARAMETER_FILE` and
|
||||||
`[EMCIO]TOOL_TABLE` through the LinuxCNC-backed INI SDK. Full machine-state
|
`[EMCIO]TOOL_TABLE` through the LinuxCNC-backed INI SDK, with invalid
|
||||||
restoration remains future work.
|
traversal or nested file names rejected by `runtime/opfs/path-model.js`.
|
||||||
|
Full machine-state restoration remains future work.
|
||||||
- Native LinuxCNC GUI code remains out of scope for implementation.
|
- Native LinuxCNC GUI code remains out of scope for implementation.
|
||||||
|
|||||||
@@ -209,6 +209,13 @@ const bridgeIniSdk = {
|
|||||||
) {
|
) {
|
||||||
return "custom.var";
|
return "custom.var";
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
path === "/work/invalid-ini-file-session.ini" &&
|
||||||
|
section === "RS274NGC" &&
|
||||||
|
tag === "PARAMETER_FILE"
|
||||||
|
) {
|
||||||
|
return "../escape.var";
|
||||||
|
}
|
||||||
if (
|
if (
|
||||||
path === "/work/ini-file-session.ini" &&
|
path === "/work/ini-file-session.ini" &&
|
||||||
section === "EMCIO" &&
|
section === "EMCIO" &&
|
||||||
@@ -216,6 +223,13 @@ const bridgeIniSdk = {
|
|||||||
) {
|
) {
|
||||||
return "custom-tool.tbl";
|
return "custom-tool.tbl";
|
||||||
}
|
}
|
||||||
|
if (
|
||||||
|
path === "/work/invalid-tool-file-session.ini" &&
|
||||||
|
section === "EMCIO" &&
|
||||||
|
tag === "TOOL_TABLE"
|
||||||
|
) {
|
||||||
|
return "nested/tool.tbl";
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
},
|
},
|
||||||
getBool(path, section, tag) {
|
getBool(path, section, tag) {
|
||||||
@@ -416,6 +430,52 @@ assert.equal(
|
|||||||
"tooldata_load=0\nload_tool_path=/work/ini-file-session-tool.tbl\nrandom_toolchanger=0\n",
|
"tooldata_load=0\nload_tool_path=/work/ini-file-session-tool.tbl\nrandom_toolchanger=0\n",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await saveMachineTextFiles("invalid-ini-file-session", {
|
||||||
|
ini: [
|
||||||
|
"[EMC]",
|
||||||
|
"MACHINE = invalid-ini-file-session",
|
||||||
|
"",
|
||||||
|
"[RS274NGC]",
|
||||||
|
"PARAMETER_FILE = ../escape.var",
|
||||||
|
"",
|
||||||
|
].join("\n"),
|
||||||
|
}, { storage });
|
||||||
|
await assert.rejects(
|
||||||
|
() => loadMachineSessionFromOpfs(
|
||||||
|
bridgeInterp,
|
||||||
|
"invalid-ini-file-session",
|
||||||
|
{
|
||||||
|
storage,
|
||||||
|
iniSdk: bridgeIniSdk,
|
||||||
|
iniWasmPath: "/work/invalid-ini-file-session.ini",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
/Invalid parameter filename/,
|
||||||
|
);
|
||||||
|
|
||||||
|
await saveMachineTextFiles("invalid-tool-file-session", {
|
||||||
|
ini: [
|
||||||
|
"[EMC]",
|
||||||
|
"MACHINE = invalid-tool-file-session",
|
||||||
|
"",
|
||||||
|
"[EMCIO]",
|
||||||
|
"TOOL_TABLE = nested/tool.tbl",
|
||||||
|
"",
|
||||||
|
].join("\n"),
|
||||||
|
}, { storage });
|
||||||
|
await assert.rejects(
|
||||||
|
() => loadMachineSessionFromOpfs(
|
||||||
|
bridgeInterp,
|
||||||
|
"invalid-tool-file-session",
|
||||||
|
{
|
||||||
|
storage,
|
||||||
|
iniSdk: bridgeIniSdk,
|
||||||
|
iniWasmPath: "/work/invalid-tool-file-session.ini",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
/Invalid tool table filename/,
|
||||||
|
);
|
||||||
|
|
||||||
await assert.rejects(
|
await assert.rejects(
|
||||||
() => loadTextFile("linuxcnc/machines/missing.ini", storage),
|
() => loadTextFile("linuxcnc/machines/missing.ini", storage),
|
||||||
/missing file/,
|
/missing file/,
|
||||||
|
|||||||
Reference in New Issue
Block a user