From 423712709a6242b5237a8fcef9e7fd1223dc7661 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Sat, 5 Dec 2015 16:03:30 -0500 Subject: [PATCH 1/2] stream_wrap: error if stream has StringDecoder If `.setEncoding` was called on input stream - all emitted `data` will be `String`s instances, not `Buffer`s. This is unacceptable for `StreamWrap`, and should not lead to the crash. Fix: /~https://github.com/nodejs/node/issues/3970 --- lib/_stream_wrap.js | 16 +++++++++++--- test/parallel/test-stream-wrap-encoding.js | 25 ++++++++++++++++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 test/parallel/test-stream-wrap-encoding.js diff --git a/lib/_stream_wrap.js b/lib/_stream_wrap.js index 924d07a986a906..7eb3008484b2aa 100644 --- a/lib/_stream_wrap.js +++ b/lib/_stream_wrap.js @@ -4,6 +4,7 @@ const assert = require('assert'); const util = require('util'); const Socket = require('net').Socket; const JSStream = process.binding('js_stream').JSStream; +const Buffer = require('buffer').Buffer; const uv = process.binding('uv'); const debug = util.debuglog('stream_wrap'); @@ -39,15 +40,24 @@ function StreamWrap(stream) { }; this.stream.pause(); - this.stream.on('error', function(err) { + this.stream.on('error', function onerror(err) { self.emit('error', err); }); - this.stream.on('data', function(chunk) { + this.stream.on('data', function ondata(chunk) { + if (!(chunk instanceof Buffer)) { + // Make sure that no further `data` events will happen + this.pause(); + this.removeListener('data', ondata); + + self.emit('error', new Error('Stream has StringDecoder')); + return; + } + debug('data', chunk.length); if (self._handle) self._handle.readBuffer(chunk); }); - this.stream.once('end', function() { + this.stream.once('end', function onend() { debug('end'); if (self._handle) self._handle.emitEOF(); diff --git a/test/parallel/test-stream-wrap-encoding.js b/test/parallel/test-stream-wrap-encoding.js new file mode 100644 index 00000000000000..aa911fb2e2a162 --- /dev/null +++ b/test/parallel/test-stream-wrap-encoding.js @@ -0,0 +1,25 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const StreamWrap = require('_stream_wrap'); +const Duplex = require('stream').Duplex; + +var done = false; + +var stream = new Duplex({ + read: function() { + }, + write: function() { + } +}); + +stream.setEncoding('ascii'); + +var wrap = new StreamWrap(stream); + +wrap.on('error', common.mustCall(function(err) { + assert(/StringDecoder/.test(err.message)); +})); + +stream.push('ohai'); From 161af4f4ff3685e9c20886ce31760d68b96f3318 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Sun, 6 Dec 2015 20:47:21 -0500 Subject: [PATCH 2/2] fix --- test/parallel/test-stream-wrap-encoding.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/parallel/test-stream-wrap-encoding.js b/test/parallel/test-stream-wrap-encoding.js index aa911fb2e2a162..d23faaab4a65f3 100644 --- a/test/parallel/test-stream-wrap-encoding.js +++ b/test/parallel/test-stream-wrap-encoding.js @@ -5,9 +5,7 @@ const assert = require('assert'); const StreamWrap = require('_stream_wrap'); const Duplex = require('stream').Duplex; -var done = false; - -var stream = new Duplex({ +const stream = new Duplex({ read: function() { }, write: function() { @@ -16,7 +14,7 @@ var stream = new Duplex({ stream.setEncoding('ascii'); -var wrap = new StreamWrap(stream); +const wrap = new StreamWrap(stream); wrap.on('error', common.mustCall(function(err) { assert(/StringDecoder/.test(err.message));