diff --git a/lib/zlib.js b/lib/zlib.js index 22675651b37105..ef272bc6010886 100644 --- a/lib/zlib.js +++ b/lib/zlib.js @@ -40,6 +40,7 @@ const { codes: { ERR_BROTLI_INVALID_PARAM, ERR_BUFFER_TOO_LARGE, + ERR_INTERNAL_ASSERTION, ERR_INVALID_ARG_TYPE, ERR_OUT_OF_RANGE, }, @@ -353,6 +354,9 @@ ZlibBase.prototype._destroy = function(err, callback) { }; ZlibBase.prototype._transform = function(chunk, encoding, cb) { + if (!Buffer.isBuffer(chunk)) { + throw new ERR_INTERNAL_ASSERTION('Chunk must be a Buffer'); + } let flushFlag = this._defaultFlushFlag; // We use a 'fake' zero-length chunk to carry information about flushes from // the public API to the actual stream implementation. diff --git a/test/parallel/test-zlib.js b/test/parallel/test-zlib.js index 646c7abded1e36..33620269323175 100644 --- a/test/parallel/test-zlib.js +++ b/test/parallel/test-zlib.js @@ -238,3 +238,15 @@ testKeys.forEach(common.mustCall((file) => { const gzip = zlib.Gzip(); assert.ok(gzip instanceof zlib.Gzip); } + +{ + // Misuse of stream internals + // Issue: https://github.com/nodejs/node/issues/37884 + assert.throws(() => zlib.createGunzip()._transform('Hello'), { + code: 'ERR_INTERNAL_ASSERTION', + }); + + assert.throws(() => zlib.createGunzip()._write('Hello'), { + code: 'ERR_INTERNAL_ASSERTION', + }); +}