stream: don't emit 'data' after 'error' or 'close'
As per doc we should not emit further events after 'close' and only 'close' after 'error'. Fixes: https://github.com/nodejs/node/issues/39630 PR-URL: https://github.com/nodejs/node/pull/39639 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
This commit is contained in:
parent
8bfb4b9815
commit
0e841b45c2
@ -276,6 +276,8 @@ function readableAddChunk(stream, chunk, encoding, addToFront) {
|
|||||||
if (addToFront) {
|
if (addToFront) {
|
||||||
if (state.endEmitted)
|
if (state.endEmitted)
|
||||||
errorOrDestroy(stream, new ERR_STREAM_UNSHIFT_AFTER_END_EVENT());
|
errorOrDestroy(stream, new ERR_STREAM_UNSHIFT_AFTER_END_EVENT());
|
||||||
|
else if (state.destroyed || state.errored)
|
||||||
|
return false;
|
||||||
else
|
else
|
||||||
addChunk(stream, state, chunk, true);
|
addChunk(stream, state, chunk, true);
|
||||||
} else if (state.ended) {
|
} else if (state.ended) {
|
||||||
@ -316,6 +318,7 @@ function addChunk(stream, state, chunk, addToFront) {
|
|||||||
} else {
|
} else {
|
||||||
state.awaitDrainWriters = null;
|
state.awaitDrainWriters = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
state.dataEmitted = true;
|
state.dataEmitted = true;
|
||||||
stream.emit('data', chunk);
|
stream.emit('data', chunk);
|
||||||
} else {
|
} else {
|
||||||
@ -542,7 +545,7 @@ Readable.prototype.read = function(n) {
|
|||||||
endReadable(this);
|
endReadable(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret !== null) {
|
if (ret !== null && !state.errorEmitted && !state.closeEmitted) {
|
||||||
state.dataEmitted = true;
|
state.dataEmitted = true;
|
||||||
this.emit('data', ret);
|
this.emit('data', ret);
|
||||||
}
|
}
|
||||||
|
@ -319,3 +319,85 @@ const assert = require('assert');
|
|||||||
})(), /AbortError/);
|
})(), /AbortError/);
|
||||||
setTimeout(() => controller.abort(), 0);
|
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');
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user