Repository navigation
fix(javascript): omit child-process spawns whose command or options Node rejects - #10528
Plastic-time wants to merge 4 commits into
Conversation
spawn, execFile, exec and fork validate the command before anything else. A missing, nullish or non-string command, a command with a NUL byte, and an empty command (except for fork) throw synchronously, so no child exists.
Node validates timeout, the spawn and fork boolean flags, serialization, shell and maxBuffer while normalizing a spawn. A literal it refuses throws before any child exists. Each rule applies only to the methods that forward that member.
fork validates its module as a path, so a URL, a URL-like object, a class with static href/protocol and a Uint8Array start a child. Share the object-valued syntax check with the option reader.
[Medium impact] The PR appears safe to merge; the previous finding is fixed and no new actionable issues were found. SummaryThe PR omits child-process facts for commands and options that Node rejects before starting a child.
Reviews (2) · Last reviewed commit: "fix(javascript): price signed numeric an..." · Reviewed by Greptile |
Codex Review Summary: ❌ FailedThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
A negative BigInt timeout and a negative non-finite maxBuffer are proven values Node rejects, so the spawn is omitted. -0 stays an accepted timeout.
Summary
JavaScript static analysis reported a child-process spawn for
node:child_processcalls that Node refuses before any child exists: a command it rejects, or an option it validates while normalizing the spawn. These calls no longer produce achildProcessSpawnsentry.Fixes #10522
Problem and expected behavior
Each of these produced one spawn fact on main, and each throws synchronously in Node 24.22.1:
Measured rules (all four methods unless noted):
null,undefined, number, boolean, array, function, NUL byte; object ornewvalue except infork;""except infork" ";fork("");fork(new URL(...))and other URL or byte valuestimeoutnullorundefined0,1e3,2 ** 53detached,windowsHide,windowsVerbatimArguments(spawn, fork)nullorundefinedserialization(spawn, fork)"json","advanced"orundefined, includingnull"json","advanced"shell(spawn, execFile)nullorundefined"","cmd.exe", booleansmaxBuffer(execFile, exec)NaN, string, BigInt0,1.5,InfinityexecFile does not forward the boolean flags or
serializationto its spawn, and exec replaces a non-stringshell, so those methods keep their spawn for the same values.Change and scope
rejectsCommandjudges the first argument. A spread or computed command stays.forkvalidates its module as a path, so a URL, a URL-like object or a Uint8Array starts a child. Forfork, only arrays, functions and regular expressions are rejected among object values.rejectsValidatedOptionreads each member through the existingstaticObjectPropertyowner, and classifies its value only as far as syntax proves it. Unknown values stay.collectJavaScriptSemanticChildProcesses.killSignal, because Node's signal list differs by platform, anduid/gid, because Windows refuses any value withENOTSUP.Contribution scope: ordinary fix within existing boundaries; maintainer scope decision not applicable.
Contract and boundary impact
Semantic owner and earliest changed stage:
collectJavaScriptSemanticChildProcessesinjavascriptSemanticChildProcesses.ts.Contribution scope fit and linked maintainer decision: not applicable.
CLI and MCP/tool-catalog contract: none.
Provider, bridge, target-format, or platform compatibility: none.
Evidence, artifact, provenance, or reconstruction contract: fewer false spawn facts; undecided calls are unchanged.
Target selection, authority, upstream behavior, and cleanup details: not applicable.
Generated metadata, package, or installation impact: none.
Read existing files or captured data.
Evidence and regression coverage
src/domain/javascript/javascriptSemanticAnalysis.child_process_command.test.ts, one row per rejected and accepted form above, across the four methods.process.execPath -e 0and recording the synchronous throw or the returned ChildProcess (killed at once).Validation performed
Windows 11 Home 10.0.26200 x64, Node 24.22.1, base 9e24b36.
npx vitest run src/domain/javascript/javascriptSemanticAnalysis.child_process_command.test.tson main source: 46 failed / 29 passed; with this change: 75 passed.npx vitest run src/domain/javascript src/application/javascript: 217 files, 6457 passed / 7 skipped.-1nand-1e400are now priced;-0stays an accepted timeout.npm run check:fast: passed (typecheck, lint)Compatibility, safety, and release
normalizeSpawnArguments; Linux was not measured.Author readiness
Human owner: @Plastic-time
Before merge
type(scope): outcome.