Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions lib/zlib.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
12 changes: 10 additions & 2 deletions src/node_zlib.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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) &&
Expand Down
33 changes: 33 additions & 0 deletions test/parallel/test-zlib-zero-windowBits.js
Original file line number Diff line number Diff line change
@@ -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'
});
}