Skip to content

Commit 6d0b226

Browse files
ronagcodebytere
authored andcommitted
stream: fix finished w/ 'close' before 'finish'
Emitting 'close' before 'finish' on a Writable should result in a premature close error. PR-URL: #31534 Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Matteo Collina <[email protected]> Reviewed-By: Rich Trott <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Anna Henningsen <[email protected]>
1 parent 1dbe765 commit 6d0b226

File tree

2 files changed

+25
-4
lines changed

2 files changed

+25
-4
lines changed

lib/internal/streams/end-of-stream.js

+12-4
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ function isWritable(stream) {
2525
!!stream._writableState;
2626
}
2727

28+
function isWritableFinished(stream) {
29+
if (stream.writableFinished) return true;
30+
const wState = stream._writableState;
31+
if (!wState || wState.errored) return false;
32+
return wState.finished || (wState.ended && wState.length === 0);
33+
}
34+
2835
function eos(stream, opts, callback) {
2936
if (arguments.length === 2) {
3037
callback = opts;
@@ -49,10 +56,11 @@ function eos(stream, opts, callback) {
4956
if (!stream.writable) onfinish();
5057
};
5158

52-
let writableEnded = stream._writableState && stream._writableState.finished;
59+
let writableFinished = stream.writableFinished ||
60+
(stream._writableState && stream._writableState.finished);
5361
const onfinish = () => {
5462
writable = false;
55-
writableEnded = true;
63+
writableFinished = true;
5664
if (!readable) callback.call(stream);
5765
};
5866

@@ -75,8 +83,8 @@ function eos(stream, opts, callback) {
7583
err = new ERR_STREAM_PREMATURE_CLOSE();
7684
return callback.call(stream, err);
7785
}
78-
if (writable && !writableEnded) {
79-
if (!stream._writableState || !stream._writableState.ended)
86+
if (writable && !writableFinished) {
87+
if (!isWritableFinished(stream))
8088
err = new ERR_STREAM_PREMATURE_CLOSE();
8189
return callback.call(stream, err);
8290
}

test/parallel/test-stream-finished.js

+13
Original file line numberDiff line numberDiff line change
@@ -202,3 +202,16 @@ const { promisify } = require('util');
202202
assert.strictEqual(err.code, 'ERR_STREAM_PREMATURE_CLOSE');
203203
}));
204204
}
205+
206+
{
207+
const w = new Writable({
208+
write(chunk, encoding, callback) {
209+
setImmediate(callback);
210+
}
211+
});
212+
finished(w, common.mustCall((err) => {
213+
assert.strictEqual(err.code, 'ERR_STREAM_PREMATURE_CLOSE');
214+
}));
215+
w.end('asd');
216+
w.destroy();
217+
}

0 commit comments

Comments
 (0)