Skip to content
Merged
Changes from 1 commit
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
3c54f81
tty: add ref() so process.stdin.ref() etc. work
insightfuls Jul 19, 2016
11aea26
doc: fix typo in STYLE_GUIDE.md
seishun Feb 28, 2017
d329abf
doc: use common malformed instead of misformatted
jsumners Feb 23, 2017
1b6ba9e
src: do not ignore IDNA conversion error
TimothyGu Feb 25, 2017
6a5d961
test: more comprehensive IDNA test cases
TimothyGu Feb 25, 2017
b968491
doc: document WHATWG IDNA methods' error handling
TimothyGu Feb 25, 2017
b116830
doc: add link to references in net.Socket
joyeecheung Mar 1, 2017
2601c06
test: skip tests with common.skip
thefourtheye Feb 27, 2017
a0c117b
doc: fixup errors.md
vsemozhetbyt Feb 26, 2017
13cb8a6
net: remove misleading comment
bnoordhuis Feb 27, 2017
4f92536
test: apply strict mode in test-repl
Trott Feb 27, 2017
83c7b24
doc: fix typo in stream doc
bradley-curran Feb 26, 2017
5963566
meta: remove out of date ROADMAP.md file
jasnell Feb 25, 2017
e468cd3
doc: argument types for console methods
ameliavoncat Feb 25, 2017
cdee945
test: improve https coverage to check create connection
Feb 17, 2017
163d2d1
timers: unlock the timers API
Trott Feb 27, 2017
924b785
test: fix test-internal-util-assertCrypto regex
danbev Feb 28, 2017
91a222d
test: enable max-len for test-repl
Trott Feb 26, 2017
00dd20c
test: fix flaky test-https-agent-create-connection
santigimeno Mar 2, 2017
3e79dff
doc: fix WHATWG URL url.protocol example
richardlau Mar 2, 2017
1445e28
test: add test-buffer-prototype-inspect
Trott Feb 28, 2017
02dbae6
buffer: refactor Buffer.prototype.inspect()
Trott Feb 28, 2017
ac3deb1
tools: remove NODE_PATH from environment for tests
Trott Feb 28, 2017
e2133f3
os: improve cpus() performance
mscdex Feb 26, 2017
d6ac192
tls: fix macro to check NPN feature
shigeki Mar 2, 2017
8377374
test: fix tests when npn feature is disabled.
shigeki Mar 2, 2017
a4d1436
test: fix args in parallel/test-fs-null-bytes.js
vsemozhetbyt Mar 3, 2017
98d3328
doc: add `Daijiro Wachi` to collaborators
watilde Mar 3, 2017
f972bd8
inspector: libuv notification on incoming message
Feb 16, 2017
f56ca30
benchmark,build,doc,lib,src,test: correct typos
bf4 Feb 6, 2017
24e6fcc
url: use `hasIntl` instead of `try-catch`
watilde Feb 28, 2017
f69685b
test: remove obsolete eslint-disable comment
Trott Mar 2, 2017
821d713
src: remove outdated FIXME in node_crypto.cc
danbev Mar 3, 2017
039a1a9
dns: minor refactor of dns module
jasnell Feb 28, 2017
b4dcb26
test: changed test1 of test-vm-timeout.js
moe-dizzle Feb 27, 2017
5df9110
test: check the origin of the blob URLs
watilde Mar 5, 2017
d06dbf0
doc: fix misleading ASCII comments
rahatarmanahmed Mar 2, 2017
986d391
doc: unlock module
Trott Mar 2, 2017
d5c4363
doc: remove Locked from stability index
Trott Mar 2, 2017
8402888
doc: fix broken URL to event loop guide
sushi90 Mar 3, 2017
7b84363
util: fix inspecting symbol key in string
barinali Mar 3, 2017
3b27b8d
doc: fixed readable.isPaused() version annotation
lfortin Mar 3, 2017
ed6d741
deps: fix CLEAR_HASH macro to be usable as a single statement
sam-github Feb 28, 2017
fdb4a6c
test: skip the test with proper TAP message
thefourtheye Feb 27, 2017
e5b530c
build: fix llvm version detection in freebsd-10
shigeki Mar 3, 2017
a7eba9c
meta: move WORKING_GROUPS.md to CTC repo
jasnell Feb 25, 2017
b56e851
net: refactor overloaded argument handling
joyeecheung Mar 3, 2017
a7d3798
2017-03-08, Version 7.7.2 (Current)
evanlucas Mar 8, 2017
c627980
Working on v7.7.3
evanlucas Mar 8, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
net: refactor overloaded argument handling
* Make normalizeArgs return either [options, null] or [options, cb]
  (the second element won't be undefined anymore) and avoid OOB read
* Use Socket.prototype.connect.call instead of .apply when the number
  of arguments is certain(returned by normalizeArgs).
* Rename some args[i] for readability
* Refactor Server.prototype.listen, separate backlogFromArgs and
  options.backlog, comment the overloading process, refactor control
  flow

PR-URL: #11667
Reviewed-By: Matteo Collina <[email protected]>
Reviewed-By: James M Snell <[email protected]>
  • Loading branch information
joyeecheung authored and evanlucas committed Mar 8, 2017
commit b56e851c4813bdec86e47e84d7c18527a01d4ffd
170 changes: 101 additions & 69 deletions lib/net.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ var cluster;
const errnoException = util._errnoException;
const exceptionWithHostPort = util._exceptionWithHostPort;
const isLegalPort = internalNet.isLegalPort;
const assertPort = internalNet.assertPort;

function noop() {}

Expand Down Expand Up @@ -60,46 +59,60 @@ exports.createServer = function(options, connectionListener) {
// connect(path, [cb]);
//
exports.connect = exports.createConnection = function() {
var args = new Array(arguments.length);
const args = new Array(arguments.length);
for (var i = 0; i < arguments.length; i++)
args[i] = arguments[i];
args = normalizeArgs(args);
debug('createConnection', args);
var s = new Socket(args[0]);
// TODO(joyeecheung): use destructuring when V8 is fast enough
const normalized = normalizeArgs(args);
const options = normalized[0];
const cb = normalized[1];
debug('createConnection', normalized);
const socket = new Socket(options);

if (args[0].timeout) {
s.setTimeout(args[0].timeout);
if (options.timeout) {
socket.setTimeout(options.timeout);
}

return Socket.prototype.connect.apply(s, args);
return Socket.prototype.connect.call(socket, options, cb);
};

// Returns an array [options, cb], where cb can be null.
// It is the same as the argument of Socket.prototype.connect().
// This is used by Server.prototype.listen() and Socket.prototype.connect().
function normalizeArgs(args) {
var options = {};

// Returns an array [options, cb], where options is an object,
// cb is either a funciton or null.
// Used to normalize arguments of Socket.prototype.connect() and
// Server.prototype.listen(). Possible combinations of paramters:
// (options[...][, cb])
// (path[...][, cb])
// ([port][, host][...][, cb])
// For Socket.prototype.connect(), the [...] part is ignored
// For Server.prototype.listen(), the [...] part is [, backlog]
// but will not be handled here (handled in listen())
function normalizeArgs(args) {
if (args.length === 0) {
return [options];
} else if (args[0] !== null && typeof args[0] === 'object') {
// connect(options, [cb])
options = args[0];
} else if (isPipeName(args[0])) {
// connect(path, [cb]);
options.path = args[0];
return [{}, null];
}

const arg0 = args[0];
var options = {};
if (typeof arg0 === 'object' && arg0 !== null) {
// (options[...][, cb])
options = arg0;
} else if (isPipeName(arg0)) {
// (path[...][, cb])
options.path = arg0;
} else {
// connect(port, [host], [cb])
options.port = args[0];
// ([port][, host][...][, cb])
options.port = arg0;
if (args.length > 1 && typeof args[1] === 'string') {
options.host = args[1];
}
}

var cb = args[args.length - 1];
if (typeof cb !== 'function')
cb = null;
return [options, cb];
return [options, null];
else
return [options, cb];
}
exports._normalizeArgs = normalizeArgs;

Expand Down Expand Up @@ -892,13 +905,16 @@ Socket.prototype.connect = function(options, cb) {

if (options === null || typeof options !== 'object') {
// Old API:
// connect(port, [host], [cb])
// connect(path, [cb]);
var args = new Array(arguments.length);
// connect(port[, host][, cb])
// connect(path[, cb]);
const args = new Array(arguments.length);
for (var i = 0; i < arguments.length; i++)
args[i] = arguments[i];
args = normalizeArgs(args);
return Socket.prototype.connect.apply(this, args);
const normalized = normalizeArgs(args);
const normalizedOptions = normalized[0];
const normalizedCb = normalized[1];
return Socket.prototype.connect.call(this,
normalizedOptions, normalizedCb);
}

if (this.destroyed) {
Expand All @@ -923,7 +939,7 @@ Socket.prototype.connect = function(options, cb) {
initSocketHandle(this);
}

if (typeof cb === 'function') {
if (cb !== null) {
this.once('connect', cb);
}

Expand Down Expand Up @@ -1333,57 +1349,73 @@ function listen(self, address, port, addressType, backlog, fd, exclusive) {


Server.prototype.listen = function() {
var args = new Array(arguments.length);
const args = new Array(arguments.length);
for (var i = 0; i < arguments.length; i++)
args[i] = arguments[i];
var [options, cb] = normalizeArgs(args);
// TODO(joyeecheung): use destructuring when V8 is fast enough
const normalized = normalizeArgs(args);
var options = normalized[0];
const cb = normalized[1];

if (typeof cb === 'function') {
var hasCallback = (cb !== null);
if (hasCallback) {
this.once('listening', cb);
}

if (args.length === 0 || typeof args[0] === 'function') {
// Bind to a random port.
options.port = 0;
}

// The third optional argument is the backlog size.
// When the ip is omitted it can be the second argument.
var backlog = toNumber(args.length > 1 && args[1]) ||
toNumber(args.length > 2 && args[2]);
const backlogFromArgs =
// (handle, backlog) or (path, backlog) or (port, backlog)
toNumber(args.length > 1 && args[1]) ||
toNumber(args.length > 2 && args[2]); // (port, host, backlog)

options = options._handle || options.handle || options;

// (handle[, backlog][, cb]) where handle is an object with a handle
if (options instanceof TCP) {
this._handle = options;
listen(this, null, -1, -1, backlog);
} else if (typeof options.fd === 'number' && options.fd >= 0) {
listen(this, null, null, null, backlog, options.fd);
} else {
backlog = options.backlog || backlog;

if (typeof options.port === 'number' || typeof options.port === 'string' ||
(typeof options.port === 'undefined' && 'port' in options)) {
// Undefined is interpreted as zero (random port) for consistency
// with net.connect().
assertPort(options.port);
if (options.host) {
lookupAndListen(this, options.port | 0, options.host, backlog,
options.exclusive);
} else {
listen(this, null, options.port | 0, 4, backlog, undefined,
options.exclusive);
}
} else if (options.path && isPipeName(options.path)) {
// UNIX socket or Windows pipe.
const pipeName = this._pipeName = options.path;
listen(this, pipeName, -1, -1, backlog, undefined, options.exclusive);
} else {
throw new Error('Invalid listen argument: ' + options);
listen(this, null, -1, -1, backlogFromArgs);
return this;
}
// (handle[, backlog][, cb]) where handle is an object with a fd
if (typeof options.fd === 'number' && options.fd >= 0) {
listen(this, null, null, null, backlogFromArgs, options.fd);
return this;
}

// ([port][, host][, backlog][, cb]) where port is omitted,
// that is, listen() or listen(cb),
// or (options[, cb]) where options.port is explicitly set as undefined,
// bind to an arbitrary unused port
if (args.length === 0 || typeof args[0] === 'function' ||
(typeof options.port === 'undefined' && 'port' in options)) {
options.port = 0;
}
// ([port][, host][, backlog][, cb]) where port is specified
// or (options[, cb]) where options.port is specified
// or if options.port is normalized as 0 before
if (typeof options.port === 'number' || typeof options.port === 'string') {
if (!isLegalPort(options.port)) {
throw new RangeError('"port" argument must be >= 0 and < 65536');
}
const backlog = options.backlog || backlogFromArgs;
// start TCP server listening on host:port
if (options.host) {
lookupAndListen(this, options.port | 0, options.host, backlog,
options.exclusive);
} else { // Undefined host, listens on unspecified address
listen(this, null, options.port | 0, 4, // addressType will be ignored
backlog, undefined, options.exclusive);
}
return this;
}

return this;
// (path[, backlog][, cb]) or (options[, cb])
// where path or options.path is a UNIX domain socket or Windows pipe
if (options.path && isPipeName(options.path)) {
const pipeName = this._pipeName = options.path;
const backlog = options.backlog || backlogFromArgs;
listen(this, pipeName, -1, -1, backlog, undefined, options.exclusive);
return this;
}

throw new Error('Invalid listen argument: ' + options);
};

function lookupAndListen(self, port, address, backlog, exclusive) {
Expand Down