Skip to content

Commit

Permalink
zlib: prevent uncaught exception in zlibBuffer
Browse files Browse the repository at this point in the history
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: #1811
Reviewed-By: Fedor Indutny <[email protected]>
Reviewed-By: Trevor Norris <[email protected]>
  • Loading branch information
targos authored and trevnorris committed Jun 15, 2015
1 parent 953b3e7 commit 3806d87
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 2 deletions.
20 changes: 18 additions & 2 deletions lib/zlib.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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();

Expand Down
22 changes: 22 additions & 0 deletions test/parallel/test-regress-GH-io-1811.js
Original file line number Diff line number Diff line change
@@ -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);

0 comments on commit 3806d87

Please sign in to comment.