-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Properly escape extra args #31
Changes from 1 commit
19443b8
2004ecc
d1c4c26
74df3ab
8a5639c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,10 @@ const packageEnvs = require('./package-envs.js') | |
const { isNodeGypPackage, defaultGypInstallScript } = require('@npmcli/node-gyp') | ||
const signalManager = require('./signal-manager.js') | ||
const isServerPackage = require('./is-server-package.js') | ||
const { ShellString, unquoted } = require('puka'); | ||
|
||
const sh = (...args) => | ||
ShellString.sh(...args).toString(process.env.__FAKE_TESTING_PLATFORM__ || process.platform) | ||
|
||
// you wouldn't like me when I'm angry... | ||
const bruce = (id, event, cmd) => | ||
|
@@ -31,7 +35,7 @@ const runScriptPkg = async options => { | |
if (options.cmd) | ||
cmd = options.cmd | ||
else if (pkg.scripts && pkg.scripts[event]) | ||
cmd = pkg.scripts[event] + args.map(a => ` ${JSON.stringify(a)}`).join('') | ||
cmd = sh`${unquoted(pkg.scripts[event])} ${args}` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is how Yarn does it: And how the original PR by the author of |
||
else if ( // If there is no preinstall or install script, default to rebuilding node-gyp packages. | ||
event === 'install' && | ||
!scripts.install && | ||
|
@@ -41,7 +45,7 @@ const runScriptPkg = async options => { | |
) | ||
cmd = defaultGypInstallScript | ||
else if (event === 'start' && await isServerPackage(path)) | ||
cmd = 'node server.js' + args.map(a => ` ${JSON.stringify(a)}`).join('') | ||
cmd = sh`node server.js ${args}` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This could still have issues if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 I’ll test this on a Windows machine soon There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tested this. You are right: If I created console.log(process.argv) And ran this from the Node.js REPL:
As one can see, However, if I install Node.js using I fixed this by shipping with a tiny
Here’s the fix: Do you see any potential problems with this approach? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should work, although just to be safe maybe rename the wrapper to something like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You could also do what |
||
|
||
if (!cmd) | ||
return { code: 0, signal: null } | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
const { EventEmitter } = require('events') | ||
const t = require('tap') | ||
const requireInject = require('require-inject') | ||
const isWindows = require('../lib/is-windows.js') | ||
|
||
let fakeIsNodeGypPackage = false | ||
let SIGNAL = null | ||
|
@@ -96,7 +97,7 @@ t.test('pkg has server.js, start not specified, with args', async t => { | |
scripts: {}, | ||
}, | ||
}) | ||
t.strictSame(res, ['sh', ['-c', 'node server.js "a" "b" "c"'], { | ||
t.strictSame(res, ['sh', ['-c', 'node server.js a b c'], { | ||
stdioString: false, | ||
event: 'start', | ||
path, | ||
|
@@ -105,10 +106,10 @@ t.test('pkg has server.js, start not specified, with args', async t => { | |
environ: 'value', | ||
}, | ||
stdio: 'pipe', | ||
cmd: 'node server.js "a" "b" "c"', | ||
cmd: 'node server.js a b c', | ||
}, { | ||
event: 'start', | ||
script: 'node server.js "a" "b" "c"', | ||
script: 'node server.js a b c', | ||
pkgid: 'foo@1.2.3', | ||
path, | ||
}]) | ||
|
@@ -288,6 +289,10 @@ t.test('pkg has foo script', t => runScriptPkg({ | |
path: 'path', | ||
}]))) | ||
|
||
const expectedCommand = isWindows | ||
? 'bar a --flag "markdown `code`" ^^^"$X^^^ \\\\\\^^^"blah\\\\\\^^^"^^^" $PWD ^^^%CD^^^% "^" ! \\ ">" "<" "|" "&" \' ^^^"\\^^^"^^^" ` " " ""' | ||
: "bar a --flag 'markdown `code`' '$X \\\"blah\\\"' '$PWD' %CD% ^ ! '\\' '>' '<' '|' '&' \\' '\"' '`' ' ' ''" | ||
|
||
t.test('pkg has foo script, with args', t => runScriptPkg({ | ||
event: 'foo', | ||
path: 'path', | ||
|
@@ -302,8 +307,8 @@ t.test('pkg has foo script, with args', t => runScriptPkg({ | |
foo: 'bar', | ||
}, | ||
}, | ||
args: ['a', 'b', 'c'], | ||
}).then(res => t.strictSame(res, ['sh', ['-c', 'bar "a" "b" "c"'], { | ||
args: ['a', '--flag', 'markdown `code`', '$X \\"blah\\"', '$PWD', '%CD%', '^', '!', '\\', '>', '<', '|', '&', "'", '"', '`', ' ', ''], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is inspired by Yarn’s tests: https://github.com/yarnpkg/yarn/blob/3119382885ea373d3c13d6a846de743eca8c914b/__tests__/integration.js#L424 |
||
}).then(res => t.strictSame(res, ['sh', ['-c', expectedCommand,], { | ||
stdioString: false, | ||
event: 'foo', | ||
path: 'path', | ||
|
@@ -312,10 +317,10 @@ t.test('pkg has foo script, with args', t => runScriptPkg({ | |
environ: 'value', | ||
}, | ||
stdio: 'pipe', | ||
cmd: 'bar "a" "b" "c"', | ||
cmd: expectedCommand, | ||
}, { | ||
event: 'foo', | ||
script: 'bar "a" "b" "c"', | ||
script: expectedCommand, | ||
pkgid: 'foo@1.2.3', | ||
path: 'path', | ||
}]))) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
puka
comes with ash
export (defined asconst sh = (...args) => ShellString.sh(...args).toString()
basically), but we’re making our own so we can test the Windows version more easily.https://gitlab.com/rhendric/puka#shellstring
process.env.__FAKE_TESTING_PLATFORM__ || process.platform
is copied from is-windows.js – let me know if you’d like to share that, and if so, how.