Skip to content

Commit c0abecd

Browse files
calvinmetcalfjasnell
authored andcommitted
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: #6170 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Matteo Collina <[email protected]>
1 parent 816df10 commit c0abecd

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
@@ -176,13 +176,19 @@ function writeAfterEnd(stream, cb) {
176176
// how many bytes or characters.
177177
function validChunk(stream, state, chunk, cb) {
178178
var valid = true;
179-
180-
if (!(chunk instanceof Buffer) &&
179+
var er = false;
180+
// Always throw error if a null is written
181+
// if we are not in object mode then throw
182+
// if it is not a buffer, string, or undefined.
183+
if (chunk === null) {
184+
er = new TypeError('May not write null values to stream');
185+
} else if (!(chunk instanceof Buffer) &&
181186
typeof chunk !== 'string' &&
182-
chunk !== null &&
183187
chunk !== undefined &&
184188
!state.objectMode) {
185-
var er = new TypeError('Invalid non-string/buffer chunk');
189+
er = new TypeError('Invalid non-string/buffer chunk');
190+
}
191+
if (er) {
186192
stream.emit('error', er);
187193
process.nextTick(cb, er);
188194
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)