-
Notifications
You must be signed in to change notification settings - Fork 7.3k
Feature/fix child process type checking #8454
Feature/fix child process type checking #8454
Conversation
errors = 0; | ||
|
||
try { | ||
// Ensure this throws a TypeError | ||
var child = spawn(invalidcmd, 'this is not an array'); |
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.
Even before my changes, I think this test was a bit overkill. It intentionally ran a bad command and passed in bad arguments to make sure that the TypeError
was thrown, and the invalid command error wasn't encountered. A simple assert.throws()
like you've done would have been simpler. I'm fine with getting rid of this code.
Would you mind removing the the errors
variable and the process.on('exit', ...)
?
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.
Not at all, I will do.
@tjfontaine @cjihrig PTAL |
@@ -610,6 +612,8 @@ exports.execFile = function(file /* args, options, callback */) { | |||
if (Array.isArray(arguments[1])) { | |||
args = arguments[1]; | |||
options = util._extend(options, arguments[2]); | |||
} else if (arguments[1] && typeof arguments[1] !== 'object') { |
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 think this could cause problems in execFile()
since arguments[1]
could be a function too. Maybe throw in a check for arguments[1] !== callback
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.
Correct. The callback is not being allowed to bubble down. This'll need to be fixed, but more than just adding a check. The values need to be assigned in that specific case. e.g.:
} else if (typeof arguments[1] === 'function') {
callback = arguments[1];
args = [];
} else if (arguments[1] && typeof arguments[1] !== 'object') {
Though this does leave the possibility of the user passing 0
to arguments[1]
and still not throwing. Instead I'd use the following:
} else if (arguments[1] && typeof arguments[1] === 'object') {
args = [];
options = util._extend(options, arguments[1]);
} else {
throw new TypeError('Incorrect value of args option');
}
I popped off the rename, 939c897, because it makes addressing comments hard without rebasing them away, I'll add it back after review. |
Addressed comments (and incorporated #8530). |
Applied this to v0.10. Here are some of the following errors:
|
Sorry, @trevnorris, those tests pass for me on Linux, what's your platform? And what did you mean by "applied to v0.10"? This PR is off the current head of I could rebase it onto it, and re-PR, of course. There are 3 branches in play, its hard to know where to direct PRs. I could even do one PR to v0.10, and another to v0.12, so that fixing the conflicts would be my problem, but I'm not really sure how helpful that would be. |
@trevnorris ping |
@sam-github Thanks for the ping. The mention of applying it to v0.10 was meant to say it was applied to the tip of v0.10, since the PR hadn't been rebased on the latest. There's no need to re-PR for just rebasing on latest v0.10. Just rebase and force push your branch. I'm rerunning the tests and will update with the results. My platform is |
The tests are still failing. Here's a strange one. Apply the following patch: diff --git a/test/simple/test-child-process-exec-error.js b/test/simple/test-child-process-exec-error.js
index 2afe114..1f9d6f5 100644
--- a/test/simple/test-child-process-exec-error.js
+++ b/test/simple/test-child-process-exec-error.js
@@ -29,9 +29,11 @@ function test(fun, code) {
fun('does-not-exist', function(err) {
assert.equal(err.code, code);
errors++;
+ console.log('>>> fun executed', process.pid, errors);
});
process.on('exit', function() {
+ console.log('>>> process exiting', process.pid, errors);
assert.equal(errors, 1);
});
} And the output I get is:
But if I move the
Any ideas what's going on? |
Its common knowledge on unix, but node documentation depends on knowing this, as it exposes both streams named after stdio, and the fd numbers, so make this explicit. Closes #8624
The test wasn't checking directly that an assertion was thrown. Instead, it was checking that spawn did not sucessfully spawn a non-existent command. However, the command chosen, dir, exists in GNU coreutils, so it exists on Linux (though not on BSD derived OS X). The test as written passed on Linux, even with the TypeError it is supposed to be checking for deleted from spawn(). It would also pass on Windows if a ls.exe existed. The approach is unnecessarily obscure, `assert.throw()` is for asserting code throws, using it is more clear and works regardless of what commands do or do not exist.
@trevnorris yes, I've figured out the problem, I'll see if I can fix it. I think checking types of args may not be possible for functions that have 4 args, 3 of which are optional. |
execFile and spawn have same API signature with respect to optional arg array and optional options object, they should have same behaviour with respect to argument validation.
Optional fork args should be type-checked with same behaviour as the equivalent argument to spawn.
@trevnorris fixed, and added regression tests. I wasn't dealing with unsigned/null as explicit "no option" place holders in the postitional list, and exec uses this feature when it calls execFile. Thanks for catching that. |
Awesome work. I'm getting a timeout on |
Its common knowledge on unix, but node documentation depends on knowing this, as it exposes both streams named after stdio, and the fd numbers, so make this explicit. Fixes: #8624 PR-URL: #8454 Reviewed-by: Trevor Norris <[email protected]>
The test wasn't checking directly that an assertion was thrown. Instead, it was checking that spawn did not sucessfully spawn a non-existent command. However, the command chosen, dir, exists in GNU coreutils, so it exists on Linux (though not on BSD derived OS X). The test as written passed on Linux, even with the TypeError it is supposed to be checking for deleted from spawn(). It would also pass on Windows if a ls.exe existed. The approach is unnecessarily obscure, assert.throw() is for asserting code throws, using it is more clear and works regardless of what commands do or do not exist. PR-URL: #8454 Reviewed-by: Trevor Norris <[email protected]>
execFile and spawn have same API signature with respect to optional arg array and optional options object, they should have same behaviour with respect to argument validation. PR-URL: #8454 Reviewed-by: Trevor Norris <[email protected]>
Optional fork args should be type-checked with same behaviour as the equivalent argument to spawn. PR-URL: #8454 Reviewed-by: Trevor Norris <[email protected]>
PR-URL: #8454 Reviewed-by: Trevor Norris <[email protected]>
@trevnorris I'll make sure to run jshint more regularly, sorry about that. |
A block of asserts were duplicated in test/simple/test-child-process-spawn-typeerror.js. This commit removes the duplicated asserts. Fixes: #8454 Reviewed-By: Colin Ihrig <[email protected]>
Its common knowledge on unix, but node documentation depends on knowing this, as it exposes both streams named after stdio, and the fd numbers, so make this explicit. Fixes: nodejs#8624 PR-URL: nodejs#8454 Reviewed-by: Trevor Norris <[email protected]>
The test wasn't checking directly that an assertion was thrown. Instead, it was checking that spawn did not sucessfully spawn a non-existent command. However, the command chosen, dir, exists in GNU coreutils, so it exists on Linux (though not on BSD derived OS X). The test as written passed on Linux, even with the TypeError it is supposed to be checking for deleted from spawn(). It would also pass on Windows if a ls.exe existed. The approach is unnecessarily obscure, assert.throw() is for asserting code throws, using it is more clear and works regardless of what commands do or do not exist. PR-URL: nodejs#8454 Reviewed-by: Trevor Norris <[email protected]>
execFile and spawn have same API signature with respect to optional arg array and optional options object, they should have same behaviour with respect to argument validation. PR-URL: nodejs#8454 Reviewed-by: Trevor Norris <[email protected]>
Optional fork args should be type-checked with same behaviour as the equivalent argument to spawn. PR-URL: nodejs#8454 Reviewed-by: Trevor Norris <[email protected]>
PR-URL: nodejs#8454 Reviewed-by: Trevor Norris <[email protected]>
A block of asserts were duplicated in test/simple/test-child-process-spawn-typeerror.js. This commit removes the duplicated asserts. Fixes: nodejs#8454 Reviewed-By: Colin Ihrig <[email protected]>
Its common knowledge on unix, but node documentation depends on knowing this, as it exposes both streams named after stdio, and the fd numbers, so make this explicit. Fixes: nodejs/node-v0.x-archive#8624 PR-URL: nodejs/node-v0.x-archive#8454 Reviewed-by: Trevor Norris <[email protected]> Cherry-picked-from: nodejs/node-v0.x-archive@13a992b
commit 709558ce0d4027978a742c618d014e5713422263 Author: cjihrig <[email protected]> Date: Wed Dec 17 14:58:09 2014 -0500 test: remove redundant code in test A block of asserts were duplicated in test/simple/test-child-process-spawn-typeerror.js. This commit removes the duplicated asserts. Fixes: nodejs/node-v0.x-archive#8454 Reviewed-By: Colin Ihrig <[email protected]> commit 9e6d2792ae2eb3ad8553192a1d9c7a7d58808123 Author: Trevor Norris <[email protected]> Date: Tue Nov 18 16:42:10 2014 -0800 lint: fix lint issues Forgot to fix these before landing the patch. Fixes: e17c5a7 commit 756612776e6bb6b4329a132948f40ad9c28555e2 Author: Sam Roberts <[email protected]> Date: Wed Oct 8 13:30:38 2014 -0700 test: test all spawn parameter positions PR-URL: nodejs/node-v0.x-archive#8454 Reviewed-by: Trevor Norris <[email protected]> commit 408812653153cc50f626c7c69b2f8ea4a4be8cec Author: Sam Roberts <[email protected]> Date: Mon Sep 29 11:26:43 2014 -0700 child_process: check fork args is an array Optional fork args should be type-checked with same behaviour as the equivalent argument to spawn. PR-URL: nodejs/node-v0.x-archive#8454 Reviewed-by: Trevor Norris <[email protected]> commit 11bff9beb2f837a923eb0e515331303f7771301e Author: Sam Roberts <[email protected]> Date: Thu Sep 25 22:28:33 2014 -0700 child_process: check execFile args is an array execFile and spawn have same API signature with respect to optional arg array and optional options object, they should have same behaviour with respect to argument validation. PR-URL: nodejs/node-v0.x-archive#8454 Reviewed-by: Trevor Norris <[email protected]> commit d531ab78c41019f6fdcaf08a1e84ab2b9e439c1b Author: cjihrig <[email protected]> Date: Wed Sep 17 17:26:46 2014 -0400 child_process: properly support optional args Currently, a TypeError is incorrectly thrown if the second argument is an object. This commit allows the args argument to be properly omitted. Fixes: nodejs/node-v0.x-archive#6068 Reviewed-by: Trevor Norris <[email protected]>
The test wasn't checking directly that an assertion was thrown. Instead, it was checking that spawn did not sucessfully spawn a non-existent command. However, the command chosen, dir, exists in GNU coreutils, so it exists on Linux (though not on BSD derived OS X). The test as written passed on Linux, even with the TypeError it is supposed to be checking for deleted from spawn(). It would also pass on Windows if a ls.exe existed. The approach is unnecessarily obscure, assert.throw() is for asserting code throws, using it is more clear and works regardless of what commands do or do not exist. PR-URL: nodejs/node-v0.x-archive#8454 Reviewed-by: Trevor Norris <[email protected]> Cherry-picked-from: nodejs/node-v0.x-archive@2ff29cc Conflicts: test/parallel/test-child-process-spawn-typeerror.js
#8392 introduced a test that doesn't fail when the code it is testing is deleted.
Also, behaviour of execFile and spawn have drifted apart again, unnecessarily, I think. This brings them into line again.
/to @cjihrig