Skip to content

Commit

Permalink
stream: give error message if write() cb called twice
Browse files Browse the repository at this point in the history
Otherwise, this condition would result in an error that just reads
`cb is not a function`, and which additionally could have lost
stack trace context through a `process.nextTick()` call.

PR-URL: nodejs#19510
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
  • Loading branch information
addaleax authored and BridgeAR committed Mar 27, 2018
1 parent cdfe47b commit d111d7b
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 0 deletions.
4 changes: 4 additions & 0 deletions lib/_stream_writable.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const { getHighWaterMark } = require('internal/streams/state');
const {
ERR_INVALID_ARG_TYPE,
ERR_METHOD_NOT_IMPLEMENTED,
ERR_MULTIPLE_CALLBACK,
ERR_STREAM_CANNOT_PIPE,
ERR_STREAM_DESTROYED,
ERR_STREAM_NULL_VALUES,
Expand Down Expand Up @@ -449,6 +450,9 @@ function onwrite(stream, er) {
var sync = state.sync;
var cb = state.writecb;

if (typeof cb !== 'function')
throw new ERR_MULTIPLE_CALLBACK();

onwriteStateUpdate(state);

if (er)
Expand Down
49 changes: 49 additions & 0 deletions test/parallel/test-stream-writable-write-cb-twice.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
'use strict';
const common = require('../common');
const { Writable } = require('stream');

{
// Sync + Sync
const writable = new Writable({
write: common.mustCall((buf, enc, cb) => {
cb();
common.expectsError(cb, {
code: 'ERR_MULTIPLE_CALLBACK',
type: Error
});
})
});
writable.write('hi');
}

{
// Sync + Async
const writable = new Writable({
write: common.mustCall((buf, enc, cb) => {
cb();
process.nextTick(() => {
common.expectsError(cb, {
code: 'ERR_MULTIPLE_CALLBACK',
type: Error
});
});
})
});
writable.write('hi');
}

{
// Async + Async
const writable = new Writable({
write: common.mustCall((buf, enc, cb) => {
process.nextTick(cb);
process.nextTick(() => {
common.expectsError(cb, {
code: 'ERR_MULTIPLE_CALLBACK',
type: Error
});
});
})
});
writable.write('hi');
}

0 comments on commit d111d7b

Please sign in to comment.