@@ -156,6 +156,56 @@ function flushCallback(level, strategy, callback) {
156156 }
157157}
158158
159+ // 1. Returns true for finite numbers
160+ // 2. Returns false for undefined and NaN
161+ // 3. Throws ERR_INVALID_ARG_TYPE for non-numbers
162+ // 4. Throws ERR_OUT_OF_RANGE for infinite numbers
163+ function checkFiniteNumber ( number , name ) {
164+ if ( Number . isFinite ( number ) ) {
165+ return true ; // is a valid number
166+ } else {
167+ // undefined or NaN
168+ if ( number === undefined || Number . isNaN ( number ) ) {
169+ return false ;
170+ }
171+
172+ // Other non-numbers
173+ if ( typeof number !== 'number' ) {
174+ const err = new errors . TypeError ( 'ERR_INVALID_ARG_TYPE' , name ,
175+ 'number' , number ) ;
176+ Error . captureStackTrace ( err , checkFiniteNumber ) ;
177+ throw err ;
178+ }
179+
180+ // Infinite numbers
181+ const err = new errors . RangeError ( 'ERR_OUT_OF_RANGE' , name ,
182+ 'a finite number' , number ) ;
183+ Error . captureStackTrace ( err , checkFiniteNumber ) ;
184+ throw err ;
185+ }
186+ }
187+
188+ function checkRanges ( number , name , lower , upper ) {
189+ if ( number < lower || number > upper ) {
190+ const err = new errors . RangeError (
191+ 'ERR_OUT_OF_RANGE' , name , `>= ${ lower } and <= ${ upper } ` , number ) ;
192+ Error . captureStackTrace ( err , checkRanges ) ;
193+ throw err ;
194+ }
195+ }
196+
197+ // 1. Returns number for finite numbers >= lower and <= upper
198+ // 2. Returns def for undefined and NaN
199+ // 3. Throws ERR_INVALID_ARG_TYPE for non-numbers
200+ // 4. Throws ERR_OUT_OF_RANGE for infinite numbers or numbers > upper or < lower
201+ function checkRangesOrGetDefault ( number , name , lower , upper , def ) {
202+ if ( checkFiniteNumber ( number , name , lower , upper ) ) {
203+ checkRanges ( number , name , lower , upper ) ;
204+ return number ;
205+ }
206+ return def ;
207+ }
208+
159209// the Zlib class they all inherit from
160210// This thing manages the queue of requests, and returns
161211// true or false if there is anything in the queue when
@@ -170,95 +220,53 @@ function Zlib(opts, mode) {
170220 var strategy = Z_DEFAULT_STRATEGY ;
171221 var dictionary ;
172222
173- if ( typeof mode !== 'number' )
174- throw new errors . TypeError ( 'ERR_INVALID_ARG_TYPE' , 'mode' , 'number' ) ;
175- if ( mode < DEFLATE || mode > UNZIP )
176- throw new errors . RangeError ( 'ERR_OUT_OF_RANGE' , ' mode' ) ;
223+ // The Zlib class is not exported to user land, the mode should only be
224+ // passed in by us.
225+ assert ( typeof mode === 'number' ) ;
226+ assert ( mode >= DEFLATE && mode <= UNZIP ) ;
177227
178228 if ( opts ) {
179229 chunkSize = opts . chunkSize ;
180- if ( chunkSize !== undefined && ! Number . isNaN ( chunkSize ) ) {
181- if ( chunkSize < Z_MIN_CHUNK || ! Number . isFinite ( chunkSize ) )
182- throw new errors . RangeError ( 'ERR_INVALID_OPT_VALUE' ,
183- 'chunkSize' ,
184- chunkSize ) ;
185- } else {
230+ if ( ! checkFiniteNumber ( chunkSize , 'options.chunkSize' ) ) {
186231 chunkSize = Z_DEFAULT_CHUNK ;
232+ } else if ( chunkSize < Z_MIN_CHUNK ) {
233+ throw new errors . RangeError ( 'ERR_OUT_OF_RANGE' , 'options.chunkSize' ,
234+ `>= ${ Z_MIN_CHUNK } ` , chunkSize ) ;
187235 }
188236
189- flush = opts . flush ;
190- if ( flush !== undefined && ! Number . isNaN ( flush ) ) {
191- if ( flush < Z_NO_FLUSH || flush > Z_BLOCK || ! Number . isFinite ( flush ) )
192- throw new errors . RangeError ( 'ERR_INVALID_OPT_VALUE' , 'flush' , flush ) ;
193- } else {
194- flush = Z_NO_FLUSH ;
195- }
237+ flush = checkRangesOrGetDefault (
238+ opts . flush , 'options.flush' ,
239+ Z_NO_FLUSH , Z_BLOCK , Z_NO_FLUSH ) ;
196240
197- finishFlush = opts . finishFlush ;
198- if ( finishFlush !== undefined && ! Number . isNaN ( finishFlush ) ) {
199- if ( finishFlush < Z_NO_FLUSH || finishFlush > Z_BLOCK ||
200- ! Number . isFinite ( finishFlush ) ) {
201- throw new errors . RangeError ( 'ERR_INVALID_OPT_VALUE' ,
202- 'finishFlush' ,
203- finishFlush ) ;
204- }
205- } else {
206- finishFlush = Z_FINISH ;
207- }
241+ finishFlush = checkRangesOrGetDefault (
242+ opts . finishFlush , 'options.finishFlush' ,
243+ Z_NO_FLUSH , Z_BLOCK , Z_FINISH ) ;
208244
209- windowBits = opts . windowBits ;
210- if ( windowBits !== undefined && ! Number . isNaN ( windowBits ) ) {
211- if ( windowBits < Z_MIN_WINDOWBITS || windowBits > Z_MAX_WINDOWBITS ||
212- ! Number . isFinite ( windowBits ) ) {
213- throw new errors . RangeError ( 'ERR_INVALID_OPT_VALUE' ,
214- 'windowBits' ,
215- windowBits ) ;
216- }
217- } else {
218- windowBits = Z_DEFAULT_WINDOWBITS ;
219- }
245+ windowBits = checkRangesOrGetDefault (
246+ opts . windowBits , 'options.windowBits' ,
247+ Z_MIN_WINDOWBITS , Z_MAX_WINDOWBITS , Z_DEFAULT_WINDOWBITS ) ;
220248
221- level = opts . level ;
222- if ( level !== undefined && ! Number . isNaN ( level ) ) {
223- if ( level < Z_MIN_LEVEL || level > Z_MAX_LEVEL ||
224- ! Number . isFinite ( level ) ) {
225- throw new errors . RangeError ( 'ERR_INVALID_OPT_VALUE' ,
226- 'level' , level ) ;
227- }
228- } else {
229- level = Z_DEFAULT_COMPRESSION ;
230- }
249+ level = checkRangesOrGetDefault (
250+ opts . level , 'options.level' ,
251+ Z_MIN_LEVEL , Z_MAX_LEVEL , Z_DEFAULT_COMPRESSION ) ;
231252
232- memLevel = opts . memLevel ;
233- if ( memLevel !== undefined && ! Number . isNaN ( memLevel ) ) {
234- if ( memLevel < Z_MIN_MEMLEVEL || memLevel > Z_MAX_MEMLEVEL ||
235- ! Number . isFinite ( memLevel ) ) {
236- throw new errors . RangeError ( 'ERR_INVALID_OPT_VALUE' ,
237- 'memLevel' , memLevel ) ;
238- }
239- } else {
240- memLevel = Z_DEFAULT_MEMLEVEL ;
241- }
253+ memLevel = checkRangesOrGetDefault (
254+ opts . memLevel , 'options.memLevel' ,
255+ Z_MIN_MEMLEVEL , Z_MAX_MEMLEVEL , Z_DEFAULT_MEMLEVEL ) ;
242256
243- strategy = opts . strategy ;
244- if ( strategy !== undefined && ! Number . isNaN ( strategy ) ) {
245- if ( strategy < Z_DEFAULT_STRATEGY || strategy > Z_FIXED ||
246- ! Number . isFinite ( strategy ) ) {
247- throw new errors . TypeError ( 'ERR_INVALID_OPT_VALUE' ,
248- 'strategy' , strategy ) ;
249- }
250- } else {
251- strategy = Z_DEFAULT_STRATEGY ;
252- }
257+ strategy = checkRangesOrGetDefault (
258+ opts . strategy , 'options.strategy' ,
259+ Z_DEFAULT_STRATEGY , Z_FIXED , Z_DEFAULT_STRATEGY ) ;
253260
254261 dictionary = opts . dictionary ;
255262 if ( dictionary !== undefined && ! isArrayBufferView ( dictionary ) ) {
256263 if ( isAnyArrayBuffer ( dictionary ) ) {
257264 dictionary = Buffer . from ( dictionary ) ;
258265 } else {
259- throw new errors . TypeError ( 'ERR_INVALID_OPT_VALUE' ,
260- 'dictionary' ,
261- dictionary ) ;
266+ throw new errors . TypeError (
267+ 'ERR_INVALID_ARG_TYPE' , 'options.dictionary' ,
268+ [ 'Buffer' , 'TypedArray' , 'DataView' , 'ArrayBuffer' ] ,
269+ dictionary ) ;
262270 }
263271 }
264272
@@ -310,14 +318,8 @@ Object.defineProperty(Zlib.prototype, '_closed', {
310318} ) ;
311319
312320Zlib . prototype . params = function params ( level , strategy , callback ) {
313- if ( level < Z_MIN_LEVEL || level > Z_MAX_LEVEL )
314- throw new errors . RangeError ( 'ERR_INVALID_ARG_VALUE' , 'level' , level ) ;
315-
316- if ( strategy !== undefined &&
317- ( strategy < Z_DEFAULT_STRATEGY || strategy > Z_FIXED ||
318- ! Number . isFinite ( strategy ) ) ) {
319- throw new errors . TypeError ( 'ERR_INVALID_ARG_VALUE' , 'strategy' , strategy ) ;
320- }
321+ checkRangesOrGetDefault ( level , 'level' , Z_MIN_LEVEL , Z_MAX_LEVEL ) ;
322+ checkRangesOrGetDefault ( strategy , 'strategy' , Z_DEFAULT_STRATEGY , Z_FIXED ) ;
321323
322324 if ( this . _level !== level || this . _strategy !== strategy ) {
323325 this . flush ( Z_SYNC_FLUSH ,
0 commit comments