Closed chrmoritz closed 7 years ago
@zkat any chance of getting this upstreamed?
Could I get a test for this? There's been a lot of thrash around how paths are escaped on various platforms and I'd feel better if I had stuff that covered this corner case for next time it gets poked at.
Unfortunately I'm not able to find a proper way to write a test for this, because the affecting string is directly read from process.argv[0]
.
Edit: Maybe it's possibly by manipulating process.argv[0]
in the tests. But I'm not sure how error prone this is, because another test could call child.spawn
and fail during the small time window between manipulation process.argv[0]
and reverting it back.
Thanks @chrmoritz and @zkat :heart:
with special characters, which were incorrectly escaped with surrounding quotation marks causing child_process.spawn to throw an ENOENT error.
While upgrading
npm
in our homebrew formulaes to v5.4.2 we found out, that ournpx
test started to regress on our versioned formulas (node@6 and node@4) with the following error:spawn '/usr/local/Cellar/node@6/6.11.4/bin/node' ENOENT
(Refs: https://github.com/Homebrew/homebrew-core/pull/19348#issuecomment-336063778). After bisectingnpx
versions I've found out that the regression was introduced betweennpx@9.2.0
andnpx@9.2.1
in https://github.com/zkat/npx/commit/761dfe9bd73e0aca8170d23187e4fbce0ef7a647. This commit changed the path passed as the (first) command argument tochild_process.spawn
ininstallPackages
from being the path tonpm
to being the path to thenode
executable.This issue was only reproducible for our versioned formulas because only these contain a special character in their path to node (e.g.
/usr/local/Cellar/node@6/6.11.4/bin/node
) and only in this casechild.escapeArg
will surround the path with single quotation marks (e.g.npmPath === '\'/usr/local/Cellar/node@6/6.11.4/bin/node\''
). Unfortunatelychild_process.spawn
doesn't accept paths surrounded with quotation marks ('
) on Unix and throws anspawn '/usr/local/Cellar/node@6/6.11.4/bin/node' ENOENT
error (Note that the'
do not mark the beginning or ending of the path string here, but are actual considered part of the actual path.)This PR fixes the issue by only running
child.escapeArg
on Windows (where it is needed to support for examples paths containing spaces, but on Unix even spaces in the path string aren't a problem forchild_process.spawn
).An alternative fix would be to remove the quotations marks in line 84 in
child.escapeArg
, but becausechild.escapeArg
is also used in other places in the code base, I'm not sure if this would cause other side effects.