From d7bf7ed9935587a6681a090e5d12840f9a60f55e Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Tue, 22 Jan 2013 13:23:46 +0100 Subject: [PATCH] zlib: don't assert on malformed dictionary Handle Z_DATA_ERROR errors from inflateSetDictionary() gracefully. Fixes the following assertion: node: ../src/node_zlib.cc:167: static void node::ZCtx::Process (uv_work_t*): Assertion `ctx->err_ == 0 && "Failed to set dictionary"' failed. Aborted (core dumped) Fixes #4632. --- src/node_zlib.cc | 14 +++++++++++--- test/simple/test-zlib-dictionary-fail.js | 12 ++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/node_zlib.cc b/src/node_zlib.cc index 3674919d47..deacb713d9 100644 --- a/src/node_zlib.cc +++ b/src/node_zlib.cc @@ -163,12 +163,16 @@ class ZCtx : public ObjectWrap { ctx->err_ = inflateSetDictionary(&ctx->strm_, ctx->dictionary_, ctx->dictionary_len_); - // TODO Handle Z_DATA_ERROR, wrong dictionary - assert(ctx->err_ == Z_OK && "Failed to set dictionary"); if (ctx->err_ == Z_OK) { // And try to decode again ctx->err_ = inflate(&ctx->strm_, ctx->flush_); + } else if (ctx->err_ == Z_DATA_ERROR) { + + // Both inflateSetDictionary() and inflate() return Z_DATA_ERROR. + // Make it possible for After() to tell a bad dictionary from bad + // input. + ctx->err_ = Z_NEED_DICT; } } break; @@ -196,7 +200,11 @@ class ZCtx : public ObjectWrap { // normal statuses, not fatal break; case Z_NEED_DICT: - ZCtx::Error(ctx, "Missing dictionary"); + if (ctx->dictionary_ == NULL) { + ZCtx::Error(ctx, "Missing dictionary"); + } else { + ZCtx::Error(ctx, "Bad dictionary"); + } return; default: // something else. diff --git a/test/simple/test-zlib-dictionary-fail.js b/test/simple/test-zlib-dictionary-fail.js index f6d1869903..fd35a0192a 100644 --- a/test/simple/test-zlib-dictionary-fail.js +++ b/test/simple/test-zlib-dictionary-fail.js @@ -34,3 +34,15 @@ 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.createInflate({ dictionary: Buffer('fail') }); + + stream.on('error', common.mustCall(function(err) { + assert(/Bad dictionary/.test(err.message)); + })); + + // String "test" encoded with dictionary "dict". + stream.write(Buffer([0x78,0xBB,0x04,0x09,0x01,0xA5])); +})();