fix: use execFile in status and logs to prevent shell interpolation of sandbox name - #281
fix: use execFile in status and logs to prevent shell interpolation of sandbox name#281areporeporepo wants to merge 1 commit into
Conversation
…f sandbox name status.ts and logs.ts used promisify(exec) with template-literal commands, passing sandboxName directly into a shell string. This allows shell metacharacters in the sandbox name to be interpreted. Switch to promisify(execFile) with argument arrays, matching the safe pattern already used in connect.ts (spawn), onboard.ts (execFileSync), and migrate.ts (execFileSync). execFile bypasses the shell entirely so the sandbox name is always passed as a single argument. Continues the hardening started in #49 and #170. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
📝 WalkthroughWalkthroughThis pull request refactors command execution in the nemoclaw project to replace the Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
Comment Tip You can get early access to new features in CodeRabbit.Enable the |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
nemoclaw/src/commands/status.test.ts (1)
96-99: Strengthen mock routing to avoid false-positive matches.
joined.includes(substring)can accidentally match unrelated args and hide regressions. Prefer exact command-key matching (e.g., first two argv tokens).Suggested tightening for `mockExecFile`
- const joined = args.join(" "); - for (const [substring, response] of Object.entries(responses)) { - if (joined.includes(substring)) { + const commandKey = `${args[0] ?? ""} ${args[1] ?? ""}`.trim(); + const response = responses[commandKey]; + if (response !== undefined) { if (response instanceof Error) { callback?.(response, { stdout: "", stderr: response.message }); } else { callback?.(null, { stdout: response, stderr: "" }); } return; - } } - callback?.(new Error(`command not found: ${joined}`), { stdout: "", stderr: "" }); + callback?.(new Error(`command not found: ${args.join(" ")}`), { stdout: "", stderr: "" });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@nemoclaw/src/commands/status.test.ts` around lines 96 - 99, The mock routing using joined.includes(substring) is too permissive and causes false-positive matches; update the mock in mockExecFile to build a precise key from the first two argv tokens (e.g., const key = args.slice(0,2).join(" ")) and compare that key for exact equality against the responses entries instead of using joined.includes(substring), ensuring responses map keys correspond to these two-token command keys (references: joined, args, responses, mockExecFile).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@nemoclaw/src/commands/status.test.ts`:
- Around line 96-99: The mock routing using joined.includes(substring) is too
permissive and causes false-positive matches; update the mock in mockExecFile to
build a precise key from the first two argv tokens (e.g., const key =
args.slice(0,2).join(" ")) and compare that key for exact equality against the
responses entries instead of using joined.includes(substring), ensuring
responses map keys correspond to these two-token command keys (references:
joined, args, responses, mockExecFile).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: c7450333-c9e1-46c8-bcd3-c27efdb4da38
📒 Files selected for processing (3)
nemoclaw/src/commands/logs.tsnemoclaw/src/commands/status.test.tsnemoclaw/src/commands/status.ts
PR NVIDIA#281 removed the shared openshell-cluster Docker network in favor of the default bridge. This restores custom bridge networking but makes each gateway use its own isolated network named openshell-cluster-{name}, matching the existing container/volume naming convention. Changes: - Add network_name() to constants.rs for per-gateway network naming - Add ensure_network() with retry/backoff and force_remove_network() parameterized by network name instead of a global constant - Attach containers to their per-gateway network via network_mode - Disconnect and remove the network during gateway destroy - Wire ensure_network() into the deploy flow before ensure_volume() - Update architecture docs to reflect per-gateway network isolation
Switch exec to execFile in status.ts and logs.ts so sandbox name is passed as an argument array instead of interpolated into a shell string. Updates existing tests to match.