lib: use validators for argument validation

This refactors internal validation helpers in `child_process` to use
the common validators in `lib/internal/validators.js` where possible.

This improves code consistency and maintainability.

PR-URL: https://github.com/nodejs/node/pull/59416
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Daeyeon Jeong <daeyeon.dev@gmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
This commit is contained in:
Nam Yooseong 2025-09-21 11:47:14 +09:00 committed by GitHub
parent f6d6b911fa
commit 39d73036e7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 39 additions and 39 deletions

View File

@ -33,7 +33,6 @@ const {
ArrayPrototypeSort, ArrayPrototypeSort,
ArrayPrototypeSplice, ArrayPrototypeSplice,
ArrayPrototypeUnshift, ArrayPrototypeUnshift,
NumberIsInteger,
ObjectAssign, ObjectAssign,
ObjectDefineProperty, ObjectDefineProperty,
ObjectPrototypeHasOwnProperty, ObjectPrototypeHasOwnProperty,
@ -70,18 +69,19 @@ const {
ERR_CHILD_PROCESS_STDIO_MAXBUFFER, ERR_CHILD_PROCESS_STDIO_MAXBUFFER,
ERR_INVALID_ARG_TYPE, ERR_INVALID_ARG_TYPE,
ERR_INVALID_ARG_VALUE, ERR_INVALID_ARG_VALUE,
ERR_OUT_OF_RANGE,
}, },
genericNodeError, genericNodeError,
} = require('internal/errors'); } = require('internal/errors');
const { clearTimeout, setTimeout } = require('timers'); const { clearTimeout, setTimeout } = require('timers');
const { getValidatedPath } = require('internal/fs/utils'); const { getValidatedPath } = require('internal/fs/utils');
const { const {
isInt32,
validateAbortSignal, validateAbortSignal,
validateArray, validateArray,
validateBoolean, validateBoolean,
validateFunction, validateFunction,
validateInteger,
validateInt32,
validateNumber,
validateObject, validateObject,
validateString, validateString,
} = require('internal/validators'); } = require('internal/validators');
@ -603,13 +603,13 @@ function normalizeSpawnArguments(file, args, options) {
} }
// Validate the uid, if present. // Validate the uid, if present.
if (options.uid != null && !isInt32(options.uid)) { if (options.uid != null) {
throw new ERR_INVALID_ARG_TYPE('options.uid', 'int32', options.uid); validateInt32(options.uid, 'options.uid');
} }
// Validate the gid, if present. // Validate the gid, if present.
if (options.gid != null && !isInt32(options.gid)) { if (options.gid != null) {
throw new ERR_INVALID_ARG_TYPE('options.gid', 'int32', options.gid); validateInt32(options.gid, 'options.gid');
} }
// Validate the shell, if present. // Validate the shell, if present.
@ -1018,17 +1018,15 @@ function validateArgumentsNullCheck(args, propName) {
function validateTimeout(timeout) { function validateTimeout(timeout) {
if (timeout != null && !(NumberIsInteger(timeout) && timeout >= 0)) { if (timeout != null) {
throw new ERR_OUT_OF_RANGE('timeout', 'an unsigned integer', timeout); validateInteger(timeout, 'timeout', 0);
} }
} }
function validateMaxBuffer(maxBuffer) { function validateMaxBuffer(maxBuffer) {
if (maxBuffer != null && !(typeof maxBuffer === 'number' && maxBuffer >= 0)) { if (maxBuffer != null) {
throw new ERR_OUT_OF_RANGE('options.maxBuffer', validateNumber(maxBuffer, 'options.maxBuffer', 0);
'a positive number',
maxBuffer);
} }
} }

View File

@ -27,11 +27,11 @@ const { getEventListeners } = require('events');
// Verify timeout verification // Verify timeout verification
throws(() => fork(fixtures.path('child-process-stay-alive-forever.js'), { throws(() => fork(fixtures.path('child-process-stay-alive-forever.js'), {
timeout: 'badValue', timeout: 'badValue',
}), /ERR_OUT_OF_RANGE/); }), /ERR_INVALID_ARG_TYPE/);
throws(() => fork(fixtures.path('child-process-stay-alive-forever.js'), { throws(() => fork(fixtures.path('child-process-stay-alive-forever.js'), {
timeout: {}, timeout: {},
}), /ERR_OUT_OF_RANGE/); }), /ERR_INVALID_ARG_TYPE/);
} }
{ {

View File

@ -28,11 +28,11 @@ const aliveForeverFile = 'child-process-stay-alive-forever.js';
// Verify timeout verification // Verify timeout verification
throws(() => spawn(process.execPath, [fixtures.path(aliveForeverFile)], { throws(() => spawn(process.execPath, [fixtures.path(aliveForeverFile)], {
timeout: 'badValue', timeout: 'badValue',
}), /ERR_OUT_OF_RANGE/); }), /ERR_INVALID_ARG_TYPE/);
throws(() => spawn(process.execPath, [fixtures.path(aliveForeverFile)], { throws(() => spawn(process.execPath, [fixtures.path(aliveForeverFile)], {
timeout: {}, timeout: {},
}), /ERR_OUT_OF_RANGE/); }), /ERR_INVALID_ARG_TYPE/);
} }
{ {

View File

@ -39,6 +39,8 @@ const invalidArgTypeError = {
name: 'TypeError' name: 'TypeError'
}; };
const invalidRangeError = { code: 'ERR_OUT_OF_RANGE', name: 'RangeError' };
assert.throws(function() { assert.throws(function() {
spawn(invalidcmd, 'this is not an array'); spawn(invalidcmd, 'this is not an array');
}, invalidArgTypeError); }, invalidArgTypeError);
@ -77,11 +79,11 @@ assert.throws(function() {
assert.throws(function() { assert.throws(function() {
spawn(cmd, [], { uid: 2 ** 63 }); spawn(cmd, [], { uid: 2 ** 63 });
}, invalidArgTypeError); }, invalidRangeError);
assert.throws(function() { assert.throws(function() {
spawn(cmd, [], { gid: 2 ** 63 }); spawn(cmd, [], { gid: 2 ** 63 });
}, invalidArgTypeError); }, invalidRangeError);
// Argument types for combinatorics. // Argument types for combinatorics.
const a = []; const a = [];

View File

@ -64,10 +64,10 @@ if (!common.isWindows) {
fail('uid', [], invalidArgTypeError); fail('uid', [], invalidArgTypeError);
fail('uid', {}, invalidArgTypeError); fail('uid', {}, invalidArgTypeError);
fail('uid', common.mustNotCall(), invalidArgTypeError); fail('uid', common.mustNotCall(), invalidArgTypeError);
fail('uid', NaN, invalidArgTypeError); fail('uid', NaN, invalidRangeError);
fail('uid', Infinity, invalidArgTypeError); fail('uid', Infinity, invalidRangeError);
fail('uid', 3.1, invalidArgTypeError); fail('uid', 3.1, invalidRangeError);
fail('uid', -3.1, invalidArgTypeError); fail('uid', -3.1, invalidRangeError);
} }
} }
@ -83,10 +83,10 @@ if (!common.isWindows) {
fail('gid', [], invalidArgTypeError); fail('gid', [], invalidArgTypeError);
fail('gid', {}, invalidArgTypeError); fail('gid', {}, invalidArgTypeError);
fail('gid', common.mustNotCall(), invalidArgTypeError); fail('gid', common.mustNotCall(), invalidArgTypeError);
fail('gid', NaN, invalidArgTypeError); fail('gid', NaN, invalidRangeError);
fail('gid', Infinity, invalidArgTypeError); fail('gid', Infinity, invalidRangeError);
fail('gid', 3.1, invalidArgTypeError); fail('gid', 3.1, invalidRangeError);
fail('gid', -3.1, invalidArgTypeError); fail('gid', -3.1, invalidRangeError);
} }
} }
} }
@ -152,12 +152,12 @@ if (!common.isWindows) {
pass('timeout', 1); pass('timeout', 1);
pass('timeout', 0); pass('timeout', 0);
fail('timeout', -1, invalidRangeError); fail('timeout', -1, invalidRangeError);
fail('timeout', true, invalidRangeError); fail('timeout', true, invalidArgTypeError);
fail('timeout', false, invalidRangeError); fail('timeout', false, invalidArgTypeError);
fail('timeout', __dirname, invalidRangeError); fail('timeout', __dirname, invalidArgTypeError);
fail('timeout', [], invalidRangeError); fail('timeout', [], invalidArgTypeError);
fail('timeout', {}, invalidRangeError); fail('timeout', {}, invalidArgTypeError);
fail('timeout', common.mustNotCall(), invalidRangeError); fail('timeout', common.mustNotCall(), invalidArgTypeError);
fail('timeout', NaN, invalidRangeError); fail('timeout', NaN, invalidRangeError);
fail('timeout', Infinity, invalidRangeError); fail('timeout', Infinity, invalidRangeError);
fail('timeout', 3.1, invalidRangeError); fail('timeout', 3.1, invalidRangeError);
@ -175,12 +175,12 @@ if (!common.isWindows) {
fail('maxBuffer', -1, invalidRangeError); fail('maxBuffer', -1, invalidRangeError);
fail('maxBuffer', NaN, invalidRangeError); fail('maxBuffer', NaN, invalidRangeError);
fail('maxBuffer', -Infinity, invalidRangeError); fail('maxBuffer', -Infinity, invalidRangeError);
fail('maxBuffer', true, invalidRangeError); fail('maxBuffer', true, invalidArgTypeError);
fail('maxBuffer', false, invalidRangeError); fail('maxBuffer', false, invalidArgTypeError);
fail('maxBuffer', __dirname, invalidRangeError); fail('maxBuffer', __dirname, invalidArgTypeError);
fail('maxBuffer', [], invalidRangeError); fail('maxBuffer', [], invalidArgTypeError);
fail('maxBuffer', {}, invalidRangeError); fail('maxBuffer', {}, invalidArgTypeError);
fail('maxBuffer', common.mustNotCall(), invalidRangeError); fail('maxBuffer', common.mustNotCall(), invalidArgTypeError);
} }
{ {