From c0abecdaf32e84a7922dc149286b4434acf48885 Mon Sep 17 00:00:00 2001 From: Calvin Metcalf Date: Tue, 12 Apr 2016 15:42:23 -0400 Subject: [PATCH] stream: make null an invalid chunk to write in object mode this harmonizes behavior between readable, writable, and transform streams so that they all handle nulls in object mode the same way by considering them invalid chunks. PR-URL: https://github.com/nodejs/node/pull/6170 Reviewed-By: James M Snell Reviewed-By: Matteo Collina --- lib/_stream_writable.js | 14 ++++-- test/parallel/test-stream-writable-null.js | 56 ++++++++++++++++++++++ 2 files changed, 66 insertions(+), 4 deletions(-) create mode 100644 test/parallel/test-stream-writable-null.js diff --git a/lib/_stream_writable.js b/lib/_stream_writable.js index 98ca05da395458..daef34b50c4fc5 100644 --- a/lib/_stream_writable.js +++ b/lib/_stream_writable.js @@ -176,13 +176,19 @@ function writeAfterEnd(stream, cb) { // how many bytes or characters. function validChunk(stream, state, chunk, cb) { var valid = true; - - if (!(chunk instanceof Buffer) && + var er = false; + // Always throw error if a null is written + // if we are not in object mode then throw + // if it is not a buffer, string, or undefined. + if (chunk === null) { + er = new TypeError('May not write null values to stream'); + } else if (!(chunk instanceof Buffer) && typeof chunk !== 'string' && - chunk !== null && chunk !== undefined && !state.objectMode) { - var er = new TypeError('Invalid non-string/buffer chunk'); + er = new TypeError('Invalid non-string/buffer chunk'); + } + if (er) { stream.emit('error', er); process.nextTick(cb, er); valid = false; diff --git a/test/parallel/test-stream-writable-null.js b/test/parallel/test-stream-writable-null.js new file mode 100644 index 00000000000000..2cc396bd916a3e --- /dev/null +++ b/test/parallel/test-stream-writable-null.js @@ -0,0 +1,56 @@ +'use strict'; +require('../common'); +const assert = require('assert'); + +const stream = require('stream'); +const util = require('util'); + +function MyWritable(options) { + stream.Writable.call(this, options); +} + +util.inherits(MyWritable, stream.Writable); + +MyWritable.prototype._write = function(chunk, encoding, callback) { + assert.notStrictEqual(chunk, null); + callback(); +}; + +assert.throws(() => { + var m = new MyWritable({objectMode: true}); + m.write(null, (err) => assert.ok(err)); +}, TypeError, 'May not write null values to stream'); +assert.doesNotThrow(() => { + var m = new MyWritable({objectMode: true}).on('error', (e) => { + assert.ok(e); + }); + m.write(null, (err) => { + assert.ok(err); + }); +}); + +assert.throws(() => { + var m = new MyWritable(); + m.write(false, (err) => assert.ok(err)); +}, TypeError, 'Invalid non-string/buffer chunk'); +assert.doesNotThrow(() => { + var m = new MyWritable().on('error', (e) => { + assert.ok(e); + }); + m.write(false, (err) => { + assert.ok(err); + }); +}); + +assert.doesNotThrow(() => { + var m = new MyWritable({objectMode: true}); + m.write(false, (err) => assert.ifError(err)); +}); +assert.doesNotThrow(() => { + var m = new MyWritable({objectMode: true}).on('error', (e) => { + assert.ifError(e || new Error('should not get here')); + }); + m.write(false, (err) => { + assert.ifError(err); + }); +});