diff --git a/doc/api/errors.md b/doc/api/errors.md index 77da558371..82246fff70 100644 --- a/doc/api/errors.md +++ b/doc/api/errors.md @@ -1474,6 +1474,11 @@ Used when a given value is out of the accepted range. Used when an attempt is made to use a `zlib` object after it has already been closed. + +### ERR_ZLIB_INITIALIZATION_FAILED + +Used when creation of a [`zlib`][] object fails due to incorrect configuration. + [`--force-fips`]: cli.html#cli_force_fips [`crypto.timingSafeEqual()`]: crypto.html#crypto_crypto_timingsafeequal_a_b [`dgram.createSocket()`]: dgram.html#dgram_dgram_createsocket_options_callback @@ -1515,3 +1520,4 @@ closed. [try-catch]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch [vm]: vm.html [WHATWG Supported Encodings]: util.html#util_whatwg_supported_encodings +[`zlib`]: zlib.html diff --git a/lib/internal/errors.js b/lib/internal/errors.js index bb32b82e60..e76bd05792 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -372,6 +372,7 @@ E('ERR_WORKER_UNSERIALIZABLE_ERROR', E('ERR_WORKER_UNSUPPORTED_EXTENSION', 'The worker script extension must be ".js" or ".mjs". Received "%s"'); E('ERR_ZLIB_BINDING_CLOSED', 'zlib binding closed'); +E('ERR_ZLIB_INITIALIZATION_FAILED', 'Initialization failed'); function invalidArgType(name, expected, actual) { internalAssert(name, 'name is required'); diff --git a/lib/zlib.js b/lib/zlib.js index 059b9aac91..751c176559 100644 --- a/lib/zlib.js +++ b/lib/zlib.js @@ -161,6 +161,12 @@ function Zlib(opts, mode) { var memLevel = Z_DEFAULT_MEMLEVEL; var strategy = Z_DEFAULT_STRATEGY; var dictionary; + + if (typeof mode !== 'number') + throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'mode', 'number'); + if (mode < DEFLATE || mode > UNZIP) + throw new errors.RangeError('ERR_OUT_OF_RANGE', 'mode'); + if (opts) { chunkSize = opts.chunkSize; if (chunkSize !== undefined && chunkSize === chunkSize) { @@ -258,8 +264,15 @@ function Zlib(opts, mode) { this._hadError = false; this._writeState = new Uint32Array(2); - this._handle.init(windowBits, level, memLevel, strategy, this._writeState, - processCallback, dictionary); + if (!this._handle.init(windowBits, + level, + memLevel, + strategy, + this._writeState, + processCallback, + dictionary)) { + throw new errors.Error('ERR_ZLIB_INITIALIZATION_FAILED'); + } this._outBuffer = Buffer.allocUnsafe(chunkSize); this._outOffset = 0; diff --git a/src/node_zlib.cc b/src/node_zlib.cc index b7283c5639..3158c3a709 100644 --- a/src/node_zlib.cc +++ b/src/node_zlib.cc @@ -425,16 +425,8 @@ class ZCtx : public AsyncWrap { static void New(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); - - if (args.Length() < 1 || !args[0]->IsInt32()) { - return env->ThrowTypeError("Bad argument"); - } + CHECK(args[0]->IsInt32()); node_zlib_mode mode = static_cast(args[0]->Int32Value()); - - if (mode < DEFLATE || mode > UNZIP) { - return env->ThrowTypeError("Bad argument"); - } - new ZCtx(env, args.This(), mode); } @@ -483,9 +475,14 @@ class ZCtx : public AsyncWrap { memcpy(dictionary, dictionary_, dictionary_len); } - Init(ctx, level, windowBits, memLevel, strategy, write_result, - write_js_callback, dictionary, dictionary_len); + bool ret = Init(ctx, level, windowBits, memLevel, strategy, write_result, + write_js_callback, dictionary, dictionary_len); + if (!ret) goto end; + SetDictionary(ctx); + + end: + return args.GetReturnValue().Set(ret); } static void Params(const FunctionCallbackInfo& args) { @@ -502,7 +499,7 @@ class ZCtx : public AsyncWrap { SetDictionary(ctx); } - static void Init(ZCtx *ctx, int level, int windowBits, int memLevel, + static bool Init(ZCtx *ctx, int level, int windowBits, int memLevel, int strategy, uint32_t* write_result, Local write_js_callback, char* dictionary, size_t dictionary_len) { @@ -568,11 +565,12 @@ class ZCtx : public AsyncWrap { ctx->dictionary_ = nullptr; } ctx->mode_ = NONE; - ctx->env()->ThrowError("Init error"); + return false; } ctx->write_result_ = write_result; ctx->write_js_callback_.Reset(ctx->env()->isolate(), write_js_callback); + return true; } static void SetDictionary(ZCtx* ctx) { diff --git a/test/parallel/test-zlib-failed-init.js b/test/parallel/test-zlib-failed-init.js index 8597543429..7dd53ea370 100644 --- a/test/parallel/test-zlib-failed-init.js +++ b/test/parallel/test-zlib-failed-init.js @@ -11,9 +11,13 @@ const zlib = require('zlib'); // no such rejection which is the reason for the version check below // (http://zlib.net/ChangeLog.txt). if (!/^1\.2\.[0-8]$/.test(process.versions.zlib)) { - assert.throws(() => { - zlib.createDeflateRaw({ windowBits: 8 }); - }, /^Error: Init error$/); + common.expectsError( + () => zlib.createDeflateRaw({ windowBits: 8 }), + { + code: 'ERR_ZLIB_INITIALIZATION_FAILED', + type: Error, + message: 'Initialization failed' + }); } // Regression tests for bugs in the validation logic.