From 3806d875d3dbff96041638299a1974579e9a5b4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Wed, 27 May 2015 13:21:56 +0200 Subject: [PATCH] zlib: prevent uncaught exception in zlibBuffer If the accumulation of data for the final Buffer is greater than kMaxLength it will throw an un-catchable RangeError. Instead now pass the generated error to the callback. PR-URL: https://github.com/nodejs/io.js/pull/1811 Reviewed-By: Fedor Indutny Reviewed-By: Trevor Norris --- lib/zlib.js | 20 ++++++++++++++++++-- test/parallel/test-regress-GH-io-1811.js | 22 ++++++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 test/parallel/test-regress-GH-io-1811.js diff --git a/lib/zlib.js b/lib/zlib.js index 2d37b72a3c8b20..67bdcaff64bed6 100644 --- a/lib/zlib.js +++ b/lib/zlib.js @@ -5,6 +5,9 @@ const Transform = require('_stream_transform'); const binding = process.binding('zlib'); const util = require('util'); const assert = require('assert').ok; +const kMaxLength = process.binding('smalloc').kMaxLength; +const kRangeErrorMessage = 'Cannot create final Buffer. ' + + 'It would be larger than 0x' + kMaxLength.toString(16) + ' bytes.'; // zlib doesn't provide these, so kludge them in following the same // const naming scheme zlib uses. @@ -210,10 +213,18 @@ function zlibBuffer(engine, buffer, callback) { } function onEnd() { - var buf = Buffer.concat(buffers, nread); + var buf; + var err = null; + + if (nread >= kMaxLength) { + err = new RangeError(kRangeErrorMessage); + } else { + buf = Buffer.concat(buffers, nread); + } + buffers = []; - callback(null, buf); engine.close(); + callback(err, buf); } } @@ -524,6 +535,11 @@ Zlib.prototype._processChunk = function(chunk, flushFlag, cb) { throw error; } + if (nread >= kMaxLength) { + this.close(); + throw new RangeError(kRangeErrorMessage); + } + var buf = Buffer.concat(buffers, nread); this.close(); diff --git a/test/parallel/test-regress-GH-io-1811.js b/test/parallel/test-regress-GH-io-1811.js new file mode 100644 index 00000000000000..2ef8ff8c090aa4 --- /dev/null +++ b/test/parallel/test-regress-GH-io-1811.js @@ -0,0 +1,22 @@ +'use strict'; + +const assert = require('assert'); + +// Change kMaxLength for zlib to trigger the error +// without having to allocate 1GB of buffers +const smalloc = process.binding('smalloc'); +smalloc.kMaxLength = 128; +const zlib = require('zlib'); +smalloc.kMaxLength = 0x3fffffff; + +const encoded = new Buffer('H4sIAAAAAAAAA0tMHFgAAIw2K/GAAAAA', 'base64'); + +// Async +zlib.gunzip(encoded, function(err) { + assert.ok(err instanceof RangeError); +}); + +// Sync +assert.throws(function() { + zlib.gunzipSync(encoded); +}, RangeError);