From 3f729aac20a68e0ca3733c492ddafb01add51d3d Mon Sep 17 00:00:00 2001 From: Jon Moss Date: Thu, 2 Aug 2018 18:51:02 -0400 Subject: [PATCH] lib: extract validateString validator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pulls out a common argument validator to `internal/validators` PR-URL: https://github.com/nodejs/node/pull/22101 Reviewed-By: Joyee Cheung Reviewed-By: Michaƫl Zasso Reviewed-By: Trivikram Kamat Reviewed-By: Colin Ihrig Reviewed-By: Anatoli Papirovski Reviewed-By: Luigi Pinca Reviewed-By: James M Snell --- lib/_http_outgoing.js | 14 ++++---------- lib/_tls_wrap.js | 5 ++--- lib/async_hooks.js | 5 ++--- lib/buffer.js | 5 ++--- lib/child_process.js | 4 ++-- lib/dgram.js | 11 +++-------- lib/dns.js | 6 +++--- lib/inspector.js | 5 ++--- lib/internal/child_process.js | 5 ++--- lib/internal/crypto/cipher.js | 9 +++------ lib/internal/crypto/diffiehellman.js | 9 +++------ lib/internal/crypto/hash.js | 7 +++---- lib/internal/crypto/sig.js | 8 +++----- lib/internal/crypto/util.js | 5 ++--- lib/internal/http2/compat.js | 25 +++++++------------------ lib/internal/validators.js | 8 +++++++- lib/net.js | 6 ++---- 17 files changed, 52 insertions(+), 85 deletions(-) diff --git a/lib/_http_outgoing.js b/lib/_http_outgoing.js index d150a9d93cdf88..7fe4e2133b46a5 100644 --- a/lib/_http_outgoing.js +++ b/lib/_http_outgoing.js @@ -45,6 +45,7 @@ const { ERR_STREAM_CANNOT_PIPE, ERR_STREAM_WRITE_AFTER_END } = require('internal/errors').codes; +const { validateString } = require('internal/validators'); const { CRLF, debug } = common; @@ -480,9 +481,7 @@ OutgoingMessage.prototype.setHeader = function setHeader(name, value) { OutgoingMessage.prototype.getHeader = function getHeader(name) { - if (typeof name !== 'string') { - throw new ERR_INVALID_ARG_TYPE('name', 'string', name); - } + validateString(name, 'name'); const headers = this[outHeadersKey]; if (headers === null) @@ -516,19 +515,14 @@ OutgoingMessage.prototype.getHeaders = function getHeaders() { OutgoingMessage.prototype.hasHeader = function hasHeader(name) { - if (typeof name !== 'string') { - throw new ERR_INVALID_ARG_TYPE('name', 'string', name); - } - + validateString(name, 'name'); return this[outHeadersKey] !== null && !!this[outHeadersKey][name.toLowerCase()]; }; OutgoingMessage.prototype.removeHeader = function removeHeader(name) { - if (typeof name !== 'string') { - throw new ERR_INVALID_ARG_TYPE('name', 'string', name); - } + validateString(name, 'name'); if (this._header) { throw new ERR_HTTP_HEADERS_SENT('remove'); diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js index 775bdbefdb201e..57eb3e72872232 100644 --- a/lib/_tls_wrap.js +++ b/lib/_tls_wrap.js @@ -50,6 +50,7 @@ const { ERR_TLS_SESSION_ATTACK, ERR_TLS_SNI_FROM_SERVER } = require('internal/errors').codes; +const { validateString } = require('internal/validators'); const kConnectOptions = Symbol('connect-options'); const kDisableRenegotiation = Symbol('disable-renegotiation'); const kErrorEmitted = Symbol('error-emitted'); @@ -645,9 +646,7 @@ TLSSocket.prototype._start = function() { }; TLSSocket.prototype.setServername = function(name) { - if (typeof name !== 'string') { - throw new ERR_INVALID_ARG_TYPE('name', 'string', name); - } + validateString(name, 'name'); if (this._tlsOptions.isServer) { throw new ERR_TLS_SNI_FROM_SERVER(); diff --git a/lib/async_hooks.js b/lib/async_hooks.js index 345b003e54997b..7d160707415a44 100644 --- a/lib/async_hooks.js +++ b/lib/async_hooks.js @@ -2,9 +2,9 @@ const { ERR_ASYNC_CALLBACK, - ERR_INVALID_ARG_TYPE, ERR_INVALID_ASYNC_ID } = require('internal/errors').codes; +const { validateString } = require('internal/validators'); const internal_async_hooks = require('internal/async_hooks'); // Get functions @@ -140,8 +140,7 @@ function showEmitBeforeAfterWarning() { class AsyncResource { constructor(type, opts = {}) { - if (typeof type !== 'string') - throw new ERR_INVALID_ARG_TYPE('type', 'string', type); + validateString(type, 'type'); if (typeof opts === 'number') { opts = { triggerAsyncId: opts, requireManualDestroy: false }; diff --git a/lib/buffer.js b/lib/buffer.js index 7902fc6fde5dcc..398357c6845568 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -69,6 +69,7 @@ const { ERR_NO_LONGER_SUPPORTED, ERR_UNKNOWN_ENCODING } = require('internal/errors').codes; +const { validateString } = require('internal/validators'); const internalBuffer = require('internal/buffer'); @@ -841,9 +842,7 @@ function _fill(buf, val, start, end, encoding) { const normalizedEncoding = normalizeEncoding(encoding); if (normalizedEncoding === undefined) { - if (typeof encoding !== 'string') { - throw new ERR_INVALID_ARG_TYPE('encoding', 'string', encoding); - } + validateString(encoding, 'encoding'); throw new ERR_UNKNOWN_ENCODING(encoding); } diff --git a/lib/child_process.js b/lib/child_process.js index d816bbf5f091a5..5452effbabaa91 100644 --- a/lib/child_process.js +++ b/lib/child_process.js @@ -37,6 +37,7 @@ const { ERR_INVALID_OPT_VALUE, ERR_OUT_OF_RANGE } = require('internal/errors').codes; +const { validateString } = require('internal/validators'); const child_process = require('internal/child_process'); const { _validateStdio, @@ -390,8 +391,7 @@ function _convertCustomFds(options) { } function normalizeSpawnArguments(file, args, options) { - if (typeof file !== 'string') - throw new ERR_INVALID_ARG_TYPE('file', 'string', file); + validateString(file, 'file'); if (file.length === 0) throw new ERR_INVALID_ARG_VALUE('file', file, 'cannot be empty'); diff --git a/lib/dgram.js b/lib/dgram.js index 292f7daf876c43..2db146886575e8 100644 --- a/lib/dgram.js +++ b/lib/dgram.js @@ -37,6 +37,7 @@ const { ERR_SOCKET_CANNOT_SEND, ERR_SOCKET_DGRAM_NOT_RUNNING } = errors.codes; +const { validateString } = require('internal/validators'); const { Buffer } = require('buffer'); const util = require('util'); const { isUint8Array } = require('internal/util/types'); @@ -269,9 +270,7 @@ Socket.prototype.sendto = function(buffer, throw new ERR_INVALID_ARG_TYPE('port', 'number', port); } - if (typeof address !== 'string') { - throw new ERR_INVALID_ARG_TYPE('address', 'string', address); - } + validateString(address, 'address'); this.send(buffer, offset, length, port, address, callback); }; @@ -570,11 +569,7 @@ Socket.prototype.setMulticastLoopback = function(arg) { Socket.prototype.setMulticastInterface = function(interfaceAddress) { healthCheck(this); - - if (typeof interfaceAddress !== 'string') { - throw new ERR_INVALID_ARG_TYPE( - 'interfaceAddress', 'string', interfaceAddress); - } + validateString(interfaceAddress, 'interfaceAddress'); const err = this[kStateSymbol].handle.setMulticastInterface(interfaceAddress); if (err) { diff --git a/lib/dns.js b/lib/dns.js index 195a0189504bc9..7059ed91ddccc7 100644 --- a/lib/dns.js +++ b/lib/dns.js @@ -39,6 +39,7 @@ const { ERR_MISSING_ARGS, ERR_SOCKET_BAD_PORT } = errors.codes; +const { validateString } = require('internal/validators'); const { GetAddrInfoReqWrap, @@ -206,9 +207,8 @@ function resolver(bindingName) { callback = arguments[2]; } - if (typeof name !== 'string') { - throw new ERR_INVALID_ARG_TYPE('name', 'string', name); - } else if (typeof callback !== 'function') { + validateString(name, 'name'); + if (typeof callback !== 'function') { throw new ERR_INVALID_CALLBACK(); } diff --git a/lib/inspector.js b/lib/inspector.js index f4e365b774be79..8827158757e126 100644 --- a/lib/inspector.js +++ b/lib/inspector.js @@ -9,6 +9,7 @@ const { ERR_INVALID_ARG_TYPE, ERR_INVALID_CALLBACK } = require('internal/errors').codes; +const { validateString } = require('internal/validators'); const util = require('util'); const { Connection, open, url } = process.binding('inspector'); const { originalConsole } = require('internal/process/per_thread'); @@ -58,9 +59,7 @@ class Session extends EventEmitter { } post(method, params, callback) { - if (typeof method !== 'string') { - throw new ERR_INVALID_ARG_TYPE('method', 'string', method); - } + validateString(method, 'method'); if (!callback && util.isFunction(params)) { callback = params; params = null; diff --git a/lib/internal/child_process.js b/lib/internal/child_process.js index d22009505a4574..f0a54ab6a18a74 100644 --- a/lib/internal/child_process.js +++ b/lib/internal/child_process.js @@ -14,6 +14,7 @@ const { ERR_MISSING_ARGS } } = require('internal/errors'); +const { validateString } = require('internal/validators'); const EventEmitter = require('events'); const net = require('net'); const dgram = require('dgram'); @@ -317,9 +318,7 @@ ChildProcess.prototype.spawn = function(options) { options.envPairs.push('NODE_CHANNEL_FD=' + ipcFd); } - if (typeof options.file !== 'string') { - throw new ERR_INVALID_ARG_TYPE('options.file', 'string', options.file); - } + validateString(options.file, 'options.file'); this.spawnfile = options.file; if (Array.isArray(options.args)) diff --git a/lib/internal/crypto/cipher.js b/lib/internal/crypto/cipher.js index 4a523473804643..fc8ee88742d135 100644 --- a/lib/internal/crypto/cipher.js +++ b/lib/internal/crypto/cipher.js @@ -10,6 +10,7 @@ const { ERR_INVALID_ARG_TYPE, ERR_INVALID_OPT_VALUE } = require('internal/errors').codes; +const { validateString } = require('internal/validators'); const { getDefaultEncoding, @@ -83,9 +84,7 @@ function createCipherBase(cipher, credential, options, decipher, iv) { } function createCipher(cipher, password, options, decipher) { - if (typeof cipher !== 'string') - throw new ERR_INVALID_ARG_TYPE('cipher', 'string', cipher); - + validateString(cipher, 'cipher'); password = toBuf(password); if (!isArrayBufferView(password)) { throw new ERR_INVALID_ARG_TYPE( @@ -99,9 +98,7 @@ function createCipher(cipher, password, options, decipher) { } function createCipherWithIV(cipher, key, options, decipher, iv) { - if (typeof cipher !== 'string') - throw new ERR_INVALID_ARG_TYPE('cipher', 'string', cipher); - + validateString(cipher, 'cipher'); key = toBuf(key); if (!isArrayBufferView(key)) { throw new ERR_INVALID_ARG_TYPE( diff --git a/lib/internal/crypto/diffiehellman.js b/lib/internal/crypto/diffiehellman.js index dad7a903b26a5e..1daf5df905f8ac 100644 --- a/lib/internal/crypto/diffiehellman.js +++ b/lib/internal/crypto/diffiehellman.js @@ -6,6 +6,7 @@ const { ERR_CRYPTO_ECDH_INVALID_PUBLIC_KEY, ERR_INVALID_ARG_TYPE } = require('internal/errors').codes; +const { validateString } = require('internal/validators'); const { isArrayBufferView } = require('internal/util/types'); const { getDefaultEncoding, @@ -167,9 +168,7 @@ function ECDH(curve) { if (!(this instanceof ECDH)) return new ECDH(curve); - if (typeof curve !== 'string') - throw new ERR_INVALID_ARG_TYPE('curve', 'string', curve); - + validateString(curve, 'curve'); this._handle = new _ECDH(curve); } @@ -200,9 +199,7 @@ ECDH.convertKey = function convertKey(key, curve, inEnc, outEnc, format) { ); } - if (typeof curve !== 'string') { - throw new ERR_INVALID_ARG_TYPE('curve', 'string', curve); - } + validateString(curve, 'curve'); const encoding = getDefaultEncoding(); inEnc = inEnc || encoding; diff --git a/lib/internal/crypto/hash.js b/lib/internal/crypto/hash.js index d172a6a3c8e90e..7127d4d7efb17a 100644 --- a/lib/internal/crypto/hash.js +++ b/lib/internal/crypto/hash.js @@ -18,6 +18,7 @@ const { ERR_CRYPTO_HASH_UPDATE_FAILED, ERR_INVALID_ARG_TYPE } = require('internal/errors').codes; +const { validateString } = require('internal/validators'); const { inherits } = require('util'); const { normalizeEncoding } = require('internal/util'); const { isArrayBufferView } = require('internal/util/types'); @@ -28,8 +29,7 @@ const kFinalized = Symbol('finalized'); function Hash(algorithm, options) { if (!(this instanceof Hash)) return new Hash(algorithm, options); - if (typeof algorithm !== 'string') - throw new ERR_INVALID_ARG_TYPE('algorithm', 'string', algorithm); + validateString(algorithm, 'algorithm'); this._handle = new _Hash(algorithm); this[kState] = { [kFinalized]: false @@ -83,8 +83,7 @@ Hash.prototype.digest = function digest(outputEncoding) { function Hmac(hmac, key, options) { if (!(this instanceof Hmac)) return new Hmac(hmac, key, options); - if (typeof hmac !== 'string') - throw new ERR_INVALID_ARG_TYPE('hmac', 'string', hmac); + validateString(hmac, 'hmac'); if (typeof key !== 'string' && !isArrayBufferView(key)) { throw new ERR_INVALID_ARG_TYPE('key', ['string', 'TypedArray', 'DataView'], key); diff --git a/lib/internal/crypto/sig.js b/lib/internal/crypto/sig.js index 8aff7354735404..ebd852402eb328 100644 --- a/lib/internal/crypto/sig.js +++ b/lib/internal/crypto/sig.js @@ -2,9 +2,9 @@ const { ERR_CRYPTO_SIGN_KEY_REQUIRED, - ERR_INVALID_ARG_TYPE, ERR_INVALID_OPT_VALUE } = require('internal/errors').codes; +const { validateString } = require('internal/validators'); const { Sign: _Sign, Verify: _Verify @@ -24,8 +24,7 @@ const { inherits } = require('util'); function Sign(algorithm, options) { if (!(this instanceof Sign)) return new Sign(algorithm, options); - if (typeof algorithm !== 'string') - throw new ERR_INVALID_ARG_TYPE('algorithm', 'string', algorithm); + validateString(algorithm, 'algorithm'); this._handle = new _Sign(); this._handle.init(algorithm); @@ -94,8 +93,7 @@ Sign.prototype.sign = function sign(options, encoding) { function Verify(algorithm, options) { if (!(this instanceof Verify)) return new Verify(algorithm, options); - if (typeof algorithm !== 'string') - throw new ERR_INVALID_ARG_TYPE('algorithm', 'string', algorithm); + validateString(algorithm, 'algorithm'); this._handle = new _Verify(); this._handle.init(algorithm); diff --git a/lib/internal/crypto/util.js b/lib/internal/crypto/util.js index 32c9eb7f6a12b6..9283e80df4e24a 100644 --- a/lib/internal/crypto/util.js +++ b/lib/internal/crypto/util.js @@ -17,6 +17,7 @@ const { ERR_CRYPTO_TIMING_SAFE_EQUAL_LENGTH, ERR_INVALID_ARG_TYPE, } = require('internal/errors').codes; +const { validateString } = require('internal/validators'); const { Buffer } = require('buffer'); const { cachedResult, @@ -53,9 +54,7 @@ const getHashes = cachedResult(() => filterDuplicateStrings(_getHashes())); const getCurves = cachedResult(() => filterDuplicateStrings(_getCurves())); function setEngine(id, flags) { - if (typeof id !== 'string') - throw new ERR_INVALID_ARG_TYPE('id', 'string', id); - + validateString(id, 'id'); if (flags && typeof flags !== 'number') throw new ERR_INVALID_ARG_TYPE('flags', 'number', flags); flags = flags >>> 0; diff --git a/lib/internal/http2/compat.js b/lib/internal/http2/compat.js index 4a006107b2fcea..0e9c2832cc7b1f 100644 --- a/lib/internal/http2/compat.js +++ b/lib/internal/http2/compat.js @@ -12,11 +12,11 @@ const { ERR_HTTP2_NO_SOCKET_MANIPULATION, ERR_HTTP2_PSEUDOHEADER_NOT_ALLOWED, ERR_HTTP2_STATUS_INVALID, - ERR_INVALID_ARG_TYPE, ERR_INVALID_ARG_VALUE, ERR_INVALID_CALLBACK, ERR_INVALID_HTTP_TOKEN } = require('internal/errors').codes; +const { validateString } = require('internal/validators'); const { kSocket } = require('internal/http2/util'); const kBeginSend = Symbol('begin-send'); @@ -342,8 +342,7 @@ class Http2ServerRequest extends Readable { } set method(method) { - if (typeof method !== 'string') - throw new ERR_INVALID_ARG_TYPE('method', 'string', method); + validateString(method, 'method'); if (method.trim() === '') throw new ERR_INVALID_ARG_VALUE('method', method); @@ -482,9 +481,7 @@ class Http2ServerResponse extends Stream { } setTrailer(name, value) { - if (typeof name !== 'string') - throw new ERR_INVALID_ARG_TYPE('name', 'string', name); - + validateString(name, 'name'); name = name.trim().toLowerCase(); assertValidHeader(name, value); this[kTrailers][name] = value; @@ -500,9 +497,7 @@ class Http2ServerResponse extends Stream { } getHeader(name) { - if (typeof name !== 'string') - throw new ERR_INVALID_ARG_TYPE('name', 'string', name); - + validateString(name, 'name'); name = name.trim().toLowerCase(); return this[kHeaders][name]; } @@ -516,17 +511,13 @@ class Http2ServerResponse extends Stream { } hasHeader(name) { - if (typeof name !== 'string') - throw new ERR_INVALID_ARG_TYPE('name', 'string', name); - + validateString(name, 'name'); name = name.trim().toLowerCase(); return Object.prototype.hasOwnProperty.call(this[kHeaders], name); } removeHeader(name) { - if (typeof name !== 'string') - throw new ERR_INVALID_ARG_TYPE('name', 'string', name); - + validateString(name, 'name'); if (this[kStream].headersSent) throw new ERR_HTTP2_HEADERS_SENT(); @@ -535,9 +526,7 @@ class Http2ServerResponse extends Stream { } setHeader(name, value) { - if (typeof name !== 'string') - throw new ERR_INVALID_ARG_TYPE('name', 'string', name); - + validateString(name, 'name'); if (this[kStream].headersSent) throw new ERR_HTTP2_HEADERS_SENT(); diff --git a/lib/internal/validators.js b/lib/internal/validators.js index ab8643b9af673c..85e69e61255d58 100644 --- a/lib/internal/validators.js +++ b/lib/internal/validators.js @@ -120,11 +120,17 @@ function validateUint32(value, name, positive) { return value; } +function validateString(value, name) { + if (typeof value !== 'string') + throw new ERR_INVALID_ARG_TYPE(name, 'string', value); +} + module.exports = { isInt32, isUint32, validateMode, validateInteger, validateInt32, - validateUint32 + validateUint32, + validateString }; diff --git a/lib/net.js b/lib/net.js index 889f28b0aa7042..4b19f6b6368641 100644 --- a/lib/net.js +++ b/lib/net.js @@ -75,7 +75,7 @@ const { ERR_SOCKET_BAD_PORT, ERR_SOCKET_CLOSED } = errors.codes; -const { validateInt32 } = require('internal/validators'); +const { validateInt32, validateString } = require('internal/validators'); const kLastWriteQueueSize = Symbol('lastWriteQueueSize'); // Lazy loaded to improve startup performance. @@ -980,9 +980,7 @@ Socket.prototype.connect = function(...args) { this.writable = true; if (pipe) { - if (typeof path !== 'string') { - throw new ERR_INVALID_ARG_TYPE('options.path', 'string', path); - } + validateString(path, 'options.path'); defaultTriggerAsyncIdScope( this[async_id_symbol], internalConnect, this, path );