zlib: fix raw inflate with custom dictionary
Moves inflateSetDictionary right after inflateInit2 when mode is INFLATERAW, since without the wrapper in appears zlib won't return Z_NEED_DICT as it would otherwise, and will thus attempt inflating without the dictionary, leading to an error. Fixes: https://github.com/nodejs/node/issues/8507 PR-URL: https://github.com/nodejs/node/pull/8512 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
parent
4019c321d4
commit
c775514e56
@ -282,8 +282,11 @@ class ZCtx : public AsyncWrap {
|
|||||||
case INFLATERAW:
|
case INFLATERAW:
|
||||||
ctx->err_ = inflate(&ctx->strm_, ctx->flush_);
|
ctx->err_ = inflate(&ctx->strm_, ctx->flush_);
|
||||||
|
|
||||||
// If data was encoded with dictionary
|
// If data was encoded with dictionary (INFLATERAW will have it set in
|
||||||
if (ctx->err_ == Z_NEED_DICT && ctx->dictionary_ != nullptr) {
|
// SetDictionary, don't repeat that here)
|
||||||
|
if (ctx->mode_ != INFLATERAW &&
|
||||||
|
ctx->err_ == Z_NEED_DICT &&
|
||||||
|
ctx->dictionary_ != nullptr) {
|
||||||
// Load it
|
// Load it
|
||||||
ctx->err_ = inflateSetDictionary(&ctx->strm_,
|
ctx->err_ = inflateSetDictionary(&ctx->strm_,
|
||||||
ctx->dictionary_,
|
ctx->dictionary_,
|
||||||
@ -552,6 +555,13 @@ class ZCtx : public AsyncWrap {
|
|||||||
ctx->dictionary_,
|
ctx->dictionary_,
|
||||||
ctx->dictionary_len_);
|
ctx->dictionary_len_);
|
||||||
break;
|
break;
|
||||||
|
case INFLATERAW:
|
||||||
|
// The other inflate cases will have the dictionary set when inflate()
|
||||||
|
// returns Z_NEED_DICT in Process()
|
||||||
|
ctx->err_ = inflateSetDictionary(&ctx->strm_,
|
||||||
|
ctx->dictionary_,
|
||||||
|
ctx->dictionary_len_);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -26,3 +26,17 @@ const zlib = require('zlib');
|
|||||||
// String "test" encoded with dictionary "dict".
|
// String "test" encoded with dictionary "dict".
|
||||||
stream.write(Buffer.from([0x78, 0xBB, 0x04, 0x09, 0x01, 0xA5]));
|
stream.write(Buffer.from([0x78, 0xBB, 0x04, 0x09, 0x01, 0xA5]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Should raise an error, not trigger an assertion in src/node_zlib.cc
|
||||||
|
{
|
||||||
|
const stream = zlib.createInflateRaw({ dictionary: Buffer.from('fail') });
|
||||||
|
|
||||||
|
stream.on('error', common.mustCall(function(err) {
|
||||||
|
// It's not possible to separate invalid dict and invalid data when using
|
||||||
|
// the raw format
|
||||||
|
assert(/invalid/.test(err.message));
|
||||||
|
}));
|
||||||
|
|
||||||
|
// String "test" encoded with dictionary "dict".
|
||||||
|
stream.write(Buffer.from([0x78, 0xBB, 0x04, 0x09, 0x01, 0xA5]));
|
||||||
|
}
|
||||||
|
@ -85,5 +85,64 @@ function deflateResetDictionaryTest() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function rawDictionaryTest() {
|
||||||
|
let output = '';
|
||||||
|
const deflate = zlib.createDeflateRaw({ dictionary: spdyDict });
|
||||||
|
const inflate = zlib.createInflateRaw({ dictionary: spdyDict });
|
||||||
|
|
||||||
|
deflate.on('data', function(chunk) {
|
||||||
|
inflate.write(chunk);
|
||||||
|
});
|
||||||
|
|
||||||
|
inflate.on('data', function(chunk) {
|
||||||
|
output += chunk;
|
||||||
|
});
|
||||||
|
|
||||||
|
deflate.on('end', function() {
|
||||||
|
inflate.end();
|
||||||
|
});
|
||||||
|
|
||||||
|
inflate.on('end', function() {
|
||||||
|
assert.equal(input, output);
|
||||||
|
});
|
||||||
|
|
||||||
|
deflate.write(input);
|
||||||
|
deflate.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
function deflateRawResetDictionaryTest() {
|
||||||
|
let doneReset = false;
|
||||||
|
let output = '';
|
||||||
|
const deflate = zlib.createDeflateRaw({ dictionary: spdyDict });
|
||||||
|
const inflate = zlib.createInflateRaw({ dictionary: spdyDict });
|
||||||
|
|
||||||
|
deflate.on('data', function(chunk) {
|
||||||
|
if (doneReset)
|
||||||
|
inflate.write(chunk);
|
||||||
|
});
|
||||||
|
|
||||||
|
inflate.on('data', function(chunk) {
|
||||||
|
output += chunk;
|
||||||
|
});
|
||||||
|
|
||||||
|
deflate.on('end', function() {
|
||||||
|
inflate.end();
|
||||||
|
});
|
||||||
|
|
||||||
|
inflate.on('end', function() {
|
||||||
|
assert.equal(input, output);
|
||||||
|
});
|
||||||
|
|
||||||
|
deflate.write(input);
|
||||||
|
deflate.flush(function() {
|
||||||
|
deflate.reset();
|
||||||
|
doneReset = true;
|
||||||
|
deflate.write(input);
|
||||||
|
deflate.end();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
basicDictionaryTest();
|
basicDictionaryTest();
|
||||||
deflateResetDictionaryTest();
|
deflateResetDictionaryTest();
|
||||||
|
rawDictionaryTest();
|
||||||
|
deflateRawResetDictionaryTest();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user