zlib: fix windowBits validation to allow 0 for decompression mode
From the zlib v1.2.11 manual: > ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, > int windowBits)); > > ... > windowBits can also be zero to request that inflate use the window > size in the zlib header of the compressed stream. The current validation of windowBits in zlib.js doesn't check for this case. PR-URL: https://github.com/nodejs/node/pull/19686 Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
This commit is contained in:
parent
a6db6404ff
commit
7bc5151d5e
16
lib/zlib.js
16
lib/zlib.js
@ -251,9 +251,19 @@ function Zlib(opts, mode) {
|
||||
opts.finishFlush, 'options.finishFlush',
|
||||
Z_NO_FLUSH, Z_BLOCK, Z_FINISH);
|
||||
|
||||
windowBits = checkRangesOrGetDefault(
|
||||
opts.windowBits, 'options.windowBits',
|
||||
Z_MIN_WINDOWBITS, Z_MAX_WINDOWBITS, Z_DEFAULT_WINDOWBITS);
|
||||
// windowBits is special. On the compression side, 0 is an invalid value.
|
||||
// But on the decompression side, a value of 0 for windowBits tells zlib
|
||||
// to use the window size in the zlib header of the compressed stream.
|
||||
if ((opts.windowBits == null || opts.windowBits === 0) &&
|
||||
(mode === INFLATE ||
|
||||
mode === GUNZIP ||
|
||||
mode === UNZIP)) {
|
||||
windowBits = 0;
|
||||
} else {
|
||||
windowBits = checkRangesOrGetDefault(
|
||||
opts.windowBits, 'options.windowBits',
|
||||
Z_MIN_WINDOWBITS, Z_MAX_WINDOWBITS, Z_DEFAULT_WINDOWBITS);
|
||||
}
|
||||
|
||||
level = checkRangesOrGetDefault(
|
||||
opts.level, 'options.level',
|
||||
|
@ -438,9 +438,17 @@ class ZCtx : public AsyncWrap {
|
||||
ZCtx* ctx;
|
||||
ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
|
||||
|
||||
// windowBits is special. On the compression side, 0 is an invalid value.
|
||||
// But on the decompression side, a value of 0 for windowBits tells zlib
|
||||
// to use the window size in the zlib header of the compressed stream.
|
||||
int windowBits = args[0]->Uint32Value();
|
||||
CHECK((windowBits >= Z_MIN_WINDOWBITS && windowBits <= Z_MAX_WINDOWBITS) &&
|
||||
"invalid windowBits");
|
||||
if (!((windowBits == 0) &&
|
||||
(ctx->mode_ == INFLATE ||
|
||||
ctx->mode_ == GUNZIP ||
|
||||
ctx->mode_ == UNZIP))) {
|
||||
CHECK((windowBits >= Z_MIN_WINDOWBITS &&
|
||||
windowBits <= Z_MAX_WINDOWBITS) && "invalid windowBits");
|
||||
}
|
||||
|
||||
int level = args[1]->Int32Value();
|
||||
CHECK((level >= Z_MIN_LEVEL && level <= Z_MAX_LEVEL) &&
|
||||
|
33
test/parallel/test-zlib-zero-windowBits.js
Normal file
33
test/parallel/test-zlib-zero-windowBits.js
Normal file
@ -0,0 +1,33 @@
|
||||
'use strict';
|
||||
|
||||
const common = require('../common');
|
||||
const assert = require('assert');
|
||||
const zlib = require('zlib');
|
||||
|
||||
|
||||
// windowBits is a special case in zlib. On the compression side, 0 is invalid.
|
||||
// On the decompression side, it indicates that zlib should use the value from
|
||||
// the header of the compressed stream.
|
||||
{
|
||||
const inflate = zlib.createInflate({ windowBits: 0 });
|
||||
assert(inflate instanceof zlib.Inflate);
|
||||
}
|
||||
|
||||
{
|
||||
const gunzip = zlib.createGunzip({ windowBits: 0 });
|
||||
assert(gunzip instanceof zlib.Gunzip);
|
||||
}
|
||||
|
||||
{
|
||||
const unzip = zlib.createUnzip({ windowBits: 0 });
|
||||
assert(unzip instanceof zlib.Unzip);
|
||||
}
|
||||
|
||||
{
|
||||
common.expectsError(() => zlib.createGzip({ windowBits: 0 }), {
|
||||
code: 'ERR_OUT_OF_RANGE',
|
||||
type: RangeError,
|
||||
message: 'The value of "options.windowBits" is out of range. ' +
|
||||
'It must be >= 8 and <= 15. Received 0'
|
||||
});
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user