From 74afe5cfea875863862368f6af0e85a031e78890 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Wed, 15 Nov 2017 12:13:43 +0100 Subject: [PATCH] zlib: fix decompression of empty data streams add4b0ab8cc0ec6 made the assumption that compressed data would never lead to an empty decompressed stream. Fix that by explicitly checking the number of read bytes. Fixes: https://github.com/nodejs/node/issues/17041 Refs: https://github.com/nodejs/node/pull/13322 --- lib/zlib.js | 5 +++++ test/parallel/test-zlib-empty-buffer.js | 26 +++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 test/parallel/test-zlib-empty-buffer.js diff --git a/lib/zlib.js b/lib/zlib.js index 2def716e9b676c..75ee0b50465111 100644 --- a/lib/zlib.js +++ b/lib/zlib.js @@ -95,6 +95,8 @@ function zlibBufferOnEnd() { var err; if (this.nread >= kMaxLength) { err = new errors.RangeError('ERR_BUFFER_TOO_LARGE'); + } else if (this.nread === 0) { + buf = Buffer.alloc(0); } else { var bufs = this.buffers; buf = (bufs.length === 1 ? bufs[0] : Buffer.concat(bufs, this.nread)); @@ -485,6 +487,9 @@ function processChunkSync(self, chunk, flushFlag) { _close(self); + if (nread === 0) + return Buffer.alloc(0); + return (buffers.length === 1 ? buffers[0] : Buffer.concat(buffers, nread)); } diff --git a/test/parallel/test-zlib-empty-buffer.js b/test/parallel/test-zlib-empty-buffer.js new file mode 100644 index 00000000000000..908c89cbbcef2e --- /dev/null +++ b/test/parallel/test-zlib-empty-buffer.js @@ -0,0 +1,26 @@ +'use strict'; +const common = require('../common'); +const zlib = require('zlib'); +const { inspect, promisify } = require('util'); +const assert = require('assert'); +const emptyBuffer = new Buffer(0); + +common.crashOnUnhandledRejection(); + +(async function() { + for (const [ compress, decompress, method ] of [ + [ zlib.deflateRawSync, zlib.inflateRawSync, 'raw sync' ], + [ zlib.deflateSync, zlib.inflateSync, 'deflate sync' ], + [ zlib.gzipSync, zlib.gunzipSync, 'gzip sync' ], + [ promisify(zlib.deflateRaw), promisify(zlib.inflateRaw), 'raw' ], + [ promisify(zlib.deflate), promisify(zlib.inflate), 'deflate' ], + [ promisify(zlib.gzip), promisify(zlib.gunzip), 'gzip' ] + ]) { + const compressed = await compress(emptyBuffer); + const decompressed = await decompress(compressed); + assert.deepStrictEqual( + emptyBuffer, decompressed, + `Expected ${inspect(compressed)} to match ${inspect(decompressed)} ` + + `to match for ${method}`); + } +})();