@@ -156,6 +156,52 @@ function flushCallback(level, strategy, callback) {
156
156
}
157
157
}
158
158
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
+
159
205
// the Zlib class they all inherit from
160
206
// This thing manages the queue of requests, and returns
161
207
// true or false if there is anything in the queue when
@@ -170,95 +216,53 @@ function Zlib(opts, mode) {
170
216
var strategy = Z_DEFAULT_STRATEGY ;
171
217
var dictionary ;
172
218
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 ) ;
177
223
178
224
if ( opts ) {
179
225
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' ) ) {
186
227
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 ) ;
187
231
}
188
232
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 ) ;
196
236
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 ) ;
208
240
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 ) ;
220
244
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 ) ;
231
248
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 ) ;
242
252
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 ) ;
253
256
254
257
dictionary = opts . dictionary ;
255
258
if ( dictionary !== undefined && ! isArrayBufferView ( dictionary ) ) {
256
259
if ( isAnyArrayBuffer ( dictionary ) ) {
257
260
dictionary = Buffer . from ( dictionary ) ;
258
261
} 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 ) ;
262
266
}
263
267
}
264
268
@@ -310,14 +314,8 @@ Object.defineProperty(Zlib.prototype, '_closed', {
310
314
} ) ;
311
315
312
316
Zlib . 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 ) ;
321
319
322
320
if ( this . _level !== level || this . _strategy !== strategy ) {
323
321
this . flush ( Z_SYNC_FLUSH ,
0 commit comments