Skip to content

Commit 401ff75

Browse files
committed
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.
1 parent aba035f commit 401ff75

File tree

2 files changed

+66
-4
lines changed

2 files changed

+66
-4
lines changed

lib/_stream_writable.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,13 +177,19 @@ function writeAfterEnd(stream, cb) {
177177
// how many bytes or characters.
178178
function validChunk(stream, state, chunk, cb) {
179179
var valid = true;
180-
181-
if (!(chunk instanceof Buffer) &&
180+
var er = false;
181+
// Always throw error if a null is written
182+
// if we are not in object mode then throw
183+
// if it is not a buffer, string, or undefined.
184+
if (chunk === null) {
185+
er = new TypeError('May not write null values to stream');
186+
} else if (!(chunk instanceof Buffer) &&
182187
typeof chunk !== 'string' &&
183-
chunk !== null &&
184188
chunk !== undefined &&
185189
!state.objectMode) {
186-
var er = new TypeError('Invalid non-string/buffer chunk');
190+
er = new TypeError('Invalid non-string/buffer chunk');
191+
}
192+
if (er) {
187193
stream.emit('error', er);
188194
process.nextTick(cb, er);
189195
valid = false;
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
'use strict';
2+
require('../common');
3+
const assert = require('assert');
4+
5+
const stream = require('stream');
6+
const util = require('util');
7+
8+
function MyWritable(options) {
9+
stream.Writable.call(this, options);
10+
}
11+
12+
util.inherits(MyWritable, stream.Writable);
13+
14+
MyWritable.prototype._write = function(chunk, encoding, callback) {
15+
assert.notStrictEqual(chunk, null);
16+
callback();
17+
};
18+
19+
assert.throws(() => {
20+
var m = new MyWritable({objectMode: true});
21+
m.write(null, (err) => assert.ok(err));
22+
}, TypeError, 'May not write null values to stream');
23+
assert.doesNotThrow(() => {
24+
var m = new MyWritable({objectMode: true}).on('error', (e) => {
25+
assert.ok(e);
26+
});
27+
m.write(null, (err) => {
28+
assert.ok(err);
29+
});
30+
});
31+
32+
assert.throws(() => {
33+
var m = new MyWritable();
34+
m.write(false, (err) => assert.ok(err));
35+
}, TypeError, 'Invalid non-string/buffer chunk');
36+
assert.doesNotThrow(() => {
37+
var m = new MyWritable().on('error', (e) => {
38+
assert.ok(e);
39+
});
40+
m.write(false, (err) => {
41+
assert.ok(err);
42+
});
43+
});
44+
45+
assert.doesNotThrow(() => {
46+
var m = new MyWritable({objectMode: true});
47+
m.write(false, (err) => assert.ifError(err));
48+
});
49+
assert.doesNotThrow(() => {
50+
var m = new MyWritable({objectMode: true}).on('error', (e) => {
51+
assert.ifError(e || new Error('should not get here'));
52+
});
53+
m.write(false, (err) => {
54+
assert.ifError(err);
55+
});
56+
});

0 commit comments

Comments
 (0)