Permalink
Browse files

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.
  • Loading branch information...
thusoy authored and MylesBorins committed Sep 20, 2016
1 parent 475fe96 commit 9a02414a29d4d515425c93370d6b73361fe100d2
Showing with 87 additions and 3 deletions.
  1. +12 −2 src/node_zlib.cc
  2. +14 −0 test/parallel/test-zlib-dictionary-fail.js
  3. +61 −1 test/parallel/test-zlib-dictionary.js
View
@@ -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_,
@@ -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;
}
@@ -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]));
})();
@@ -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');
@@ -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.