mirror of https://github.com/lukechilds/node.git
Browse Source
Fix the uncommon situation when a readable stream is piped twice into the same destination stream, and then unpiped once. Previously, the `unpipe` event handlers weren’t able to tell whether they were corresponding to the “right” conceptual pipe that was being removed; this fixes this by adding a counter to the `unpipe` event handler and only removing a single piping destination at most. Fixes: https://github.com/nodejs/node/issues/12718 PR-URL: https://github.com/nodejs/node/pull/12746 Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>v6
2 changed files with 87 additions and 5 deletions
@ -0,0 +1,78 @@ |
|||
'use strict'; |
|||
const common = require('../common'); |
|||
|
|||
// Regression test for https://github.com/nodejs/node/issues/12718.
|
|||
// Tests that piping a source stream twice to the same destination stream
|
|||
// works, and that a subsequent unpipe() call only removes the pipe *once*.
|
|||
const assert = require('assert'); |
|||
const { PassThrough, Writable } = require('stream'); |
|||
|
|||
{ |
|||
const passThrough = new PassThrough(); |
|||
const dest = new Writable({ |
|||
write: common.mustCall((chunk, encoding, cb) => { |
|||
assert.strictEqual(`${chunk}`, 'foobar'); |
|||
cb(); |
|||
}) |
|||
}); |
|||
|
|||
passThrough.pipe(dest); |
|||
passThrough.pipe(dest); |
|||
|
|||
assert.strictEqual(passThrough._events.data.length, 2); |
|||
assert.strictEqual(passThrough._readableState.pipesCount, 2); |
|||
assert.strictEqual(passThrough._readableState.pipes[0], dest); |
|||
assert.strictEqual(passThrough._readableState.pipes[1], dest); |
|||
|
|||
passThrough.unpipe(dest); |
|||
|
|||
assert.strictEqual(passThrough._events.data.length, 1); |
|||
assert.strictEqual(passThrough._readableState.pipesCount, 1); |
|||
assert.strictEqual(passThrough._readableState.pipes, dest); |
|||
|
|||
passThrough.write('foobar'); |
|||
passThrough.pipe(dest); |
|||
} |
|||
|
|||
{ |
|||
const passThrough = new PassThrough(); |
|||
const dest = new Writable({ |
|||
write: common.mustCall((chunk, encoding, cb) => { |
|||
assert.strictEqual(`${chunk}`, 'foobar'); |
|||
cb(); |
|||
}, 2) |
|||
}); |
|||
|
|||
passThrough.pipe(dest); |
|||
passThrough.pipe(dest); |
|||
|
|||
assert.strictEqual(passThrough._events.data.length, 2); |
|||
assert.strictEqual(passThrough._readableState.pipesCount, 2); |
|||
assert.strictEqual(passThrough._readableState.pipes[0], dest); |
|||
assert.strictEqual(passThrough._readableState.pipes[1], dest); |
|||
|
|||
passThrough.write('foobar'); |
|||
} |
|||
|
|||
{ |
|||
const passThrough = new PassThrough(); |
|||
const dest = new Writable({ |
|||
write: common.mustNotCall() |
|||
}); |
|||
|
|||
passThrough.pipe(dest); |
|||
passThrough.pipe(dest); |
|||
|
|||
assert.strictEqual(passThrough._events.data.length, 2); |
|||
assert.strictEqual(passThrough._readableState.pipesCount, 2); |
|||
assert.strictEqual(passThrough._readableState.pipes[0], dest); |
|||
assert.strictEqual(passThrough._readableState.pipes[1], dest); |
|||
|
|||
passThrough.unpipe(dest); |
|||
passThrough.unpipe(dest); |
|||
|
|||
assert.strictEqual(passThrough._events.data, undefined); |
|||
assert.strictEqual(passThrough._readableState.pipesCount, 0); |
|||
|
|||
passThrough.write('foobar'); |
|||
} |
Loading…
Reference in new issue