Skip to content
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

lib: refactor to use validateFunction #37045

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions lib/assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ const { isError } = require('internal/util');

const errorCache = new SafeMap();
const CallTracker = require('internal/assert/calltracker');
const {
validateFunction,
} = require('internal/validators');

let isDeepEqual;
let isDeepStrictEqual;
Expand Down Expand Up @@ -693,9 +696,7 @@ function expectedException(actual, expected, message, fn) {
}

function getActual(fn) {
if (typeof fn !== 'function') {
throw new ERR_INVALID_ARG_TYPE('fn', 'Function', fn);
}
validateFunction(fn, 'fn');
try {
fn();
} catch (e) {
Expand Down
9 changes: 5 additions & 4 deletions lib/async_hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ const {
const {
ERR_ASYNC_CALLBACK,
ERR_ASYNC_TYPE,
ERR_INVALID_ARG_TYPE,
ERR_INVALID_ASYNC_ID
} = require('internal/errors').codes;
const { validateString } = require('internal/validators');
const {
validateFunction,
validateString,
} = require('internal/validators');
const internal_async_hooks = require('internal/async_hooks');

// Get functions
Expand Down Expand Up @@ -221,8 +223,7 @@ class AsyncResource {
}

bind(fn, thisArg = this) {
if (typeof fn !== 'function')
throw new ERR_INVALID_ARG_TYPE('fn', 'Function', fn);
validateFunction(fn, 'fn');
const ret =
FunctionPrototypeBind(
this.runInAsyncScope,
Expand Down
8 changes: 4 additions & 4 deletions lib/diagnostics_channel.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ const {
ERR_INVALID_ARG_TYPE,
}
} = require('internal/errors');
const {
validateFunction,
} = require('internal/validators');

const { triggerUncaughtException } = internalBinding('errors');

Expand All @@ -23,10 +26,7 @@ const { WeakReference } = internalBinding('util');
// TODO(qard): should there be a C++ channel interface?
class ActiveChannel {
subscribe(subscription) {
if (typeof subscription !== 'function') {
throw new ERR_INVALID_ARG_TYPE('subscription', ['function'],
subscription);
}
validateFunction(subscription, 'subscription');
ArrayPrototypePush(this._subscribers, subscription);
}

Expand Down
7 changes: 3 additions & 4 deletions lib/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ const {
} = require('internal/util/inspect');

const {
validateAbortSignal
validateAbortSignal,
validateFunction,
} = require('internal/validators');

const kCapture = Symbol('kCapture');
Expand Down Expand Up @@ -130,9 +131,7 @@ let defaultMaxListeners = 10;
let isEventTarget;

function checkListener(listener) {
if (typeof listener !== 'function') {
throw new ERR_INVALID_ARG_TYPE('listener', 'Function', listener);
}
validateFunction(listener, 'listener');
}

ObjectDefineProperty(EventEmitter, 'defaultMaxListeners', {
Expand Down
7 changes: 3 additions & 4 deletions lib/fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,9 @@ const {
validateBoolean,
validateBuffer,
validateCallback,
validateFunction,
validateInteger,
validateInt32
validateInt32,
} = require('internal/validators');
// 2 ** 32 - 1
const kMaxUserId = 4294967295;
Expand Down Expand Up @@ -1630,9 +1631,7 @@ function watchFile(filename, options, listener) {
...options
};

if (typeof listener !== 'function') {
throw new ERR_INVALID_ARG_TYPE('listener', 'Function', listener);
}
validateFunction(listener, 'listener');

stat = statWatchers.get(filename);

Expand Down
13 changes: 9 additions & 4 deletions lib/internal/dgram.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,14 @@ const {
const { codes } = require('internal/errors');
const { UDP } = internalBinding('udp_wrap');
const { guessHandleType } = internalBinding('util');
const { isInt32 } = require('internal/validators');
const {
isInt32,
validateFunction,
} = require('internal/validators');
const { UV_EINVAL } = internalBinding('uv');
const { ERR_INVALID_ARG_TYPE, ERR_SOCKET_BAD_TYPE } = codes;
const {
ERR_SOCKET_BAD_TYPE,
} = codes;
const kStateSymbol = Symbol('state symbol');
let dns; // Lazy load for startup performance.

Expand All @@ -31,8 +36,8 @@ function newHandle(type, lookup) {
}

lookup = dns.lookup;
} else if (typeof lookup !== 'function') {
throw new ERR_INVALID_ARG_TYPE('lookup', 'Function', lookup);
} else {
validateFunction(lookup, 'lookup');
}

if (type === 'udp4') {
Expand Down
43 changes: 14 additions & 29 deletions lib/internal/fs/streams.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ const {
ERR_METHOD_NOT_IMPLEMENTED,
} = require('internal/errors').codes;
const { deprecate } = require('internal/util');
const { validateInteger } = require('internal/validators');
const {
validateFunction,
validateInteger,
} = require('internal/validators');
const { errorOrDestroy } = require('internal/streams/destroy');
const fs = require('fs');
const { kRef, kUnref, FileHandle } = require('internal/fs/promises');
Expand Down Expand Up @@ -155,20 +158,9 @@ function ReadStream(path, options) {

this[kFs] = options.fs || fs;

if (typeof this[kFs].open !== 'function') {
throw new ERR_INVALID_ARG_TYPE('options.fs.open', 'function',
this[kFs].open);
}

if (typeof this[kFs].read !== 'function') {
throw new ERR_INVALID_ARG_TYPE('options.fs.read', 'function',
this[kFs].read);
}

if (typeof this[kFs].close !== 'function') {
throw new ERR_INVALID_ARG_TYPE('options.fs.close', 'function',
this[kFs].close);
}
validateFunction(this[kFs].open, 'options.fs.open');
validateFunction(this[kFs].read, 'options.fs.read');
validateFunction(this[kFs].close, 'options.fs.close');

options.autoDestroy = options.autoClose === undefined ?
true : options.autoClose;
Expand Down Expand Up @@ -310,30 +302,23 @@ function WriteStream(path, options) {
options.decodeStrings = true;

this[kFs] = options.fs || fs;
if (typeof this[kFs].open !== 'function') {
throw new ERR_INVALID_ARG_TYPE('options.fs.open', 'function',
this[kFs].open);
}

validateFunction(this[kFs].open, 'options.fs.open');

if (!this[kFs].write && !this[kFs].writev) {
throw new ERR_INVALID_ARG_TYPE('options.fs.write', 'function',
this[kFs].write);
}

if (this[kFs].write && typeof this[kFs].write !== 'function') {
throw new ERR_INVALID_ARG_TYPE('options.fs.write', 'function',
this[kFs].write);
if (this[kFs].write) {
validateFunction(this[kFs].write, 'options.fs.write');
}

if (this[kFs].writev && typeof this[kFs].writev !== 'function') {
throw new ERR_INVALID_ARG_TYPE('options.fs.writev', 'function',
this[kFs].writev);
if (this[kFs].writev) {
validateFunction(this[kFs].writev, 'options.fs.writev');
}

if (typeof this[kFs].close !== 'function') {
throw new ERR_INVALID_ARG_TYPE('options.fs.close', 'function',
this[kFs].close);
}
validateFunction(this[kFs].close, 'options.fs.close');

// It's enough to override either, in which case only one will be used.
if (!this[kFs].write) {
Expand Down
12 changes: 5 additions & 7 deletions lib/internal/process/task_queues.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ const {
emitDestroy,
symbols: { async_id_symbol, trigger_async_id_symbol }
} = require('internal/async_hooks');
const {
ERR_INVALID_ARG_TYPE
} = require('internal/errors').codes;
const FixedQueue = require('internal/fixed_queue');

const { validateCallback } = require('internal/validators');
const {
validateCallback,
validateFunction,
} = require('internal/validators');

// *Must* match Environment::TickInfo::Fields in src/env.h.
const kHasTickScheduled = 0;
Expand Down Expand Up @@ -154,9 +154,7 @@ function runMicrotask() {
}

function queueMicrotask(callback) {
if (typeof callback !== 'function') {
throw new ERR_INVALID_ARG_TYPE('callback', 'function', callback);
}
validateFunction(callback, 'callback');

const asyncResource = createMicrotaskResource();
asyncResource.callback = callback;
Expand Down
6 changes: 4 additions & 2 deletions lib/internal/quic/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ const {
const {
validateBoolean,
validateBuffer,
validateFunction,
validateInteger,
validateObject,
validatePort,
Expand Down Expand Up @@ -175,8 +176,9 @@ function validateCloseCode(code) {
}

function validateLookup(lookup) {
if (lookup && typeof lookup !== 'function')
throw new ERR_INVALID_ARG_TYPE('options.lookup', 'function', lookup);
if (lookup) {
validateFunction(lookup, 'options.lookup');
}
}

function validatePreferredAddress(address) {
Expand Down
7 changes: 4 additions & 3 deletions lib/internal/streams/end-of-stream.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ const {
ERR_STREAM_PREMATURE_CLOSE
} = require('internal/errors').codes;
const { once } = require('internal/util');
const {
validateFunction,
} = require('internal/validators');

function isSocket(stream) {
return (
Expand Down Expand Up @@ -68,9 +71,7 @@ function eos(stream, options, callback) {
} else if (typeof options !== 'object') {
throw new ERR_INVALID_ARG_TYPE('options', 'object', options);
}
if (typeof callback !== 'function') {
throw new ERR_INVALID_ARG_TYPE('callback', 'function', callback);
}
validateFunction(callback, 'callback');

callback = once(callback);

Expand Down
6 changes: 6 additions & 0 deletions lib/internal/validators.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,11 @@ const validateAbortSignal = hideStackFrames((signal, name) => {
}
});

const validateFunction = hideStackFrames((value, name) => {
if (typeof value !== 'function')
throw new ERR_INVALID_ARG_TYPE(name, 'Function', value);
});

module.exports = {
isInt32,
isUint32,
Expand All @@ -236,6 +241,7 @@ module.exports = {
validateBoolean,
validateBuffer,
validateEncoding,
validateFunction,
validateInt32,
validateInteger,
validateNumber,
Expand Down
10 changes: 3 additions & 7 deletions lib/internal/vm/module.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ const {
} = require('internal/errors').codes;
const {
validateBoolean,
validateFunction,
validateInt32,
validateUint32,
validateString,
Expand Down Expand Up @@ -187,9 +188,7 @@ class Module {
if (this[kWrap] === undefined) {
throw new ERR_VM_MODULE_NOT_MODULE();
}
if (typeof linker !== 'function') {
throw new ERR_INVALID_ARG_TYPE('linker', 'function', linker);
}
validateFunction(linker, 'linker');
if (this.status === 'linked') {
throw new ERR_VM_MODULE_ALREADY_LINKED();
}
Expand Down Expand Up @@ -407,10 +406,7 @@ class SyntheticModule extends Module {
}
});
}
if (typeof evaluateCallback !== 'function') {
throw new ERR_INVALID_ARG_TYPE('evaluateCallback', 'function',
evaluateCallback);
}
validateFunction(evaluateCallback, 'evaluateCallback');

if (typeof options !== 'object' || options === null) {
throw new ERR_INVALID_ARG_TYPE('options', 'Object', options);
Expand Down
9 changes: 5 additions & 4 deletions lib/perf_hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,10 @@ const {
kHandle,
} = require('internal/histogram');

const { validateCallback } = require('internal/validators');
const {
validateCallback,
validateFunction,
} = require('internal/validators');

const { setImmediate } = require('timers');
const kCallback = Symbol('callback');
Expand Down Expand Up @@ -463,9 +466,7 @@ class Performance {
}

timerify(fn) {
if (typeof fn !== 'function') {
throw new ERR_INVALID_ARG_TYPE('fn', 'Function', fn);
}
validateFunction(fn, 'fn');
if (fn[kTimerified])
return fn[kTimerified];
const ret = timerify(fn, fn.length);
Expand Down
8 changes: 6 additions & 2 deletions lib/repl.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ const {
} = internalBinding('contextify');

const history = require('internal/repl/history');
const {
validateFunction,
} = require('internal/validators');

let nextREPLResourceNumber = 1;
// This prevents v8 code cache from getting confused and using a different
// cache from a resource of the same name
Expand Down Expand Up @@ -1432,8 +1436,8 @@ REPLServer.prototype.completeOnEditorMode = (callback) => (err, results) => {
REPLServer.prototype.defineCommand = function(keyword, cmd) {
if (typeof cmd === 'function') {
cmd = { action: cmd };
} else if (typeof cmd.action !== 'function') {
throw new ERR_INVALID_ARG_TYPE('cmd.action', 'Function', cmd.action);
} else {
validateFunction(cmd.action, 'cmd.action');
}
this.commands[keyword] = cmd;
};
Expand Down
6 changes: 4 additions & 2 deletions lib/zlib.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ const {
kMaxLength
} = require('buffer');
const { owner_symbol } = require('internal/async_hooks').symbols;
const {
validateFunction,
} = require('internal/validators');

const kFlushFlag = Symbol('kFlushFlag');
const kError = Symbol('kError');
Expand Down Expand Up @@ -107,8 +110,7 @@ for (const ckey of ObjectKeys(codes)) {
}

function zlibBuffer(engine, buffer, callback) {
if (typeof callback !== 'function')
throw new ERR_INVALID_ARG_TYPE('callback', 'function', callback);
validateFunction(callback, 'callback');
// Streams do not support non-Buffer ArrayBufferViews yet. Convert it to a
// Buffer without copying.
if (isArrayBufferView(buffer) &&
Expand Down