Repository navigation
fix: quote Windows arguments that contain spaces - #1412
Open
ClayChipps wants to merge 1 commit into
Open
ClayChipps wants to merge 1 commit into
ClayChipps wants to merge 1 commit into
Conversation
spawn() uses windowsVerbatimArguments, so Node joins the arguments with spaces and does no quoting. An argument containing whitespace reached npm as several: installing `pkg@>=1.0.0 <2.0.0` also installed `<2.0.0`, which npm-package-arg reads as a nameless range and resolves to the unrelated package `undefined`. JIT plugins with a spaced range in oclif.jitPlugins hit this on every install and `plugins update`. Quote such arguments the way CommandLineToArgvW expects, which is what libuv does when arguments are not verbatim. Arguments without whitespace or quotes are passed through unchanged, so the verbatim behaviour that keeps shell metacharacters literal is untouched. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
On Windows,
spawn()passes arguments withwindowsVerbatimArguments: trueand does no quoting, so an argument containing whitespace reaches npm as several arguments.This shows up with JIT plugins whose
oclif.jitPluginsrange contains a space, e.g.">=0.4.0 <1.0.0". The JIT install runs:npm receives
@scope/pkg@>=0.4.0and<1.0.0as two specs.npm-package-argparses<1.0.0as a range with no name, and npm resolves it to the unrelated, deprecated packageundefined. That package gets installed into the CLI's data dir and saved in itspackage.json. The real plugin still installs, so the problem is easy to miss.plugins updatedoes the same thing every time, because it passes the saved range (or thejitPluginsrange) to npm the same way.This is the same root cause as #1387. #1388 fixed it for a space in
process.execPathby quoting the Node path, but the arguments are still passed unquoted.The fix
quoteWindowsArgquotes an argument that contains whitespace or", using theCommandLineToArgvWrules. That is what libuv does when arguments are not verbatim: wrap in quotes, escape embedded quotes, and double backslashes that precede a quote. Arguments without whitespace or quotes pass through unchanged.windowsVerbatimArgumentsstays on, so the existing guarantee that shell metacharacters stay literal (should not interpret shell metacharacters in arguments) is unaffected.Testing
should pass an argument containing spaces as one argumentround-trips a spaced range, an embedded quote, and a path with spaces and trailing backslashes throughspawn. On Windows it fails without the fix (["@scope/pkg@>=1.0.0","<2.0.0","say","hi",…]) and passes with it. On other platforms it passes either way, as expected.quoteWindowsArg's quoting rules.test/spawn.test.ts,test/plugins.test.tsandtest/commands/**pass on Windows (Node 24).tsc -p testandeslint src testare clean.What issues does this PR fix or reference?
Related: #1387, #1388
🤖 Generated with Claude Code