summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcjihrig <cjihrig@gmail.com>2014-12-16 17:17:28 -0500
committercjihrig <cjihrig@gmail.com>2015-01-22 13:14:05 -0500
commitf34757398fcc393685b4dfbcbdc692fb38332d6c (patch)
treed81527d66fb1fc4bf122b70a662b76f80f74f553
parentf2b378b850b3bc5ac7e30fb7a204ef19ca4f8604 (diff)
downloadnode-new-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.js12
-rw-r--r--lib/timers.js15
-rw-r--r--test/simple/test-net-settimeout.js2
-rw-r--r--test/simple/test-net-socket-timeout.js25
4 files changed, 44 insertions, 10 deletions
diff --git a/lib/net.js b/lib/net.js
index 5ce970ffef..d353ff70b0 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 08a9dd5558..5ef5f37ed7 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 da13385b94..bce73584fe 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 2256d6813a..7f874c0cef 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();