From 9ff6f42b6a9c37fa278ede2c7b28f0ac75f5a63b Mon Sep 17 00:00:00 2001 From: Marcos Casagrande Date: Fri, 1 Jun 2018 20:03:30 -0300 Subject: [PATCH] stream: fix end not being called when reading some base64 files This fixes 'end' not being called when reading base64 files with highWaterMark equal to: file length - 1, and fixes 'data' not being called on some edge cases when highWaterMark was lower than file length. Fixes: https://github.com/nodejs/node/issues/19862 --- lib/_stream_readable.js | 2 +- test/parallel/test-fs-read-stream-events.js | 35 +++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 test/parallel/test-fs-read-stream-events.js diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js index cd8669830a5368..3a593ac05422af 100644 --- a/lib/_stream_readable.js +++ b/lib/_stream_readable.js @@ -530,7 +530,7 @@ function maybeReadMore(stream, state) { function maybeReadMore_(stream, state) { var len = state.length; - while (!state.reading && !state.flowing && !state.ended && + while (!state.reading && !state.ended && state.length < state.highWaterMark) { debug('maybeReadMore read 0'); stream.read(0); diff --git a/test/parallel/test-fs-read-stream-events.js b/test/parallel/test-fs-read-stream-events.js new file mode 100644 index 00000000000000..8282fb4846a747 --- /dev/null +++ b/test/parallel/test-fs-read-stream-events.js @@ -0,0 +1,35 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const path = require('path'); +const fs = require('fs'); + +const tmpdir = require('../common/tmpdir'); + +const encodings = ['utf8', 'base64', 'ascii', 'binary', 'hex', 'utf16le']; + +function test(encoding) { + + const file = path.join(tmpdir.path, `read-stream-events-${encoding}.txt`); + + const data = '1234'; + fs.writeFileSync(file, data); + + const rs = fs.createReadStream(file, { + encoding, + highWaterMark: data.length - 1 + }); + + let chunks = ''; + + rs.on('data', common.mustCall(function(data) { + chunks += Buffer.from(data, encoding); + }, 2)); + + rs.on('end', common.mustCall(function() { + assert.strictEqual(chunks, data); + })); +} + +for (const encoding of encodings) + test(encoding);