diff --git a/benchmark/misc/punycode.js b/benchmark/misc/punycode.js index 630aea3195f098..40bcd70302003c 100644 --- a/benchmark/misc/punycode.js +++ b/benchmark/misc/punycode.js @@ -1,11 +1,14 @@ 'use strict'; const common = require('../common.js'); -const icu = process.binding('icu'); +let icu; +try { + icu = process.binding('icu'); +} catch (err) {} const punycode = require('punycode'); const bench = common.createBenchmark(main, { - method: ['punycode', 'icu'], + method: ['punycode'].concat(icu !== undefined ? ['icu'] : []), n: [1024], val: [ 'افغانستا.icom.museum', @@ -69,8 +72,11 @@ function main(conf) { runPunycode(n, val); break; case 'icu': - runICU(n, val); - break; + if (icu !== undefined) { + runICU(n, val); + break; + } + // fallthrough default: throw new Error('Unexpected method'); } diff --git a/lib/fs.js b/lib/fs.js index bfd085b4213881..b5565201e2abdd 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -1950,8 +1950,7 @@ function ReadStream(path, options) { this.flags = options.flags === undefined ? 'r' : options.flags; this.mode = options.mode === undefined ? 0o666 : options.mode; - this.start = typeof this.fd !== 'number' && options.start === undefined ? - 0 : options.start; + this.start = options.start; this.end = options.end; this.autoClose = options.autoClose === undefined ? true : options.autoClose; this.pos = undefined; @@ -1974,6 +1973,12 @@ function ReadStream(path, options) { this.pos = this.start; } + // Backwards compatibility: Make sure `end` is a number regardless of `start`. + // TODO(addaleax): Make the above typecheck not depend on `start` instead. + // (That is a semver-major change). + if (typeof this.end !== 'number') + this.end = Infinity; + if (typeof this.fd !== 'number') this.open(); @@ -2028,6 +2033,8 @@ ReadStream.prototype._read = function(n) { if (this.pos !== undefined) toRead = Math.min(this.end - this.pos + 1, toRead); + else + toRead = Math.min(this.end - this.bytesRead + 1, toRead); // already read everything we were supposed to read! // treat as EOF. diff --git a/test/known_issues/known_issues.status b/test/known_issues/known_issues.status index 46c8ed32741c7d..e21913e232c03f 100644 --- a/test/known_issues/known_issues.status +++ b/test/known_issues/known_issues.status @@ -7,8 +7,6 @@ prefix known_issues [true] # This section applies to all platforms [$system==win32] -test-stdout-buffer-flush-on-exit: SKIP -test-cluster-disconnect-handles: SKIP [$system==linux] diff --git a/test/parallel/test-fs-read-stream.js b/test/parallel/test-fs-read-stream.js index 6748c68b52596c..11d1c2f63ff507 100644 --- a/test/parallel/test-fs-read-stream.js +++ b/test/parallel/test-fs-read-stream.js @@ -22,6 +22,7 @@ 'use strict'; const common = require('../common'); +const child_process = require('child_process'); const assert = require('assert'); const fs = require('fs'); const fixtures = require('../common/fixtures'); @@ -171,6 +172,31 @@ assert.throws(function() { })); } +if (!common.isWindows) { + // Verify that end works when start is not specified, and we do not try to + // use positioned reads. This makes sure that this keeps working for + // non-seekable file descriptors. + common.refreshTmpDir(); + const filename = `${common.tmpDir}/foo.pipe`; + const mkfifoResult = child_process.spawnSync('mkfifo', [filename]); + if (!mkfifoResult.error) { + child_process.exec(`echo "xyz foobar" > '${filename}'`); + const stream = new fs.createReadStream(filename, { end: 1 }); + stream.data = ''; + + stream.on('data', function(chunk) { + stream.data += chunk; + }); + + stream.on('end', common.mustCall(function() { + assert.strictEqual('xy', stream.data); + fs.unlinkSync(filename); + })); + } else { + common.printSkipMessage('mkfifo not available'); + } +} + { // pause and then resume immediately. const pauseRes = fs.createReadStream(rangeFile);