Skip to content

Commit

Permalink
stream: don't emit 'data' after 'error' or 'close'
Browse files Browse the repository at this point in the history
As per doc we should not emit further events after 'close' and
only 'close' after 'error'.

Fixes: #39630

PR-URL: #39639
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: Benjamin Gruenbaum <[email protected]>
Reviewed-By: Antoine du Hamel <[email protected]>
Reviewed-By: Ruben Bridgewater <[email protected]>
  • Loading branch information
ronag committed Aug 6, 2021
1 parent 8bfb4b9 commit 0e841b4
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 1 deletion.
5 changes: 4 additions & 1 deletion lib/internal/streams/readable.js
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,8 @@ function readableAddChunk(stream, chunk, encoding, addToFront) {
if (addToFront) {
if (state.endEmitted)
errorOrDestroy(stream, new ERR_STREAM_UNSHIFT_AFTER_END_EVENT());
else if (state.destroyed || state.errored)
return false;
else
addChunk(stream, state, chunk, true);
} else if (state.ended) {
Expand Down Expand Up @@ -316,6 +318,7 @@ function addChunk(stream, state, chunk, addToFront) {
} else {
state.awaitDrainWriters = null;
}

state.dataEmitted = true;
stream.emit('data', chunk);
} else {
Expand Down Expand Up @@ -542,7 +545,7 @@ Readable.prototype.read = function(n) {
endReadable(this);
}

if (ret !== null) {
if (ret !== null && !state.errorEmitted && !state.closeEmitted) {
state.dataEmitted = true;
this.emit('data', ret);
}
Expand Down
82 changes: 82 additions & 0 deletions test/parallel/test-stream-readable-destroy.js
Original file line number Diff line number Diff line change
Expand Up @@ -319,3 +319,85 @@ const assert = require('assert');
})(), /AbortError/);
setTimeout(() => controller.abort(), 0);
}

{
const read = new Readable({
read() {
},
});

read.on('data', common.mustNotCall());
read.on('error', common.mustCall((e) => {
read.push('asd');
read.read();
}));
read.on('close', common.mustCall((e) => {
read.push('asd');
read.read();
}));
read.destroy(new Error('asd'));
}

{
const read = new Readable({
read() {
},
});

read.on('data', common.mustNotCall());
read.on('close', common.mustCall((e) => {
read.push('asd');
read.read();
}));
read.destroy();
}

{
const read = new Readable({
read() {
},
});

read.on('data', common.mustNotCall());
read.on('close', common.mustCall((e) => {
read.push('asd');
read.unshift('asd');
}));
read.destroy();
}

{
const read = new Readable({
read() {
},
});

read.on('data', common.mustNotCall());
read.destroy();
read.unshift('asd');
}

{
const read = new Readable({
read() {
},
});

read.resume();
read.on('data', common.mustNotCall());
read.on('close', common.mustCall((e) => {
read.push('asd');
}));
read.destroy();
}

{
const read = new Readable({
read() {
},
});

read.on('data', common.mustNotCall());
read.destroy();
read.push('asd');
}

0 comments on commit 0e841b4

Please sign in to comment.