From 11918c4aedd27c0ed6b5f029fb2a50c889530db5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Nie=C3=9Fen?= Date: Wed, 10 May 2017 15:36:22 +0200 Subject: [PATCH] stream: fix highWaterMark integer overflow Fixes integer overflows when supplying values exceeding MAX_SAFE_INTEGER for highWaterMark. PR-URL: https://github.com/nodejs/node/pull/12593 Reviewed-By: Matteo Collina Reviewed-By: Luca Maraschi Reviewed-By: James M Snell Reviewed-By: Colin Ihrig --- lib/_stream_readable.js | 2 +- lib/_stream_writable.js | 2 +- test/parallel/test-streams-highwatermark.js | 18 ++++++++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 test/parallel/test-streams-highwatermark.js diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js index 9887bd774e1159..702d87b549b857 100644 --- a/lib/_stream_readable.js +++ b/lib/_stream_readable.js @@ -72,7 +72,7 @@ function ReadableState(options, stream) { this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm; // cast to ints. - this.highWaterMark = ~~this.highWaterMark; + this.highWaterMark = Math.floor(this.highWaterMark); // 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 a0a37fbb7a0421..c3c2ce0710ad18 100644 --- a/lib/_stream_writable.js +++ b/lib/_stream_writable.js @@ -55,7 +55,7 @@ function WritableState(options, stream) { this.highWaterMark = (hwm || hwm === 0) ? hwm : defaultHwm; // cast to ints. - this.highWaterMark = ~~this.highWaterMark; + this.highWaterMark = Math.floor(this.highWaterMark); // drain event flag. this.needDrain = false; diff --git a/test/parallel/test-streams-highwatermark.js b/test/parallel/test-streams-highwatermark.js new file mode 100644 index 00000000000000..aca2415bd8e15f --- /dev/null +++ b/test/parallel/test-streams-highwatermark.js @@ -0,0 +1,18 @@ +'use strict'; +require('../common'); + +// This test ensures that the stream implementation correctly handles values +// for highWaterMark which exceed the range of signed 32 bit integers. + +const assert = require('assert'); +const stream = require('stream'); + +// This number exceeds the range of 32 bit integer arithmetic but should still +// be handled correctly. +const ovfl = Number.MAX_SAFE_INTEGER; + +const readable = stream.Readable({ highWaterMark: ovfl }); +assert.strictEqual(readable._readableState.highWaterMark, ovfl); + +const writable = stream.Writable({ highWaterMark: ovfl }); +assert.strictEqual(writable._writableState.highWaterMark, ovfl);