diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js index 702d87b549b857..e71ea0cae57ed0 100644 --- a/lib/_stream_readable.js +++ b/lib/_stream_readable.js @@ -68,11 +68,20 @@ function ReadableState(options, stream) { // the point at which it stops calling _read() to fill the buffer // Note: 0 is a valid value, means "don't call _read preemptively ever" var hwm = options.highWaterMark; - var defaultHwm = this.objectMode ? 16 : 16 * 1024; - this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm; + if (hwm == null) { + this.highWaterMark = this.objectMode ? 16 : 16 * 1024; + } else { + if (typeof hwm !== 'number') { + throw new TypeError('"highWaterMark" must be a number'); + } - // cast to ints. - this.highWaterMark = Math.floor(this.highWaterMark); + if (hwm < 0) { + throw new RangeError('"highWaterMark" must not be negative'); + } + + // cast to ints. + this.highWaterMark = Math.floor(hwm); + } // A linked list is used to store data chunks instead of an array because the // linked list can remove elements from the beginning faster than diff --git a/lib/_stream_writable.js b/lib/_stream_writable.js index c3c2ce0710ad18..ca039b0c8b573f 100644 --- a/lib/_stream_writable.js +++ b/lib/_stream_writable.js @@ -51,11 +51,20 @@ function WritableState(options, stream) { // Note: 0 is a valid value, means that we always return false if // the entire buffer is not flushed immediately on write() var hwm = options.highWaterMark; - var defaultHwm = this.objectMode ? 16 : 16 * 1024; - this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm; + if (hwm == null) { + this.highWaterMark = this.objectMode ? 16 : 16 * 1024; + } else { + if (typeof hwm !== 'number') { + throw new TypeError('"highWaterMark" must be a number'); + } - // cast to ints. - this.highWaterMark = Math.floor(this.highWaterMark); + if (hwm < 0) { + throw new RangeError('"highWaterMark" must not be negative'); + } + + // cast to ints. + this.highWaterMark = Math.floor(hwm); + } // drain event flag. this.needDrain = false; diff --git a/test/parallel/test-streams-highwatermark.js b/test/parallel/test-streams-highwatermark.js index aca2415bd8e15f..cd83a0aa382e78 100644 --- a/test/parallel/test-streams-highwatermark.js +++ b/test/parallel/test-streams-highwatermark.js @@ -2,7 +2,8 @@ require('../common'); // This test ensures that the stream implementation correctly handles values -// for highWaterMark which exceed the range of signed 32 bit integers. +// for highWaterMark which exceed the range of signed 32 bit integers and +// rejects invalid values. const assert = require('assert'); const stream = require('stream'); @@ -16,3 +17,21 @@ assert.strictEqual(readable._readableState.highWaterMark, ovfl); const writable = stream.Writable({ highWaterMark: ovfl }); assert.strictEqual(writable._writableState.highWaterMark, ovfl); + +[true, false, '5', {}].forEach((invalidValue) => { + assert.throws(() => { + stream.Readable({ highWaterMark: invalidValue }); + }, /^TypeError: "highWaterMark" must be a number$/); + + assert.throws(() => { + stream.Writable({ highWaterMark: invalidValue }); + }, /^TypeError: "highWaterMark" must be a number$/); +}); + +assert.throws(() => { + stream.Readable({ highWaterMark: -5 }); +}, /^RangeError: "highWaterMark" must not be negative$/); + +assert.throws(() => { + stream.Writable({ highWaterMark: -5 }); +}, /^RangeError: "highWaterMark" must not be negative$/);