Skip to content

Commit

Permalink
zlib: fix raw inflate with custom dictionary
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
thusoy authored and Myles Borins committed Nov 22, 2016
1 parent 475fe96 commit 9a02414
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 3 deletions.
14 changes: 12 additions & 2 deletions src/node_zlib.cc
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,11 @@ class ZCtx : public AsyncWrap {
case INFLATERAW:
ctx->err_ = inflate(&ctx->strm_, ctx->flush_);

// If data was encoded with dictionary
if (ctx->err_ == Z_NEED_DICT && ctx->dictionary_ != nullptr) {
// If data was encoded with dictionary (INFLATERAW will have it set in
// SetDictionary, don't repeat that here)
if (ctx->mode_ != INFLATERAW &&
ctx->err_ == Z_NEED_DICT &&
ctx->dictionary_ != nullptr) {
// Load it
ctx->err_ = inflateSetDictionary(&ctx->strm_,
ctx->dictionary_,
Expand Down Expand Up @@ -491,6 +494,13 @@ class ZCtx : public AsyncWrap {
ctx->dictionary_,
ctx->dictionary_len_);
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:
break;
}
Expand Down
14 changes: 14 additions & 0 deletions test/parallel/test-zlib-dictionary-fail.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,17 @@ var zlib = require('zlib');
// String "test" encoded with dictionary "dict".
stream.write(Buffer([0x78, 0xBB, 0x04, 0x09, 0x01, 0xA5]));
})();

// Should raise an error, not trigger an assertion in src/node_zlib.cc
(function() {
var stream = zlib.createInflateRaw({ dictionary: Buffer('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([0x78, 0xBB, 0x04, 0x09, 0x01, 0xA5]));
})();
62 changes: 61 additions & 1 deletion test/parallel/test-zlib-dictionary.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';
// test compression/decompression with dictionary

require('../common');
const common = require('../common');
const assert = require('assert');
const zlib = require('zlib');

Expand Down Expand Up @@ -69,6 +69,66 @@ function run(num) {
}
run(1);

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', common.mustCall(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', common.mustCall(function() {
assert.equal(input, output);
}));

deflate.write(input);
deflate.flush(function() {
deflate.reset();
doneReset = true;
deflate.write(input);
deflate.end();
});
}

rawDictionaryTest();
deflateRawResetDictionaryTest();

process.on('exit', function() {
assert.equal(called, 2);
});

0 comments on commit 9a02414

Please sign in to comment.