Skip to content

Commit 9d2b89d

Browse files
committed
net: allow port 0 in connect()
The added validation allows non-negative numbers and numeric strings. All other values result in a thrown exception. Fixes: nodejs/node-v0.x-archive#9194 PR-URL: nodejs/node-v0.x-archive#9268 Reviewed-By: Julien Gilli <[email protected]> Reviewed-By: Trevor Norris <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 31421af commit 9d2b89d

File tree

4 files changed

+97
-33
lines changed

4 files changed

+97
-33
lines changed

lib/net.js

+11-3
Original file line numberDiff line numberDiff line change
@@ -882,7 +882,7 @@ Socket.prototype.connect = function(options, cb) {
882882
} else {
883883
const dns = require('dns');
884884
var host = options.host || 'localhost';
885-
var port = options.port | 0;
885+
var port = 0;
886886
var localAddress = options.localAddress;
887887
var localPort = options.localPort;
888888
var dnsopts = {
@@ -896,8 +896,16 @@ Socket.prototype.connect = function(options, cb) {
896896
if (localPort && typeof localPort !== 'number')
897897
throw new TypeError('localPort should be a number: ' + localPort);
898898

899-
if (port <= 0 || port > 65535)
900-
throw new RangeError('port should be > 0 and < 65536: ' + port);
899+
if (typeof options.port === 'number')
900+
port = options.port;
901+
else if (typeof options.port === 'string')
902+
port = options.port.trim() === '' ? -1 : +options.port;
903+
else if (options.port !== undefined)
904+
throw new TypeError('port should be a number or string: ' + options.port);
905+
906+
if (port < 0 || port > 65535 || isNaN(port))
907+
throw new RangeError('port should be >= 0 and < 65536: ' +
908+
options.port);
901909

902910
if (dnsopts.family !== 4 && dnsopts.family !== 6)
903911
dnsopts.hints = dns.ADDRCONFIG | dns.V4MAPPED;

src/tcp_wrap.cc

+2-2
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ void TCPWrap::Connect(const FunctionCallbackInfo<Value>& args) {
350350

351351
CHECK(args[0]->IsObject());
352352
CHECK(args[1]->IsString());
353-
CHECK(args[2]->Uint32Value());
353+
CHECK(args[2]->IsUint32());
354354

355355
Local<Object> req_wrap_obj = args[0].As<Object>();
356356
node::Utf8Value ip_address(env->isolate(), args[1]);
@@ -381,7 +381,7 @@ void TCPWrap::Connect6(const FunctionCallbackInfo<Value>& args) {
381381

382382
CHECK(args[0]->IsObject());
383383
CHECK(args[1]->IsString());
384-
CHECK(args[2]->Uint32Value());
384+
CHECK(args[2]->IsUint32());
385385

386386
Local<Object> req_wrap_obj = args[0].As<Object>();
387387
node::Utf8Value ip_address(env->isolate(), args[1]);

test/parallel/test-net-create-connection.js

+74-8
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,99 @@ var assert = require('assert');
33
var net = require('net');
44

55
var tcpPort = common.PORT;
6+
var expectedConnections = 7;
67
var clientConnected = 0;
78
var serverConnected = 0;
89

910
var server = net.createServer(function(socket) {
1011
socket.end();
11-
if (++serverConnected === 4) {
12+
if (++serverConnected === expectedConnections) {
1213
server.close();
1314
}
1415
});
16+
1517
server.listen(tcpPort, 'localhost', function() {
1618
function cb() {
1719
++clientConnected;
1820
}
1921

22+
function fail(opts, errtype, msg) {
23+
assert.throws(function() {
24+
var client = net.createConnection(opts, cb);
25+
}, function (err) {
26+
return err instanceof errtype && msg === err.message;
27+
});
28+
}
29+
2030
net.createConnection(tcpPort).on('connect', cb);
2131
net.createConnection(tcpPort, 'localhost').on('connect', cb);
2232
net.createConnection(tcpPort, cb);
2333
net.createConnection(tcpPort, 'localhost', cb);
34+
net.createConnection(tcpPort + '', 'localhost', cb);
35+
net.createConnection({port: tcpPort + ''}).on('connect', cb);
36+
net.createConnection({port: '0x' + tcpPort.toString(16)}, cb);
37+
38+
fail({
39+
port: true
40+
}, TypeError, 'port should be a number or string: true');
41+
42+
fail({
43+
port: false
44+
}, TypeError, 'port should be a number or string: false');
45+
46+
fail({
47+
port: []
48+
}, TypeError, 'port should be a number or string: ');
49+
50+
fail({
51+
port: {}
52+
}, TypeError, 'port should be a number or string: [object Object]');
53+
54+
fail({
55+
port: null
56+
}, TypeError, 'port should be a number or string: null');
57+
58+
fail({
59+
port: ''
60+
}, RangeError, 'port should be >= 0 and < 65536: ');
61+
62+
fail({
63+
port: ' '
64+
}, RangeError, 'port should be >= 0 and < 65536: ');
2465

25-
assert.throws(function () {
26-
net.createConnection({
27-
port: 'invalid!'
28-
}, cb);
29-
});
66+
fail({
67+
port: '0x'
68+
}, RangeError, 'port should be >= 0 and < 65536: 0x');
69+
70+
fail({
71+
port: '-0x1'
72+
}, RangeError, 'port should be >= 0 and < 65536: -0x1');
73+
74+
fail({
75+
port: NaN
76+
}, RangeError, 'port should be >= 0 and < 65536: NaN');
77+
78+
fail({
79+
port: Infinity
80+
}, RangeError, 'port should be >= 0 and < 65536: Infinity');
81+
82+
fail({
83+
port: -1
84+
}, RangeError, 'port should be >= 0 and < 65536: -1');
85+
86+
fail({
87+
port: 65536
88+
}, RangeError, 'port should be >= 0 and < 65536: 65536');
3089
});
3190

32-
process.on('exit', function() {
33-
assert.equal(clientConnected, 4);
91+
// Try connecting to random ports, but do so once the server is closed
92+
server.on('close', function() {
93+
function nop() {}
94+
95+
net.createConnection({port: 0}).on('error', nop);
96+
net.createConnection({port: undefined}).on('error', nop);
3497
});
3598

99+
process.on('exit', function() {
100+
assert.equal(clientConnected, expectedConnections);
101+
});

test/parallel/test-net-localerror.js

+10-20
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,17 @@ var common = require('../common');
22
var assert = require('assert');
33
var net = require('net');
44

5-
connect({
6-
host: 'localhost',
7-
port: common.PORT,
8-
localPort: 'foobar',
9-
}, 'localPort should be a number: foobar');
5+
connect({
6+
host: 'localhost',
7+
port: common.PORT,
8+
localPort: 'foobar',
9+
}, 'localPort should be a number: foobar');
1010

11-
connect({
12-
host: 'localhost',
13-
port: common.PORT,
14-
localAddress: 'foobar',
15-
}, 'localAddress should be a valid IP: foobar');
16-
17-
connect({
18-
host: 'localhost',
19-
port: 65536
20-
}, 'port should be > 0 and < 65536: 65536');
21-
22-
connect({
23-
host: 'localhost',
24-
port: 0
25-
}, 'port should be > 0 and < 65536: 0');
11+
connect({
12+
host: 'localhost',
13+
port: common.PORT,
14+
localAddress: 'foobar',
15+
}, 'localAddress should be a valid IP: foobar');
2616

2717
function connect(opts, msg) {
2818
assert.throws(function() {

0 commit comments

Comments
 (0)