Skip to content

Commit 9a02414

Browse files
thusoyMyles Borins
authored and
Myles Borins
committed
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.
1 parent 475fe96 commit 9a02414

File tree

3 files changed

+87
-3
lines changed

3 files changed

+87
-3
lines changed

src/node_zlib.cc

+12-2
Original file line numberDiff line numberDiff line change
@@ -238,8 +238,11 @@ class ZCtx : public AsyncWrap {
238238
case INFLATERAW:
239239
ctx->err_ = inflate(&ctx->strm_, ctx->flush_);
240240

241-
// If data was encoded with dictionary
242-
if (ctx->err_ == Z_NEED_DICT && ctx->dictionary_ != nullptr) {
241+
// If data was encoded with dictionary (INFLATERAW will have it set in
242+
// SetDictionary, don't repeat that here)
243+
if (ctx->mode_ != INFLATERAW &&
244+
ctx->err_ == Z_NEED_DICT &&
245+
ctx->dictionary_ != nullptr) {
243246
// Load it
244247
ctx->err_ = inflateSetDictionary(&ctx->strm_,
245248
ctx->dictionary_,
@@ -491,6 +494,13 @@ class ZCtx : public AsyncWrap {
491494
ctx->dictionary_,
492495
ctx->dictionary_len_);
493496
break;
497+
case INFLATERAW:
498+
// The other inflate cases will have the dictionary set when inflate()
499+
// returns Z_NEED_DICT in Process()
500+
ctx->err_ = inflateSetDictionary(&ctx->strm_,
501+
ctx->dictionary_,
502+
ctx->dictionary_len_);
503+
break;
494504
default:
495505
break;
496506
}

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

+14
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,17 @@ var zlib = require('zlib');
2626
// String "test" encoded with dictionary "dict".
2727
stream.write(Buffer([0x78, 0xBB, 0x04, 0x09, 0x01, 0xA5]));
2828
})();
29+
30+
// Should raise an error, not trigger an assertion in src/node_zlib.cc
31+
(function() {
32+
var stream = zlib.createInflateRaw({ dictionary: Buffer('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([0x78, 0xBB, 0x04, 0x09, 0x01, 0xA5]));
42+
})();

test/parallel/test-zlib-dictionary.js

+61-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict';
22
// test compression/decompression with dictionary
33

4-
require('../common');
4+
const common = require('../common');
55
const assert = require('assert');
66
const zlib = require('zlib');
77

@@ -69,6 +69,66 @@ function run(num) {
6969
}
7070
run(1);
7171

72+
function rawDictionaryTest() {
73+
let output = '';
74+
const deflate = zlib.createDeflateRaw({ dictionary: spdyDict });
75+
const inflate = zlib.createInflateRaw({ dictionary: spdyDict });
76+
77+
deflate.on('data', function(chunk) {
78+
inflate.write(chunk);
79+
});
80+
81+
inflate.on('data', function(chunk) {
82+
output += chunk;
83+
});
84+
85+
deflate.on('end', function() {
86+
inflate.end();
87+
});
88+
89+
inflate.on('end', common.mustCall(function() {
90+
assert.equal(input, output);
91+
}));
92+
93+
deflate.write(input);
94+
deflate.end();
95+
}
96+
97+
function deflateRawResetDictionaryTest() {
98+
let doneReset = false;
99+
let output = '';
100+
const deflate = zlib.createDeflateRaw({ dictionary: spdyDict });
101+
const inflate = zlib.createInflateRaw({ dictionary: spdyDict });
102+
103+
deflate.on('data', function(chunk) {
104+
if (doneReset)
105+
inflate.write(chunk);
106+
});
107+
108+
inflate.on('data', function(chunk) {
109+
output += chunk;
110+
});
111+
112+
deflate.on('end', function() {
113+
inflate.end();
114+
});
115+
116+
inflate.on('end', common.mustCall(function() {
117+
assert.equal(input, output);
118+
}));
119+
120+
deflate.write(input);
121+
deflate.flush(function() {
122+
deflate.reset();
123+
doneReset = true;
124+
deflate.write(input);
125+
deflate.end();
126+
});
127+
}
128+
129+
rawDictionaryTest();
130+
deflateRawResetDictionaryTest();
131+
72132
process.on('exit', function() {
73133
assert.equal(called, 2);
74134
});

0 commit comments

Comments
 (0)