@@ -156,6 +156,52 @@ function flushCallback(level, strategy, callback) {
156156 }
157157}
158158
159+ // 1. Returns false for undefined and NaN
160+ // 2. Returns true for finite numbers
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+ // Common case
165+ if ( number === undefined || Number . isNaN ( number ) ) {
166+ return false ;
167+ }
168+
169+ if ( Number . isFinite ( number ) ) {
170+ return true ; // is a valid number
171+ }
172+
173+ // Other non-numbers
174+ if ( typeof number !== 'number' ) {
175+ const err = new errors . TypeError ( 'ERR_INVALID_ARG_TYPE' , name ,
176+ 'number' , number ) ;
177+ Error . captureStackTrace ( err , checkFiniteNumber ) ;
178+ throw err ;
179+ }
180+
181+ // Infinite numbers
182+ const err = new errors . RangeError ( 'ERR_OUT_OF_RANGE' , name ,
183+ 'a finite number' , number ) ;
184+ Error . captureStackTrace ( err , checkFiniteNumber ) ;
185+ throw err ;
186+ }
187+
188+ // 1. Returns def for undefined and NaN
189+ // 2. Returns number for finite numbers >= lower and <= upper
190+ // 3. Throws ERR_INVALID_ARG_TYPE for non-numbers
191+ // 4. Throws ERR_OUT_OF_RANGE for infinite numbers or numbers > upper or < lower
192+ function checkRangesOrGetDefault ( number , name , lower , upper , def ) {
193+ if ( ! checkFiniteNumber ( number , name , lower , upper ) ) {
194+ return def ;
195+ }
196+ if ( number < lower || number > upper ) {
197+ const err = new errors . RangeError ( 'ERR_OUT_OF_RANGE' , name ,
198+ `>= ${ lower } and <= ${ upper } ` , number ) ;
199+ Error . captureStackTrace ( err , checkRangesOrGetDefault ) ;
200+ throw err ;
201+ }
202+ return number ;
203+ }
204+
159205// the Zlib class they all inherit from
160206// This thing manages the queue of requests, and returns
161207// true or false if there is anything in the queue when
@@ -170,95 +216,53 @@ function Zlib(opts, mode) {
170216 var strategy = Z_DEFAULT_STRATEGY ;
171217 var dictionary ;
172218
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' ) ;
219+ // The Zlib class is not exported to user land, the mode should only be
220+ // passed in by us.
221+ assert ( typeof mode === 'number' ) ;
222+ assert ( mode >= DEFLATE && mode <= UNZIP ) ;
177223
178224 if ( opts ) {
179225 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 {
226+ if ( ! checkFiniteNumber ( chunkSize , 'options.chunkSize' ) ) {
186227 chunkSize = Z_DEFAULT_CHUNK ;
228+ } else if ( chunkSize < Z_MIN_CHUNK ) {
229+ throw new errors . RangeError ( 'ERR_OUT_OF_RANGE' , 'options.chunkSize' ,
230+ `>= ${ Z_MIN_CHUNK } ` , chunkSize ) ;
187231 }
188232
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- }
233+ flush = checkRangesOrGetDefault (
234+ opts . flush , 'options.flush' ,
235+ Z_NO_FLUSH , Z_BLOCK , Z_NO_FLUSH ) ;
196236
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- }
237+ finishFlush = checkRangesOrGetDefault (
238+ opts . finishFlush , 'options.finishFlush' ,
239+ Z_NO_FLUSH , Z_BLOCK , Z_FINISH ) ;
208240
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- }
241+ windowBits = checkRangesOrGetDefault (
242+ opts . windowBits , 'options.windowBits' ,
243+ Z_MIN_WINDOWBITS , Z_MAX_WINDOWBITS , Z_DEFAULT_WINDOWBITS ) ;
220244
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- }
245+ level = checkRangesOrGetDefault (
246+ opts . level , 'options.level' ,
247+ Z_MIN_LEVEL , Z_MAX_LEVEL , Z_DEFAULT_COMPRESSION ) ;
231248
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- }
249+ memLevel = checkRangesOrGetDefault (
250+ opts . memLevel , 'options.memLevel' ,
251+ Z_MIN_MEMLEVEL , Z_MAX_MEMLEVEL , Z_DEFAULT_MEMLEVEL ) ;
242252
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- }
253+ strategy = checkRangesOrGetDefault (
254+ opts . strategy , 'options.strategy' ,
255+ Z_DEFAULT_STRATEGY , Z_FIXED , Z_DEFAULT_STRATEGY ) ;
253256
254257 dictionary = opts . dictionary ;
255258 if ( dictionary !== undefined && ! isArrayBufferView ( dictionary ) ) {
256259 if ( isAnyArrayBuffer ( dictionary ) ) {
257260 dictionary = Buffer . from ( dictionary ) ;
258261 } else {
259- throw new errors . TypeError ( 'ERR_INVALID_OPT_VALUE' ,
260- 'dictionary' ,
261- dictionary ) ;
262+ throw new errors . TypeError (
263+ 'ERR_INVALID_ARG_TYPE' , 'options.dictionary' ,
264+ [ 'Buffer' , 'TypedArray' , 'DataView' , 'ArrayBuffer' ] ,
265+ dictionary ) ;
262266 }
263267 }
264268
@@ -310,14 +314,8 @@ Object.defineProperty(Zlib.prototype, '_closed', {
310314} ) ;
311315
312316Zlib . 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- }
317+ checkRangesOrGetDefault ( level , 'level' , Z_MIN_LEVEL , Z_MAX_LEVEL ) ;
318+ checkRangesOrGetDefault ( strategy , 'strategy' , Z_DEFAULT_STRATEGY , Z_FIXED ) ;
321319
322320 if ( this . _level !== level || this . _strategy !== strategy ) {
323321 this . flush ( Z_SYNC_FLUSH ,
0 commit comments