diff --git a/lib/internal/validators.js b/lib/internal/validators.js index 68ba56cf6a5b20..56f561212645f2 100644 --- a/lib/internal/validators.js +++ b/lib/internal/validators.js @@ -7,6 +7,7 @@ const { ArrayPrototypeIncludes, ArrayPrototypeJoin, ArrayPrototypeMap, + NumberIsFinite, NumberIsInteger, NumberIsNaN, NumberMAX_SAFE_INTEGER, @@ -567,6 +568,46 @@ const validateLinkHeaderValue = hideStackFrames((hints) => { ); }); +// 1. Returns false for undefined and NaN +// 2. Returns true for finite numbers +// 3. Throws ERR_INVALID_ARG_TYPE for non-numbers +// 4. Throws ERR_OUT_OF_RANGE for infinite numbers +const validateFiniteNumber = hideStackFrames((number, name) => { + // Common case + if (number === undefined) { + return false; + } + + if (NumberIsFinite(number)) { + return true; // Is a valid number + } + + if (NumberIsNaN(number)) { + return false; + } + + validateNumber(number, name); + + // Infinite numbers + throw new ERR_OUT_OF_RANGE(name, 'a finite number', number); +}); + +// 1. Returns def for number when it's undefined or NaN +// 2. Returns number for finite numbers >= lower and <= upper +// 3. Throws ERR_INVALID_ARG_TYPE for non-numbers +// 4. Throws ERR_OUT_OF_RANGE for infinite numbers or numbers > upper or < lower +const checkRangesOrGetDefault = hideStackFrames( + (number, name, lower, upper, def) => { + if (!validateFiniteNumber(number, name)) { + return def; + } + if (number < lower || number > upper) { + throw new ERR_OUT_OF_RANGE(name, `>= ${lower} and <= ${upper}`, number); + } + return number; + }, +); + module.exports = { isInt32, isUint32, @@ -601,4 +642,6 @@ module.exports = { validateAbortSignal, validateLinkHeaderValue, validateInternalField, + validateFiniteNumber, + checkRangesOrGetDefault, }; diff --git a/lib/zlib.js b/lib/zlib.js index 1a00ea59b484a6..a2c092f1037261 100644 --- a/lib/zlib.js +++ b/lib/zlib.js @@ -28,7 +28,6 @@ const { ArrayPrototypePush, FunctionPrototypeBind, MathMaxApply, - NumberIsFinite, NumberIsNaN, ObjectDefineProperties, ObjectDefineProperty, @@ -51,7 +50,6 @@ const { ERR_ZLIB_INITIALIZATION_FAILED, }, genericNodeError, - hideStackFrames, } = require('internal/errors'); const { Transform, finished } = require('stream'); const { @@ -71,9 +69,10 @@ const { } = require('buffer'); const { owner_symbol } = require('internal/async_hooks').symbols; const { + checkRangesOrGetDefault, validateFunction, - validateNumber, validateUint32, + validateFiniteNumber, } = require('internal/validators'); const kFlushFlag = Symbol('kFlushFlag'); @@ -195,47 +194,6 @@ function zlibOnError(message, errno, code) { self[kError] = error; } -// 1. Returns false for undefined and NaN -// 2. Returns true for finite numbers -// 3. Throws ERR_INVALID_ARG_TYPE for non-numbers -// 4. Throws ERR_OUT_OF_RANGE for infinite numbers -const checkFiniteNumber = hideStackFrames((number, name) => { - // Common case - if (number === undefined) { - return false; - } - - if (NumberIsFinite(number)) { - return true; // Is a valid number - } - - if (NumberIsNaN(number)) { - return false; - } - - validateNumber.withoutStackTrace(number, name); - - // Infinite numbers - throw new ERR_OUT_OF_RANGE.HideStackFramesError(name, 'a finite number', number); -}); - -// 1. Returns def for number when it's undefined or NaN -// 2. Returns number for finite numbers >= lower and <= upper -// 3. Throws ERR_INVALID_ARG_TYPE for non-numbers -// 4. Throws ERR_OUT_OF_RANGE for infinite numbers or numbers > upper or < lower -const checkRangesOrGetDefault = hideStackFrames( - (number, name, lower, upper, def) => { - if (!checkFiniteNumber.withoutStackTrace(number, name)) { - return def; - } - if (number < lower || number > upper) { - throw new ERR_OUT_OF_RANGE.HideStackFramesError(name, - `>= ${lower} and <= ${upper}`, number); - } - return number; - }, -); - const FLUSH_BOUND = [ [ Z_NO_FLUSH, Z_BLOCK ], [ BROTLI_OPERATION_PROCESS, BROTLI_OPERATION_EMIT_METADATA ], @@ -261,7 +219,7 @@ function ZlibBase(opts, mode, handle, { flush, finishFlush, fullFlush }) { if (opts) { chunkSize = opts.chunkSize; - if (!checkFiniteNumber(chunkSize, 'options.chunkSize')) { + if (!validateFiniteNumber(chunkSize, 'options.chunkSize')) { chunkSize = Z_DEFAULT_CHUNK; } else if (chunkSize < Z_MIN_CHUNK) { throw new ERR_OUT_OF_RANGE('options.chunkSize',