From 14e3ad0c5ecc092de9fa986a6722e34f55e4d88c Mon Sep 17 00:00:00 2001 From: Eugene Ostroukhov Date: Wed, 1 Mar 2017 15:52:43 -0800 Subject: [PATCH 01/48] inspector: proper WS URLs when bound to 0.0.0.0 JSON target list response will now return appropriate IP address for instances listening on 0.0.0.0. Backport of https://github.com/nodejs/node/pull/11755 PR-URL: https://github.com/nodejs/node/pull/11850 Refs: https://github.com/nodejs/node/issues/11591 Reviewed-By: Ben Noordhuis Reviewed-By: Italo A. Casas Reviewed-By: James Snell --- src/inspector_socket_server.cc | 26 +++++++++- test/inspector/inspector-helper.js | 25 +++++---- test/inspector/test-inspector-ip-detection.js | 52 +++++++++++++++++++ test/inspector/test-inspector.js | 12 ++--- 4 files changed, 99 insertions(+), 16 deletions(-) create mode 100644 test/inspector/test-inspector-ip-detection.js diff --git a/src/inspector_socket_server.cc b/src/inspector_socket_server.cc index ee44a69a683690..1c8fa70b65a3b3 100644 --- a/src/inspector_socket_server.cc +++ b/src/inspector_socket_server.cc @@ -139,6 +139,28 @@ void SendProtocolJson(InspectorSocket* socket) { SendHttpResponse(socket, data); } +int GetSocketHost(uv_tcp_t* socket, std::string* out_host) { + char ip[INET6_ADDRSTRLEN]; + sockaddr_storage addr; + int len = sizeof(addr); + int err = uv_tcp_getsockname(socket, + reinterpret_cast(&addr), + &len); + if (err != 0) + return err; + if (addr.ss_family == AF_INET6) { + const sockaddr_in6* v6 = reinterpret_cast(&addr); + err = uv_ip6_name(v6, ip, sizeof(ip)); + } else { + const sockaddr_in* v4 = reinterpret_cast(&addr); + err = uv_ip4_name(v4, ip, sizeof(ip)); + } + if (err != 0) + return err; + *out_host = ip; + return err; +} + int GetPort(uv_tcp_t* socket, int* out_port) { sockaddr_storage addr; int len = sizeof(addr); @@ -341,7 +363,9 @@ void InspectorSocketServer::SendListResponse(InspectorSocket* socket) { } } if (!connected) { - std::string address = GetWsUrl(host_, port_, id); + std::string host; + GetSocketHost(&socket->client, &host); + std::string address = GetWsUrl(host, port_, id); std::ostringstream frontend_url; frontend_url << "chrome-devtools://devtools/bundled"; frontend_url << "/inspector.html?experiments=true&v8only=true&ws="; diff --git a/test/inspector/inspector-helper.js b/test/inspector/inspector-helper.js index beaf1a8aa1a3fd..004f4f93e4c309 100644 --- a/test/inspector/inspector-helper.js +++ b/test/inspector/inspector-helper.js @@ -80,8 +80,8 @@ function tearDown(child, err) { } } -function checkHttpResponse(port, path, callback) { - http.get({port, path}, function(res) { +function checkHttpResponse(host, port, path, callback, errorcb) { + const req = http.get({host, port, path}, function(res) { let response = ''; res.setEncoding('utf8'); res @@ -98,6 +98,8 @@ function checkHttpResponse(port, path, callback) { callback(err, json); }); }); + if (errorcb) + req.on('error', errorcb); } function makeBufferingDataCallback(dataCallback) { @@ -295,7 +297,7 @@ TestSession.prototype.disconnect = function(childDone) { TestSession.prototype.testHttpResponse = function(path, check) { return this.enqueue((callback) => - checkHttpResponse(this.harness_.port, path, (err, response) => { + checkHttpResponse(null, this.harness_.port, path, (err, response) => { check.call(this, err, response); callback(); })); @@ -361,12 +363,17 @@ Harness.prototype.enqueue_ = function(task) { return this; }; -Harness.prototype.testHttpResponse = function(path, check) { +Harness.prototype.testHttpResponse = function(host, path, check, errorcb) { return this.enqueue_((doneCallback) => { - checkHttpResponse(this.port, path, (err, response) => { - check.call(this, err, response); - doneCallback(); - }); + function wrap(callback) { + if (callback) { + return function() { + callback(...arguments); + doneCallback(); + }; + } + } + checkHttpResponse(host, this.port, path, wrap(check), wrap(errorcb)); }); }; @@ -404,7 +411,7 @@ Harness.prototype.wsHandshake = function(devtoolsUrl, tests, readyCallback) { Harness.prototype.runFrontendSession = function(tests) { return this.enqueue_((callback) => { - checkHttpResponse(this.port, '/json/list', (err, response) => { + checkHttpResponse(null, this.port, '/json/list', (err, response) => { assert.ifError(err); this.wsHandshake(response[0]['webSocketDebuggerUrl'], tests, callback); }); diff --git a/test/inspector/test-inspector-ip-detection.js b/test/inspector/test-inspector-ip-detection.js new file mode 100644 index 00000000000000..4d138d03177d9b --- /dev/null +++ b/test/inspector/test-inspector-ip-detection.js @@ -0,0 +1,52 @@ +'use strict'; +const common = require('../common'); +common.skipIfInspectorDisabled && common.skipIfInspectorDisabled(); + +const assert = require('assert'); +const helper = require('./inspector-helper.js'); +const os = require('os'); + +const ip = pickIPv4Address(); + +if (!ip) { + common.skip('No IP address found'); + return; +} + +function checkListResponse(instance, err, response) { + assert.ifError(err); + const res = response[0]; + const wsUrl = res['webSocketDebuggerUrl']; + assert.ok(wsUrl); + const match = wsUrl.match(/^ws:\/\/(.*):9229\/(.*)/); + assert.strictEqual(ip, match[1]); + assert.strictEqual(res['id'], match[2]); + assert.strictEqual(ip, res['devtoolsFrontendUrl'].match(/.*ws=(.*):9229/)[1]); + instance.childInstanceDone = true; +} + +function checkError(instance, error) { + // Some OSes will not allow us to connect + if (error.code === 'EHOSTUNREACH') { + common.skip('Unable to connect to self'); + } else { + throw error; + } + instance.childInstanceDone = true; +} + +function runTests(instance) { + instance + .testHttpResponse(ip, '/json/list', checkListResponse.bind(null, instance), + checkError.bind(null, instance)) + .kill(); +} + +function pickIPv4Address() { + for (const i of [].concat(...Object.values(os.networkInterfaces()))) { + if (i.family === 'IPv4' && i.address !== '127.0.0.1') + return i.address; + } +} + +helper.startNodeForInspectorTest(runTests, '--inspect-brk=0.0.0.0'); diff --git a/test/inspector/test-inspector.js b/test/inspector/test-inspector.js index a1c69cb6fbb2fe..23dfa98ff62603 100644 --- a/test/inspector/test-inspector.js +++ b/test/inspector/test-inspector.js @@ -208,12 +208,12 @@ function testWaitsForFrontendDisconnect(session, harness) { function runTests(harness) { harness - .testHttpResponse('/json', checkListResponse) - .testHttpResponse('/json/list', checkListResponse) - .testHttpResponse('/json/version', checkVersion) - .testHttpResponse('/json/activate', checkBadPath) - .testHttpResponse('/json/activate/boom', checkBadPath) - .testHttpResponse('/json/badpath', checkBadPath) + .testHttpResponse(null, '/json', checkListResponse) + .testHttpResponse(null, '/json/list', checkListResponse) + .testHttpResponse(null, '/json/version', checkVersion) + .testHttpResponse(null, '/json/activate', checkBadPath) + .testHttpResponse(null, '/json/activate/boom', checkBadPath) + .testHttpResponse(null, '/json/badpath', checkBadPath) .runFrontendSession([ testNoUrlsWhenConnected, testBreakpointOnStart, From 5b1d61ce09023e7a104f28d90d974013381c3591 Mon Sep 17 00:00:00 2001 From: Vse Mozhet Byt Date: Sun, 19 Feb 2017 18:23:59 +0200 Subject: [PATCH 02/48] child_process: fix deoptimizing use of arguments Removed or fixed use of arguments in execFile(), normalizeExecArgs(), and normalizeSpawnArguments(). Refs: https://github.com/nodejs/node/issues/10323 Refs: https://bugs.chromium.org/p/v8/issues/detail?id=6010 Backport-Of: https://github.com/nodejs/node/pull/11535 PR-URL: https://github.com/nodejs/node/pull/11748 Reviewed-By: James M Snell --- .../child_process/child-process-params.js | 146 ++++++++++++++++++ lib/child_process.js | 32 ++-- 2 files changed, 158 insertions(+), 20 deletions(-) create mode 100644 benchmark/child_process/child-process-params.js diff --git a/benchmark/child_process/child-process-params.js b/benchmark/child_process/child-process-params.js new file mode 100644 index 00000000000000..644b2136a0f03f --- /dev/null +++ b/benchmark/child_process/child-process-params.js @@ -0,0 +1,146 @@ +'use strict'; + +const common = require('../common.js'); +const cp = require('child_process'); + +const command = 'echo'; +const args = ['hello']; +const options = {}; +const cb = () => {}; + +const configs = { + n: [1e3], + methodName: [ + 'exec', 'execSync', + 'execFile', 'execFileSync', + 'spawn', 'spawnSync', + ], + params: [1, 2, 3, 4], +}; + +const bench = common.createBenchmark(main, configs); + +function main(conf) { + const n = +conf.n; + const methodName = conf.methodName; + const params = +conf.params; + + const method = cp[methodName]; + + switch (methodName) { + case 'exec': + switch (params) { + case 1: + bench.start(); + for (let i = 0; i < n; i++) method(command).kill(); + bench.end(n); + break; + case 2: + bench.start(); + for (let i = 0; i < n; i++) method(command, options).kill(); + bench.end(n); + break; + case 3: + bench.start(); + for (let i = 0; i < n; i++) method(command, options, cb).kill(); + bench.end(n); + break; + } + break; + case 'execSync': + switch (params) { + case 1: + bench.start(); + for (let i = 0; i < n; i++) method(command); + bench.end(n); + break; + case 2: + bench.start(); + for (let i = 0; i < n; i++) method(command, options); + bench.end(n); + break; + } + break; + case 'execFile': + switch (params) { + case 1: + bench.start(); + for (let i = 0; i < n; i++) method(command).kill(); + bench.end(n); + break; + case 2: + bench.start(); + for (let i = 0; i < n; i++) method(command, args).kill(); + bench.end(n); + break; + case 3: + bench.start(); + for (let i = 0; i < n; i++) method(command, args, options).kill(); + bench.end(n); + break; + case 4: + bench.start(); + for (let i = 0; i < n; i++) method(command, args, options, cb).kill(); + bench.end(n); + break; + } + break; + case 'execFileSync': + switch (params) { + case 1: + bench.start(); + for (let i = 0; i < n; i++) method(command); + bench.end(n); + break; + case 2: + bench.start(); + for (let i = 0; i < n; i++) method(command, args); + bench.end(n); + break; + case 3: + bench.start(); + for (let i = 0; i < n; i++) method(command, args, options); + bench.end(n); + break; + } + break; + case 'spawn': + switch (params) { + case 1: + bench.start(); + for (let i = 0; i < n; i++) method(command).kill(); + bench.end(n); + break; + case 2: + bench.start(); + for (let i = 0; i < n; i++) method(command, args).kill(); + bench.end(n); + break; + case 3: + bench.start(); + for (let i = 0; i < n; i++) method(command, args, options).kill(); + bench.end(n); + break; + } + break; + case 'spawnSync': + switch (params) { + case 1: + bench.start(); + for (let i = 0; i < n; i++) method(command); + bench.end(n); + break; + case 2: + bench.start(); + for (let i = 0; i < n; i++) method(command, args); + bench.end(n); + break; + case 3: + bench.start(); + for (let i = 0; i < n; i++) method(command, args, options); + bench.end(n); + break; + } + break; + } +} diff --git a/lib/child_process.js b/lib/child_process.js index 2ae9e3671d23e9..b7fdb5ce8bb53f 100644 --- a/lib/child_process.js +++ b/lib/child_process.js @@ -79,16 +79,10 @@ exports._forkChild = function(fd) { }; -function normalizeExecArgs(command /*, options, callback*/) { - let options; - let callback; - - if (typeof arguments[1] === 'function') { +function normalizeExecArgs(command, options, callback) { + if (typeof options === 'function') { + callback = options; options = undefined; - callback = arguments[1]; - } else { - options = arguments[1]; - callback = arguments[2]; } // Make a shallow copy so we don't clobber the user's options object. @@ -142,7 +136,7 @@ exports.execFile = function(file /*, args, options, callback*/) { callback = arguments[pos++]; } - if (!callback && arguments[pos] != null) { + if (!callback && pos < arguments.length && arguments[pos] != null) { throw new TypeError('Incorrect value of args option'); } @@ -175,6 +169,8 @@ exports.execFile = function(file /*, args, options, callback*/) { var ex = null; + var cmd = file; + function exithandler(code, signal) { if (exited) return; exited = true; @@ -202,7 +198,6 @@ exports.execFile = function(file /*, args, options, callback*/) { return; } - var cmd = file; if (args.length !== 0) cmd += ' ' + args.join(' '); @@ -311,18 +306,15 @@ function _convertCustomFds(options) { } } -function normalizeSpawnArguments(file /*, args, options*/) { - var args, options; - - if (Array.isArray(arguments[1])) { - args = arguments[1].slice(0); - options = arguments[2]; - } else if (arguments[1] !== undefined && - (arguments[1] === null || typeof arguments[1] !== 'object')) { +function normalizeSpawnArguments(file, args, options) { + if (Array.isArray(args)) { + args = args.slice(0); + } else if (args !== undefined && + (args === null || typeof args !== 'object')) { throw new TypeError('Incorrect value of args option'); } else { + options = args; args = []; - options = arguments[1]; } if (options === undefined) From 9a5991303944d7cb8a1af9a2d97d3342b4762e0e Mon Sep 17 00:00:00 2001 From: James M Snell Date: Mon, 27 Feb 2017 09:43:40 -0800 Subject: [PATCH 03/48] util: avoid using forEach PR-URL: https://github.com/nodejs/node/pull/11582 Reviewed-By: Matteo Collina Reviewed-By: Colin Ihrig --- lib/util.js | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/lib/util.js b/lib/util.js index 8c880c674b5ad3..3378109b6126ed 100644 --- a/lib/util.js +++ b/lib/util.js @@ -682,12 +682,13 @@ function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { if (remaining > 0) { output.push(`... ${remaining} more item${remaining > 1 ? 's' : ''}`); } - keys.forEach(function(key) { + for (var n = 0; n < keys.length; n++) { + var key = keys[n]; if (typeof key === 'symbol' || !key.match(/^\d+$/)) { output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, key, true)); } - }); + } return output; } @@ -718,10 +719,10 @@ function formatSet(ctx, value, recurseTimes, visibleKeys, keys) { var str = formatValue(ctx, v, nextRecurseTimes); output.push(str); }); - keys.forEach(function(key) { + for (var n = 0; n < keys.length; n++) { output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - key, false)); - }); + keys[n], false)); + } return output; } @@ -735,10 +736,10 @@ function formatMap(ctx, value, recurseTimes, visibleKeys, keys) { str += formatValue(ctx, v, nextRecurseTimes); output.push(str); }); - keys.forEach(function(key) { + for (var n = 0; n < keys.length; n++) { output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - key, false)); - }); + keys[n], false)); + } return output; } @@ -768,10 +769,10 @@ function formatPromise(ctx, value, recurseTimes, visibleKeys, keys) { output.push(str); } } - keys.forEach(function(key) { + for (var n = 0; n < keys.length; n++) { output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - key, false)); - }); + keys[n], false)); + } return output; } From 540830116be5617cfd02407fecda2e6941f35296 Mon Sep 17 00:00:00 2001 From: jBarz Date: Thu, 9 Mar 2017 08:33:59 -0500 Subject: [PATCH 04/48] tls: keep track of stream that is closed TLSWrap object keeps a pointer reference to the underlying TCPWrap object. This TCPWrap object could be closed and deleted by the event-loop which leaves us with a dangling pointer. So the TLSWrap object needs to track the "close" event on the TCPWrap object. PR-URL: https://github.com/nodejs/node/pull/11776 Reviewed-By: Fedor Indutny Reviewed-By: James M Snell Reviewed-By: Brian White --- lib/_tls_wrap.js | 6 ++++ src/tls_wrap.cc | 11 ++++++- src/tls_wrap.h | 1 + test/parallel/test-tls-socket-close.js | 43 ++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 test/parallel/test-tls-socket-close.js diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js index ebd36519cf1525..06b555a1254cbe 100644 --- a/lib/_tls_wrap.js +++ b/lib/_tls_wrap.js @@ -374,6 +374,12 @@ TLSSocket.prototype._wrapHandle = function(wrap) { res = null; }); + if (wrap) { + wrap.on('close', function() { + res.onStreamClose(); + }); + } + return res; }; diff --git a/src/tls_wrap.cc b/src/tls_wrap.cc index 581e017ef85016..879b40862b0acb 100644 --- a/src/tls_wrap.cc +++ b/src/tls_wrap.cc @@ -522,7 +522,7 @@ int TLSWrap::GetFD() { bool TLSWrap::IsAlive() { - return ssl_ != nullptr && stream_->IsAlive(); + return ssl_ != nullptr && stream_ != nullptr && stream_->IsAlive(); } @@ -781,6 +781,14 @@ void TLSWrap::EnableSessionCallbacks( } +void TLSWrap::OnStreamClose(const FunctionCallbackInfo& args) { + TLSWrap* wrap; + ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); + + wrap->stream_ = nullptr; +} + + void TLSWrap::DestroySSL(const FunctionCallbackInfo& args) { TLSWrap* wrap; ASSIGN_OR_RETURN_UNWRAP(&wrap, args.Holder()); @@ -911,6 +919,7 @@ void TLSWrap::Initialize(Local target, env->SetProtoMethod(t, "enableSessionCallbacks", EnableSessionCallbacks); env->SetProtoMethod(t, "destroySSL", DestroySSL); env->SetProtoMethod(t, "enableCertCb", EnableCertCb); + env->SetProtoMethod(t, "onStreamClose", OnStreamClose); StreamBase::AddMethods(env, t, StreamBase::kFlagHasWritev); SSLWrap::AddMethods(env, t); diff --git a/src/tls_wrap.h b/src/tls_wrap.h index f390c9fe9281f7..0efdbf0e3991d3 100644 --- a/src/tls_wrap.h +++ b/src/tls_wrap.h @@ -137,6 +137,7 @@ class TLSWrap : public AsyncWrap, static void EnableCertCb( const v8::FunctionCallbackInfo& args); static void DestroySSL(const v8::FunctionCallbackInfo& args); + static void OnStreamClose(const v8::FunctionCallbackInfo& args); #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB static void GetServername(const v8::FunctionCallbackInfo& args); diff --git a/test/parallel/test-tls-socket-close.js b/test/parallel/test-tls-socket-close.js new file mode 100644 index 00000000000000..440c0c4ff7cde7 --- /dev/null +++ b/test/parallel/test-tls-socket-close.js @@ -0,0 +1,43 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const tls = require('tls'); +const fs = require('fs'); +const net = require('net'); + +const key = fs.readFileSync(common.fixturesDir + '/keys/agent2-key.pem'); +const cert = fs.readFileSync(common.fixturesDir + '/keys/agent2-cert.pem'); + +const T = 100; + +// tls server +const tlsServer = tls.createServer({ cert, key }, (socket) => { + setTimeout(() => { + socket.on('error', (error) => { + assert.strictEqual(error.code, 'EINVAL'); + tlsServer.close(); + netServer.close(); + }); + socket.write('bar'); + }, T * 2); +}); + +// plain tcp server +const netServer = net.createServer((socket) => { + // if client wants to use tls + tlsServer.emit('connection', socket); + + socket.setTimeout(T, () => { + // this breaks if TLSSocket is already managing the socket: + socket.destroy(); + }); +}).listen(0, common.mustCall(function() { + + // connect client + tls.connect({ + host: 'localhost', + port: this.address().port, + rejectUnauthorized: false + }).write('foo'); +})); From 646ee559df99f2f22c3eb0cf05684ed9931f28c6 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Sat, 25 Feb 2017 22:41:45 -0800 Subject: [PATCH 05/48] tls: avoid using forEach PR-URL: https://github.com/nodejs/node/pull/11582 Reviewed-By: Matteo Collina Reviewed-By: Colin Ihrig --- lib/_tls_wrap.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js index 06b555a1254cbe..4ad79cf7a28d15 100644 --- a/lib/_tls_wrap.js +++ b/lib/_tls_wrap.js @@ -300,12 +300,16 @@ var proxiedMethods = [ ]; // Proxy HandleWrap, PipeWrap and TCPWrap methods -proxiedMethods.forEach(function(name) { - tls_wrap.TLSWrap.prototype[name] = function methodProxy(...args) { +function makeMethodProxy(name) { + return function methodProxy(...args) { if (this._parent[name]) return this._parent[name].apply(this._parent, args); }; -}); +} +for (var n = 0; n < proxiedMethods.length; n++) { + tls_wrap.TLSWrap.prototype[proxiedMethods[n]] = + makeMethodProxy(proxiedMethods[n]); +} tls_wrap.TLSWrap.prototype.close = function close(cb) { let ssl; From 5f6025ba68c0bb19366dc874369cc58d872c5cee Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Sat, 4 Mar 2017 18:54:48 +0800 Subject: [PATCH 06/48] test: fail when child dies in fork-net Previously when the child dies with errors in this test, the parent will just hang and timeout, the errors in the child would be swallowed. This makes it fail so at least there is more information about why this test fails. Also removes the unnecessary child.kill() call. PR-URL: https://github.com/nodejs/node/pull/11684 Ref: https://github.com/nodejs/node/pull/11667 Reviewed-By: Colin Ihrig Reviewed-By: James M Snell --- test/parallel/test-child-process-fork-net.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/parallel/test-child-process-fork-net.js b/test/parallel/test-child-process-fork-net.js index 157704a9ccf9c9..8b8cc44bd418d8 100644 --- a/test/parallel/test-child-process-fork-net.js +++ b/test/parallel/test-child-process-fork-net.js @@ -1,5 +1,5 @@ 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const fork = require('child_process').fork; const net = require('net'); @@ -60,9 +60,10 @@ if (process.argv[2] === 'child') { const child = fork(process.argv[1], ['child']); - child.on('exit', function() { - console.log('CHILD: died'); - }); + child.on('exit', common.mustCall(function(code, signal) { + const message = `CHILD: died with ${code}, ${signal}`; + assert.strictEqual(code, 0, message); + })); // send net.Server to child and test by connecting const testServer = function(callback) { @@ -171,7 +172,6 @@ if (process.argv[2] === 'child') { testSocket(function() { socketSuccess = true; - child.kill(); }); }); From c9cf9222489b94a84852e24e43c1065ba63b32f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matej=20Kraj=C4=8Dovi=C4=8D?= Date: Sun, 12 Mar 2017 16:09:32 +0100 Subject: [PATCH 07/48] test: add regex to assert.throws Make sure test matches this specific error message. PR-URL: https://github.com/nodejs/node/pull/11815 Reviewed-By: Anna Henningsen Reviewed-By: Luigi Pinca Reviewed-By: Colin Ihrig Reviewed-By: Yuta Hiroto Reviewed-By: James M Snell --- test/parallel/test-vm-run-in-new-context.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/parallel/test-vm-run-in-new-context.js b/test/parallel/test-vm-run-in-new-context.js index 7b096ffc3fdc5f..3f8c632859db0f 100644 --- a/test/parallel/test-vm-run-in-new-context.js +++ b/test/parallel/test-vm-run-in-new-context.js @@ -17,7 +17,7 @@ assert.strictEqual('passed', result); console.error('thrown error'); assert.throws(function() { vm.runInNewContext('throw new Error(\'test\');'); -}); +}, /^Error: test$/); global.hello = 5; vm.runInNewContext('hello = 2'); From d2c9111614a6a46af509c8703ba2797aaf3606d5 Mon Sep 17 00:00:00 2001 From: Alexey Orlenko Date: Wed, 8 Mar 2017 02:37:35 +0200 Subject: [PATCH 08/48] test: fix repl-function-redefinition-edge-case MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `test/known_issues/test-repl-function-redefinition-edge-case.js` had been introduced as a part of https://github.com/nodejs/node/pull/7624 but the meat of the test became fixed in 007386ee81ceeffd65c2248869717b0717db3e46. Despite that, the test continued to fail since it was broken itself: there was a missing colon in the expected output. This commit adds the missing colon and moves the test from `test/known_issues` to `test/parallel`. PR-URL: https://github.com/nodejs/node/pull/11772 Reviewed-By: Anna Henningsen Reviewed-By: Michaël Zasso Reviewed-By: James M Snell Reviewed-By: Michael Dawson Reviewed-By: Colin Ihrig --- .../test-repl-function-definition-edge-case.js} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename test/{known_issues/test-repl-function-redefinition-edge-case.js => parallel/test-repl-function-definition-edge-case.js} (95%) diff --git a/test/known_issues/test-repl-function-redefinition-edge-case.js b/test/parallel/test-repl-function-definition-edge-case.js similarity index 95% rename from test/known_issues/test-repl-function-redefinition-edge-case.js rename to test/parallel/test-repl-function-definition-edge-case.js index 03b721fba7e7d5..1e3063e3db53ff 100644 --- a/test/known_issues/test-repl-function-redefinition-edge-case.js +++ b/test/parallel/test-repl-function-definition-edge-case.js @@ -13,7 +13,7 @@ r.input.emit('data', 'function a() { return 42; } (1)\n'); r.input.emit('data', 'a\n'); r.input.emit('data', '.exit'); -const expected = '1\n[Function a]\n'; +const expected = '1\n[Function: a]\n'; const got = r.output.accumulator.join(''); assert.strictEqual(got, expected); From 2df662c95a48ebef22f09c91497466fea732483b Mon Sep 17 00:00:00 2001 From: Daijiro Wachi Date: Tue, 14 Mar 2017 20:43:39 +0100 Subject: [PATCH 09/48] test: test resolveObject with an empty path Add a case to test an URL object that has no path at all for `url.resolveObject`. PR-URL: https://github.com/nodejs/node/pull/11811 Reviewed-By: James M Snell Reviewed-By: Colin Ihrig Reviewed-By: Yuta Hiroto Reviewed-By: Joyee Cheung --- test/parallel/test-url-relative.js | 432 +++++++++++++++++++++++++++++ 1 file changed, 432 insertions(+) create mode 100644 test/parallel/test-url-relative.js diff --git a/test/parallel/test-url-relative.js b/test/parallel/test-url-relative.js new file mode 100644 index 00000000000000..cf379e591d6088 --- /dev/null +++ b/test/parallel/test-url-relative.js @@ -0,0 +1,432 @@ +'use strict'; +require('../common'); +const assert = require('assert'); +const inspect = require('util').inspect; +const url = require('url'); + +/* + [from, path, expected] +*/ +const relativeTests = [ + ['/foo/bar/baz', 'quux', '/foo/bar/quux'], + ['/foo/bar/baz', 'quux/asdf', '/foo/bar/quux/asdf'], + ['/foo/bar/baz', 'quux/baz', '/foo/bar/quux/baz'], + ['/foo/bar/baz', '../quux/baz', '/foo/quux/baz'], + ['/foo/bar/baz', '/bar', '/bar'], + ['/foo/bar/baz/', 'quux', '/foo/bar/baz/quux'], + ['/foo/bar/baz/', 'quux/baz', '/foo/bar/baz/quux/baz'], + ['/foo/bar/baz', '../../../../../../../../quux/baz', '/quux/baz'], + ['/foo/bar/baz', '../../../../../../../quux/baz', '/quux/baz'], + ['/foo', '.', '/'], + ['/foo', '..', '/'], + ['/foo/', '.', '/foo/'], + ['/foo/', '..', '/'], + ['/foo/bar', '.', '/foo/'], + ['/foo/bar', '..', '/'], + ['/foo/bar/', '.', '/foo/bar/'], + ['/foo/bar/', '..', '/foo/'], + ['foo/bar', '../../../baz', '../../baz'], + ['foo/bar/', '../../../baz', '../baz'], + ['http://example.com/b//c//d;p?q#blarg', 'https:#hash2', 'https:///#hash2'], + ['http://example.com/b//c//d;p?q#blarg', + 'https:/p/a/t/h?s#hash2', + 'https://p/a/t/h?s#hash2'], + ['http://example.com/b//c//d;p?q#blarg', + 'https://u:p@h.com/p/a/t/h?s#hash2', + 'https://u:p@h.com/p/a/t/h?s#hash2'], + ['http://example.com/b//c//d;p?q#blarg', + 'https:/a/b/c/d', + 'https://a/b/c/d'], + ['http://example.com/b//c//d;p?q#blarg', + 'http:#hash2', + 'http://example.com/b//c//d;p?q#hash2'], + ['http://example.com/b//c//d;p?q#blarg', + 'http:/p/a/t/h?s#hash2', + 'http://example.com/p/a/t/h?s#hash2'], + ['http://example.com/b//c//d;p?q#blarg', + 'http://u:p@h.com/p/a/t/h?s#hash2', + 'http://u:p@h.com/p/a/t/h?s#hash2'], + ['http://example.com/b//c//d;p?q#blarg', + 'http:/a/b/c/d', + 'http://example.com/a/b/c/d'], + ['/foo/bar/baz', '/../etc/passwd', '/etc/passwd'], + ['http://localhost', 'file:///Users/foo', 'file:///Users/foo'], + ['http://localhost', 'file://foo/Users', 'file://foo/Users'] +]; +relativeTests.forEach(function(relativeTest) { + const a = url.resolve(relativeTest[0], relativeTest[1]); + const e = relativeTest[2]; + assert.strictEqual(a, e, + `resolve(${relativeTest[0]}, ${relativeTest[1]})` + + ` == ${e}\n actual=${a}`); +}); + +// +// Tests below taken from Chiron +// http://code.google.com/p/chironjs/source/browse/trunk/src/test/http/url.js +// +// Copyright (c) 2002-2008 Kris Kowal +// used with permission under MIT License +// +// Changes marked with @isaacs + +const bases = [ + 'http://a/b/c/d;p?q', + 'http://a/b/c/d;p?q=1/2', + 'http://a/b/c/d;p=1/2?q', + 'fred:///s//a/b/c', + 'http:///s//a/b/c' +]; + +//[to, from, result] +const relativeTests2 = [ + // http://lists.w3.org/Archives/Public/uri/2004Feb/0114.html + ['../c', 'foo:a/b', 'foo:c'], + ['foo:.', 'foo:a', 'foo:'], + ['/foo/../../../bar', 'zz:abc', 'zz:/bar'], + ['/foo/../bar', 'zz:abc', 'zz:/bar'], + // @isaacs Disagree. Not how web browsers resolve this. + ['foo/../../../bar', 'zz:abc', 'zz:bar'], + // ['foo/../../../bar', 'zz:abc', 'zz:../../bar'], // @isaacs Added + ['foo/../bar', 'zz:abc', 'zz:bar'], + ['zz:.', 'zz:abc', 'zz:'], + ['/.', bases[0], 'http://a/'], + ['/.foo', bases[0], 'http://a/.foo'], + ['.foo', bases[0], 'http://a/b/c/.foo'], + + // http://gbiv.com/protocols/uri/test/rel_examples1.html + // examples from RFC 2396 + ['g:h', bases[0], 'g:h'], + ['g', bases[0], 'http://a/b/c/g'], + ['./g', bases[0], 'http://a/b/c/g'], + ['g/', bases[0], 'http://a/b/c/g/'], + ['/g', bases[0], 'http://a/g'], + ['//g', bases[0], 'http://g/'], + // changed with RFC 2396bis + //('?y', bases[0], 'http://a/b/c/d;p?y'], + ['?y', bases[0], 'http://a/b/c/d;p?y'], + ['g?y', bases[0], 'http://a/b/c/g?y'], + // changed with RFC 2396bis + //('#s', bases[0], CURRENT_DOC_URI + '#s'], + ['#s', bases[0], 'http://a/b/c/d;p?q#s'], + ['g#s', bases[0], 'http://a/b/c/g#s'], + ['g?y#s', bases[0], 'http://a/b/c/g?y#s'], + [';x', bases[0], 'http://a/b/c/;x'], + ['g;x', bases[0], 'http://a/b/c/g;x'], + ['g;x?y#s', bases[0], 'http://a/b/c/g;x?y#s'], + // changed with RFC 2396bis + //('', bases[0], CURRENT_DOC_URI], + ['', bases[0], 'http://a/b/c/d;p?q'], + ['.', bases[0], 'http://a/b/c/'], + ['./', bases[0], 'http://a/b/c/'], + ['..', bases[0], 'http://a/b/'], + ['../', bases[0], 'http://a/b/'], + ['../g', bases[0], 'http://a/b/g'], + ['../..', bases[0], 'http://a/'], + ['../../', bases[0], 'http://a/'], + ['../../g', bases[0], 'http://a/g'], + ['../../../g', bases[0], ('http://a/../g', 'http://a/g')], + ['../../../../g', bases[0], ('http://a/../../g', 'http://a/g')], + // changed with RFC 2396bis + //('/./g', bases[0], 'http://a/./g'], + ['/./g', bases[0], 'http://a/g'], + // changed with RFC 2396bis + //('/../g', bases[0], 'http://a/../g'], + ['/../g', bases[0], 'http://a/g'], + ['g.', bases[0], 'http://a/b/c/g.'], + ['.g', bases[0], 'http://a/b/c/.g'], + ['g..', bases[0], 'http://a/b/c/g..'], + ['..g', bases[0], 'http://a/b/c/..g'], + ['./../g', bases[0], 'http://a/b/g'], + ['./g/.', bases[0], 'http://a/b/c/g/'], + ['g/./h', bases[0], 'http://a/b/c/g/h'], + ['g/../h', bases[0], 'http://a/b/c/h'], + ['g;x=1/./y', bases[0], 'http://a/b/c/g;x=1/y'], + ['g;x=1/../y', bases[0], 'http://a/b/c/y'], + ['g?y/./x', bases[0], 'http://a/b/c/g?y/./x'], + ['g?y/../x', bases[0], 'http://a/b/c/g?y/../x'], + ['g#s/./x', bases[0], 'http://a/b/c/g#s/./x'], + ['g#s/../x', bases[0], 'http://a/b/c/g#s/../x'], + ['http:g', bases[0], ('http:g', 'http://a/b/c/g')], + ['http:', bases[0], ('http:', bases[0])], + // not sure where this one originated + ['/a/b/c/./../../g', bases[0], 'http://a/a/g'], + + // http://gbiv.com/protocols/uri/test/rel_examples2.html + // slashes in base URI's query args + ['g', bases[1], 'http://a/b/c/g'], + ['./g', bases[1], 'http://a/b/c/g'], + ['g/', bases[1], 'http://a/b/c/g/'], + ['/g', bases[1], 'http://a/g'], + ['//g', bases[1], 'http://g/'], + // changed in RFC 2396bis + //('?y', bases[1], 'http://a/b/c/?y'], + ['?y', bases[1], 'http://a/b/c/d;p?y'], + ['g?y', bases[1], 'http://a/b/c/g?y'], + ['g?y/./x', bases[1], 'http://a/b/c/g?y/./x'], + ['g?y/../x', bases[1], 'http://a/b/c/g?y/../x'], + ['g#s', bases[1], 'http://a/b/c/g#s'], + ['g#s/./x', bases[1], 'http://a/b/c/g#s/./x'], + ['g#s/../x', bases[1], 'http://a/b/c/g#s/../x'], + ['./', bases[1], 'http://a/b/c/'], + ['../', bases[1], 'http://a/b/'], + ['../g', bases[1], 'http://a/b/g'], + ['../../', bases[1], 'http://a/'], + ['../../g', bases[1], 'http://a/g'], + + // http://gbiv.com/protocols/uri/test/rel_examples3.html + // slashes in path params + // all of these changed in RFC 2396bis + ['g', bases[2], 'http://a/b/c/d;p=1/g'], + ['./g', bases[2], 'http://a/b/c/d;p=1/g'], + ['g/', bases[2], 'http://a/b/c/d;p=1/g/'], + ['g?y', bases[2], 'http://a/b/c/d;p=1/g?y'], + [';x', bases[2], 'http://a/b/c/d;p=1/;x'], + ['g;x', bases[2], 'http://a/b/c/d;p=1/g;x'], + ['g;x=1/./y', bases[2], 'http://a/b/c/d;p=1/g;x=1/y'], + ['g;x=1/../y', bases[2], 'http://a/b/c/d;p=1/y'], + ['./', bases[2], 'http://a/b/c/d;p=1/'], + ['../', bases[2], 'http://a/b/c/'], + ['../g', bases[2], 'http://a/b/c/g'], + ['../../', bases[2], 'http://a/b/'], + ['../../g', bases[2], 'http://a/b/g'], + + // http://gbiv.com/protocols/uri/test/rel_examples4.html + // double and triple slash, unknown scheme + ['g:h', bases[3], 'g:h'], + ['g', bases[3], 'fred:///s//a/b/g'], + ['./g', bases[3], 'fred:///s//a/b/g'], + ['g/', bases[3], 'fred:///s//a/b/g/'], + ['/g', bases[3], 'fred:///g'], // may change to fred:///s//a/g + ['//g', bases[3], 'fred://g'], // may change to fred:///s//g + ['//g/x', bases[3], 'fred://g/x'], // may change to fred:///s//g/x + ['///g', bases[3], 'fred:///g'], + ['./', bases[3], 'fred:///s//a/b/'], + ['../', bases[3], 'fred:///s//a/'], + ['../g', bases[3], 'fred:///s//a/g'], + + ['../../', bases[3], 'fred:///s//'], + ['../../g', bases[3], 'fred:///s//g'], + ['../../../g', bases[3], 'fred:///s/g'], + // may change to fred:///s//a/../../../g + ['../../../../g', bases[3], 'fred:///g'], + + // http://gbiv.com/protocols/uri/test/rel_examples5.html + // double and triple slash, well-known scheme + ['g:h', bases[4], 'g:h'], + ['g', bases[4], 'http:///s//a/b/g'], + ['./g', bases[4], 'http:///s//a/b/g'], + ['g/', bases[4], 'http:///s//a/b/g/'], + ['/g', bases[4], 'http:///g'], // may change to http:///s//a/g + ['//g', bases[4], 'http://g/'], // may change to http:///s//g + ['//g/x', bases[4], 'http://g/x'], // may change to http:///s//g/x + ['///g', bases[4], 'http:///g'], + ['./', bases[4], 'http:///s//a/b/'], + ['../', bases[4], 'http:///s//a/'], + ['../g', bases[4], 'http:///s//a/g'], + ['../../', bases[4], 'http:///s//'], + ['../../g', bases[4], 'http:///s//g'], + // may change to http:///s//a/../../g + ['../../../g', bases[4], 'http:///s/g'], + // may change to http:///s//a/../../../g + ['../../../../g', bases[4], 'http:///g'], + + // from Dan Connelly's tests in http://www.w3.org/2000/10/swap/uripath.py + ['bar:abc', 'foo:xyz', 'bar:abc'], + ['../abc', 'http://example/x/y/z', 'http://example/x/abc'], + ['http://example/x/abc', 'http://example2/x/y/z', 'http://example/x/abc'], + ['../r', 'http://ex/x/y/z', 'http://ex/x/r'], + ['q/r', 'http://ex/x/y', 'http://ex/x/q/r'], + ['q/r#s', 'http://ex/x/y', 'http://ex/x/q/r#s'], + ['q/r#s/t', 'http://ex/x/y', 'http://ex/x/q/r#s/t'], + ['ftp://ex/x/q/r', 'http://ex/x/y', 'ftp://ex/x/q/r'], + ['', 'http://ex/x/y', 'http://ex/x/y'], + ['', 'http://ex/x/y/', 'http://ex/x/y/'], + ['', 'http://ex/x/y/pdq', 'http://ex/x/y/pdq'], + ['z/', 'http://ex/x/y/', 'http://ex/x/y/z/'], + ['#Animal', + 'file:/swap/test/animal.rdf', + 'file:/swap/test/animal.rdf#Animal'], + ['../abc', 'file:/e/x/y/z', 'file:/e/x/abc'], + ['/example/x/abc', 'file:/example2/x/y/z', 'file:/example/x/abc'], + ['../r', 'file:/ex/x/y/z', 'file:/ex/x/r'], + ['/r', 'file:/ex/x/y/z', 'file:/r'], + ['q/r', 'file:/ex/x/y', 'file:/ex/x/q/r'], + ['q/r#s', 'file:/ex/x/y', 'file:/ex/x/q/r#s'], + ['q/r#', 'file:/ex/x/y', 'file:/ex/x/q/r#'], + ['q/r#s/t', 'file:/ex/x/y', 'file:/ex/x/q/r#s/t'], + ['ftp://ex/x/q/r', 'file:/ex/x/y', 'ftp://ex/x/q/r'], + ['', 'file:/ex/x/y', 'file:/ex/x/y'], + ['', 'file:/ex/x/y/', 'file:/ex/x/y/'], + ['', 'file:/ex/x/y/pdq', 'file:/ex/x/y/pdq'], + ['z/', 'file:/ex/x/y/', 'file:/ex/x/y/z/'], + ['file://meetings.example.com/cal#m1', + 'file:/devel/WWW/2000/10/swap/test/reluri-1.n3', + 'file://meetings.example.com/cal#m1'], + ['file://meetings.example.com/cal#m1', + 'file:/home/connolly/w3ccvs/WWW/2000/10/swap/test/reluri-1.n3', + 'file://meetings.example.com/cal#m1'], + ['./#blort', 'file:/some/dir/foo', 'file:/some/dir/#blort'], + ['./#', 'file:/some/dir/foo', 'file:/some/dir/#'], + // Ryan Lee + ['./', 'http://example/x/abc.efg', 'http://example/x/'], + + + // Graham Klyne's tests + // http://www.ninebynine.org/Software/HaskellUtils/Network/UriTest.xls + // 01-31 are from Connelly's cases + + // 32-49 + ['./q:r', 'http://ex/x/y', 'http://ex/x/q:r'], + ['./p=q:r', 'http://ex/x/y', 'http://ex/x/p=q:r'], + ['?pp/rr', 'http://ex/x/y?pp/qq', 'http://ex/x/y?pp/rr'], + ['y/z', 'http://ex/x/y?pp/qq', 'http://ex/x/y/z'], + ['local/qual@domain.org#frag', + 'mailto:local', + 'mailto:local/qual@domain.org#frag'], + ['more/qual2@domain2.org#frag', + 'mailto:local/qual1@domain1.org', + 'mailto:local/more/qual2@domain2.org#frag'], + ['y?q', 'http://ex/x/y?q', 'http://ex/x/y?q'], + ['/x/y?q', 'http://ex?p', 'http://ex/x/y?q'], + ['c/d', 'foo:a/b', 'foo:a/c/d'], + ['/c/d', 'foo:a/b', 'foo:/c/d'], + ['', 'foo:a/b?c#d', 'foo:a/b?c'], + ['b/c', 'foo:a', 'foo:b/c'], + ['../b/c', 'foo:/a/y/z', 'foo:/a/b/c'], + ['./b/c', 'foo:a', 'foo:b/c'], + ['/./b/c', 'foo:a', 'foo:/b/c'], + ['../../d', 'foo://a//b/c', 'foo://a/d'], + ['.', 'foo:a', 'foo:'], + ['..', 'foo:a', 'foo:'], + + // 50-57[cf. TimBL comments -- + // http://lists.w3.org/Archives/Public/uri/2003Feb/0028.html, + // http://lists.w3.org/Archives/Public/uri/2003Jan/0008.html) + ['abc', 'http://example/x/y%2Fz', 'http://example/x/abc'], + ['../../x%2Fabc', 'http://example/a/x/y/z', 'http://example/a/x%2Fabc'], + ['../x%2Fabc', 'http://example/a/x/y%2Fz', 'http://example/a/x%2Fabc'], + ['abc', 'http://example/x%2Fy/z', 'http://example/x%2Fy/abc'], + ['q%3Ar', 'http://ex/x/y', 'http://ex/x/q%3Ar'], + ['/x%2Fabc', 'http://example/x/y%2Fz', 'http://example/x%2Fabc'], + ['/x%2Fabc', 'http://example/x/y/z', 'http://example/x%2Fabc'], + ['/x%2Fabc', 'http://example/x/y%2Fz', 'http://example/x%2Fabc'], + + // 70-77 + ['local2@domain2', 'mailto:local1@domain1?query1', 'mailto:local2@domain2'], + ['local2@domain2?query2', + 'mailto:local1@domain1', + 'mailto:local2@domain2?query2'], + ['local2@domain2?query2', + 'mailto:local1@domain1?query1', + 'mailto:local2@domain2?query2'], + ['?query2', 'mailto:local@domain?query1', 'mailto:local@domain?query2'], + ['local@domain?query2', 'mailto:?query1', 'mailto:local@domain?query2'], + ['?query2', 'mailto:local@domain?query1', 'mailto:local@domain?query2'], + ['http://example/a/b?c/../d', 'foo:bar', 'http://example/a/b?c/../d'], + ['http://example/a/b#c/../d', 'foo:bar', 'http://example/a/b#c/../d'], + + // 82-88 + // @isaacs Disagree. Not how browsers do it. + // ['http:this', 'http://example.org/base/uri', 'http:this'], + // @isaacs Added + ['http:this', 'http://example.org/base/uri', 'http://example.org/base/this'], + ['http:this', 'http:base', 'http:this'], + ['.//g', 'f:/a', 'f://g'], + ['b/c//d/e', 'f://example.org/base/a', 'f://example.org/base/b/c//d/e'], + ['m2@example.ord/c2@example.org', + 'mid:m@example.ord/c@example.org', + 'mid:m@example.ord/m2@example.ord/c2@example.org'], + ['mini1.xml', + 'file:///C:/DEV/Haskell/lib/HXmlToolbox-3.01/examples/', + 'file:///C:/DEV/Haskell/lib/HXmlToolbox-3.01/examples/mini1.xml'], + ['../b/c', 'foo:a/y/z', 'foo:a/b/c'], + + //changeing auth + ['http://diff:auth@www.example.com', + 'http://asdf:qwer@www.example.com', + 'http://diff:auth@www.example.com/'], + + // changing port + ['https://example.com:81/', + 'https://example.com:82/', + 'https://example.com:81/'], + + // https://github.com/nodejs/node/issues/1435 + ['https://another.host.com/', + 'https://user:password@example.org/', + 'https://another.host.com/'], + ['//another.host.com/', + 'https://user:password@example.org/', + 'https://another.host.com/'], + ['http://another.host.com/', + 'https://user:password@example.org/', + 'http://another.host.com/'], + ['mailto:another.host.com', + 'mailto:user@example.org', + 'mailto:another.host.com'], + ['https://example.com/foo', + 'https://user:password@example.com', + 'https://user:password@example.com/foo'], + + // No path at all + ['#hash1', '#hash2', '#hash1'] +]; +relativeTests2.forEach(function(relativeTest) { + const a = url.resolve(relativeTest[1], relativeTest[0]); + const e = url.format(relativeTest[2]); + assert.strictEqual(a, e, + `resolve(${relativeTest[0]}, ${relativeTest[1]})` + + ` == ${e}\n actual=${a}`); +}); + +//if format and parse are inverse operations then +//resolveObject(parse(x), y) == parse(resolve(x, y)) + +//format: [from, path, expected] +relativeTests.forEach(function(relativeTest) { + let actual = url.resolveObject(url.parse(relativeTest[0]), relativeTest[1]); + let expected = url.parse(relativeTest[2]); + + + assert.deepStrictEqual(actual, expected); + + expected = relativeTest[2]; + actual = url.format(actual); + + assert.strictEqual(actual, expected, + `format(${actual}) == ${expected}\n` + + `actual: ${actual}`); +}); + +//format: [to, from, result] +// the test: ['.//g', 'f:/a', 'f://g'] is a fundamental problem +// url.parse('f:/a') does not have a host +// url.resolve('f:/a', './/g') does not have a host because you have moved +// down to the g directory. i.e. f: //g, however when this url is parsed +// f:// will indicate that the host is g which is not the case. +// it is unclear to me how to keep this information from being lost +// it may be that a pathname of ////g should collapse to /g but this seems +// to be a lot of work for an edge case. Right now I remove the test +if (relativeTests2[181][0] === './/g' && + relativeTests2[181][1] === 'f:/a' && + relativeTests2[181][2] === 'f://g') { + relativeTests2.splice(181, 1); +} +relativeTests2.forEach(function(relativeTest) { + let actual = url.resolveObject(url.parse(relativeTest[1]), relativeTest[0]); + let expected = url.parse(relativeTest[2]); + + assert.deepStrictEqual( + actual, + expected, + `expected ${inspect(expected)} but got ${inspect(actual)}` + ); + + expected = url.format(relativeTest[2]); + actual = url.format(actual); + + assert.strictEqual(actual, expected, + `format(${relativeTest[1]}) == ${expected}\n` + + `actual: ${actual}`); +}); From 2649dab2744b98d7733275a12835e127084b5cb1 Mon Sep 17 00:00:00 2001 From: AnnaMag Date: Thu, 9 Mar 2017 14:00:34 +0000 Subject: [PATCH 10/48] test: added test for indexed properties MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, indexed properties are correctly copied onto the sandbox by CopyProperties(). This will break when CopyProperties() is removed after adjusting NamedPropertyHandlerConfiguration config() to use property callbacks from the new V8 API. To fix it, we will set a config for indexed properties. This test is a preparation step for the patch that removes CopyProperties(). PR-URL: https://github.com/nodejs/node/pull/11769 Reviewed-By: Franziska Hinkelmann Reviewed-By: Michaël Zasso Reviewed-By: James M Snell Reviewed-By: Colin Ihrig Reviewed-By: Brian White --- test/parallel/test-vm-indexed-properties.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 test/parallel/test-vm-indexed-properties.js diff --git a/test/parallel/test-vm-indexed-properties.js b/test/parallel/test-vm-indexed-properties.js new file mode 100644 index 00000000000000..34ef8d020b2181 --- /dev/null +++ b/test/parallel/test-vm-indexed-properties.js @@ -0,0 +1,17 @@ +'use strict'; + +require('../common'); +const assert = require('assert'); +const vm = require('vm'); + +const code = `Object.defineProperty(this, 99, { + value: 20, + enumerable: true + });`; + + +const sandbox = {}; +const ctx = vm.createContext(sandbox); +vm.runInContext(code, ctx); + +assert.strictEqual(sandbox[99], 20); From f9c831f4b1c271e67813dc1e1584378fbcb9ff73 Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Sun, 12 Mar 2017 09:10:50 -0700 Subject: [PATCH 11/48] test: fix flaky test-domain-abort-on-uncaught test-domain-abort-on-uncaught is flaky under load. Move it to sequential so it is not competing with other tests for resources. PR-URL: https://github.com/nodejs/node/pull/11817 Fixes: https://github.com/nodejs/node/issues/11814 Reviewed-By: Colin Ihrig Reviewed-By: Gibson Fahnestock Reviewed-By: Daijiro Wachi Reviewed-By: Santiago Gimeno Reviewed-By: Yuta Hiroto Reviewed-By: James M Snell --- test/{parallel => sequential}/test-domain-abort-on-uncaught.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{parallel => sequential}/test-domain-abort-on-uncaught.js (100%) diff --git a/test/parallel/test-domain-abort-on-uncaught.js b/test/sequential/test-domain-abort-on-uncaught.js similarity index 100% rename from test/parallel/test-domain-abort-on-uncaught.js rename to test/sequential/test-domain-abort-on-uncaught.js From 560d8eed9ac0234ad35e724e5ee56cdbdb5818f8 Mon Sep 17 00:00:00 2001 From: Gireesh Punathil Date: Mon, 6 Mar 2017 10:24:07 -0500 Subject: [PATCH 12/48] test: delay child exit in AIX for pseudo-tty tests The tests in pseudo-tty takes the form of child node writing some data and exiting, while parent python consume them through pseudo tty implementations, and validate the result. While there is no synchronization between child and parent, this works for most platforms, except AIX, where the child exits even before the parent could setup the read loop, under race conditions Fixing the race condition is ideally done through sending ACK messages to and forth, but involves massive changes and have side effect. The workaround is to address them in AIX alone, by adding a reasonable delay. PR-URL: https://github.com/nodejs/node/pull/11715 Fixes: https://github.com/nodejs/node/issues/7973 Fixes: https://github.com/nodejs/node/issues/9765 Fixes: https://github.com/nodejs/node/issues/11541 Reviewed-By: Michael Dawson Reviewed-By: James M Snell Reviewed-By: Gibson Fahnestock --- test/pseudo-tty/no_dropped_stdio.js | 10 +++++++--- test/pseudo-tty/no_interleaved_stdio.js | 10 +++++++--- test/pseudo-tty/pseudo-tty.status | 3 --- test/pseudo-tty/test-stderr-stdout-handle-sigwinch.js | 6 +++++- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/test/pseudo-tty/no_dropped_stdio.js b/test/pseudo-tty/no_dropped_stdio.js index b24d234a38b2b7..f7d9625c62b0c7 100644 --- a/test/pseudo-tty/no_dropped_stdio.js +++ b/test/pseudo-tty/no_dropped_stdio.js @@ -1,7 +1,7 @@ // https://github.com/nodejs/node/issues/6456#issuecomment-219320599 // https://gist.github.com/isaacs/1495b91ec66b21d30b10572d72ad2cdd 'use strict'; -require('../common'); +const common = require('../common'); // 1000 bytes wrapped at 50 columns // \n turns into a double-byte character @@ -11,5 +11,9 @@ let out = ('o'.repeat(48) + '\n').repeat(20); // This results in 1025 bytes, just enough to overflow the 1kb OS X TTY buffer. out += 'o'.repeat(24) + 'O'; -process.stdout.write(out); -process.exit(0); +// In AIX, the child exits even before the python parent +// can setup the readloop. Provide a reasonable delay. +setTimeout(function() { + process.stdout.write(out); + process.exit(0); +}, common.isAix ? 200 : 0); diff --git a/test/pseudo-tty/no_interleaved_stdio.js b/test/pseudo-tty/no_interleaved_stdio.js index ff3ed8594a0baa..ba3989f93878bc 100644 --- a/test/pseudo-tty/no_interleaved_stdio.js +++ b/test/pseudo-tty/no_interleaved_stdio.js @@ -1,7 +1,7 @@ // https://github.com/nodejs/node/issues/6456#issuecomment-219320599 // https://gist.github.com/isaacs/1495b91ec66b21d30b10572d72ad2cdd 'use strict'; -require('../common'); +const common = require('../common'); // 1000 bytes wrapped at 50 columns // \n turns into a double-byte character @@ -13,5 +13,9 @@ out += 'o'.repeat(24) + 'O'; const err = '__This is some stderr__'; -process.stdout.write(out); -process.stderr.write(err); +// In AIX, the child exits even before the python parent +// can setup the readloop. Provide a reasonable delay. +setTimeout(function() { + process.stdout.write(out); + process.stderr.write(err); +}, common.isAix ? 200 : 0); diff --git a/test/pseudo-tty/pseudo-tty.status b/test/pseudo-tty/pseudo-tty.status index 50f54de029d874..13279019b6bd72 100644 --- a/test/pseudo-tty/pseudo-tty.status +++ b/test/pseudo-tty/pseudo-tty.status @@ -1,8 +1,5 @@ prefix pseudo-tty [$system==aix] -# test issue only, covered under https://github.com/nodejs/node/issues/7973 -no_dropped_stdio : SKIP -no_interleaved_stdio : SKIP # being investigated under https://github.com/nodejs/node/issues/9728 test-tty-wrap : FAIL, PASS diff --git a/test/pseudo-tty/test-stderr-stdout-handle-sigwinch.js b/test/pseudo-tty/test-stderr-stdout-handle-sigwinch.js index f828e92afbe71c..4d87e15d342c36 100644 --- a/test/pseudo-tty/test-stderr-stdout-handle-sigwinch.js +++ b/test/pseudo-tty/test-stderr-stdout-handle-sigwinch.js @@ -27,4 +27,8 @@ process.stdout._refreshSize = wrap(originalRefreshSizeStdout, process.stdout, 'calling stdout._refreshSize'); -process.emit('SIGWINCH'); +// In AIX, the child exits even before the python parent +// can setup the readloop. Provide a reasonable delay. +setTimeout(function() { + process.emit('SIGWINCH'); +}, common.isAix ? 200 : 0); From 3ae58acd29fcbde16206f238a2a4cc935892b2de Mon Sep 17 00:00:00 2001 From: AnnaMag Date: Thu, 2 Mar 2017 16:03:54 +0000 Subject: [PATCH 13/48] test: failing behaviour on sandboxed Proxy CopyProperties() causes sandboxed Proxy to throw error when in fact no code has been run. The function will be removed with the updates to the V8 API. Here, failing Proxy test case is moved to known_issues. PR-URL: https://github.com/nodejs/node/pull/11671 Reviewed-By: James M Snell Reviewed-By: Franziska Hinkelmann --- test/known_issues/test-vm-proxy-failure-CP.js | 20 +++++++++++++++++++ test/parallel/test-vm-proxies.js | 13 ------------ 2 files changed, 20 insertions(+), 13 deletions(-) create mode 100644 test/known_issues/test-vm-proxy-failure-CP.js diff --git a/test/known_issues/test-vm-proxy-failure-CP.js b/test/known_issues/test-vm-proxy-failure-CP.js new file mode 100644 index 00000000000000..de644599b233b8 --- /dev/null +++ b/test/known_issues/test-vm-proxy-failure-CP.js @@ -0,0 +1,20 @@ +'use strict'; + +// Sandbox throws in CopyProperties() despite no code being run +// Issue: https://github.com/nodejs/node/issues/11902 + + +require('../common'); +const assert = require('assert'); +const vm = require('vm'); + +const handler = { + getOwnPropertyDescriptor: (target, prop) => { + throw new Error('whoops'); + } +}; +const sandbox = new Proxy({foo: 'bar'}, handler); +const context = vm.createContext(sandbox); + + +assert.doesNotThrow(() => vm.runInContext('', context)); diff --git a/test/parallel/test-vm-proxies.js b/test/parallel/test-vm-proxies.js index 25e16e8f5ccc55..266b212fb827b8 100644 --- a/test/parallel/test-vm-proxies.js +++ b/test/parallel/test-vm-proxies.js @@ -16,16 +16,3 @@ sandbox = { Proxy: Proxy }; vm.runInNewContext('this.Proxy = Proxy', sandbox); assert.strictEqual(typeof sandbox.Proxy, 'function'); assert.strictEqual(sandbox.Proxy, Proxy); - -// Handle a sandbox that throws while copying properties -assert.throws(() => { - const handler = { - getOwnPropertyDescriptor: (target, prop) => { - throw new Error('whoops'); - } - }; - const sandbox = new Proxy({foo: 'bar'}, handler); - const context = vm.createContext(sandbox); - - vm.runInContext('', context); -}, /whoops/); From 8bda7b8d39b85c77c53f510beadd6e4d898890ad Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Fri, 10 Mar 2017 22:40:06 -0800 Subject: [PATCH 14/48] test: add coverage for child_process bounds check Make sure that monkey-patching process.execArgv doesn't cause child_process to incorrectly munge execArgv in fork(). This basically is adding coverage for an `index > 0` check (see Refs). Previously, that condition was never false in any of the tests. PR-URL: https://github.com/nodejs/node/pull/11800 Reviewed-By: James M Snell Reviewed-By: Colin Ihrig Reviewed-By: Gibson Fahnestock Reviewed-By: Yuta Hiroto Refs: https://github.com/nodejs/node/blob/c67207731f16a78f6cae90e49c53b10728241ecf/lib/child_process.js#L76 --- test/parallel/test-cli-eval.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/parallel/test-cli-eval.js b/test/parallel/test-cli-eval.js index 260acdb0d6f90a..9f781642a9724e 100644 --- a/test/parallel/test-cli-eval.js +++ b/test/parallel/test-cli-eval.js @@ -122,6 +122,17 @@ child.exec(`${nodejs} --use-strict -p process.execArgv`, assert.strictEqual(stdout, ''); assert.strictEqual(stderr, ''); })); + + // Make sure that monkey-patching process.execArgv doesn't cause child_process + // to incorrectly munge execArgv. + child.exec( + `${nodejs} -e "process.execArgv = ['-e', 'console.log(42)', 'thirdArg'];` + + `require('child_process').fork('${emptyFile}')"`, + common.mustCall((err, stdout, stderr) => { + assert.ifError(err); + assert.strictEqual(stdout, '42\n'); + assert.strictEqual(stderr, ''); + })); } // Regression test for https://github.com/nodejs/node/issues/8534. From 2cab00aec0e4ba546ae751cd3c3182aac309e782 Mon Sep 17 00:00:00 2001 From: AnnaMag Date: Tue, 14 Mar 2017 22:53:13 +0000 Subject: [PATCH 15/48] test: fix assertion in vm test Prototypes are not strict equal when they are from different contexts. Therefore, assert.strictEqual() fails for objects that are created in different contexts, e.g., in vm.runInContext(). Instead of expecting the prototypes to be equal, only check the properties of the objects for equality. PR-URL: https://github.com/nodejs/node/pull/11862 Reviewed-By: Anna Henningsen Reviewed-By: James M Snell Reviewed-By: Colin Ihrig Reviewed-By: Franziska Hinkelmann --- test/known_issues/test-vm-getters.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/known_issues/test-vm-getters.js b/test/known_issues/test-vm-getters.js index f815e6d658351d..af27eeee644032 100644 --- a/test/known_issues/test-vm-getters.js +++ b/test/known_issues/test-vm-getters.js @@ -16,4 +16,9 @@ const context = vm.createContext(sandbox); const code = 'Object.getOwnPropertyDescriptor(this, "prop");'; const result = vm.runInContext(code, context); -assert.strictEqual(result, descriptor); +// Ref: https://github.com/nodejs/node/issues/11803 + +assert.deepStrictEqual(Object.keys(result), Object.keys(descriptor)); +for (const prop of Object.keys(result)) { + assert.strictEqual(result[prop], descriptor[prop]); +} From 90be5a1f19132bef103fd6a0b14149381c8ec77f Mon Sep 17 00:00:00 2001 From: James M Snell Date: Sat, 25 Feb 2017 22:16:57 -0800 Subject: [PATCH 16/48] stream: avoid using forEach PR-URL: https://github.com/nodejs/node/pull/11582 Reviewed-By: Matteo Collina Reviewed-By: Colin Ihrig --- lib/_stream_readable.js | 9 +++++---- lib/_stream_wrap.js | 5 ++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js index d6af8589f3bc85..e33441971fe746 100644 --- a/lib/_stream_readable.js +++ b/lib/_stream_readable.js @@ -13,6 +13,8 @@ var StringDecoder; util.inherits(Readable, Stream); +const kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume']; + function prependListener(emitter, event, fn) { // Sadly this is not cacheable as some libraries bundle their own // event emitter implementation with them. @@ -811,10 +813,9 @@ Readable.prototype.wrap = function(stream) { } // proxy certain important events. - const events = ['error', 'close', 'destroy', 'pause', 'resume']; - events.forEach(function(ev) { - stream.on(ev, self.emit.bind(self, ev)); - }); + for (var n = 0; n < kProxyEvents.length; n++) { + stream.on(kProxyEvents[n], self.emit.bind(self, kProxyEvents[n])); + } // when we try to consume some more bytes, simply unpause the // underlying stream. diff --git a/lib/_stream_wrap.js b/lib/_stream_wrap.js index fbc32965980e96..2ddf15069e5361 100644 --- a/lib/_stream_wrap.js +++ b/lib/_stream_wrap.js @@ -118,9 +118,8 @@ StreamWrap.prototype.doWrite = function doWrite(req, bufs) { const item = self._enqueue('write', req); self.stream.cork(); - bufs.forEach(function(buf) { - self.stream.write(buf, done); - }); + for (var n = 0; n < bufs.length; n++) + self.stream.write(bufs[n], done); self.stream.uncork(); function done(err) { From 62e726109add261271f35b69a128d29d3039d25d Mon Sep 17 00:00:00 2001 From: James M Snell Date: Mon, 27 Feb 2017 09:28:15 -0800 Subject: [PATCH 17/48] repl: avoid using forEach PR-URL: https://github.com/nodejs/node/pull/11582 Reviewed-By: Matteo Collina Reviewed-By: Colin Ihrig --- lib/repl.js | 63 ++++++++++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/lib/repl.js b/lib/repl.js index 72fd37e0a4a08f..c73a5069bbe181 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -47,7 +47,10 @@ const GLOBAL_OBJECT_PROPERTIES = [ 'ReferenceError', 'SyntaxError', 'TypeError', 'URIError', 'Math', 'JSON' ]; const GLOBAL_OBJECT_PROPERTY_MAP = {}; -GLOBAL_OBJECT_PROPERTIES.forEach((p) => GLOBAL_OBJECT_PROPERTY_MAP[p] = p); +for (var n = 0; n < GLOBAL_OBJECT_PROPERTIES.length; n++) { + GLOBAL_OBJECT_PROPERTY_MAP[GLOBAL_OBJECT_PROPERTIES[n]] = + GLOBAL_OBJECT_PROPERTIES[n]; +} try { // hack for require.resolve("./relative") to work properly. @@ -692,13 +695,17 @@ REPLServer.prototype.createContext = function() { enumerable: true, get: () => _console }); - Object.getOwnPropertyNames(global).filter((name) => { - if (name === 'console' || name === 'global') return false; - return GLOBAL_OBJECT_PROPERTY_MAP[name] === undefined; - }).forEach((name) => { - Object.defineProperty(context, name, - Object.getOwnPropertyDescriptor(global, name)); - }); + + var names = Object.getOwnPropertyNames(global); + for (var n = 0; n < names.length; n++) { + var name = names[n]; + if (name === 'console' || name === 'global') + continue; + if (GLOBAL_OBJECT_PROPERTY_MAP[name] === undefined) { + Object.defineProperty(context, name, + Object.getOwnPropertyDescriptor(global, name)); + } + } } const module = new Module(''); @@ -769,10 +776,8 @@ function ArrayStream() { Stream.call(this); this.run = function(data) { - var self = this; - data.forEach(function(line) { - self.emit('data', line + '\n'); - }); + for (var n = 0; n < data.length; n++) + this.emit('data', `${data[n]}\n`); }; } util.inherits(ArrayStream, Stream); @@ -816,11 +821,11 @@ function complete(line, callback) { var tmp = this.lines.slice(); // Kill off all function declarations to push all local variables into // global scope - this.lines.level.forEach(function(kill) { - if (kill.isFunction) { + for (var n = 0; n < this.lines.level.length; n++) { + var kill = this.lines.level[n]; + if (kill.isFunction) tmp[kill.line] = ''; - } - }); + } var flat = new ArrayStream(); // make a new "input" stream var magic = new REPLServer('', flat); // make a nested REPL replMap.set(magic, replMap.get(this)); @@ -954,9 +959,8 @@ function complete(line, callback) { addStandardGlobals(completionGroups, filter); } else if (Array.isArray(globals[0])) { // Add grouped globals - globals.forEach(function(group) { - completionGroups.push(group); - }); + for (var n = 0; n < globals.length; n++) + completionGroups.push(globals[n]); } else { completionGroups.push(globals); addStandardGlobals(completionGroups, filter); @@ -1264,12 +1268,13 @@ function defineDefaultCommands(repl) { (max, name) => Math.max(max, name.length), 0 ); - names.forEach((name) => { - const cmd = this.commands[name]; - const spaces = ' '.repeat(longestNameLength - name.length + 3); - const line = '.' + name + (cmd.help ? spaces + cmd.help : '') + '\n'; + for (var n = 0; n < names.length; n++) { + var name = names[n]; + var cmd = this.commands[name]; + var spaces = ' '.repeat(longestNameLength - name.length + 3); + var line = `.${name}${cmd.help ? spaces + cmd.help : ''}\n`; this.outputStream.write(line); - }); + } this.displayPrompt(); } }); @@ -1293,15 +1298,13 @@ function defineDefaultCommands(repl) { try { var stats = fs.statSync(file); if (stats && stats.isFile()) { - var self = this; var data = fs.readFileSync(file, 'utf8'); var lines = data.split('\n'); this.displayPrompt(); - lines.forEach(function(line) { - if (line) { - self.write(line + '\n'); - } - }); + for (var n = 0; n < lines.length; n++) { + if (lines[n]) + this.write(`${lines[n]}\n`); + } } else { this.outputStream.write('Failed to load:' + file + ' is not a valid file\n'); From e19ca8ba1184ca910b59ccc235eebb6a72491e3e Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Mon, 13 Mar 2017 20:46:57 -0700 Subject: [PATCH 18/48] readline: remove unneeded eslint-disable comment MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove a comment disabling an ESLint rule that is not triggered by the code anyway. PR-URL: https://github.com/nodejs/node/pull/11836 Reviewed-By: Colin Ihrig Reviewed-By: Yuta Hiroto Reviewed-By: Teddy Katz Reviewed-By: Michaël Zasso Reviewed-By: James M Snell Reviewed-By: Luigi Pinca Reviewed-By: Franziska Hinkelmann --- lib/internal/readline.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/internal/readline.js b/lib/internal/readline.js index 60fe946560aaaa..9f1884ad0ea9e1 100644 --- a/lib/internal/readline.js +++ b/lib/internal/readline.js @@ -1,7 +1,6 @@ 'use strict'; // Regex used for ansi escape code splitting -// eslint-disable-next-line no-control-regex // Adopted from https://github.com/chalk/ansi-regex/blob/master/index.js // License: MIT, authors: @sindresorhus, Qix-, and arjunmehta // Matches all ansi escape code sequences in a string From a0b1aa1161de365de63093a8ad9f4eb6d4e5cc1e Mon Sep 17 00:00:00 2001 From: James M Snell Date: Sun, 26 Feb 2017 18:15:36 -0800 Subject: [PATCH 19/48] readline: avoid using forEach PR-URL: https://github.com/nodejs/node/pull/11582 Reviewed-By: Matteo Collina Reviewed-By: Colin Ihrig --- lib/readline.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/readline.js b/lib/readline.js index a571657a726d2a..52bdd976155439 100644 --- a/lib/readline.js +++ b/lib/readline.js @@ -371,9 +371,8 @@ Interface.prototype._normalWrite = function(b) { // either '' or (conceivably) the unfinished portion of the next line string = lines.pop(); this._line_buffer = string; - lines.forEach(function(line) { - this._onLine(line); - }, this); + for (var n = 0; n < lines.length; n++) + this._onLine(lines[n]); } else if (string) { // no newlines this time, save what we have for next time this._line_buffer = string; From c0a2e02f51e3b625ce0356b07b3ab53df8693254 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Sun, 26 Feb 2017 18:08:04 -0800 Subject: [PATCH 20/48] net: avoid using forEach PR-URL: https://github.com/nodejs/node/pull/11582 Reviewed-By: Matteo Collina Reviewed-By: Colin Ihrig --- lib/net.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/net.js b/lib/net.js index 3c009a00fb77c0..309f38c360736b 100644 --- a/lib/net.js +++ b/lib/net.js @@ -1502,9 +1502,9 @@ Server.prototype.getConnections = function(cb) { if (--left === 0) return end(null, total); } - this._slaves.forEach(function(slave) { - slave.getConnections(oncount); - }); + for (var n = 0; n < this._slaves.length; n++) { + this._slaves[n].getConnections(oncount); + } }; @@ -1540,9 +1540,8 @@ Server.prototype.close = function(cb) { this._connections++; // Poll slaves - this._slaves.forEach(function(slave) { - slave.close(onSlaveClose); - }); + for (var n = 0; n < this._slaves.length; n++) + this._slaves[n].close(onSlaveClose); } else { this._emitCloseIfDrained(); } From 7e230727fcb35616415badf0f8e1c9729ba0f61d Mon Sep 17 00:00:00 2001 From: James M Snell Date: Mon, 27 Feb 2017 09:33:07 -0800 Subject: [PATCH 21/48] module: avoid using forEach PR-URL: https://github.com/nodejs/node/pull/11582 Reviewed-By: Matteo Collina Reviewed-By: Colin Ihrig --- lib/module.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/module.js b/lib/module.js index 0c66d3390d222c..d485c7c9a804a3 100644 --- a/lib/module.js +++ b/lib/module.js @@ -661,9 +661,8 @@ Module._preloadModules = function(requests) { throw e; } } - requests.forEach(function(request) { - parent.require(request); - }); + for (var n = 0; n < requests.length; n++) + parent.require(requests[n]); }; Module._initPaths(); From 77c69f7acee32e8896247c15d88a351c971ed6f2 Mon Sep 17 00:00:00 2001 From: DavidCai Date: Tue, 14 Mar 2017 00:11:35 +0800 Subject: [PATCH 22/48] lib, test: add duplicate symbol checking in E() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add duplicate symbol checking in E() to avoid potential confusing result. Increase coverage of internal/errors. PR-URL: https://github.com/nodejs/node/pull/11829 Reviewed-By: James M Snell Reviewed-By: Colin Ihrig Reviewed-By: Michaël Zasso Reviewed-By: Franziska Hinkelmann --- lib/internal/errors.js | 2 ++ test/parallel/test-internal-errors.js | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/lib/internal/errors.js b/lib/internal/errors.js index f2376f70371c60..3cab1409422d6f 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -60,6 +60,8 @@ function message(key, args) { // Utility function for registering the error codes. Only used here. Exported // *only* to allow for testing. function E(sym, val) { + const assert = lazyAssert(); + assert(messages.has(sym) === false, `Error symbol: ${sym} was already used.`); messages.set(sym, typeof val === 'function' ? val : String(val)); } diff --git a/test/parallel/test-internal-errors.js b/test/parallel/test-internal-errors.js index 354209fbadaade..014a0a7a038c6e 100644 --- a/test/parallel/test-internal-errors.js +++ b/test/parallel/test-internal-errors.js @@ -12,6 +12,7 @@ const err1 = new errors.Error('TEST_ERROR_1', 'test'); const err2 = new errors.TypeError('TEST_ERROR_1', 'test'); const err3 = new errors.RangeError('TEST_ERROR_1', 'test'); const err4 = new errors.Error('TEST_ERROR_2', 'abc', 'xyz'); +const err5 = new errors.Error('TEST_ERROR_1'); assert(err1 instanceof Error); assert.strictEqual(err1.name, 'Error[TEST_ERROR_1]'); @@ -33,6 +34,11 @@ assert.strictEqual(err4.name, 'Error[TEST_ERROR_2]'); assert.strictEqual(err4.message, 'abc xyz'); assert.strictEqual(err4.code, 'TEST_ERROR_2'); +assert(err5 instanceof Error); +assert.strictEqual(err5.name, 'Error[TEST_ERROR_1]'); +assert.strictEqual(err5.message, 'Error for testing purposes: %s'); +assert.strictEqual(err5.code, 'TEST_ERROR_1'); + assert.throws( () => new errors.Error('TEST_FOO_KEY'), /^AssertionError: An invalid error message key was used: TEST_FOO_KEY.$/); @@ -118,3 +124,9 @@ assert.throws(() => { type: TypeError, message: /^Error for testing 2/ })); }, /AssertionError: .+ does not match \S/); + +assert.doesNotThrow(() => errors.E('TEST_ERROR_USED_SYMBOL')); +assert.throws( + () => errors.E('TEST_ERROR_USED_SYMBOL'), + /^AssertionError: Error symbol: TEST_ERROR_USED_SYMBOL was already used\.$/ +); From 9cc712ca1859a430d2fe76393c372b6669a040c2 Mon Sep 17 00:00:00 2001 From: mr-spd Date: Mon, 13 Mar 2017 17:38:32 +0100 Subject: [PATCH 23/48] lib: remove unused msg parameter in debug_agent Removed the msg parameter in the Client function of _debug_agent.js, because it is unused. PR-URL: https://github.com/nodejs/node/pull/11833 Reviewed-By: James M Snell Reviewed-By: Daniel Bevenius Reviewed-By: Gibson Fahnestock Reviewed-By: Colin Ihrig Reviewed-By: Yuta Hiroto Reviewed-By: Franziska Hinkelmann Reviewed-By: Jackson Tian --- lib/_debug_agent.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/_debug_agent.js b/lib/_debug_agent.js index c731ca374b5e87..a820b21615a2d7 100644 --- a/lib/_debug_agent.js +++ b/lib/_debug_agent.js @@ -107,7 +107,7 @@ function Client(agent, socket) { } util.inherits(Client, Transform); -Client.prototype.destroy = function destroy(msg) { +Client.prototype.destroy = function destroy() { this.socket.destroy(); this.emit('close'); From fbbcd1aa89da882cc802cb8127c0d42656d7068b Mon Sep 17 00:00:00 2001 From: Jan Krems Date: Wed, 15 Mar 2017 12:42:33 -0700 Subject: [PATCH 24/48] lib: Fix swallowed events in inspect integration PR-URL: https://github.com/nodejs/node/pull/11869 Reviewed-By: Anna Henningsen Reviewed-By: Rich Trott Reviewed-By: James M Snell Reviewed-By: Colin Ihrig --- lib/internal/bootstrap_node.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/internal/bootstrap_node.js b/lib/internal/bootstrap_node.js index 12faa6bf00afb1..1dd51c01ff7a96 100644 --- a/lib/internal/bootstrap_node.js +++ b/lib/internal/bootstrap_node.js @@ -81,7 +81,9 @@ } else if (process.argv[1] === 'inspect') { // Start the debugger agent - NativeModule.require('node-inspect/lib/_inspect').start(); + process.nextTick(function() { + NativeModule.require('node-inspect/lib/_inspect').start(); + }); } else if (process.argv[1] === '--remote_debugging_server') { // Start the debugging server From cde5d71db1cd0bed82a298194f0105ac2220077c Mon Sep 17 00:00:00 2001 From: Vse Mozhet Byt Date: Sun, 12 Mar 2017 13:11:13 +0200 Subject: [PATCH 25/48] doc: var -> let / const in events.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/11810 Reviewed-By: Luigi Pinca Reviewed-By: Michaël Zasso Reviewed-By: Anna Henningsen Reviewed-By: Colin Ihrig Reviewed-By: Gibson Fahnestock Reviewed-By: James M Snell --- doc/api/events.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/api/events.md b/doc/api/events.md index 5f12cfe3191837..0cc9a0206b55c3 100644 --- a/doc/api/events.md +++ b/doc/api/events.md @@ -98,7 +98,7 @@ listener will be invoked _every time_ the named event is emitted. ```js const myEmitter = new MyEmitter(); -var m = 0; +let m = 0; myEmitter.on('event', () => { console.log(++m); }); @@ -114,7 +114,7 @@ the listener is unregistered and *then* called. ```js const myEmitter = new MyEmitter(); -var m = 0; +let m = 0; myEmitter.once('event', () => { console.log(++m); }); @@ -502,7 +502,7 @@ Removes the specified `listener` from the listener array for the event named `eventName`. ```js -var callback = (stream) => { +const callback = (stream) => { console.log('someone connected!'); }; server.on('connection', callback); @@ -524,12 +524,12 @@ events will behave as expected. ```js const myEmitter = new MyEmitter(); -var callbackA = () => { +const callbackA = () => { console.log('A'); myEmitter.removeListener('event', callbackB); }; -var callbackB = () => { +const callbackB = () => { console.log('B'); }; From e6f113d3d5b03dcef715fa85acd5e3335c1689e3 Mon Sep 17 00:00:00 2001 From: Vse Mozhet Byt Date: Sun, 12 Mar 2017 13:14:00 +0200 Subject: [PATCH 26/48] doc: console.log() -> console.error() in events.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/11810 Reviewed-By: Luigi Pinca Reviewed-By: Michaël Zasso Reviewed-By: Anna Henningsen Reviewed-By: Colin Ihrig Reviewed-By: Gibson Fahnestock Reviewed-By: James M Snell --- doc/api/events.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/api/events.md b/doc/api/events.md index 0cc9a0206b55c3..7c72245ced6ca5 100644 --- a/doc/api/events.md +++ b/doc/api/events.md @@ -148,7 +148,7 @@ can be used. (_Note, however, that the `domain` module has been deprecated_) const myEmitter = new MyEmitter(); process.on('uncaughtException', (err) => { - console.log('whoops! there was an error'); + console.error('whoops! there was an error'); }); myEmitter.emit('error', new Error('whoops!')); @@ -160,7 +160,7 @@ As a best practice, listeners should always be added for the `'error'` events. ```js const myEmitter = new MyEmitter(); myEmitter.on('error', (err) => { - console.log('whoops! there was an error'); + console.error('whoops! there was an error'); }); myEmitter.emit('error', new Error('whoops!')); // Prints: whoops! there was an error From ae52b63df2e8bb60e07ba86e90ae40296a8370da Mon Sep 17 00:00:00 2001 From: Alexander Date: Sat, 11 Mar 2017 23:26:50 +0300 Subject: [PATCH 27/48] doc: correct comment error in stream.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix comment about remove listener (not setting) PR-URL: https://github.com/nodejs/node/pull/11804 Reviewed-By: Anna Henningsen Reviewed-By: James M Snell Reviewed-By: Luigi Pinca Reviewed-By: Colin Ihrig Reviewed-By: Michaël Zasso Reviewed-By: Brian White --- doc/api/stream.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/stream.md b/doc/api/stream.md index c48dfe050808ee..75cba6fd514bd2 100644 --- a/doc/api/stream.md +++ b/doc/api/stream.md @@ -1016,7 +1016,7 @@ function parseHeader(stream, callback) { const remaining = split.join('\n\n'); const buf = Buffer.from(remaining, 'utf8'); stream.removeListener('error', callback); - // set the readable listener before unshifting + // remove the readable listener before unshifting stream.removeListener('readable', onReadable); if (buf.length) stream.unshift(buf); From 75fcf53173bef218b05e05f91b8289149aee4daa Mon Sep 17 00:00:00 2001 From: Amelia Clarke Date: Sat, 11 Mar 2017 00:15:20 -0800 Subject: [PATCH 28/48] doc: missing argument types for events methods Refs: https://github.com/nodejs/node/issues/9399 PR-URL: https://github.com/nodejs/node/pull/11802 Reviewed-By: James M Snell Reviewed-By: Colin Ihrig Reviewed-By: Brian White --- doc/api/events.md | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/doc/api/events.md b/doc/api/events.md index 7c72245ced6ca5..5c0614b68bf2df 100644 --- a/doc/api/events.md +++ b/doc/api/events.md @@ -185,7 +185,7 @@ added and `'removeListener'` when existing listeners are removed. added: v0.1.26 --> -* `eventName` {string|symbol} The name of the event being listened for +* `eventName` {any} The name of the event being listened for * `listener` {Function} The event handler function The `EventEmitter` instance will emit its own `'newListener'` event *before* @@ -229,7 +229,7 @@ changes: now yields the original listener function. --> -* `eventName` {string|symbol} The event name +* `eventName` {any} The event name * `listener` {Function} The event handler function The `'removeListener'` event is emitted *after* the `listener` is removed. @@ -296,6 +296,8 @@ Its `name` property is set to `'MaxListenersExceededWarning'`. +- `eventName` {any} +- `listener` {Function} Alias for `emitter.on(eventName, listener)`. @@ -303,6 +305,8 @@ Alias for `emitter.on(eventName, listener)`. +- `eventName` {any} +- `...args` {any} Synchronously calls each of the listeners registered for the event named `eventName`, in the order they were registered, passing the supplied arguments @@ -345,7 +349,7 @@ set by [`emitter.setMaxListeners(n)`][] or defaults to added: v3.2.0 --> -* `eventName` {string|symbol} The name of the event being listened for +* `eventName` {any} The name of the event being listened for Returns the number of listeners listening to the event named `eventName`. @@ -358,6 +362,7 @@ changes: description: For listeners attached using `.once()` this returns the original listeners instead of wrapper functions now. --> +- `eventName` {any} Returns a copy of the array of listeners for the event named `eventName`. @@ -374,7 +379,7 @@ console.log(util.inspect(server.listeners('connection'))); added: v0.1.101 --> -* `eventName` {string|symbol} The name of the event. +* `eventName` {any} The name of the event. * `listener` {Function} The callback function Adds the `listener` function to the end of the listeners array for the @@ -410,7 +415,7 @@ myEE.emit('foo'); added: v0.3.0 --> -* `eventName` {string|symbol} The name of the event. +* `eventName` {any} The name of the event. * `listener` {Function} The callback function Adds a **one time** `listener` function for the event named `eventName`. The @@ -443,7 +448,7 @@ myEE.emit('foo'); added: v6.0.0 --> -* `eventName` {string|symbol} The name of the event. +* `eventName` {any} The name of the event. * `listener` {Function} The callback function Adds the `listener` function to the *beginning* of the listeners array for the @@ -465,7 +470,7 @@ Returns a reference to the `EventEmitter`, so that calls can be chained. added: v6.0.0 --> -* `eventName` {string|symbol} The name of the event. +* `eventName` {any} The name of the event. * `listener` {Function} The callback function Adds a **one time** `listener` function for the event named `eventName` to the @@ -484,6 +489,7 @@ Returns a reference to the `EventEmitter`, so that calls can be chained. +- `eventName` {any} Removes all listeners, or those of the specified `eventName`. @@ -497,6 +503,8 @@ Returns a reference to the `EventEmitter`, so that calls can be chained. +- `eventName` {any} +- `listener` {Function} Removes the specified `listener` from the listener array for the event named `eventName`. @@ -564,6 +572,7 @@ Returns a reference to the `EventEmitter`, so that calls can be chained. +- `n` {integer} By default EventEmitters will print a warning if more than `10` listeners are added for a particular event. This is a useful default that helps finding From e84e33c87ce38532232b0419761c23933c0d7157 Mon Sep 17 00:00:00 2001 From: Gaara Date: Fri, 10 Mar 2017 10:52:43 +0800 Subject: [PATCH 29/48] doc: fix a typo in api/process.md Fix a mistyped module name in example REPL sessions found in the description of the 'warning' event: it should be `events` instead of `event`. PR-URL: https://github.com/nodejs/node/pull/11780 Reviewed-By: James M Snell Reviewed-By: Rich Trott Reviewed-By: Luigi Pinca Reviewed-By: Colin Ihrig --- doc/api/process.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/api/process.md b/doc/api/process.md index ff70f81244afc7..f158a1bc8efa14 100644 --- a/doc/api/process.md +++ b/doc/api/process.md @@ -298,7 +298,7 @@ too many listeners have been added to an event ```txt $ node -> event.defaultMaxListeners = 1; +> events.defaultMaxListeners = 1; > process.on('foo', () => {}); > process.on('foo', () => {}); > (node:38638) Warning: Possible EventEmitter memory leak detected. 2 foo @@ -311,7 +311,7 @@ adds a custom handler to the `'warning'` event: ```txt $ node --no-warnings > var p = process.on('warning', (warning) => console.warn('Do not do that!')); -> event.defaultMaxListeners = 1; +> events.defaultMaxListeners = 1; > process.on('foo', () => {}); > process.on('foo', () => {}); > Do not do that! From 78ca15dd785abb588e86e50f119afe88a0352372 Mon Sep 17 00:00:00 2001 From: Amelia Clarke Date: Wed, 8 Mar 2017 21:33:31 -0800 Subject: [PATCH 30/48] doc: argument types for dns methods Refs: https://github.com/nodejs/node/issues/9399 PR-URL: https://github.com/nodejs/node/pull/11764 Reviewed-By: Anna Henningsen Reviewed-By: Timothy Gu Reviewed-By: James M Snell Reviewed-By: Michael Dawson Reviewed-By: Colin Ihrig --- doc/api/dns.md | 139 +++++++++++++++++++++++++++++++------------------ 1 file changed, 89 insertions(+), 50 deletions(-) diff --git a/doc/api/dns.md b/doc/api/dns.md index 7f075be3114279..45d494eab3bcf2 100644 --- a/doc/api/dns.md +++ b/doc/api/dns.md @@ -70,33 +70,25 @@ changes: pr-url: https://github.com/nodejs/node/pull/744 description: The `all` option is supported now. --> +- `hostname` {string} +- `options` {integer | Object} + - `family` {integer} The record family. Must be `4` or `6`. IPv4 + and IPv6 addresses are both returned by default. + - `hints` {number} One or more [supported `getaddrinfo` flags][]. Multiple + flags may be passed by bitwise `OR`ing their values. + - `all` {boolean} When `true`, the callback returns all resolved addresses in + an array. Otherwise, returns a single address. Defaults to `false`. +- `callback` {Function} + - `err` {Error} + - `address` {string} A string representation of an IPv4 or IPv6 address. + - `family` {integer} `4` or `6`, denoting the family of `address`. Resolves a hostname (e.g. `'nodejs.org'`) into the first found A (IPv4) or -AAAA (IPv6) record. `options` can be an object or integer. If `options` is -not provided, then IPv4 and IPv6 addresses are both valid. If `options` is -an integer, then it must be `4` or `6`. - -Alternatively, `options` can be an object containing these properties: - -* `family` {number} - The record family. If present, must be the integer - `4` or `6`. If not provided, both IP v4 and v6 addresses are accepted. -* `hints`: {number} - If present, it should be one or more of the supported - `getaddrinfo` flags. If `hints` is not provided, then no flags are passed to - `getaddrinfo`. Multiple flags can be passed through `hints` by bitwise - `OR`ing their values. - See [supported `getaddrinfo` flags][] for more information on supported - flags. -* `all`: {boolean} - When `true`, the callback returns all resolved addresses - in an array, otherwise returns a single address. Defaults to `false`. - -All properties are optional. - -The `callback` function has arguments `(err, address, family)`. `address` is a -string representation of an IPv4 or IPv6 address. `family` is either the -integer `4` or `6` and denotes the family of `address` (not necessarily the -value initially passed to `lookup`). - -With the `all` option set to `true`, the arguments change to +AAAA (IPv6) record. All `option` properties are optional. If `options` is an +integer, then it must be `4` or `6` – if `options` is not provided, then IPv4 +and IPv6 addresses are both returned if found. + +With the `all` option set to `true`, the arguments for `callback` change to `(err, addresses)`, with `addresses` being an array of objects with the properties `address` and `family`. @@ -147,6 +139,12 @@ on some operating systems (e.g FreeBSD 10.1). +- `address` {string} +- `port` {number} +- `callback` {Function} + - `err` {Error} + - `hostname` {string} e.g. `example.com` + - `service` {string} e.g. `http` Resolves the given `address` and `port` into a hostname and service using the operating system's underlying `getnameinfo` implementation. @@ -155,10 +153,7 @@ If `address` is not a valid IP address, a `TypeError` will be thrown. The `port` will be coerced to a number. If it is not a legal port, a `TypeError` will be thrown. -The callback has arguments `(err, hostname, service)`. The `hostname` and -`service` arguments are strings (e.g. `'localhost'` and `'http'` respectively). - -On error, `err` is an [`Error`][] object, where `err.code` is the error code. +On an error, `err` is an [`Error`][] object, where `err.code` is the error code. ```js const dns = require('dns'); @@ -172,6 +167,11 @@ dns.lookupService('127.0.0.1', 22, (err, hostname, service) => { +- `hostname` {string} +- `rrtype` {string} +- `callback` {Function} + - `err` {Error} + - `addresses` {string[] | Object[] | string[][] | Object} Uses the DNS protocol to resolve a hostname (e.g. `'nodejs.org'`) into an array of the record types specified by `rrtype`. @@ -208,18 +208,21 @@ changes: description: This method now supports passing `options`, specifically `options.ttl`. --> +- `hostname` {string} Hostname to resolve. +- `options` {Object} + - `ttl` {boolean} Retrieve the Time-To-Live value (TTL) of each record. + When `true`, the callback receives an array of + `{ address: '1.2.3.4', ttl: 60 }` objects rather than an array of strings, + with the TTL expressed in seconds. +- `callback` {Function} + - `err` {Error} + - `addresses` {string[] | Object[]} Uses the DNS protocol to resolve a IPv4 addresses (`A` records) for the `hostname`. The `addresses` argument passed to the `callback` function will contain an array of IPv4 addresses (e.g. `['74.125.79.104', '74.125.79.105', '74.125.79.106']`). -* `hostname` {string} Hostname to resolve. -* `options` {Object} - * `ttl` {boolean} Retrieve the Time-To-Live value (TTL) of each record. - The callback receives an array of `{ address: '1.2.3.4', ttl: 60 }` objects - rather than an array of strings. The TTL is expressed in seconds. -* `callback` {Function} An `(err, result)` callback function. ## dns.resolve6(hostname[, options], callback) +- `hostname` {string} Hostname to resolve. +- `options` {Object} + - `ttl` {boolean} Retrieve the Time-To-Live value (TTL) of each record. + When `true`, the callback receives an array of + `{ address: '0:1:2:3:4:5:6:7', ttl: 60 }` objects rather than an array of + strings, with the TTL expressed in seconds. +- `callback` {Function} + - `err` {Error} + - `addresses` {string[] | Object[]} Uses the DNS protocol to resolve a IPv6 addresses (`AAAA` records) for the `hostname`. The `addresses` argument passed to the `callback` function will contain an array of IPv6 addresses. -* `hostname` {string} Hostname to resolve. -* `options` {Object} - * `ttl` {boolean} Retrieve the Time-To-Live value (TTL) of each record. - The callback receives an array of `{ address: '0:1:2:3:4:5:6:7', ttl: 60 }` - objects rather than an array of strings. The TTL is expressed in seconds. -* `callback` {Function} An `(err, result)` callback function. ## dns.resolveCname(hostname, callback) +- `hostname` {string} +- `callback` {Function} + - `err` {Error} + - `addresses` {string[]} Uses the DNS protocol to resolve `CNAME` records for the `hostname`. The `addresses` argument passed to the `callback` function @@ -256,6 +266,10 @@ will contain an array of canonical name records available for the `hostname` +- `hostname` {string} +- `callback` {Function} + - `err` {Error} + - `addresses` {Object[]} Uses the DNS protocol to resolve mail exchange records (`MX` records) for the `hostname`. The `addresses` argument passed to the `callback` function will @@ -266,11 +280,14 @@ property (e.g. `[{priority: 10, exchange: 'mx.example.com'}, ...]`). +- `hostname` {string} +- `callback` {Function} + - `err` {Error} + - `addresses` {Object[]} Uses the DNS protocol to resolve regular expression based records (`NAPTR` -records) for the `hostname`. The `callback` function has arguments -`(err, addresses)`. The `addresses` argument passed to the `callback` function -will contain an array of objects with the following properties: +records) for the `hostname`. The `addresses` argument passed to the `callback` +function will contain an array of objects with the following properties: * `flags` * `service` @@ -296,16 +313,24 @@ For example: +- `hostname` {string} +- `callback` {Function} + - `err` {Error} + - `addresses` {string[]} Uses the DNS protocol to resolve name server records (`NS` records) for the `hostname`. The `addresses` argument passed to the `callback` function will contain an array of name server records available for `hostname` (e.g. `['ns1.example.com', 'ns2.example.com']`). -## dns.resolvePtr(hostname, callback) +## dns.resolvePtr(hostname) +- `hostname` {string} +- `callback` {Function} + - `err` {Error} + - `addresses` {string[]} Uses the DNS protocol to resolve pointer records (`PTR` records) for the `hostname`. The `addresses` argument passed to the `callback` function will @@ -315,9 +340,13 @@ be an array of strings containing the reply records. +- `hostname` {string} +- `callback` {Function} + - `err` {Error} + - `address` {Object} Uses the DNS protocol to resolve a start of authority record (`SOA` record) for -the `hostname`. The `addresses` argument passed to the `callback` function will +the `hostname`. The `address` argument passed to the `callback` function will be an object with the following properties: * `nsname` @@ -344,6 +373,10 @@ be an object with the following properties: +- `hostname` {string} +- `callback` {Function} + - `err` {Error} + - `addresses` {Object[]} Uses the DNS protocol to resolve service records (`SRV` records) for the `hostname`. The `addresses` argument passed to the `callback` function will @@ -367,6 +400,10 @@ be an array of objects with the following properties: +- `hostname` {string} +- `callback` {Function} + - `err` {Error} + - `addresses` {string[][]} Uses the DNS protocol to resolve text queries (`TXT` records) for the `hostname`. The `addresses` argument passed to the `callback` function is @@ -379,13 +416,14 @@ treated separately. +- `ip` {string} +- `callback` {Function} + - `err` {Error} + - `hostnames` {string[]} Performs a reverse DNS query that resolves an IPv4 or IPv6 address to an array of hostnames. -The `callback` function has arguments `(err, hostnames)`, where `hostnames` -is an array of resolved hostnames for the given `ip`. - On error, `err` is an [`Error`][] object, where `err.code` is one of the [DNS error codes][]. @@ -393,11 +431,12 @@ one of the [DNS error codes][]. +- `servers` {string[]} Sets the IP addresses of the servers to be used when resolving. The `servers` argument is an array of IPv4 or IPv6 addresses. -If a port specified on the address it will be removed. +If a port is specified on the address, it will be removed. An error will be thrown if an invalid address is provided. From 54879ab7d102abf4ae80d871c7c30e07a3d02cdf Mon Sep 17 00:00:00 2001 From: Christian d'Heureuse Date: Sun, 12 Mar 2017 02:35:42 +0100 Subject: [PATCH 31/48] doc: fix mistakes in stream doc (object mode) This patch fixes some trivial documentation mistakes for streams operating in object mode. For `unshift()`, `_write()`, `push()` and `_transform()`, the data type of the `chunk` parameter is extended with `any` and the description is corrected to take into account that streams can operate in object mode. PR-URL: https://github.com/nodejs/node/pull/11807 Reviewed-By: James M Snell Reviewed-By: Matteo Collina Reviewed-By: Colin Ihrig Reviewed-By: Franziska Hinkelmann Reviewed-By: Anna Henningsen --- doc/api/stream.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/doc/api/stream.md b/doc/api/stream.md index 75cba6fd514bd2..289250c638ff15 100644 --- a/doc/api/stream.md +++ b/doc/api/stream.md @@ -981,7 +981,7 @@ setTimeout(() => { added: v0.9.11 --> -* `chunk` {Buffer|string} Chunk of data to unshift onto the read queue +* `chunk` {Buffer|string|any} Chunk of data to unshift onto the read queue The `readable.unshift()` method pushes a chunk of data back into the internal buffer. This is useful in certain situations where a stream is being consumed by @@ -1295,8 +1295,9 @@ const myWritable = new Writable({ #### writable.\_write(chunk, encoding, callback) -* `chunk` {Buffer|string} The chunk to be written. Will **always** - be a buffer unless the `decodeStrings` option was set to `false`. +* `chunk` {Buffer|string|any} The chunk to be written. Will **always** + be a buffer unless the `decodeStrings` option was set to `false` + or the stream is operating in object mode. * `encoding` {string} If the chunk is a string, then `encoding` is the character encoding of that string. If chunk is a `Buffer`, or if the stream is operating in object mode, `encoding` may be ignored. @@ -1500,13 +1501,13 @@ user programs. #### readable.push(chunk[, encoding]) -* `chunk` {Buffer|null|string} Chunk of data to push into the read queue +* `chunk` {Buffer|null|string|any} Chunk of data to push into the read queue * `encoding` {string} Encoding of String chunks. Must be a valid Buffer encoding, such as `'utf8'` or `'ascii'` * Returns {boolean} `true` if additional chunks of data may continued to be pushed; `false` otherwise. -When `chunk` is a `Buffer` or `string`, the `chunk` of data will be added to the +When `chunk` is not `null`, the `chunk` of data will be added to the internal queue for users of the stream to consume. Passing `chunk` as `null` signals the end of the stream (EOF), after which no more data can be written. @@ -1873,8 +1874,9 @@ user programs. #### transform.\_transform(chunk, encoding, callback) -* `chunk` {Buffer|string} The chunk to be transformed. Will **always** - be a buffer unless the `decodeStrings` option was set to `false`. +* `chunk` {Buffer|string|any} The chunk to be transformed. Will **always** + be a buffer unless the `decodeStrings` option was set to `false` + or the stream is operating in object mode. * `encoding` {string} If the chunk is a string, then this is the encoding type. If chunk is a buffer, then this is the special value - 'buffer', ignore it in this case. From 9861ec93d4b5420eb48b9169f1bec16b052354bf Mon Sep 17 00:00:00 2001 From: cjihrig Date: Tue, 14 Mar 2017 10:43:08 -0400 Subject: [PATCH 32/48] doc: increase Buffer.concat() documentation This commit adds documentation for two edge cases in Buffer.concat(). Those cases are: - totalLength is specified, but is not an integer. - The combined buffer length is greater than totalLength. PR-URL: https://github.com/nodejs/node/pull/11845 Fixes: https://github.com/nodejs/node/issues/11605 Reviewed-By: James M Snell Reviewed-By: Joyee Cheung Reviewed-By: Luigi Pinca --- doc/api/buffer.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/api/buffer.md b/doc/api/buffer.md index 19a82a72c803dd..b5c1e9895d1fdc 100644 --- a/doc/api/buffer.md +++ b/doc/api/buffer.md @@ -747,6 +747,10 @@ in `list`. This however causes an additional loop to be executed in order to calculate the `totalLength`, so it is faster to provide the length explicitly if it is already known. +If `totalLength` is provided, it is coerced to an unsigned integer. If the +combined length of the `Buffer`s in `list` exceeds `totalLength`, the result is +truncated to `totalLength`. + Example: Create a single `Buffer` from a list of three `Buffer` instances ```js From 7c7228ed4b833b3bee77eabd3a31a9d1c0a66339 Mon Sep 17 00:00:00 2001 From: detailyang Date: Tue, 14 Mar 2017 17:07:09 +0800 Subject: [PATCH 33/48] doc: gcc version is at least 4.8.5 in BUILDING.md >= 4.8.5 is required because of compiler bugs in earlier versions PR-URL: https://github.com/nodejs/node/pull/11840 Reviewed-By: Colin Ihrig Reviewed-By: Ben Noordhuis Reviewed-By: Luigi Pinca Reviewed-By: James M Snell --- BUILDING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BUILDING.md b/BUILDING.md index 75ef93f8c73a13..2dd5c142779ead 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -13,7 +13,7 @@ file a new issue. Prerequisites: -* `gcc` and `g++` 4.8 or newer, or +* `gcc` and `g++` 4.8.5 or newer, or * `clang` and `clang++` 3.4 or newer * Python 2.6 or 2.7 * GNU Make 3.81 or newer From 6d6a65e2ad71f96976584f73bd73bb95d31d27d3 Mon Sep 17 00:00:00 2001 From: Sam Roberts Date: Fri, 10 Mar 2017 11:35:46 -0800 Subject: [PATCH 34/48] doc: linkable commit message guidelines Put the commit guidelines themselves under a heading to be more prominent, and to allow linking directly to them (instead of the section on how to use git). Link the pull request template to the guidelines, so contributors can find them. PR-URL: https://github.com/nodejs/node/pull/11792 Reviewed-By: Rich Trott Reviewed-By: Joyee Cheung Reviewed-By: Luigi Pinca Reviewed-By: Anna Henningsen Reviewed-By: James M Snell --- .github/PULL_REQUEST_TEMPLATE.md | 4 +++- CONTRIBUTING.md | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index e14f5fc937d620..24b66f8b2f8b4d 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -13,7 +13,9 @@ Contributors guide: https://github.com/nodejs/node/blob/master/CONTRIBUTING.md - [ ] `make -j4 test` (UNIX), or `vcbuild test nosign` (Windows) passes - [ ] tests and/or benchmarks are included - [ ] documentation is changed or added -- [ ] commit message follows commit guidelines +- [ ] commit message follows [commit guidelines][] ##### Affected core subsystem(s) + +[commit guidelines]: https://github.com/nodejs/node/blob/master/CONTRIBUTING.md#commit-guidelines diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 290cad8faaeb7a..923fb0299046fb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -95,6 +95,8 @@ $ git add my/changed/files $ git commit ``` +### Commit guidelines + Writing good commit logs is important. A commit log should describe what changed and why. Follow these guidelines when writing one: From 0c091262bdb30dfa7899fb0335182db92377cb55 Mon Sep 17 00:00:00 2001 From: Ruslan Bekenev Date: Sat, 25 Feb 2017 23:11:50 +0300 Subject: [PATCH 35/48] doc: add note that vm module is not a security mechanism the text added in this commit should warn users about wrong idea that vm module can be secure to run unsafe scripts in sandboxes PR-URL: https://github.com/nodejs/node/pull/11557 Reviewed-By: James M Snell Reviewed-By: Evan Lucas Reviewed-By: Colin Ihrig Reviewed-By: Ben Noordhuis --- doc/api/vm.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/api/vm.md b/doc/api/vm.md index 025e9725a94e66..b6fb90440a1993 100644 --- a/doc/api/vm.md +++ b/doc/api/vm.md @@ -14,6 +14,9 @@ const vm = require('vm'); JavaScript code can be compiled and run immediately or compiled, saved, and run later. +*Note*: The vm module is not a security mechanism. +**Do not use it to run untrusted code**. + ## Class: vm.Script + +Activate inspector on host:port. Default is 127.0.0.1:9229. + +V8 inspector integration allows tools such as Chrome DevTools and IDEs to debug +and profile Node.js instances. The tools attach to Node.js instances via a +tcp port and communicate using the [Chrome Debugging Protocol][]. + + +### `--inspect-brk[=host:port]` + + +Activate inspector on host:port and break at start of user script. + + ### `--no-deprecation`