Skip to content

Commit 1547495

Browse files
thusoyFishrock123
authored andcommitted
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: #8507 PR-URL: #8512 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent c98d0c9 commit 1547495

File tree

3 files changed

+85
-2
lines changed

3 files changed

+85
-2
lines changed

src/node_zlib.cc

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -282,8 +282,11 @@ class ZCtx : public AsyncWrap {
282282
case INFLATERAW:
283283
ctx->err_ = inflate(&ctx->strm_, ctx->flush_);
284284

285-
// If data was encoded with dictionary
286-
if (ctx->err_ == Z_NEED_DICT && ctx->dictionary_ != nullptr) {
285+
// If data was encoded with dictionary (INFLATERAW will have it set in
286+
// SetDictionary, don't repeat that here)
287+
if (ctx->mode_ != INFLATERAW &&
288+
ctx->err_ == Z_NEED_DICT &&
289+
ctx->dictionary_ != nullptr) {
287290
// Load it
288291
ctx->err_ = inflateSetDictionary(&ctx->strm_,
289292
ctx->dictionary_,
@@ -552,6 +555,13 @@ class ZCtx : public AsyncWrap {
552555
ctx->dictionary_,
553556
ctx->dictionary_len_);
554557
break;
558+
case INFLATERAW:
559+
// The other inflate cases will have the dictionary set when inflate()
560+
// returns Z_NEED_DICT in Process()
561+
ctx->err_ = inflateSetDictionary(&ctx->strm_,
562+
ctx->dictionary_,
563+
ctx->dictionary_len_);
564+
break;
555565
default:
556566
break;
557567
}

test/parallel/test-zlib-dictionary-fail.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,17 @@ const zlib = require('zlib');
2626
// String "test" encoded with dictionary "dict".
2727
stream.write(Buffer.from([0x78, 0xBB, 0x04, 0x09, 0x01, 0xA5]));
2828
}
29+
30+
// Should raise an error, not trigger an assertion in src/node_zlib.cc
31+
{
32+
const stream = zlib.createInflateRaw({ dictionary: Buffer.from('fail') });
33+
34+
stream.on('error', common.mustCall(function(err) {
35+
// It's not possible to separate invalid dict and invalid data when using
36+
// the raw format
37+
assert(/invalid/.test(err.message));
38+
}));
39+
40+
// String "test" encoded with dictionary "dict".
41+
stream.write(Buffer.from([0x78, 0xBB, 0x04, 0x09, 0x01, 0xA5]));
42+
}

test/parallel/test-zlib-dictionary.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,5 +85,64 @@ function deflateResetDictionaryTest() {
8585
});
8686
}
8787

88+
function rawDictionaryTest() {
89+
let output = '';
90+
const deflate = zlib.createDeflateRaw({ dictionary: spdyDict });
91+
const inflate = zlib.createInflateRaw({ dictionary: spdyDict });
92+
93+
deflate.on('data', function(chunk) {
94+
inflate.write(chunk);
95+
});
96+
97+
inflate.on('data', function(chunk) {
98+
output += chunk;
99+
});
100+
101+
deflate.on('end', function() {
102+
inflate.end();
103+
});
104+
105+
inflate.on('end', function() {
106+
assert.equal(input, output);
107+
});
108+
109+
deflate.write(input);
110+
deflate.end();
111+
}
112+
113+
function deflateRawResetDictionaryTest() {
114+
let doneReset = false;
115+
let output = '';
116+
const deflate = zlib.createDeflateRaw({ dictionary: spdyDict });
117+
const inflate = zlib.createInflateRaw({ dictionary: spdyDict });
118+
119+
deflate.on('data', function(chunk) {
120+
if (doneReset)
121+
inflate.write(chunk);
122+
});
123+
124+
inflate.on('data', function(chunk) {
125+
output += chunk;
126+
});
127+
128+
deflate.on('end', function() {
129+
inflate.end();
130+
});
131+
132+
inflate.on('end', function() {
133+
assert.equal(input, output);
134+
});
135+
136+
deflate.write(input);
137+
deflate.flush(function() {
138+
deflate.reset();
139+
doneReset = true;
140+
deflate.write(input);
141+
deflate.end();
142+
});
143+
}
144+
88145
basicDictionaryTest();
89146
deflateResetDictionaryTest();
147+
rawDictionaryTest();
148+
deflateRawResetDictionaryTest();

0 commit comments

Comments
 (0)