Skip to content

Commit b636ba8

Browse files
committed
net: make connect() input validation synchronous
Socket.prototype.connect() sometimes throws on bad inputs after an asynchronous operation. This commit makes the input validation synchronous. This commit also removes some hard coded IP addresses. PR-URL: nodejs/node-v0.x-archive#8180 Fixes: nodejs/node-v0.x-archive#8140 Reviewed-By: Trevor Norris <[email protected]> Reviewed-By: Fedor Indutny <[email protected]> Reviewed-By: Timothy J Fontaine <[email protected]>
1 parent 8cfbeed commit b636ba8

File tree

3 files changed

+65
-81
lines changed

3 files changed

+65
-81
lines changed

lib/net.js

+29-48
Original file line numberDiff line numberDiff line change
@@ -785,34 +785,18 @@ function connect(self, address, port, addressType, localAddress, localPort) {
785785
assert.ok(self._connecting);
786786

787787
var err;
788-
if (localAddress || localPort) {
789-
if (localAddress && !exports.isIP(localAddress))
790-
err = new TypeError(
791-
'localAddress should be a valid IP: ' + localAddress);
792-
793-
if (localPort && !util.isNumber(localPort))
794-
err = new TypeError('localPort should be a number: ' + localPort);
795788

789+
if (localAddress || localPort) {
796790
var bind;
797791

798-
switch (addressType) {
799-
case 4:
800-
if (!localAddress)
801-
localAddress = '0.0.0.0';
802-
bind = self._handle.bind;
803-
break;
804-
case 6:
805-
if (!localAddress)
806-
localAddress = '::';
807-
bind = self._handle.bind6;
808-
break;
809-
default:
810-
err = new TypeError('Invalid addressType: ' + addressType);
811-
break;
812-
}
813-
814-
if (err) {
815-
self._destroy(err);
792+
if (addressType === 4) {
793+
localAddress = localAddress || '0.0.0.0';
794+
bind = self._handle.bind;
795+
} else if (addressType === 6) {
796+
localAddress = localAddress || '::';
797+
bind = self._handle.bind6;
798+
} else {
799+
self._destroy(new TypeError('Invalid addressType: ' + addressType));
816800
return;
817801
}
818802

@@ -832,15 +816,12 @@ function connect(self, address, port, addressType, localAddress, localPort) {
832816
if (addressType === 6 || addressType === 4) {
833817
var req = new TCPConnectWrap();
834818
req.oncomplete = afterConnect;
835-
port = port | 0;
836-
if (port <= 0 || port > 65535)
837-
throw new RangeError('Port should be > 0 and < 65536');
838819

839-
if (addressType === 6) {
840-
err = self._handle.connect6(req, address, port);
841-
} else if (addressType === 4) {
820+
if (addressType === 4)
842821
err = self._handle.connect(req, address, port);
843-
}
822+
else
823+
err = self._handle.connect6(req, address, port);
824+
844825
} else {
845826
var req = new PipeConnectWrap();
846827
req.oncomplete = afterConnect;
@@ -898,19 +879,26 @@ Socket.prototype.connect = function(options, cb) {
898879
if (pipe) {
899880
connect(self, options.path);
900881

901-
} else if (!options.host) {
902-
debug('connect: missing host');
903-
self._host = '127.0.0.1';
904-
connect(self, self._host, options.port, 4);
905-
906882
} else {
907883
var dns = require('dns');
908-
var host = options.host;
884+
var host = options.host || 'localhost';
885+
var port = options.port | 0;
886+
var localAddress = options.localAddress;
887+
var localPort = options.localPort;
909888
var dnsopts = {
910889
family: options.family,
911890
hints: 0
912891
};
913892

893+
if (localAddress && !exports.isIP(localAddress))
894+
throw new TypeError('localAddress must be a valid IP: ' + localAddress);
895+
896+
if (localPort && !util.isNumber(localPort))
897+
throw new TypeError('localPort should be a number: ' + localPort);
898+
899+
if (port <= 0 || port > 65535)
900+
throw new RangeError('port should be > 0 and < 65536: ' + port);
901+
914902
if (dnsopts.family !== 4 && dnsopts.family !== 6)
915903
dnsopts.hints = dns.ADDRCONFIG | dns.V4MAPPED;
916904

@@ -936,19 +924,12 @@ Socket.prototype.connect = function(options, cb) {
936924
});
937925
} else {
938926
timers._unrefActive(self);
939-
940-
addressType = addressType || 4;
941-
942-
// node_net.cc handles null host names graciously but user land
943-
// expects remoteAddress to have a meaningful value
944-
ip = ip || (addressType === 4 ? '127.0.0.1' : '0:0:0:0:0:0:0:1');
945-
946927
connect(self,
947928
ip,
948-
options.port,
929+
port,
949930
addressType,
950-
options.localAddress,
951-
options.localPort);
931+
localAddress,
932+
localPort);
952933
}
953934
});
954935
}

test/simple/test-net-localerror.js

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

26-
var server = net.createServer(function(socket) {
27-
assert.ok(false, 'no clients should connect');
28-
}).listen(common.PORT).on('listening', function() {
29-
server.unref();
26+
connect({
27+
host: 'localhost',
28+
port: common.PORT,
29+
localPort: 'foobar',
30+
}, 'localPort should be a number: foobar');
3031

31-
function test1(next) {
32-
connect({
33-
host: '127.0.0.1',
34-
port: common.PORT,
35-
localPort: 'foobar',
36-
},
37-
'localPort should be a number: foobar',
38-
next);
39-
}
32+
connect({
33+
host: 'localhost',
34+
port: common.PORT,
35+
localAddress: 'foobar',
36+
}, 'localAddress should be a valid IP: foobar');
4037

41-
function test2(next) {
42-
connect({
43-
host: '127.0.0.1',
44-
port: common.PORT,
45-
localAddress: 'foobar',
46-
},
47-
'localAddress should be a valid IP: foobar',
48-
next)
49-
}
38+
connect({
39+
host: 'localhost',
40+
port: 65536
41+
}, 'port should be > 0 and < 65536: 65536');
5042

51-
test1(test2);
52-
})
43+
connect({
44+
host: 'localhost',
45+
port: 0
46+
}, 'port should be > 0 and < 65536: 0');
5347

54-
function connect(opts, msg, cb) {
55-
var client = net.connect(opts).on('connect', function() {
56-
assert.ok(false, 'we should never connect');
57-
}).on('error', function(err) {
58-
assert.strictEqual(err.message, msg);
59-
if (cb) cb();
60-
});
48+
function connect(opts, msg) {
49+
assert.throws(function() {
50+
var client = net.connect(opts);
51+
}, msg);
6152
}

test/simple/test-process-active-wraps.js

+14-2
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,16 @@ var handles = [];
4141
})();
4242

4343
(function() {
44+
function onlookup() {
45+
setImmediate(function() {
46+
assert.equal(process._getActiveRequests().length, 0);
47+
});
48+
};
49+
4450
expect(1, 0);
4551
var conn = net.createConnection(common.PORT);
46-
conn.on('error', function() { /* ignore */ });
52+
conn.on('lookup', onlookup);
53+
conn.on('error', function() { assert(false); });
4754
expect(2, 1);
4855
conn.destroy();
4956
expect(2, 1); // client handle doesn't shut down until next tick
@@ -52,10 +59,15 @@ var handles = [];
5259

5360
(function() {
5461
var n = 0;
62+
5563
handles.forEach(function(handle) {
5664
handle.once('close', onclose);
5765
});
5866
function onclose() {
59-
if (++n === handles.length) setImmediate(expect, 0, 0);
67+
if (++n === handles.length) {
68+
setImmediate(function() {
69+
assert.equal(process._getActiveHandles().length, 0);
70+
});
71+
}
6072
}
6173
})();

0 commit comments

Comments
 (0)