-
-
Notifications
You must be signed in to change notification settings - Fork 35.4k
zlib: fix node crashing on invalid options #13098
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
7d78533
c5440af
c5f18b1
e5c39bd
7b39725
f91e191
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -182,37 +182,37 @@ class Zlib extends Transform { | |
| this._finishFlushFlag = opts.finishFlush !== undefined ? | ||
| opts.finishFlush : constants.Z_FINISH; | ||
|
|
||
| if (opts.chunkSize) { | ||
| if (opts.chunkSize !== undefined) { | ||
| if (opts.chunkSize < constants.Z_MIN_CHUNK) { | ||
| throw new RangeError('Invalid chunk size: ' + opts.chunkSize); | ||
| } | ||
| } | ||
|
|
||
| if (opts.windowBits) { | ||
| if (opts.windowBits !== undefined) { | ||
| if (opts.windowBits < constants.Z_MIN_WINDOWBITS || | ||
| opts.windowBits > constants.Z_MAX_WINDOWBITS) { | ||
| throw new RangeError('Invalid windowBits: ' + opts.windowBits); | ||
| } | ||
| } | ||
|
|
||
| if (opts.level) { | ||
| if (opts.level !== undefined) { | ||
| if (opts.level < constants.Z_MIN_LEVEL || | ||
| opts.level > constants.Z_MAX_LEVEL) { | ||
| throw new RangeError('Invalid compression level: ' + opts.level); | ||
| } | ||
| } | ||
|
|
||
| if (opts.memLevel) { | ||
| if (opts.memLevel !== undefined) { | ||
| if (opts.memLevel < constants.Z_MIN_MEMLEVEL || | ||
| opts.memLevel > constants.Z_MAX_MEMLEVEL) { | ||
| throw new RangeError('Invalid memLevel: ' + opts.memLevel); | ||
| } | ||
| } | ||
|
|
||
| if (opts.strategy && isInvalidStrategy(opts.strategy)) | ||
| if (opts.strategy !== undefined && isInvalidStrategy(opts.strategy)) | ||
| throw new TypeError('Invalid strategy: ' + opts.strategy); | ||
|
|
||
| if (opts.dictionary) { | ||
| if (opts.dictionary !== undefined) { | ||
| if (!ArrayBuffer.isView(opts.dictionary)) { | ||
| throw new TypeError( | ||
| 'Invalid dictionary: it should be a Buffer, TypedArray, or DataView'); | ||
|
|
@@ -224,16 +224,28 @@ class Zlib extends Transform { | |
| this._hadError = false; | ||
|
|
||
| var level = constants.Z_DEFAULT_COMPRESSION; | ||
| if (typeof opts.level === 'number') level = opts.level; | ||
| if (typeof opts.level === 'number' && | ||
| Number.isFinite(opts.level)) { | ||
| level = opts.level; | ||
| } | ||
|
|
||
| var strategy = constants.Z_DEFAULT_STRATEGY; | ||
| if (typeof opts.strategy === 'number') strategy = opts.strategy; | ||
| if (typeof opts.strategy === 'number' && | ||
| Number.isFinite(opts.strategy)) { | ||
| strategy = opts.strategy; | ||
| } | ||
|
|
||
| var windowBits = constants.Z_DEFAULT_WINDOWBITS; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Couldn't these both just be ternaries?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They could, and I'd like them to be, but I just wrote these in a style consistent with the code above. How about me addressing this comment in a follow-up PR, together with some more refactoring like replacing most
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure |
||
| if (typeof opts.windowBits === 'number') windowBits = opts.windowBits; | ||
| if (typeof opts.windowBits === 'number' && | ||
| Number.isFinite(opts.windowBits)) { | ||
| windowBits = opts.windowBits; | ||
| } | ||
|
|
||
| var memLevel = constants.Z_DEFAULT_MEMLEVEL; | ||
| if (typeof opts.memLevel === 'number') memLevel = opts.memLevel; | ||
| if (typeof opts.memLevel === 'number' && | ||
| Number.isFinite(opts.memLevel)) { | ||
| memLevel = opts.memLevel; | ||
| } | ||
|
|
||
| this._handle.init(windowBits, | ||
| level, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,3 +11,27 @@ const zlib = require('zlib'); | |
| assert.throws(() => { | ||
| zlib.createDeflateRaw({ windowBits: 8 }); | ||
| }, /^Error: Init error$/); | ||
|
|
||
| // Regression tests for bugs in the validation logic. | ||
|
|
||
| assert.throws(() => { | ||
| zlib.createGzip({ chunkSize: 0 }); | ||
| }, /^RangeError: Invalid chunk size: 0$/); | ||
|
|
||
| assert.throws(() => { | ||
| zlib.createGzip({ windowBits: 0 }); | ||
| }, /^RangeError: Invalid windowBits: 0$/); | ||
|
|
||
| assert.throws(() => { | ||
| zlib.createGzip({ memLevel: 0 }); | ||
| }, /^RangeError: Invalid memLevel: 0$/); | ||
|
|
||
| { | ||
| const stream = zlib.createGzip({ level: NaN }); | ||
| assert.ok(!Number.isNaN(stream._level)); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we check if the values are |
||
| } | ||
|
|
||
| { | ||
| const stream = zlib.createGzip({ strategy: NaN }); | ||
| assert.ok(!Number.isNaN(stream._strategy)); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: isn't
Number.isFinite()sufficient here? I think it would be easier to read without thetypeofcheck.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is, thanks.