Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 34.3k
child_process: spawn() and spawnSync() validation#8312
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
Uh oh!
There was an error while loading. Please reload this page.
Conversation
cjihrig commented Aug 28, 2016 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
lib/child_process.js Outdated
Fishrock123Aug 28, 2016 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
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.
Maybe a helper would be better?
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.
Sounds like string, null and undefined are allowed.
On Aug 29, 2016 12:09 AM, "Jeremiah Senkpiel" [email protected]
wrote:
In lib/child_process.js
#8312 (comment):@@ -329,6 +329,49 @@ function normalizeSpawnArguments(file /, args, options/){
else if (options === null || typeof options !== 'object')
throw new TypeError('"options" argument must be an object');
- // Validate the cwd, if present.
- if (options.cwd !== undefined &&
options.cwd !== null &&!typeof options.cwd === 'string')Maybe a helper would be better? won't !typeof options.cwd === 'string'
cover all these 3 cases?—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/nodejs/node/pull/8312/files/b4a6558fcbcf6cde50ff29af2d3487896ad91c68#r76536916,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABjB841u9wl3B9jlsDIb7RdsDKU0iWTcks5qkdXdgaJpZM4Ju-4I
.
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.
Do you mean another function like isOptionalString() (where the optional part covers null and undefined)?
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.
!typeof options.cwd === 'string' is always false, it should be !(typeof options.cwd === 'string') or (better) typeof options.cwd !== 'string'.
cjihrig commented Sep 1, 2016
@bnoordhuis any opinion on the approach here? |
bnoordhuis commented Sep 2, 2016
The Moving the validation logic to JS land basically LGTM though. |
bnoordhuis commented Oct 12, 2016
@cjihrig Ping. |
cjihrig commented Oct 12, 2016
I plan on getting back to this next week. Sorry for the delay. |
c133999 to 83c7a88Compareaf5c2f5 to 76d7181Compare50f599e to 146129bComparecjihrig commented Oct 18, 2016
@bnoordhuis updated, PTAL. |
cjihrig commented Oct 26, 2016
@bnoordhuis ping |
cjihrig commented Nov 15, 2016
ping @nodejs/collaborators |
sam-github commented Nov 16, 2016 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
I'll look at this, but because the test was added in the same commit as the additional checks, its hard to evaluate what is different, i.e., what the behaviour used to be. If the test was added, then the commit that changed the behaviour changed the test... it would be easy to understand the change. |
sam-github commented Nov 16, 2016 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
Many thumbs up for solid testing of these APIs, and better input validation. cwd, detached, uid, gid are all implemented in Its not clear what tests should go where, and its also very difficult to determine what kind of test coverage there is, not in the line sense, but in the sense of: are the tests against spawnSync here valid for any of the other Sync calls? Any other spawn calls? Its painful, but maybe the tests should be factored so they can be applied to all the child_process functions that use the same normalize? Or perhaps the tests should all just be in one file, with a comment in the test saying that even though it appears that only one API is tested, the underlying code is the same, so its hitting every API? Unrelated to this PR, but I'm pretty disappointed that the arg permutation tests in test-child-process-spawn-typeerror.js were never extended to include *Sync, since arg permutations was such a rich source of bugs and inconsistencies, and I'm poking around, but I can't see any tests for their arg permutations. But even though that problem is unrelated, its why I suggest that having the tests be organized in a way that its (EDIT) "easy" for a reader to verify the coverage scenarios is important. |
lib/child_process.js Outdated
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.
Does this have to be, literally, boolean? I would expect it to have to be truthy/falsy
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.
It could probably be coerced to a Boolean, but the extra strictness is good IMO. Not that it matters much, but windowsVerbatimArguments isn't documented anyway, IIRC.
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.
I agree, its internal-only, so maybe not so important, and better to start strict. I don't agree strictness is generally good in this case, btw. It creates a bizarre API wherein truthy is sometimes true/false, sometimes null/undefined/0/"" are also false, sometimes not, and sometimes function/[]/{}/non-zero/"strings" are also true, and sometimes null or undefined are a "third way", neither true or false but some kind of other behaviour. Ouch. Anyhow, as a semi-private (but used by modules on npmjs.org none-the-less) API, I'm OK with this restriction.
cjihrig commented Nov 16, 2016
I just did that because
I agree that the tests are kind of all over the place. This PR is a step towards consolidating the behavior of
I think just about everything goes through |
sam-github commented Nov 16, 2016
The tests you add seemed like an obvious candidate to be in a "spawn typeerror" test, but I understand the distinction you draw above. If you do draw that distinction, my request is that the name of the tests (and a comment at their top) clearly communicate it: the names/comments should indicate what that test is for, so that we don't get diffusion and confusion of tests over time. For example:
I suggest a rename like this because it would be a disaster if someone created a |
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.
Assert NaN is not valid. Ditto below.
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.
0 and 1 are usually acceptable as truthy values, I think they should be accepted here.
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.
I'd personally go for strict.
bnoordhuis left a comment
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.
LGTM. Good test coverage.
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.
I'd personally go for strict.
lib/child_process.js Outdated
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.
Nit: If the input is an empty string, the error message might not be exactly appropriate.
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.
Updated to specify "non-empty string"
cjihrig commented Dec 22, 2016 • edited
Loading Uh oh!
There was an error while loading. Please reload this page.
edited
Uh oh!
There was an error while loading. Please reload this page.
CI: https://ci.nodejs.org/job/node-test-pull-request/5539/ New CI because Windows: https://ci.nodejs.org/job/node-test-pull-request/5545/ |
cjihrig commented Dec 23, 2016
CI is all green. |
This commit verifies that the child process handle is of the correct type before trying to close it in CloseHandlesAndDeleteLoop(). This catches the case where input validation failed, and the child process was never actually spawned. Fixes: nodejs#8096Fixes: nodejs#8539 Refs: nodejs#9722 PR-URL: nodejs#8312 Reviewed-By: Ben Noordhuis <[email protected]>
This commit applies stricter input validation in normalizeSpawnArguments(), which is run by all of the child_process methods. Additional checks are added for spawnSync() specific inputs. Fixes: nodejs#8096Fixes: nodejs#8539 Refs: nodejs#9722 PR-URL: nodejs#8312 Reviewed-By: Ben Noordhuis <[email protected]>
This commit removes C++ checks from spawn() and spawnSync() that are duplicates of the JavaScript type checking. Fixes: nodejs#8096Fixes: nodejs#8539 Refs: nodejs#9722 PR-URL: nodejs#8312 Reviewed-By: Ben Noordhuis <[email protected]>
cjihrig commented Dec 25, 2016
MylesBorins commented Jan 16, 2017
@Fishrock123 the bot should likely not be adding lts labels to anything labelled semver major |
Fishrock123 commented Jan 16, 2017
This commit verifies that the child process handle is of the correct type before trying to close it in CloseHandlesAndDeleteLoop(). This catches the case where input validation failed, and the child process was never actually spawned. Fixes: nodejs#8096Fixes: nodejs#8539 Refs: nodejs#9722 PR-URL: nodejs#8312 Reviewed-By: Ben Noordhuis <[email protected]>
This commit applies stricter input validation in normalizeSpawnArguments(), which is run by all of the child_process methods. Additional checks are added for spawnSync() specific inputs. Fixes: nodejs#8096Fixes: nodejs#8539 Refs: nodejs#9722 PR-URL: nodejs#8312 Reviewed-By: Ben Noordhuis <[email protected]>
This commit removes C++ checks from spawn() and spawnSync() that are duplicates of the JavaScript type checking. Fixes: nodejs#8096Fixes: nodejs#8539 Refs: nodejs#9722 PR-URL: nodejs#8312 Reviewed-By: Ben Noordhuis <[email protected]>
Checklist
make -j4 test(UNIX), orvcbuild test nosign(Windows) passesAffected core subsystem(s)
child_process, src
Description of change
This PR is intended to fix#8096. The first commit prevents the abort from #8096 by verifying that the handle type is correct before trying to close it. This commit is semver-patch.
This leaves an uninformative
EINVALerror being thrown due to the bad input. So, the second commit in this PR addresses that by producing more helpful errors in the JavaScript layer. In doing so, it better unifies thespawn()andspawnSync()input checking (which also nicely bubbles up to the otherchild_processmethods). AdditionalspawnSync()specific checks are also provided. This commit is semver-major due to the changes in error messages.The third commit removes redundant C++ type checks that are now done in the JS layer.
cc: @bnoordhuis, @targos, and @retrohacker from #8096
Fixes: #8096
Fixes: #8539