Skip to content

Commit d7aaae1

Browse files
committed
squash: strict validation, test for bad input
1 parent 79ae91a commit d7aaae1

File tree

2 files changed

+81
-25
lines changed

2 files changed

+81
-25
lines changed

lib/child_process.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,7 @@ function copyProcessEnvToEnv(env, name, optionEnv) {
546546

547547
function normalizeSpawnArguments(file, args, options) {
548548
file = getValidatedPath(file, 'file');
549+
validateString(file, 'file');
549550

550551
if (file.length === 0)
551552
throw new ERR_INVALID_ARG_VALUE('file', file, 'cannot be empty');
Lines changed: 80 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,97 @@
11
import { isWindows, mustCall, mustSucceed, mustNotCall } from '../common/index.mjs';
2-
import { strictEqual } from 'node:assert';
3-
import { pathToFileURL } from 'node:url';
2+
import { strictEqual, throws } from 'node:assert';
43
import cp from 'node:child_process';
4+
import url from 'node:url';
55
import tmpdir from '../common/tmpdir.js';
66

77
tmpdir.refresh();
88

99
const cwd = tmpdir.path;
10+
const cwdUrl = url.pathToFileURL(cwd);
1011
const whichCommand = isWindows ? 'where.exe cmd.exe' : 'which pwd';
1112
const pwdFullPath = `${cp.execSync(whichCommand)}`.trim();
12-
const pwdUrl = pathToFileURL(pwdFullPath);
13-
const pwdCommandAndOptions = isWindows ?
14-
[pwdUrl, ['/d', '/c', 'cd'], { cwd: pathToFileURL(cwd) }] :
15-
[pwdUrl, [], { cwd: pathToFileURL(cwd) }];
13+
const pwdWHATWGUrl = url.pathToFileURL(pwdFullPath);
1614

17-
{
18-
cp.execFile(...pwdCommandAndOptions, mustSucceed((stdout) => {
15+
// Test for WHATWG URL instance, legacy URL, and URL-like object
16+
for (const pwdUrl of [
17+
pwdWHATWGUrl,
18+
new url.URL(pwdWHATWGUrl),
19+
{
20+
href: pwdWHATWGUrl.href,
21+
origin: pwdWHATWGUrl.origin,
22+
protocol: pwdWHATWGUrl.protocol,
23+
username: pwdWHATWGUrl.username,
24+
password: pwdWHATWGUrl.password,
25+
host: pwdWHATWGUrl.host,
26+
hostname: pwdWHATWGUrl.hostname,
27+
port: pwdWHATWGUrl.port,
28+
pathname: pwdWHATWGUrl.pathname,
29+
search: pwdWHATWGUrl.search,
30+
searchParams: new URLSearchParams(pwdWHATWGUrl.searchParams),
31+
hash: pwdWHATWGUrl.hash,
32+
},
33+
]) {
34+
const pwdCommandAndOptions = isWindows ?
35+
[pwdUrl, ['/d', '/c', 'cd'], { cwd: cwdUrl }] :
36+
[pwdUrl, [], { cwd: cwdUrl }];
37+
38+
{
39+
cp.execFile(...pwdCommandAndOptions, mustSucceed((stdout) => {
40+
strictEqual(`${stdout}`.trim(), cwd);
41+
}));
42+
}
43+
44+
{
45+
const stdout = cp.execFileSync(...pwdCommandAndOptions);
1946
strictEqual(`${stdout}`.trim(), cwd);
20-
}));
21-
}
47+
}
2248

23-
{
24-
const stdout = cp.execFileSync(...pwdCommandAndOptions);
25-
strictEqual(`${stdout}`.trim(), cwd);
26-
}
49+
{
50+
const pwd = cp.spawn(...pwdCommandAndOptions);
51+
pwd.stdout.on('data', mustCall((stdout) => {
52+
strictEqual(`${stdout}`.trim(), cwd);
53+
}));
54+
pwd.stderr.on('data', mustNotCall());
55+
pwd.on('close', mustCall((code) => {
56+
strictEqual(code, 0);
57+
}));
58+
}
2759

28-
{
29-
const pwd = cp.spawn(...pwdCommandAndOptions);
30-
pwd.stdout.on('data', mustCall((stdout) => {
60+
{
61+
const stdout = cp.spawnSync(...pwdCommandAndOptions).stdout;
3162
strictEqual(`${stdout}`.trim(), cwd);
32-
}));
33-
pwd.stderr.on('data', mustNotCall());
34-
pwd.on('close', mustCall((code) => {
35-
strictEqual(code, 0);
36-
}));
63+
}
64+
3765
}
3866

39-
{
40-
const stdout = cp.spawnSync(...pwdCommandAndOptions).stdout;
41-
strictEqual(`${stdout}`.trim(), cwd);
67+
// Test for non-URL objects
68+
for (const badFile of [
69+
Buffer.from(pwdFullPath),
70+
{},
71+
{ href: pwdWHATWGUrl.href },
72+
{ pathname: pwdWHATWGUrl.pathname },
73+
]) {
74+
const pwdCommandAndOptions = isWindows ?
75+
[badFile, ['/d', '/c', 'cd'], { cwd: cwdUrl }] :
76+
[badFile, [], { cwd: cwdUrl }];
77+
78+
throws(
79+
() => cp.execFile(...pwdCommandAndOptions, mustNotCall()),
80+
{ code: 'ERR_INVALID_ARG_TYPE' },
81+
);
82+
83+
throws(
84+
() => cp.execFileSync(...pwdCommandAndOptions),
85+
{ code: 'ERR_INVALID_ARG_TYPE' },
86+
);
87+
88+
throws(
89+
() => cp.spawn(...pwdCommandAndOptions),
90+
{ code: 'ERR_INVALID_ARG_TYPE' },
91+
);
92+
93+
throws(
94+
() => cp.spawnSync(...pwdCommandAndOptions),
95+
{ code: 'ERR_INVALID_ARG_TYPE' },
96+
);
4297
}

0 commit comments

Comments
 (0)