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
lib: ensure readable stream flows to end
If a readable stream was set up with `highWaterMark 0`, the while-loop
in `maybeReadMore_` function would never execute.

The while loop now has an extra or-condition for the case where the
stream is flowing and there are no items. The or-condition is adapted
from the emit-condition of the `addChunk` function.

The `addChunk` also contains a check for `state.sync`. However that part
of the check was omitted here because the `maybeReadMore_` is executed
using `process.nextTick`. `state.sync` is set and then unset  within the
`read()` function so it should never be in effect in `maybeReadMore_`.

Fixes: #24915
  • Loading branch information
Rantanen committed Dec 9, 2018
commit 66853605e2e3bd4280cd5143ec4a1bbba4b6bdba
3 changes: 2 additions & 1 deletion lib/_stream_readable.js
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,8 @@ function maybeReadMore(stream, state) {
function maybeReadMore_(stream, state) {
var len = state.length;
Comment thread
Rantanen marked this conversation as resolved.
Outdated
while (!state.reading && !state.ended &&
state.length < state.highWaterMark) {
(state.length < state.highWaterMark ||
state.flowing && state.length === 0)) {
Comment thread
Rantanen marked this conversation as resolved.
Outdated
debug('maybeReadMore read 0');
stream.read(0);
if (len === state.length)
Expand Down
27 changes: 27 additions & 0 deletions test/parallel/test-stream-readable-hwm-0-async.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
'use strict';

const common = require('../common');

// This test ensures that Readable stream will call _read() for streams
// with highWaterMark === 0 upon .read(0) instead of just trying to
// emit 'readable' event.

const { Readable } = require('stream');

let count = 5;

const r = new Readable({
// Called 6 times: First 5 return data, last one signals end of stream.
read: common.mustCall(() => {
process.nextTick(common.mustCall(() => {
if (count--)
r.push('a');
else
r.push(null);
}));
}, 6),
highWaterMark: 0,
});

r.on('end', common.mustCall());
r.on('data', common.mustCall(5));