Skip to content

Commit 3806d87

Browse files
targostrevnorris
authored andcommitted
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: #1811 Reviewed-By: Fedor Indutny <[email protected]> Reviewed-By: Trevor Norris <[email protected]>
1 parent 953b3e7 commit 3806d87

File tree

2 files changed

+40
-2
lines changed

2 files changed

+40
-2
lines changed

lib/zlib.js

+18-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ const Transform = require('_stream_transform');
55
const binding = process.binding('zlib');
66
const util = require('util');
77
const assert = require('assert').ok;
8+
const kMaxLength = process.binding('smalloc').kMaxLength;
9+
const kRangeErrorMessage = 'Cannot create final Buffer. ' +
10+
'It would be larger than 0x' + kMaxLength.toString(16) + ' bytes.';
811

912
// zlib doesn't provide these, so kludge them in following the same
1013
// const naming scheme zlib uses.
@@ -210,10 +213,18 @@ function zlibBuffer(engine, buffer, callback) {
210213
}
211214

212215
function onEnd() {
213-
var buf = Buffer.concat(buffers, nread);
216+
var buf;
217+
var err = null;
218+
219+
if (nread >= kMaxLength) {
220+
err = new RangeError(kRangeErrorMessage);
221+
} else {
222+
buf = Buffer.concat(buffers, nread);
223+
}
224+
214225
buffers = [];
215-
callback(null, buf);
216226
engine.close();
227+
callback(err, buf);
217228
}
218229
}
219230

@@ -524,6 +535,11 @@ Zlib.prototype._processChunk = function(chunk, flushFlag, cb) {
524535
throw error;
525536
}
526537

538+
if (nread >= kMaxLength) {
539+
this.close();
540+
throw new RangeError(kRangeErrorMessage);
541+
}
542+
527543
var buf = Buffer.concat(buffers, nread);
528544
this.close();
529545

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
'use strict';
2+
3+
const assert = require('assert');
4+
5+
// Change kMaxLength for zlib to trigger the error
6+
// without having to allocate 1GB of buffers
7+
const smalloc = process.binding('smalloc');
8+
smalloc.kMaxLength = 128;
9+
const zlib = require('zlib');
10+
smalloc.kMaxLength = 0x3fffffff;
11+
12+
const encoded = new Buffer('H4sIAAAAAAAAA0tMHFgAAIw2K/GAAAAA', 'base64');
13+
14+
// Async
15+
zlib.gunzip(encoded, function(err) {
16+
assert.ok(err instanceof RangeError);
17+
});
18+
19+
// Sync
20+
assert.throws(function() {
21+
zlib.gunzipSync(encoded);
22+
}, RangeError);

0 commit comments

Comments
 (0)