Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
zlib: allow writes after readable 'end' to finish
Call the callback for writes that occur after the stream is closed.
This also requires changes to the code to not call `.destroy()`
on the stream in `.on('end')`, and to ignore chunks written
afterwards.

Previously, these writes would just queue up silently, as their
`_write()` callback would never have been called.

Fixes: #30976
  • Loading branch information
addaleax committed Dec 24, 2019
commit dc162493a55e749c8c2dc29e688a675de5173757
14 changes: 5 additions & 9 deletions lib/zlib.js
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ function ZlibBase(opts, mode, handle, { flush, finishFlush, fullFlush }) {
this._defaultFlushFlag = flush;
this._finishFlushFlag = finishFlush;
this._defaultFullFlushFlag = fullFlush;
this.once('end', this.close);
this.once('end', _close.bind(this, this));
Comment thread
addaleax marked this conversation as resolved.
Resolved
this._info = opts && opts.info;
}
ObjectSetPrototypeOf(ZlibBase.prototype, Transform.prototype);
Expand Down Expand Up @@ -487,7 +487,7 @@ function processChunkSync(self, chunk, flushFlag) {

function processChunk(self, chunk, flushFlag, cb) {
const handle = self._handle;
assert(handle, 'zlib binding closed');
if (!handle) return process.nextTick(cb);

handle.buffer = chunk;
handle.cb = cb;
Expand All @@ -513,13 +513,9 @@ function processCallback() {
const self = this[owner_symbol];
const state = self._writeState;

if (self._hadError) {
this.buffer = null;
return;
}

if (self.destroyed) {
if (self._hadError || self.destroyed) {
this.buffer = null;
this.cb();
return;
}

Expand All @@ -539,7 +535,7 @@ function processCallback() {
}

if (self.destroyed) {
return;
return this.cb();
Comment thread
addaleax marked this conversation as resolved.
Resolved
}

// Exhausted the output buffer, or used all the input create a new one.
Expand Down
16 changes: 16 additions & 0 deletions test/parallel/test-zlib-write-after-end.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'use strict';
const common = require('../common');
const zlib = require('zlib');

// Regression test for https://github.com/nodejs/node/issues/30976
// Writes to a stream should finish even after the readable side has been ended.

const data = zlib.deflateRawSync('Welcome');

const inflate = zlib.createInflateRaw();

inflate.resume();
inflate.write(data, common.mustCall());
inflate.write(Buffer.from([0x00]), common.mustCall());
inflate.write(Buffer.from([0x00]), common.mustCall());
inflate.flush(common.mustCall());