diff options
author | cjihrig <cjihrig@gmail.com> | 2014-12-16 17:17:28 -0500 |
---|---|---|
committer | cjihrig <cjihrig@gmail.com> | 2015-01-22 13:14:05 -0500 |
commit | f34757398fcc393685b4dfbcbdc692fb38332d6c (patch) | |
tree | d81527d66fb1fc4bf122b70a662b76f80f74f553 | |
parent | f2b378b850b3bc5ac7e30fb7a204ef19ca4f8604 (diff) | |
download | node-f34757398fcc393685b4dfbcbdc692fb38332d6c.tar.gz |
net: throw on invalid socket timeouts
This commit restricts socket timeouts non-negative, finite
numbers. Any other value throws a TypeError or RangeError.
This prevents subtle bugs that can happen due to type
coercion.
Fixes: https://github.com/joyent/node/issues/8618
PR-URL: https://github.com/joyent/node/pull/8884
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Timothy J Fontaine <tjfontaine@gmail.com>
-rw-r--r-- | lib/net.js | 12 | ||||
-rw-r--r-- | lib/timers.js | 15 | ||||
-rw-r--r-- | test/simple/test-net-settimeout.js | 2 | ||||
-rw-r--r-- | test/simple/test-net-socket-timeout.js | 25 |
4 files changed, 44 insertions, 10 deletions
diff --git a/lib/net.js b/lib/net.js index 5ce970ffe..d353ff70b 100644 --- a/lib/net.js +++ b/lib/net.js @@ -320,17 +320,17 @@ Socket.prototype.listen = function() { Socket.prototype.setTimeout = function(msecs, callback) { - if (msecs > 0 && isFinite(msecs)) { + if (msecs === 0) { + timers.unenroll(this); + if (callback) { + this.removeListener('timeout', callback); + } + } else { timers.enroll(this, msecs); timers._unrefActive(this); if (callback) { this.once('timeout', callback); } - } else if (msecs === 0) { - timers.unenroll(this); - if (callback) { - this.removeListener('timeout', callback); - } } }; diff --git a/lib/timers.js b/lib/timers.js index 08a9dd555..5ef5f37ed 100644 --- a/lib/timers.js +++ b/lib/timers.js @@ -28,7 +28,8 @@ var kOnTimeout = Timer.kOnTimeout | 0; // Timeout values > TIMEOUT_MAX are set to 1. var TIMEOUT_MAX = 2147483647; // 2^31-1 -var debug = require('util').debuglog('timer'); +var util = require('util'); +var debug = util.debuglog('timer'); // IDLE TIMEOUTS @@ -151,13 +152,21 @@ var unenroll = exports.unenroll = function(item) { // Does not start the time, just sets up the members needed. exports.enroll = function(item, msecs) { + if (!util.isNumber(msecs)) { + throw new TypeError('msecs must be a number'); + } + + if (msecs < 0 || !isFinite(msecs)) { + throw new RangeError('msecs must be a non-negative finite number'); + } + // if this item was already in a list somewhere // then we should unenroll it from that if (item._idleNext) unenroll(item); // Ensure that msecs fits into signed int32 - if (msecs > 0x7fffffff) { - msecs = 0x7fffffff; + if (msecs > TIMEOUT_MAX) { + msecs = TIMEOUT_MAX; } item._idleTimeout = msecs; diff --git a/test/simple/test-net-settimeout.js b/test/simple/test-net-settimeout.js index da13385b9..bce73584f 100644 --- a/test/simple/test-net-settimeout.js +++ b/test/simple/test-net-settimeout.js @@ -33,7 +33,7 @@ var server = net.createServer(function(c) { }); server.listen(common.PORT); -var killers = [0, Infinity, NaN]; +var killers = [0]; var left = killers.length; killers.forEach(function(killer) { diff --git a/test/simple/test-net-socket-timeout.js b/test/simple/test-net-socket-timeout.js index 2256d6813..7f874c0ce 100644 --- a/test/simple/test-net-socket-timeout.js +++ b/test/simple/test-net-socket-timeout.js @@ -23,6 +23,31 @@ var common = require('../common'); var net = require('net'); var assert = require('assert'); +// Verify that invalid delays throw +var noop = function() {}; +var s = new net.Socket(); +var nonNumericDelays = ['100', true, false, undefined, null, '', {}, noop, []]; +var badRangeDelays = [-0.001, -1, -Infinity, Infinity, NaN]; +var validDelays = [0, 0.001, 1, 1e6]; + +for (var i = 0; i < nonNumericDelays.length; i++) { + assert.throws(function() { + s.setTimeout(nonNumericDelays[i], noop); + }, TypeError); +} + +for (var i = 0; i < badRangeDelays.length; i++) { + assert.throws(function() { + s.setTimeout(badRangeDelays[i], noop); + }, RangeError); +} + +for (var i = 0; i < validDelays.length; i++) { + assert.doesNotThrow(function() { + s.setTimeout(validDelays[i], noop); + }); +} + var timedout = false; var server = net.Server(); |