Skip to content

Commit 8b43d3f

Browse files
committed
zlib: do not emit event on *Sync() methods
Asynchronous functions in `zlib` should not emit the close event. This fixes an issue where asynchronous calls in a for loop could exhaust memory because the pending event prevents the objects from being garbage collected. Fixes: #1668 PR-URL: #5707 Reviewed-By: jasnell - James M Snell <[email protected]> Reviewed-By: trevnorris - Trevor Norris <[email protected]> Reviewed-By: Сковорода Никита Андреевич <[email protected]>
1 parent a53b2ac commit 8b43d3f

File tree

2 files changed

+32
-8
lines changed

2 files changed

+32
-8
lines changed

‎lib/zlib.js‎

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -454,18 +454,21 @@ Zlib.prototype.flush = function(kind, callback) {
454454
};
455455

456456
Zlib.prototype.close = function(callback) {
457+
_close(this, callback);
458+
process.nextTick(emitCloseNT, this);
459+
};
460+
461+
function _close(engine, callback) {
457462
if (callback)
458463
process.nextTick(callback);
459464

460-
if (this._closed)
465+
if (engine._closed)
461466
return;
462467

463-
this._closed = true;
468+
engine._closed = true;
464469

465-
this._handle.close();
466-
467-
process.nextTick(emitCloseNT, this);
468-
};
470+
engine._handle.close();
471+
}
469472

470473
function emitCloseNT(self) {
471474
self.emit('close');
@@ -535,12 +538,12 @@ Zlib.prototype._processChunk = function(chunk, flushFlag, cb) {
535538
}
536539

537540
if (nread >= kMaxLength) {
538-
this.close();
541+
_close(this);
539542
throw new RangeError(kRangeErrorMessage);
540543
}
541544

542545
var buf = Buffer.concat(buffers, nread);
543-
this.close();
546+
_close(this);
544547

545548
return buf;
546549
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
'use strict';
2+
require('../common');
3+
const zlib = require('zlib');
4+
const assert = require('assert');
5+
6+
const shouldNotBeCalled = () => { throw new Error('unexpected event'); };
7+
8+
const message = 'Come on, Fhqwhgads.';
9+
10+
const zipper = new zlib.Gzip();
11+
zipper.on('close', shouldNotBeCalled);
12+
13+
const buffer = new Buffer(message);
14+
const zipped = zipper._processChunk(buffer, zlib.Z_FINISH);
15+
16+
const unzipper = new zlib.Gunzip();
17+
unzipper.on('close', shouldNotBeCalled);
18+
19+
const unzipped = unzipper._processChunk(zipped, zlib.Z_FINISH);
20+
assert.notEqual(zipped.toString(), message);
21+
assert.strictEqual(unzipped.toString(), message);

0 commit comments

Comments
 (0)