Skip to content
This repository was archived by the owner on Apr 22, 2023. It is now read-only.

Commit f347573

Browse files
committed
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: #8618 PR-URL: #8884 Reviewed-By: Trevor Norris <trev.norris@gmail.com> Reviewed-By: Timothy J Fontaine <tjfontaine@gmail.com>
1 parent f2b378b commit f347573

File tree

4 files changed

+44
-10
lines changed

4 files changed

+44
-10
lines changed

lib/net.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -320,17 +320,17 @@ Socket.prototype.listen = function() {
320320

321321

322322
Socket.prototype.setTimeout = function(msecs, callback) {
323-
if (msecs > 0 && isFinite(msecs)) {
323+
if (msecs === 0) {
324+
timers.unenroll(this);
325+
if (callback) {
326+
this.removeListener('timeout', callback);
327+
}
328+
} else {
324329
timers.enroll(this, msecs);
325330
timers._unrefActive(this);
326331
if (callback) {
327332
this.once('timeout', callback);
328333
}
329-
} else if (msecs === 0) {
330-
timers.unenroll(this);
331-
if (callback) {
332-
this.removeListener('timeout', callback);
333-
}
334334
}
335335
};
336336

lib/timers.js

+12-3
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ var kOnTimeout = Timer.kOnTimeout | 0;
2828
// Timeout values > TIMEOUT_MAX are set to 1.
2929
var TIMEOUT_MAX = 2147483647; // 2^31-1
3030

31-
var debug = require('util').debuglog('timer');
31+
var util = require('util');
32+
var debug = util.debuglog('timer');
3233

3334

3435
// IDLE TIMEOUTS
@@ -151,13 +152,21 @@ var unenroll = exports.unenroll = function(item) {
151152

152153
// Does not start the time, just sets up the members needed.
153154
exports.enroll = function(item, msecs) {
155+
if (!util.isNumber(msecs)) {
156+
throw new TypeError('msecs must be a number');
157+
}
158+
159+
if (msecs < 0 || !isFinite(msecs)) {
160+
throw new RangeError('msecs must be a non-negative finite number');
161+
}
162+
154163
// if this item was already in a list somewhere
155164
// then we should unenroll it from that
156165
if (item._idleNext) unenroll(item);
157166

158167
// Ensure that msecs fits into signed int32
159-
if (msecs > 0x7fffffff) {
160-
msecs = 0x7fffffff;
168+
if (msecs > TIMEOUT_MAX) {
169+
msecs = TIMEOUT_MAX;
161170
}
162171

163172
item._idleTimeout = msecs;

test/simple/test-net-settimeout.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ var server = net.createServer(function(c) {
3333
});
3434
server.listen(common.PORT);
3535

36-
var killers = [0, Infinity, NaN];
36+
var killers = [0];
3737

3838
var left = killers.length;
3939
killers.forEach(function(killer) {

test/simple/test-net-socket-timeout.js

+25
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,31 @@ var common = require('../common');
2323
var net = require('net');
2424
var assert = require('assert');
2525

26+
// Verify that invalid delays throw
27+
var noop = function() {};
28+
var s = new net.Socket();
29+
var nonNumericDelays = ['100', true, false, undefined, null, '', {}, noop, []];
30+
var badRangeDelays = [-0.001, -1, -Infinity, Infinity, NaN];
31+
var validDelays = [0, 0.001, 1, 1e6];
32+
33+
for (var i = 0; i < nonNumericDelays.length; i++) {
34+
assert.throws(function() {
35+
s.setTimeout(nonNumericDelays[i], noop);
36+
}, TypeError);
37+
}
38+
39+
for (var i = 0; i < badRangeDelays.length; i++) {
40+
assert.throws(function() {
41+
s.setTimeout(badRangeDelays[i], noop);
42+
}, RangeError);
43+
}
44+
45+
for (var i = 0; i < validDelays.length; i++) {
46+
assert.doesNotThrow(function() {
47+
s.setTimeout(validDelays[i], noop);
48+
});
49+
}
50+
2651
var timedout = false;
2752

2853
var server = net.Server();

0 commit comments

Comments
 (0)