From 792acc17bf0f8573f97d80528c2fa677b9f84966 Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Fri, 16 Jun 2017 15:47:48 -0400 Subject: [PATCH 01/92] net: fix abort on bad address input Backport-PR-URL: https://github.com/nodejs/node/pull/14390 PR-URL: https://github.com/nodejs/node/pull/13726 Reviewed-By: Anna Henningsen Reviewed-By: Refael Ackermann Reviewed-By: Colin Ihrig Reviewed-By: Luigi Pinca Reviewed-By: James M Snell --- lib/net.js | 10 +++++--- .../test-net-better-error-messages-path.js | 23 +++++++++++++------ 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/lib/net.js b/lib/net.js index 5e653c61d2106c..4f1395ec2ed73a 100644 --- a/lib/net.js +++ b/lib/net.js @@ -912,8 +912,9 @@ Socket.prototype.connect = function(options, cb) { this._sockname = null; } - var pipe = !!options.path; - debug('pipe', pipe, options.path); + const path = options.path; + var pipe = !!path; + debug('pipe', pipe, path); if (!this._handle) { this._handle = pipe ? new Pipe() : new TCP(); @@ -930,7 +931,10 @@ Socket.prototype.connect = function(options, cb) { this.writable = true; if (pipe) { - connect(this, options.path); + if (typeof path !== 'string') { + throw new TypeError('"path" option must be a string: ' + path); + } + connect(this, path); } else { lookupAndConnect(this, options); } diff --git a/test/parallel/test-net-better-error-messages-path.js b/test/parallel/test-net-better-error-messages-path.js index f4d00c7aebf055..5f6203a5c2fe45 100644 --- a/test/parallel/test-net-better-error-messages-path.js +++ b/test/parallel/test-net-better-error-messages-path.js @@ -2,12 +2,21 @@ const common = require('../common'); const net = require('net'); const assert = require('assert'); -const fp = '/tmp/fadagagsdfgsdf'; -const c = net.connect(fp); -c.on('connect', common.mustNotCall()); +{ + const fp = '/tmp/fadagagsdfgsdf'; + const c = net.connect(fp); -c.on('error', common.mustCall(function(e) { - assert.strictEqual(e.code, 'ENOENT'); - assert.strictEqual(e.message, `connect ENOENT ${fp}`); -})); + c.on('connect', common.mustNotCall()); + c.on('error', common.mustCall(function(e) { + assert.strictEqual(e.code, 'ENOENT'); + assert.strictEqual(e.message, `connect ENOENT ${fp}`); + })); +} + +{ + assert.throws( + () => net.createConnection({ path: {} }), + /"path" option must be a string: \[object Object]/ + ); +} From 38ae5c4e34bb3395eb567185ceef12fc47771344 Mon Sep 17 00:00:00 2001 From: Vse Mozhet Byt Date: Sat, 15 Jul 2017 03:30:28 +0300 Subject: [PATCH 02/92] doc, lib, test: do not re-require needlessly PR-URL: https://github.com/nodejs/node/pull/14244 Reviewed-By: Alexey Orlenko --- doc/api/child_process.md | 5 ++-- lib/internal/process.js | 14 +++++----- lib/repl.js | 4 +-- test/common/index.js | 16 +++-------- .../test-assert-typedarray-deepequal.js | 6 ++--- test/parallel/test-assert.js | 2 +- .../test-child-process-fork-and-spawn.js | 3 +-- ...test-child-process-send-returns-boolean.js | 3 +-- test/parallel/test-domain-exit-dispose.js | 1 - .../parallel/test-http-invalidheaderfield2.js | 19 +++++++------ test/parallel/test-listen-fd-detached.js | 1 - .../test-net-pause-resume-connecting.js | 10 +++---- test/parallel/test-process-exit-code.js | 27 ++++++++++--------- test/parallel/test-readline-interface.js | 3 +-- test/parallel/test-require-symlink.js | 3 +-- test/parallel/test-tls-session-cache.js | 17 ++++++------ test/pummel/test-vm-memleak.js | 5 ++-- .../sequential/test-child-process-execsync.js | 3 +-- test/sequential/test-module-loading.js | 2 +- 19 files changed, 65 insertions(+), 79 deletions(-) diff --git a/doc/api/child_process.md b/doc/api/child_process.md index 6aab69b7ceb681..1a61e026c4077a 100644 --- a/doc/api/child_process.md +++ b/doc/api/child_process.md @@ -1046,8 +1046,9 @@ socket to the child process. The example below spawns two children that each handle connections with "normal" or "special" priority: ```js -const normal = require('child_process').fork('subprocess.js', ['normal']); -const special = require('child_process').fork('subprocess.js', ['special']); +const { fork } = require('child_process'); +const normal = fork('subprocess.js', ['normal']); +const special = fork('subprocess.js', ['special']); // Open up the server and send sockets to child const server = require('net').createServer(); diff --git a/lib/internal/process.js b/lib/internal/process.js index c8a58504fcf307..76098bb4d8a5b6 100644 --- a/lib/internal/process.js +++ b/lib/internal/process.js @@ -1,5 +1,7 @@ 'use strict'; +const util = require('util'); + var _lazyConstants = null; function lazyConstants() { @@ -185,10 +187,8 @@ function setupKillAndExit() { } } - if (err) { - const errnoException = require('util')._errnoException; - throw errnoException(err, 'kill'); - } + if (err) + throw util._errnoException(err, 'kill'); return true; }; @@ -220,8 +220,7 @@ function setupSignalHandlers() { const err = wrap.start(signum); if (err) { wrap.close(); - const errnoException = require('util')._errnoException; - throw errnoException(err, 'uv_signal_start'); + throw util._errnoException(err, 'uv_signal_start'); } signalWraps[type] = wrap; @@ -261,9 +260,8 @@ function setupChannel() { function setupRawDebug() { - const format = require('util').format; const rawDebug = process._rawDebug; process._rawDebug = function() { - rawDebug(format.apply(null, arguments)); + rawDebug(util.format.apply(null, arguments)); }; } diff --git a/lib/repl.js b/lib/repl.js index eb539cca0ef456..b48242be1bc763 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -61,7 +61,7 @@ try { } // hack for repl require to work properly with node_modules folders -module.paths = require('module')._nodeModulePaths(module.filename); +module.paths = Module._nodeModulePaths(module.filename); // If obj.hasOwnProperty has been overridden, then calling // obj.hasOwnProperty(prop) will break. @@ -869,7 +869,7 @@ function complete(line, callback) { filter = match[1]; var dir, files, f, name, base, ext, abs, subfiles, s; group = []; - var paths = module.paths.concat(require('module').globalPaths); + var paths = module.paths.concat(Module.globalPaths); for (i = 0; i < paths.length; i++) { dir = path.resolve(paths[i], subdir); try { diff --git a/test/common/index.js b/test/common/index.js index 9932a6daf2bda6..df223e051935a8 100644 --- a/test/common/index.js +++ b/test/common/index.js @@ -4,7 +4,7 @@ const path = require('path'); const fs = require('fs'); const assert = require('assert'); const os = require('os'); -const child_process = require('child_process'); +const { exec, execSync, spawn, spawnSync } = require('child_process'); const stream = require('stream'); const util = require('util'); const Timer = process.binding('timer_wrap').Timer; @@ -121,7 +121,7 @@ Object.defineProperty(exports, 'inFreeBSDJail', { if (inFreeBSDJail !== null) return inFreeBSDJail; if (exports.isFreeBSD && - child_process.execSync('sysctl -n security.jail.jailed').toString() === + execSync('sysctl -n security.jail.jailed').toString() === '1\n') { inFreeBSDJail = true; } else { @@ -168,7 +168,7 @@ Object.defineProperty(exports, 'opensslCli', {get: function() { if (exports.isWindows) opensslCli += '.exe'; - const opensslCmd = child_process.spawnSync(opensslCli, ['version']); + const opensslCmd = spawnSync(opensslCli, ['version']); if (opensslCmd.status !== 0 || opensslCmd.error !== undefined) { // openssl command cannot be executed opensslCli = false; @@ -219,7 +219,7 @@ exports.childShouldThrowAndAbort = function() { } testCmd += `"${process.argv[0]}" --abort-on-uncaught-exception `; testCmd += `"${process.argv[1]}" child`; - const child = child_process.exec(testCmd); + const child = exec(testCmd); child.on('exit', function onExit(exitCode, signal) { const errMsg = 'Test should have aborted ' + `but instead exited with exit code ${exitCode}` + @@ -239,8 +239,6 @@ exports.ddCommand = function(filename, kilobytes) { exports.spawnCat = function(options) { - const spawn = require('child_process').spawn; - if (exports.isWindows) { return spawn('more', [], options); } else { @@ -250,8 +248,6 @@ exports.spawnCat = function(options) { exports.spawnSyncCat = function(options) { - const spawnSync = require('child_process').spawnSync; - if (exports.isWindows) { return spawnSync('more', [], options); } else { @@ -261,8 +257,6 @@ exports.spawnSyncCat = function(options) { exports.spawnPwd = function(options) { - const spawn = require('child_process').spawn; - if (exports.isWindows) { return spawn('cmd.exe', ['/c', 'cd'], options); } else { @@ -272,8 +266,6 @@ exports.spawnPwd = function(options) { exports.spawnSyncPwd = function(options) { - const spawnSync = require('child_process').spawnSync; - if (exports.isWindows) { return spawnSync('cmd.exe', ['/c', 'cd'], options); } else { diff --git a/test/parallel/test-assert-typedarray-deepequal.js b/test/parallel/test-assert-typedarray-deepequal.js index f5ecb274a86a32..7eed19cc539466 100644 --- a/test/parallel/test-assert-typedarray-deepequal.js +++ b/test/parallel/test-assert-typedarray-deepequal.js @@ -2,7 +2,6 @@ require('../common'); const assert = require('assert'); -const a = require('assert'); function makeBlock(f) { const args = Array.prototype.slice.call(arguments, 1); @@ -51,7 +50,8 @@ equalArrayPairs.forEach((arrayPair) => { notEqualArrayPairs.forEach((arrayPair) => { assert.throws( - makeBlock(a.deepEqual, arrayPair[0], arrayPair[1]), - a.AssertionError + // eslint-disable-next-line no-restricted-properties + makeBlock(assert.deepEqual, arrayPair[0], arrayPair[1]), + assert.AssertionError ); }); diff --git a/test/parallel/test-assert.js b/test/parallel/test-assert.js index 30ab10a1283b82..3579c10f159ad5 100644 --- a/test/parallel/test-assert.js +++ b/test/parallel/test-assert.js @@ -1,7 +1,7 @@ 'use strict'; require('../common'); const assert = require('assert'); -const a = require('assert'); +const a = assert; function makeBlock(f) { const args = Array.prototype.slice.call(arguments, 1); diff --git a/test/parallel/test-child-process-fork-and-spawn.js b/test/parallel/test-child-process-fork-and-spawn.js index 5807147a1c947d..b3e7e29f7d9bd0 100644 --- a/test/parallel/test-child-process-fork-and-spawn.js +++ b/test/parallel/test-child-process-fork-and-spawn.js @@ -1,8 +1,7 @@ 'use strict'; const common = require('../common'); const assert = require('assert'); -const spawn = require('child_process').spawn; -const fork = require('child_process').fork; +const { fork, spawn } = require('child_process'); // Fork, then spawn. The spawned process should not hang. switch (process.argv[2] || '') { diff --git a/test/parallel/test-child-process-send-returns-boolean.js b/test/parallel/test-child-process-send-returns-boolean.js index 379f76a67390b9..d986b633d4140b 100644 --- a/test/parallel/test-child-process-send-returns-boolean.js +++ b/test/parallel/test-child-process-send-returns-boolean.js @@ -3,8 +3,7 @@ const common = require('../common'); const assert = require('assert'); const path = require('path'); const net = require('net'); -const fork = require('child_process').fork; -const spawn = require('child_process').spawn; +const { fork, spawn } = require('child_process'); const emptyFile = path.join(common.fixturesDir, 'empty.js'); diff --git a/test/parallel/test-domain-exit-dispose.js b/test/parallel/test-domain-exit-dispose.js index a9c69ac3396712..686cdb890defb2 100644 --- a/test/parallel/test-domain-exit-dispose.js +++ b/test/parallel/test-domain-exit-dispose.js @@ -1,5 +1,4 @@ 'use strict'; -require('../common'); const common = require('../common'); const assert = require('assert'); const domain = require('domain'); diff --git a/test/parallel/test-http-invalidheaderfield2.js b/test/parallel/test-http-invalidheaderfield2.js index 2267c8565cb634..40415d9c368891 100644 --- a/test/parallel/test-http-invalidheaderfield2.js +++ b/test/parallel/test-http-invalidheaderfield2.js @@ -2,8 +2,7 @@ require('../common'); const assert = require('assert'); const inspect = require('util').inspect; -const checkIsHttpToken = require('_http_common')._checkIsHttpToken; -const checkInvalidHeaderChar = require('_http_common')._checkInvalidHeaderChar; +const { _checkIsHttpToken, _checkInvalidHeaderChar } = require('_http_common'); // Good header field names [ @@ -29,8 +28,8 @@ const checkInvalidHeaderChar = require('_http_common')._checkInvalidHeaderChar; '3.14159265359' ].forEach(function(str) { assert.strictEqual( - checkIsHttpToken(str), true, - `checkIsHttpToken(${inspect(str)}) unexpectedly failed`); + _checkIsHttpToken(str), true, + `_checkIsHttpToken(${inspect(str)}) unexpectedly failed`); }); // Bad header field names [ @@ -55,8 +54,8 @@ const checkInvalidHeaderChar = require('_http_common')._checkInvalidHeaderChar; 'This,That' ].forEach(function(str) { assert.strictEqual( - checkIsHttpToken(str), false, - `checkIsHttpToken(${inspect(str)}) unexpectedly succeeded`); + _checkIsHttpToken(str), false, + `_checkIsHttpToken(${inspect(str)}) unexpectedly succeeded`); }); @@ -68,8 +67,8 @@ const checkInvalidHeaderChar = require('_http_common')._checkInvalidHeaderChar; '!@#$%^&*()-_=+\\;\':"[]{}<>,./?|~`' ].forEach(function(str) { assert.strictEqual( - checkInvalidHeaderChar(str), false, - `checkInvalidHeaderChar(${inspect(str)}) unexpectedly failed`); + _checkInvalidHeaderChar(str), false, + `_checkInvalidHeaderChar(${inspect(str)}) unexpectedly failed`); }); // Bad header field values @@ -84,6 +83,6 @@ const checkInvalidHeaderChar = require('_http_common')._checkInvalidHeaderChar; 'Ding!\x07' ].forEach(function(str) { assert.strictEqual( - checkInvalidHeaderChar(str), true, - `checkInvalidHeaderChar(${inspect(str)}) unexpectedly succeeded`); + _checkInvalidHeaderChar(str), true, + `_checkInvalidHeaderChar(${inspect(str)}) unexpectedly succeeded`); }); diff --git a/test/parallel/test-listen-fd-detached.js b/test/parallel/test-listen-fd-detached.js index 86d866afd13483..c9b840e2d8f04a 100644 --- a/test/parallel/test-listen-fd-detached.js +++ b/test/parallel/test-listen-fd-detached.js @@ -64,7 +64,6 @@ function parent() { }).listen(0, function() { console.error('server listening on %d', this.address().port); - const spawn = require('child_process').spawn; const child = spawn(process.execPath, [__filename, 'child'], { stdio: [ 'ignore', 'ignore', 'ignore', server._handle ], detached: true diff --git a/test/parallel/test-net-pause-resume-connecting.js b/test/parallel/test-net-pause-resume-connecting.js index 1ae51d51fb25f2..602a449359f456 100644 --- a/test/parallel/test-net-pause-resume-connecting.js +++ b/test/parallel/test-net-pause-resume-connecting.js @@ -19,27 +19,27 @@ const server = net.createServer(function(conn) { server.listen(0, function() { // Client 1 - conn = require('net').createConnection(this.address().port, 'localhost'); + conn = net.createConnection(this.address().port, 'localhost'); conn.resume(); conn.on('data', onDataOk); // Client 2 - conn = require('net').createConnection(this.address().port, 'localhost'); + conn = net.createConnection(this.address().port, 'localhost'); conn.pause(); conn.resume(); conn.on('data', onDataOk); // Client 3 - conn = require('net').createConnection(this.address().port, 'localhost'); + conn = net.createConnection(this.address().port, 'localhost'); conn.pause(); conn.on('data', common.mustNotCall()); scheduleTearDown(conn); // Client 4 - conn = require('net').createConnection(this.address().port, 'localhost'); + conn = net.createConnection(this.address().port, 'localhost'); conn.resume(); conn.pause(); conn.resume(); @@ -47,7 +47,7 @@ server.listen(0, function() { // Client 5 - conn = require('net').createConnection(this.address().port, 'localhost'); + conn = net.createConnection(this.address().port, 'localhost'); conn.resume(); conn.resume(); conn.pause(); diff --git a/test/parallel/test-process-exit-code.js b/test/parallel/test-process-exit-code.js index a956ee19310f26..c26a72fcc596d7 100644 --- a/test/parallel/test-process-exit-code.js +++ b/test/parallel/test-process-exit-code.js @@ -62,22 +62,23 @@ function child5() { } function parent() { + const { spawn } = require('child_process'); + const node = process.execPath; + const f = __filename; + const option = { stdio: [ 0, 1, 'ignore' ] }; + + const test = (arg, exit) => { + spawn(node, [f, arg], option).on('exit', (code) => { + assert.strictEqual( + code, exit, + `wrong exit for ${arg}\nexpected:${exit} but got:${code}`); + console.log('ok - %s exited with %d', arg, exit); + }); + }; + test('child1', 42); test('child2', 42); test('child3', 0); test('child4', 1); test('child5', 99); } - -function test(arg, exit) { - const spawn = require('child_process').spawn; - const node = process.execPath; - const f = __filename; - const option = { stdio: [ 0, 1, 'ignore' ] }; - spawn(node, [f, arg], option).on('exit', function(code) { - assert.strictEqual( - code, exit, - `wrong exit for ${arg}\nexpected:${exit} but got:${code}`); - console.log('ok - %s exited with %d', arg, exit); - }); -} diff --git a/test/parallel/test-readline-interface.js b/test/parallel/test-readline-interface.js index d101a4582dfadb..83b9912e471faa 100644 --- a/test/parallel/test-readline-interface.js +++ b/test/parallel/test-readline-interface.js @@ -4,8 +4,7 @@ const assert = require('assert'); const readline = require('readline'); const EventEmitter = require('events').EventEmitter; const inherits = require('util').inherits; -const Writable = require('stream').Writable; -const Readable = require('stream').Readable; +const { Writable, Readable } = require('stream'); function FakeInput() { EventEmitter.call(this); diff --git a/test/parallel/test-require-symlink.js b/test/parallel/test-require-symlink.js index 85fcb2d2d16f9d..f5129e02739ca0 100644 --- a/test/parallel/test-require-symlink.js +++ b/test/parallel/test-require-symlink.js @@ -4,8 +4,7 @@ const common = require('../common'); const assert = require('assert'); const path = require('path'); const fs = require('fs'); -const exec = require('child_process').exec; -const spawn = require('child_process').spawn; +const { exec, spawn } = require('child_process'); common.refreshTmpDir(); diff --git a/test/parallel/test-tls-session-cache.js b/test/parallel/test-tls-session-cache.js index 326e760f495e82..69ad1074e586fa 100644 --- a/test/parallel/test-tls-session-cache.js +++ b/test/parallel/test-tls-session-cache.js @@ -7,6 +7,15 @@ if (!common.opensslCli) if (!common.hasCrypto) common.skip('missing crypto'); +const assert = require('assert'); +const tls = require('tls'); +const fs = require('fs'); +const { join } = require('path'); +const { spawn } = require('child_process'); + +const keyFile = join(common.fixturesDir, 'agent.key'); +const certFile = join(common.fixturesDir, 'agent.crt'); + doTest({ tickets: false }, function() { doTest({ tickets: true }, function() { console.error('all done'); @@ -14,14 +23,6 @@ doTest({ tickets: false }, function() { }); function doTest(testOptions, callback) { - const assert = require('assert'); - const tls = require('tls'); - const fs = require('fs'); - const join = require('path').join; - const spawn = require('child_process').spawn; - - const keyFile = join(common.fixturesDir, 'agent.key'); - const certFile = join(common.fixturesDir, 'agent.crt'); const key = fs.readFileSync(keyFile); const cert = fs.readFileSync(certFile); const options = { diff --git a/test/pummel/test-vm-memleak.js b/test/pummel/test-vm-memleak.js index 8503e2389b44a7..8bcd08b48606af 100644 --- a/test/pummel/test-vm-memleak.js +++ b/test/pummel/test-vm-memleak.js @@ -3,6 +3,7 @@ require('../common'); const assert = require('assert'); +const vm = require('vm'); const start = Date.now(); let maxMem = 0; @@ -14,7 +15,7 @@ assert(ok, 'Run this test with --max_old_space_size=32.'); const interval = setInterval(function() { try { - require('vm').runInNewContext('throw 1;'); + vm.runInNewContext('throw 1;'); } catch (e) { } @@ -31,7 +32,7 @@ const interval = setInterval(function() { function testContextLeak() { for (let i = 0; i < 1000; i++) - require('vm').createContext({}); + vm.createContext({}); } process.on('exit', function() { diff --git a/test/sequential/test-child-process-execsync.js b/test/sequential/test-child-process-execsync.js index 61e3bf60f75b13..cccd3b7e77d6f3 100644 --- a/test/sequential/test-child-process-execsync.js +++ b/test/sequential/test-child-process-execsync.js @@ -2,8 +2,7 @@ const common = require('../common'); const assert = require('assert'); -const execSync = require('child_process').execSync; -const execFileSync = require('child_process').execFileSync; +const { execFileSync, execSync } = require('child_process'); const TIMER = 200; const SLEEP = 2000; diff --git a/test/sequential/test-module-loading.js b/test/sequential/test-module-loading.js index 8fd681cc651be8..73f40890a422f9 100644 --- a/test/sequential/test-module-loading.js +++ b/test/sequential/test-module-loading.js @@ -110,7 +110,7 @@ try { assert.strictEqual('blah', e.message); } -assert.strictEqual(require('path').dirname(__filename), __dirname); +assert.strictEqual(path.dirname(__filename), __dirname); console.error('load custom file types with extensions'); require.extensions['.test'] = function(module, filename) { From 66cdcd9d5b77d3525704fb93ccaf59a3b282b1fd Mon Sep 17 00:00:00 2001 From: liusi Date: Wed, 15 Mar 2017 11:12:32 +0800 Subject: [PATCH 03/92] build: add cpp linting to windows build This PR adds cpp linting to windows build script. After this change, running command `vcbuild lint` will run both cpp linting and javascript linting on a windows machine. Backport-PR-URL: https://github.com/nodejs/node/pull/14879 PR-URL: https://github.com/nodejs/node/pull/11856 Fixes: https://github.com/nodejs/node/issues/11816 Reviewed-By: James M Snell Reviewed-By: Ben Noordhuis --- CONTRIBUTING.md | 3 ++- tools/cpplint.py | 3 ++- vcbuild.bat | 55 +++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 54 insertions(+), 7 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c012c2258ca84c..b69f2e0708fa9c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -176,7 +176,8 @@ Running `make test`/`vcbuild test` will run the linter as well unless one or more tests fail. If you want to run the linter without running tests, use -`make lint`/`vcbuild lint`. +`make lint`/`vcbuild lint`. It will run both JavaScript linting and +C++ linting. If you are updating tests and just want to run a single test to check it, you can use this syntax to run it exactly as the test harness would: diff --git a/tools/cpplint.py b/tools/cpplint.py index b5a05f0af39ba7..305220060c5cdb 100644 --- a/tools/cpplint.py +++ b/tools/cpplint.py @@ -1074,7 +1074,8 @@ def RepositoryName(self): """ fullname = self.FullName() # XXX(bnoordhuis) Expects that cpplint.py lives in the tools/ directory. - toplevel = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) + toplevel = os.path.abspath( + os.path.join(os.path.dirname(__file__), '..')).replace('\\', '/') prefix = os.path.commonprefix([fullname, toplevel]) return fullname[len(prefix) + 1:] diff --git a/vcbuild.bat b/vcbuild.bat index 1b933b05686c1b..d33e4b7dfc16ab 100644 --- a/vcbuild.bat +++ b/vcbuild.bat @@ -27,6 +27,7 @@ set msi= set upload= set licensertf= set jslint= +set cpplint= set buildnodeweak= set noetw= set noetw_msi_arg= @@ -57,7 +58,7 @@ if /i "%1"=="nosnapshot" set nosnapshot=1&goto arg-ok if /i "%1"=="noetw" set noetw=1&goto arg-ok if /i "%1"=="noperfctr" set noperfctr=1&goto arg-ok if /i "%1"=="licensertf" set licensertf=1&goto arg-ok -if /i "%1"=="test" set test_args=%test_args% doctool known_issues message parallel sequential addons -J&set jslint=1&set build_addons=1&goto arg-ok +if /i "%1"=="test" set test_args=%test_args% doctool known_issues message parallel sequential addons -J&set cpplint=1&set jslint=1&set build_addons=1&goto arg-ok if /i "%1"=="test-ci" set test_args=%test_args% %test_ci_args% -p tap --logfile test.tap doctool inspector known_issues message sequential parallel addons&set cctest_args=%cctest_args% --gtest_output=tap:cctest.tap&set build_addons=1&goto arg-ok if /i "%1"=="test-addons" set test_args=%test_args% addons&set build_addons=1&goto arg-ok if /i "%1"=="test-simple" set test_args=%test_args% sequential parallel -J&goto arg-ok @@ -67,10 +68,12 @@ if /i "%1"=="test-inspector" set test_args=%test_args% inspector&goto arg-ok if /i "%1"=="test-tick-processor" set test_args=%test_args% tick-processor&goto arg-ok if /i "%1"=="test-internet" set test_args=%test_args% internet&goto arg-ok if /i "%1"=="test-pummel" set test_args=%test_args% pummel&goto arg-ok -if /i "%1"=="test-all" set test_args=%test_args% sequential parallel message gc inspector internet pummel&set buildnodeweak=1&set jslint=1&goto arg-ok +if /i "%1"=="test-all" set test_args=%test_args% sequential parallel message gc inspector internet pummel&set buildnodeweak=1&set cpplint=1&set jslint=1&goto arg-ok if /i "%1"=="test-known-issues" set test_args=%test_args% known_issues&goto arg-ok if /i "%1"=="jslint" set jslint=1&goto arg-ok if /i "%1"=="jslint-ci" set jslint_ci=1&goto arg-ok +if /i "%1"=="lint" set cpplint=1&set jslint=1&goto arg-ok +if /i "%1"=="lint-ci" set cpplint=1&set jslint_ci=1&goto arg-ok if /i "%1"=="package" set package=1&goto arg-ok if /i "%1"=="msi" set msi=1&set licensertf=1&set download_arg="--download=all"&set i18n_arg=small-icu&goto arg-ok if /i "%1"=="build-release" set build_release=1&goto arg-ok @@ -323,25 +326,67 @@ for /d %%F in (test\addons\??_*) do ( "%node_exe%" tools\doc\addon-verify.js if %errorlevel% neq 0 exit /b %errorlevel% :: building addons -SetLocal EnableDelayedExpansion +setlocal EnableDelayedExpansion for /d %%F in (test\addons\*) do ( "%node_exe%" deps\npm\node_modules\node-gyp\bin\node-gyp rebuild ^ --directory="%%F" ^ --nodedir="%cd%" if !errorlevel! neq 0 exit /b !errorlevel! ) -EndLocal +endlocal goto run-tests :run-tests -if "%test_args%"=="" goto jslint +if "%test_args%"=="" goto cpplint if "%config%"=="Debug" set test_args=--mode=debug %test_args% if "%config%"=="Release" set test_args=--mode=release %test_args% echo running 'cctest %cctest_args%' "%config%\cctest" %cctest_args% call :run-python tools\test.py %test_args% +goto cpplint + +:cpplint +if not defined cpplint goto jslint +echo running cpplint +set cppfilelist= +setlocal enabledelayedexpansion +for /f "tokens=*" %%G in ('dir /b /s /a src\*.c src\*.cc src\*.h ^ +test\addons\*.cc test\addons\*.h test\cctest\*.cc test\cctest\*.h ^ +test\gc\binding.cc tools\icu\*.cc tools\icu\*.h') do ( + set relpath=%%G + set relpath=!relpath:*%~dp0=! + call :add-to-list !relpath! +) +( endlocal + set cppfilelist=%localcppfilelist% +) +python tools/cpplint.py %cppfilelist% +python tools/check-imports.py goto jslint +:add-to-list +echo %1 | findstr /c:"src\node_root_certs.h" +if %errorlevel% equ 0 goto exit + +echo %1 | findstr /c:"src\queue.h" +if %errorlevel% equ 0 goto exit + +echo %1 | findstr /c:"src\tree.h" +if %errorlevel% equ 0 goto exit + +@rem skip subfolders under /src +echo %1 | findstr /r /c:"src\\.*\\.*" +if %errorlevel% equ 0 goto exit + +echo %1 | findstr /r /c:"test\\addons\\[0-9].*_.*\.h" +if %errorlevel% equ 0 goto exit + +echo %1 | findstr /r /c:"test\\addons\\[0-9].*_.*\.cc" +if %errorlevel% equ 0 goto exit + +set "localcppfilelist=%localcppfilelist% %1" +goto exit + :jslint if defined jslint_ci goto jslint-ci if not defined jslint goto exit From c9ae894277e57c9c6b348b677477d64e86dd287d Mon Sep 17 00:00:00 2001 From: Morgan Brenner Date: Wed, 22 Mar 2017 15:23:00 -0400 Subject: [PATCH 04/92] build: add lint option to vcbuild.bat help https://github.com/nodejs/node/pull/14879/commits/180bec189f247f97f505eedb9ab36620dc4cd773 PR-URL: https://github.com/nodejs/node/pull/11992 Fixes: https://github.com/nodejs/node/issues/11971 Reviewed-By: Gibson Fahnestock Reviewed-By: Vse Mozhet Byt Reviewed-By: James M Snell Reviewed-By: Richard Lau Reviewed-By: Colin Ihrig --- vcbuild.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vcbuild.bat b/vcbuild.bat index d33e4b7dfc16ab..5fe74496d78a7b 100644 --- a/vcbuild.bat +++ b/vcbuild.bat @@ -410,7 +410,7 @@ echo Failed to create vc project files. goto exit :help -echo vcbuild.bat [debug/release] [msi] [test-all/test-uv/test-inspector/test-internet/test-pummel/test-simple/test-message] [clean] [noprojgen] [small-icu/full-icu/without-intl] [nobuild] [nosign] [x86/x64] [vc2015] [download-all] [enable-vtune] +echo vcbuild.bat [debug/release] [msi] [test-all/test-uv/test-inspector/test-internet/test-pummel/test-simple/test-message] [clean] [noprojgen] [small-icu/full-icu/without-intl] [nobuild] [nosign] [x86/x64] [vc2015] [download-all] [enable-vtune] [lint/lint-ci] echo Examples: echo vcbuild.bat : builds release build echo vcbuild.bat debug : builds debug build From 14cc1abb5662e8baa8ff51875f332d02b1a9a8ab Mon Sep 17 00:00:00 2001 From: Kyle Farnung Date: Thu, 6 Jul 2017 16:03:27 -0700 Subject: [PATCH 05/92] build: split up cpplint to avoid long cmd lines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refactors cpplint slightly to allow multiple runs of it. This allows downstream projects to run cpplint on their dependencies. Backport-PR-URL: https://github.com/nodejs/node/pull/14879 PR-URL: https://github.com/nodejs/node/pull/14116 Reviewed-By: Refael Ackermann Reviewed-By: Kunal Pathak Reviewed-By: João Reis --- vcbuild.bat | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/vcbuild.bat b/vcbuild.bat index 5fe74496d78a7b..8fbb8d365f76e4 100644 --- a/vcbuild.bat +++ b/vcbuild.bat @@ -72,6 +72,7 @@ if /i "%1"=="test-all" set test_args=%test_args% sequential parallel messag if /i "%1"=="test-known-issues" set test_args=%test_args% known_issues&goto arg-ok if /i "%1"=="jslint" set jslint=1&goto arg-ok if /i "%1"=="jslint-ci" set jslint_ci=1&goto arg-ok +if /i "%1"=="cpplint" set cpplint=1&goto arg-ok if /i "%1"=="lint" set cpplint=1&set jslint=1&goto arg-ok if /i "%1"=="lint-ci" set cpplint=1&set jslint_ci=1&goto arg-ok if /i "%1"=="package" set package=1&goto arg-ok @@ -347,12 +348,16 @@ goto cpplint :cpplint if not defined cpplint goto jslint -echo running cpplint +call :run-cpplint src\*.c src\*.cc src\*.h test\addons\*.cc test\addons\*.h test\cctest\*.cc test\cctest\*.h tools\icu\*.cc tools\icu\*.h +call :run-python tools/check-imports.py +goto jslint + +:run-cpplint +if "%*"=="" goto exit +echo running cpplint '%*' set cppfilelist= setlocal enabledelayedexpansion -for /f "tokens=*" %%G in ('dir /b /s /a src\*.c src\*.cc src\*.h ^ -test\addons\*.cc test\addons\*.h test\cctest\*.cc test\cctest\*.h ^ -test\gc\binding.cc tools\icu\*.cc tools\icu\*.h') do ( +for /f "tokens=*" %%G in ('dir /b /s /a %*') do ( set relpath=%%G set relpath=!relpath:*%~dp0=! call :add-to-list !relpath! @@ -360,9 +365,8 @@ test\gc\binding.cc tools\icu\*.cc tools\icu\*.h') do ( ( endlocal set cppfilelist=%localcppfilelist% ) -python tools/cpplint.py %cppfilelist% -python tools/check-imports.py -goto jslint +call :run-python tools/cpplint.py %cppfilelist% +goto exit :add-to-list echo %1 | findstr /c:"src\node_root_certs.h" From 86047729605ad71654e5262593c5200417944736 Mon Sep 17 00:00:00 2001 From: Azard Date: Fri, 18 Aug 2017 01:18:52 +0800 Subject: [PATCH 06/92] readline: remove max limit of crlfDelay Backport-PR-URL: https://github.com/nodejs/node/pull/14899 PR-URL: https://github.com/nodejs/node/pull/13497 Reviewed-By: Prince John Wesley Reviewed-By: James M Snell Reviewed-By: Anna Henningsen Reviewed-By: Refael Ackermann --- doc/api/readline.md | 4 +- lib/readline.js | 5 +- test/parallel/test-readline-interface.js | 70 ++++++++++++++++++++++-- 3 files changed, 69 insertions(+), 10 deletions(-) diff --git a/doc/api/readline.md b/doc/api/readline.md index fab1e9b3ed80f3..bac425fa37e659 100644 --- a/doc/api/readline.md +++ b/doc/api/readline.md @@ -362,7 +362,9 @@ added: v0.1.98 * `crlfDelay` {number} If the delay between `\r` and `\n` exceeds `crlfDelay` milliseconds, both `\r` and `\n` will be treated as separate end-of-line input. Default to `100` milliseconds. - `crlfDelay` will be coerced to `[100, 2000]` range. + `crlfDelay` will be coerced to a number no less than `100`. It can be set to + `Infinity`, in which case `\r` followed by `\n` will always be considered a + single newline. * `removeHistoryDuplicates` {boolean} If `true`, when a new input line added to the history list duplicates an older one, this removes the older line from the list. Defaults to `false`. diff --git a/lib/readline.js b/lib/readline.js index c167db6eb10f08..ca99fe15c0a593 100644 --- a/lib/readline.js +++ b/lib/readline.js @@ -8,7 +8,6 @@ const kHistorySize = 30; const kMincrlfDelay = 100; -const kMaxcrlfDelay = 2000; const util = require('util'); const debug = util.debuglog('readline'); @@ -83,8 +82,8 @@ function Interface(input, output, completer, terminal) { this.input = input; this.historySize = historySize; this.removeHistoryDuplicates = !!removeHistoryDuplicates; - this.crlfDelay = Math.max(kMincrlfDelay, - Math.min(kMaxcrlfDelay, crlfDelay >>> 0)); + this.crlfDelay = crlfDelay ? + Math.max(kMincrlfDelay, crlfDelay) : kMincrlfDelay; // Check arity, 2 - for async, 1 for sync if (typeof completer === 'function') { diff --git a/test/parallel/test-readline-interface.js b/test/parallel/test-readline-interface.js index 83b9912e471faa..dbde3fda66679e 100644 --- a/test/parallel/test-readline-interface.js +++ b/test/parallel/test-readline-interface.js @@ -40,14 +40,25 @@ function isWarned(emitter) { } { - // Maximum crlfDelay is 2000ms + // set crlfDelay to float 100.5ms const fi = new FakeInput(); const rli = new readline.Interface({ input: fi, output: fi, - crlfDelay: 1 << 30 + crlfDelay: 100.5 }); - assert.strictEqual(rli.crlfDelay, 2000); + assert.strictEqual(rli.crlfDelay, 100.5); + rli.close(); +} + +{ + const fi = new FakeInput(); + const rli = new readline.Interface({ + input: fi, + output: fi, + crlfDelay: 5000 + }); + assert.strictEqual(rli.crlfDelay, 5000); rli.close(); } @@ -225,7 +236,7 @@ function isWarned(emitter) { rli.close(); // Emit two line events when the delay - // between \r and \n exceeds crlfDelay + // between \r and \n exceeds crlfDelay { const fi = new FakeInput(); const delay = 200; @@ -247,8 +258,55 @@ function isWarned(emitter) { }), delay * 2); } + // Emit one line events when the delay between \r and \n is + // over the default crlfDelay but within the setting value + { + const fi = new FakeInput(); + const delay = 200; + const crlfDelay = 500; + const rli = new readline.Interface({ + input: fi, + output: fi, + terminal: terminal, + crlfDelay + }); + let callCount = 0; + rli.on('line', function(line) { + callCount++; + }); + fi.emit('data', '\r'); + setTimeout(common.mustCall(() => { + fi.emit('data', '\n'); + assert.strictEqual(callCount, 1); + rli.close(); + }), delay); + } + + // set crlfDelay to `Infinity` is allowed + { + const fi = new FakeInput(); + const delay = 200; + const crlfDelay = Infinity; + const rli = new readline.Interface({ + input: fi, + output: fi, + terminal: terminal, + crlfDelay + }); + let callCount = 0; + rli.on('line', function(line) { + callCount++; + }); + fi.emit('data', '\r'); + setTimeout(common.mustCall(() => { + fi.emit('data', '\n'); + assert.strictEqual(callCount, 1); + rli.close(); + }), delay); + } + // \t when there is no completer function should behave like an ordinary - // character + // character fi = new FakeInput(); rli = new readline.Interface({ input: fi, output: fi, terminal: true }); called = false; @@ -494,7 +552,7 @@ function isWarned(emitter) { assert.strictEqual(isWarned(process.stdout._events), false); } - //can create a new readline Interface with a null output arugument + // can create a new readline Interface with a null output arugument fi = new FakeInput(); rli = new readline.Interface({input: fi, output: null, terminal: terminal }); From 8dfc2838c88d42c0c9fc5659fe18457452085b5d Mon Sep 17 00:00:00 2001 From: Azard Date: Tue, 8 Aug 2017 03:15:19 +0800 Subject: [PATCH 07/92] test: fix test-readline-interface Previous unit test delay is too short for parallel test on raspberry pi, it will fail sometimes. This PR use common.platformTimeout and widen the time gap. PR-URL: https://github.com/nodejs/node/pull/14677 Ref: https://github.com/nodejs/node/issues/14674 Reviewed-By: Refael Ackermann Reviewed-By: Colin Ihrig Reviewed-By: James M Snell Reviewed-By: Rich Trott --- test/parallel/test-readline-interface.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/parallel/test-readline-interface.js b/test/parallel/test-readline-interface.js index dbde3fda66679e..c1f1002d3e201e 100644 --- a/test/parallel/test-readline-interface.js +++ b/test/parallel/test-readline-interface.js @@ -262,8 +262,8 @@ function isWarned(emitter) { // over the default crlfDelay but within the setting value { const fi = new FakeInput(); - const delay = 200; - const crlfDelay = 500; + const delay = 125; + const crlfDelay = common.platformTimeout(1000); const rli = new readline.Interface({ input: fi, output: fi, From 921876dcd1c728066141f7bbff7160568cc8adba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Wed, 6 Sep 2017 09:59:44 +0200 Subject: [PATCH 08/92] deps: backport 071b655 from V8 upstream Original commit message: [PATCH] [debugger] Scope iterator should not visit inner function literals. R=marja@chromium.org BUG=chromium:621361 Review-Url: https://codereview.chromium.org/2185913003 Cr-Commit-Position: refs/heads/master@{#38087} Fixes: https://github.com/nodejs/node/issues/15075 PR-URL: https://github.com/nodejs/node/pull/15215 Reviewed-By: Colin Ihrig Reviewed-By: James M Snell Reviewed-By: Gibson Fahnestock Reviewed-By: Franziska Hinkelmann Reviewed-By: Michael Dawson --- deps/v8/include/v8-version.h | 2 +- deps/v8/src/debug/debug-scopes.cc | 6 +++ .../mjsunit/regress/regress-crbug-621361.js | 40 +++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 deps/v8/test/mjsunit/regress/regress-crbug-621361.js diff --git a/deps/v8/include/v8-version.h b/deps/v8/include/v8-version.h index 955fcd5646cef5..e7931da11e423f 100644 --- a/deps/v8/include/v8-version.h +++ b/deps/v8/include/v8-version.h @@ -11,7 +11,7 @@ #define V8_MAJOR_VERSION 5 #define V8_MINOR_VERSION 1 #define V8_BUILD_NUMBER 281 -#define V8_PATCH_LEVEL 107 +#define V8_PATCH_LEVEL 108 // Use 1 for candidates and 0 otherwise. // (Boolean macro values are not supported by all preprocessors.) diff --git a/deps/v8/src/debug/debug-scopes.cc b/deps/v8/src/debug/debug-scopes.cc index d9c615b01b4c58..88024021143ffe 100644 --- a/deps/v8/src/debug/debug-scopes.cc +++ b/deps/v8/src/debug/debug-scopes.cc @@ -842,6 +842,12 @@ bool ScopeIterator::CopyContextExtensionToScopeObject( void ScopeIterator::GetNestedScopeChain(Isolate* isolate, Scope* scope, int position) { + if (scope->is_function_scope()) { + // Do not collect scopes of nested inner functions inside the current one. + Handle function = + Handle::cast(frame_inspector_->GetFunction()); + if (scope->end_position() < function->shared()->end_position()) return; + } if (!scope->is_eval_scope()) { nested_scope_chain_.Add(ExtendedScopeInfo(scope->GetScopeInfo(isolate), scope->start_position(), diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-621361.js b/deps/v8/test/mjsunit/regress/regress-crbug-621361.js new file mode 100644 index 00000000000000..f9496ae87d9f8b --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-621361.js @@ -0,0 +1,40 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --expose-debug-as debug + +var Debug = debug.Debug; +var steps = 0; +var exception = null; + +function listener(event, execState, eventData, data) { + if (event != Debug.DebugEvent.Break) return; + try { + assertEquals([ debug.ScopeType.Local, + debug.ScopeType.Script, + debug.ScopeType.Global], + execState.frame().allScopes().map(s => s.scopeType())); + var x_value = execState.frame().evaluate("x").value(); + if (steps < 2) { + assertEquals(undefined, x_value); + execState.prepareStep(Debug.StepAction.StepIn); + } else { + assertEquals("l => l", x_value.toString()); + } + steps++; + } catch (e) { + exception = e; + } +} + +Debug.setListener(listener); + +(function() { + debugger; + var x = l => l; +})(); + +Debug.setListener(null); +assertNull(exception); +assertEquals(3, steps); From f8b85e16cdb90cee350ce122dcb9ac93485c1ad0 Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Sun, 30 Jul 2017 13:46:34 -0700 Subject: [PATCH 09/92] tools: replace assert-throw-arguments custom lint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The functionality of ESLint custom rule assert-throws-arguments can be replaced with no-restricted-syntax entries. Backport-PR-URL: https://github.com/nodejs/node/pull/15253 PR-URL: https://github.com/nodejs/node/pull/14547 Reviewed-By: Colin Ihrig Reviewed-By: Luigi Pinca Reviewed-By: Timothy Gu Reviewed-By: Tobias Nießen Reviewed-By: James M Snell --- .eslintrc.yaml | 7 ++- doc/api/assert.md | 2 +- test/parallel/test-assert.js | 6 +- tools/eslint-rules/assert-throws-arguments.js | 60 ------------------- 4 files changed, 10 insertions(+), 65 deletions(-) delete mode 100644 tools/eslint-rules/assert-throws-arguments.js diff --git a/.eslintrc.yaml b/.eslintrc.yaml index 1e660b8de77056..95ff2ba3c0c77e 100644 --- a/.eslintrc.yaml +++ b/.eslintrc.yaml @@ -117,6 +117,12 @@ rules: no-mixed-spaces-and-tabs: 2 no-multiple-empty-lines: [2, {max: 2, maxEOF: 0, maxBOF: 0}] no-restricted-syntax: [2, { + selector: "CallExpression[callee.object.name='assert'][callee.property.name='throws'][arguments.1.type='Literal']:not([arguments.1.regex])", + message: "use a regular expression for second argument of assert.throws()" + }, { + selector: "CallExpression[callee.object.name='assert'][callee.property.name='throws'][arguments.length<2]", + message: "assert.throws() must be invoked with at least two arguments." + }, { selector: "CallExpression[callee.name='setTimeout'][arguments.length<2]", message: "setTimeout() must be invoked with at least two arguments." }, { @@ -161,7 +167,6 @@ rules: template-curly-spacing: 2 # Custom rules in tools/eslint-rules - assert-throws-arguments: [2, { requireTwo: true }] # Global scoped method and vars globals: diff --git a/doc/api/assert.md b/doc/api/assert.md index 0b7621520b688f..2adc5549efb959 100644 --- a/doc/api/assert.md +++ b/doc/api/assert.md @@ -478,7 +478,7 @@ Note that `error` can not be a string. If a string is provided as the second argument, then `error` is assumed to be omitted and the string will be used for `message` instead. This can lead to easy-to-miss mistakes: - + ```js // THIS IS A MISTAKE! DO NOT DO THIS! assert.throws(myFunction, 'missing foo', 'did not throw with expected message'); diff --git a/test/parallel/test-assert.js b/test/parallel/test-assert.js index 3579c10f159ad5..aa51eb7e523e2e 100644 --- a/test/parallel/test-assert.js +++ b/test/parallel/test-assert.js @@ -345,11 +345,11 @@ function thrower(errorConstructor) { assert.throws(makeBlock(thrower, a.AssertionError), a.AssertionError, 'message'); assert.throws(makeBlock(thrower, a.AssertionError), a.AssertionError); -// eslint-disable-next-line assert-throws-arguments +// eslint-disable-next-line no-restricted-syntax assert.throws(makeBlock(thrower, a.AssertionError)); // if not passing an error, catch all. -// eslint-disable-next-line assert-throws-arguments +// eslint-disable-next-line no-restricted-syntax assert.throws(makeBlock(thrower, TypeError)); // when passing a type, only catch errors of the appropriate type @@ -524,7 +524,7 @@ testAssertionMessage({a: NaN, b: Infinity, c: -Infinity}, // #2893 try { - // eslint-disable-next-line assert-throws-arguments + // eslint-disable-next-line no-restricted-syntax assert.throws(function() { assert.ifError(null); }); diff --git a/tools/eslint-rules/assert-throws-arguments.js b/tools/eslint-rules/assert-throws-arguments.js deleted file mode 100644 index 3b51188c0c89bc..00000000000000 --- a/tools/eslint-rules/assert-throws-arguments.js +++ /dev/null @@ -1,60 +0,0 @@ -/** - * @fileoverview Check that assert.throws is never called with a string as - * second argument. - * @author Michaël Zasso - */ -'use strict'; - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -function checkThrowsArguments(context, node) { - if (node.callee.type === 'MemberExpression' && - node.callee.object.name === 'assert' && - node.callee.property.name === 'throws') { - const args = node.arguments; - if (args.length > 3) { - context.report({ - message: 'Too many arguments', - node: node - }); - } else if (args.length > 1) { - const error = args[1]; - if (error.type === 'Literal' && typeof error.value === 'string' || - error.type === 'TemplateLiteral') { - context.report({ - message: 'Unexpected string as second argument', - node: error - }); - } - } else { - if (context.options[0].requireTwo) { - context.report({ - message: 'Expected at least two arguments', - node: node - }); - } - } - } -} - -module.exports = { - meta: { - schema: [ - { - type: 'object', - properties: { - requireTwo: { - type: 'boolean' - } - } - } - ] - }, - create: function(context) { - return { - CallExpression: (node) => checkThrowsArguments(context, node) - }; - } -}; From 4e1a50a079b5e0c6f5e7baeae7f1381a69cba1d0 Mon Sep 17 00:00:00 2001 From: jBarz Date: Fri, 8 Sep 2017 06:31:41 -0400 Subject: [PATCH 10/92] deps: backport 0353a1e from V8 upstream Original commit message: Avoid disassembling Interpreted Regexp code I found that v8 will crash when --print-code is turned on while Regexp is interpreted. It crashes when trying to print Relocation info during Disassembly. It should probably avoid printing out disassembly when the Code object is a bytecode regexp. Bug: Change-Id: I35b531cb03996a303248652871452266c78fee38 Reviewed-on: https://chromium-review.googlesource.com/642127 Reviewed-by: Yang Guo PR-URL: https://github.com/nodejs/node/pull/15287 Reviewed-By: Franziska Hinkelmann Reviewed-By: James M Snell --- deps/v8/src/regexp/jsregexp.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/v8/src/regexp/jsregexp.cc b/deps/v8/src/regexp/jsregexp.cc index bbbfbeb79924ad..4cfeab0d4f88f3 100644 --- a/deps/v8/src/regexp/jsregexp.cc +++ b/deps/v8/src/regexp/jsregexp.cc @@ -1131,7 +1131,7 @@ RegExpEngine::CompilationResult RegExpCompiler::Assemble( Handle code = macro_assembler_->GetCode(pattern); heap->IncreaseTotalRegexpCodeGenerated(code->Size()); work_list_ = NULL; -#ifdef ENABLE_DISASSEMBLER +#if defined(ENABLE_DISASSEMBLER) && !defined(V8_INTERPRETED_REGEXP) if (FLAG_print_code) { CodeTracer::Scope trace_scope(heap->isolate()->GetCodeTracer()); OFStream os(trace_scope.file()); From 90fcccd7a35834780dd838eff941de188d25cb45 Mon Sep 17 00:00:00 2001 From: Timothy Gu Date: Mon, 26 Jun 2017 13:05:49 +0800 Subject: [PATCH 11/92] doc: add documentation on ICU PR-URL: https://github.com/nodejs/node/pull/13916 Refs: https://github.com/nodejs/node/pull/13644#discussion_r121616327 Reviewed-By: Vse Mozhet Byt --- doc/api/_toc.md | 1 + doc/api/all.md | 1 + doc/api/intl.md | 198 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 200 insertions(+) create mode 100644 doc/api/intl.md diff --git a/doc/api/_toc.md b/doc/api/_toc.md index 2527ad84e2e360..5f7bca59e87d75 100644 --- a/doc/api/_toc.md +++ b/doc/api/_toc.md @@ -22,6 +22,7 @@ * [Globals](globals.html) * [HTTP](http.html) * [HTTPS](https.html) +* [Internationalization](intl.html) * [Modules](modules.html) * [Net](net.html) * [OS](os.html) diff --git a/doc/api/all.md b/doc/api/all.md index 93c7a300a162e9..e2428cf376c1c4 100644 --- a/doc/api/all.md +++ b/doc/api/all.md @@ -18,6 +18,7 @@ @include globals @include http @include https +@include intl @include modules @include net @include os diff --git a/doc/api/intl.md b/doc/api/intl.md new file mode 100644 index 00000000000000..8939dddbdd57b2 --- /dev/null +++ b/doc/api/intl.md @@ -0,0 +1,198 @@ +# Internationalization Support + +Node.js has many features that make it easier to write internationalized +programs. Some of them are: + +- Locale-sensitive or Unicode-aware functions in the [ECMAScript Language + Specification][ECMA-262]: + - [`String.prototype.normalize()`][] + - [`String.prototype.toLowerCase()`][] + - [`String.prototype.toUpperCase()`][] +- All functionality described in the [ECMAScript Internationalization API + Specification][ECMA-402] (aka ECMA-402): + - [`Intl`][] object + - Locale-sensitive methods like [`String.prototype.localeCompare()`][] and + [`Date.prototype.toLocaleString()`][] + +Node.js (and its underlying V8 engine) uses [ICU][] to implement these features +in native C/C++ code. However, some of them require a very large ICU data file +in order to support all locales of the world. Because it is expected that most +Node.js users will make use of only a small portion of ICU functionality, only +a subset of the full ICU data set is provided by Node.js by default. Several +options are provided for customizing and expanding the ICU data set either when +building or running Node.js. + +## Options for building Node.js + +To control how ICU is used in Node.js, four `configure` options are available +during compilation. Additional details on how to compile Node.js are documented +in [BUILDING.md][]. + +- `--with-intl=none` / `--without-intl` +- `--with-intl=system-icu` +- `--with-intl=small-icu` (default) +- `--with-intl=full-icu` + +An overview of available Node.js and JavaScript features for each `configure` +option: + +| | `none` | `system-icu` | `small-icu` | `full-icu` +|-----------------------------------------|-----------------------------------|------------------------------|------------------------|------------ +| [`String.prototype.normalize()`][] | none (function is no-op) | full | full | full +| `String.prototype.to*Case()` | full | full | full | full +| [`Intl`][] | none (object does not exist) | partial/full (depends on OS) | partial (English-only) | full +| [`String.prototype.localeCompare()`][] | partial (not locale-aware) | full | full | full +| `String.prototype.toLocale*Case()` | partial (not locale-aware) | full | full | full +| [`Number.prototype.toLocaleString()`][] | partial (not locale-aware) | partial/full (depends on OS) | partial (English-only) | full +| `Date.prototype.toLocale*String()` | partial (not locale-aware) | partial/full (depends on OS) | partial (English-only) | full + +*Note*: The "(not locale-aware)" designation denotes that the function carries +out its operation just like the non-`Locale` version of the function, if one +exists. For example, under `none` mode, `Date.prototype.toLocaleString()`'s +operation is identical to that of `Date.prototype.toString()`. + +### Disable all internationalization features (`none`) + +If this option is chosen, most internationalization features mentioned above +will be **unavailable** in the resulting `node` binary. + +### Build with a pre-installed ICU (`system-icu`) + +Node.js can link against an ICU build already installed on the system. In fact, +most Linux distributions already come with ICU installed, and this option would +make it possible to reuse the same set of data used by other components in the +OS. + +Functionalities that only require the ICU library itself, such as +[`String.prototype.normalize()`][], are fully supported under `system-icu`. +Features that require ICU locale data in addition, such as +[`Intl.DateTimeFormat`][] *may* be fully or partially supported, depending on +the completeness of the ICU data installed on the system. + +### Embed a limited set of ICU data (`small-icu`) + +This option makes the resulting binary link against the ICU library statically, +and includes a subset of ICU data (typically only the English locale) within +the `node` executable. + +Functionalities that only require the ICU library itself, such as +[`String.prototype.normalize()`][], are fully supported under `small-icu`. +Features that require ICU locale data in addition, such as +[`Intl.DateTimeFormat`][], generally only work with the English locale: + +```js +const january = new Date(9e8); +const english = new Intl.DateTimeFormat('en', { month: 'long' }); +const spanish = new Intl.DateTimeFormat('es', { month: 'long' }); + +console.log(english.format(january)); +// Prints "January" +console.log(spanish.format(january)); +// Prints "January" or "M01" on small-icu +// Should print "enero" +``` + +This mode provides a good balance between features and binary size, and it is +the default behavior if no `--with-intl` flag is passed. The official binaries +are also built in this mode. + +#### Providing ICU data at runtime + +If the `small-icu` option is used, one can still provide additional locale data +at runtime so that the JS methods would work for all ICU locales. Assuming the +data file is stored at `/some/directory`, it can be made available to ICU +through either: + +* The [`NODE_ICU_DATA`][] environmental variable: + + ```shell + env NODE_ICU_DATA=/some/directory node + ``` + +* The [`--icu-data-dir`][] CLI parameter: + + ```shell + node --icu-data-dir=/some/directory + ``` + +(If both are specified, the `--icu-data-dir` CLI parameter takes precedence.) + +ICU is able to automatically find and load a variety of data formats, but the +data must be appropriate for the ICU version, and the file correctly named. +The most common name for the data file is `icudt5X[bl].dat`, where `5X` denotes +the intended ICU version, and `b` or `l` indicates the system's endianness. +Check ["ICU Data"][] article in the ICU User Guide for other supported formats +and more details on ICU data in general. + +The [full-icu][] npm module can greatly simplify ICU data installation by +detecting the ICU version of the running `node` executable and downloading the +appropriate data file. After installing the module through `npm i full-icu`, +the data file will be available at `./node_modules/full-icu`. This path can be +then passed either to `NODE_ICU_DATA` or `--icu-data-dir` as shown above to +enable full `Intl` support. + +### Embed the entire ICU (`full-icu`) + +This option makes the resulting binary link against ICU statically and include +a full set of ICU data. A binary created this way has no further external +dependencies and supports all locales, but might be rather large. See +[BUILDING.md][BUILDING.md#full-icu] on how to compile a binary using this mode. + +## Detecting internationalization support + +To verify that ICU is enabled at all (`system-icu`, `small-icu`, or +`full-icu`), simply checking the existence of `Intl` should suffice: + +```js +const hasICU = typeof Intl === 'object'; +``` + +Alternatively, checking for `process.versions.icu`, a property defined only +when ICU is enabled, works too: + +```js +const hasICU = typeof process.versions.icu === 'string'; +``` + +To check for support for a non-English locale (i.e. `full-icu` or +`system-icu`), [`Intl.DateTimeFormat`][] can be a good distinguishing factor: + +```js +const hasFullICU = (() => { + try { + const january = new Date(9e8); + const spanish = new Intl.DateTimeFormat('es', { month: 'long' }); + return spanish.format(january) === 'enero'; + } catch (err) { + return false; + } +})(); +``` + +For more verbose tests for `Intl` support, the following resources may be found +to be helpful: + +- [btest402][]: Generally used to check whether Node.js with `Intl` support is + built correctly. +- [Test262][]: ECMAScript's official conformance test suite includes a section + dedicated to ECMA-402. + +[btest402]: https://github.com/srl295/btest402 +[BUILDING.md]: https://github.com/nodejs/node/blob/master/BUILDING.md +[BUILDING.md#full-icu]: https://github.com/nodejs/node/blob/master/BUILDING.md#build-with-full-icu-support-all-locales-supported-by-icu +[`Date.prototype.toLocaleString()`]: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleString +[ECMA-262]: https://tc39.github.io/ecma262/ +[ECMA-402]: https://tc39.github.io/ecma402/ +[full-icu]: https://www.npmjs.com/package/full-icu +[ICU]: http://icu-project.org/ +["ICU Data"]: http://userguide.icu-project.org/icudata +[`--icu-data-dir`]: cli.html#cli_icu_data_dir_file +[`Intl`]: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Intl +[`Intl.DateTimeFormat`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat +[`NODE_ICU_DATA`]: cli.html#cli_node_icu_data_file +[`Number.prototype.toLocaleString()`]: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Number/toLocaleString +[`String.prototype.localeCompare()`]: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare +[`String.prototype.normalize()`]: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/normalize +[`String.prototype.toLowerCase()`]: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase +[`String.prototype.toUpperCase()`]: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase +[Test262]: https://github.com/tc39/test262/tree/master/test/intl402 From 362a7c0d8b3fb76964fd824a02a4dd96162f38d6 Mon Sep 17 00:00:00 2001 From: Shivanth MP Date: Sun, 23 Jul 2017 21:47:07 +0530 Subject: [PATCH 12/92] repl: do not consider `...` as a REPL command This fix makes ... in REPL to be considered as a javascript construct rather than a REPL keyword. Fixes: https://github.com/nodejs/node/issues/14426 Backport-PR-URL: https://github.com/nodejs/node/pull/14915 PR-URL: https://github.com/nodejs/node/pull/14467 Reviewed-By: Roman Reiss Reviewed-By: Anna Henningsen Reviewed-By: Jeremiah Senkpiel --- lib/repl.js | 9 +++++---- test/parallel/test-repl.js | 8 +++++++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/lib/repl.js b/lib/repl.js index b48242be1bc763..127fd80bf82f65 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -519,10 +519,11 @@ function REPLServer(prompt, // Check to see if a REPL keyword was used. If it returns true, // display next prompt and return. - if (cmd && cmd.charAt(0) === '.' && isNaN(parseFloat(cmd))) { - var matches = cmd.match(/^\.([^\s]+)\s*(.*)$/); - var keyword = matches && matches[1]; - var rest = matches && matches[2]; + if (cmd && cmd.charAt(0) === '.' && cmd.charAt(1) !== '.' && + isNaN(parseFloat(cmd))) { + const matches = cmd.match(/^\.([^\s]+)\s*(.*)$/); + const keyword = matches && matches[1]; + const rest = matches && matches[2]; if (self.parseREPLKeyword(keyword, rest) === true) { return; } else if (!self.bufferedCommand) { diff --git a/test/parallel/test-repl.js b/test/parallel/test-repl.js index c471b185dd6531..3b705f7b6be97f 100644 --- a/test/parallel/test-repl.js +++ b/test/parallel/test-repl.js @@ -387,7 +387,13 @@ function error_test() { { client: client_unix, send: '(function() {\nif (false) {} /bar"/;\n}())', expect: `${prompt_multiline}${prompt_multiline}undefined\n${prompt_unix}` - } + }, + // Do not parse `...[]` as a REPL keyword + { client: client_unix, send: '...[]\n', + expect: `${prompt_multiline}` }, + // bring back the repl to prompt + { client: client_unix, send: '.break', + expect: `${prompt_unix}` } ]); } From f7b6d198b9eed93e1cb7b2d723f59653df718318 Mon Sep 17 00:00:00 2001 From: Refael Ackermann Date: Mon, 3 Jul 2017 12:51:45 -0400 Subject: [PATCH 13/92] tools: eslint - use `error` and `off` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backport-PR-URL: https://github.com/nodejs/node/pull/14841 PR-URL: https://github.com/nodejs/node/pull/14061 Reviewed-By: Benjamin Gruenbaum Reviewed-By: Michaël Zasso Reviewed-By: Vse Mozhet Byt Reviewed-By: Colin Ihrig Reviewed-By: Franziska Hinkelmann Reviewed-By: Luigi Pinca --- .eslintrc.yaml | 196 ++++++++++++++++++++++---------------------- doc/.eslintrc.yaml | 12 +-- lib/.eslintrc.yaml | 6 +- test/.eslintrc.yaml | 8 +- 4 files changed, 111 insertions(+), 111 deletions(-) diff --git a/.eslintrc.yaml b/.eslintrc.yaml index 95ff2ba3c0c77e..080d52123523e2 100644 --- a/.eslintrc.yaml +++ b/.eslintrc.yaml @@ -13,67 +13,67 @@ parserOptions: rules: # Possible Errors # http://eslint.org/docs/rules/#possible-errors - comma-dangle: [2, only-multiline] - no-control-regex: 2 - no-debugger: 2 - no-dupe-args: 2 - no-dupe-keys: 2 - no-duplicate-case: 2 - no-empty-character-class: 2 - no-ex-assign: 2 - no-extra-boolean-cast: 2 - no-extra-parens: [2, functions] - no-extra-semi: 2 - no-func-assign: 2 - no-invalid-regexp: 2 - no-irregular-whitespace: 2 - no-obj-calls: 2 - no-proto: 2 - no-template-curly-in-string: 2 - no-unexpected-multiline: 2 - no-unreachable: 2 - no-unsafe-negation: 2 - use-isnan: 2 - valid-typeof: 2 + comma-dangle: [error, only-multiline] + no-control-regex: error + no-debugger: error + no-dupe-args: error + no-dupe-keys: error + no-duplicate-case: error + no-empty-character-class: error + no-ex-assign: error + no-extra-boolean-cast: error + no-extra-parens: [error, functions] + no-extra-semi: error + no-func-assign: error + no-invalid-regexp: error + no-irregular-whitespace: error + no-obj-calls: error + no-proto: error + no-template-curly-in-string: error + no-unexpected-multiline: error + no-unreachable: error + no-unsafe-negation: error + use-isnan: error + valid-typeof: error # Best Practices # http://eslint.org/docs/rules/#best-practices - dot-location: [2, property] - no-fallthrough: 2 - no-global-assign: 2 - no-multi-spaces: [2, {ignoreEOLComments: true}] - no-octal: 2 - no-redeclare: 2 - no-self-assign: 2 - no-unused-labels: 2 - no-useless-call: 2 - no-useless-concat: 2 - no-useless-escape: 2 - no-useless-return: 2 - no-void: 2 - no-with: 2 + dot-location: [error, property] + no-fallthrough: error + no-global-assign: error + no-multi-spaces: [error, {ignoreEOLComments: true}] + no-octal: error + no-redeclare: error + no-self-assign: error + no-unused-labels: error + no-useless-call: error + no-useless-concat: error + no-useless-escape: error + no-useless-return: error + no-void: error + no-with: error # Strict Mode # http://eslint.org/docs/rules/#strict-mode - strict: [2, global] + strict: [error, global] # Variables # http://eslint.org/docs/rules/#variables - no-delete-var: 2 - no-undef: 2 - no-unused-vars: [2, {args: none}] - no-use-before-define: [2, {classes: true, - functions: false, - variables: false}] + no-delete-var: error + no-undef: error + no-unused-vars: [error, {args: none}] + no-use-before-define: [error, {classes: true, + functions: false, + variables: false}] # Node.js and CommonJS # http://eslint.org/docs/rules/#nodejs-and-commonjs - no-mixed-requires: 2 - no-new-require: 2 - no-path-concat: 2 - no-restricted-modules: [2, sys, _linklist] + no-mixed-requires: error + no-new-require: error + no-path-concat: error + no-restricted-modules: [error, sys, _linklist] no-restricted-properties: - - 2 + - error - object: assert property: deepEqual message: Use assert.deepStrictEqual(). @@ -90,33 +90,33 @@ rules: # Stylistic Issues # http://eslint.org/docs/rules/#stylistic-issues - block-spacing: 2 - brace-style: [2, 1tbs, {allowSingleLine: true}] - comma-spacing: 2 - comma-style: 2 - computed-property-spacing: 2 - eol-last: 2 - func-call-spacing: 2 - func-name-matching: 2 - func-style: [2, declaration, {allowArrowFunctions: true}] - indent: [2, 2, {ArrayExpression: first, - CallExpression: {arguments: first}, - FunctionDeclaration: {parameters: first}, - FunctionExpression: {parameters: first}, - MemberExpression: off, - ObjectExpression: first, - SwitchCase: 1}] - key-spacing: [2, {mode: minimum}] - keyword-spacing: 2 - linebreak-style: [2, unix] - max-len: [2, {code: 80, - ignoreRegExpLiterals: true, - ignoreUrls: true, - tabWidth: 2}] - new-parens: 2 - no-mixed-spaces-and-tabs: 2 - no-multiple-empty-lines: [2, {max: 2, maxEOF: 0, maxBOF: 0}] - no-restricted-syntax: [2, { + block-spacing: error + brace-style: [error, 1tbs, {allowSingleLine: true}] + comma-spacing: error + comma-style: error + computed-property-spacing: error + eol-last: error + func-call-spacing: error + func-name-matching: error + func-style: [error, declaration, {allowArrowFunctions: true}] + indent: [error, 2, {ArrayExpression: first, + CallExpression: {arguments: first}, + FunctionDeclaration: {parameters: first}, + FunctionExpression: {parameters: first}, + MemberExpression: off, + ObjectExpression: first, + SwitchCase: 1}] + key-spacing: [error, {mode: minimum}] + keyword-spacing: error + linebreak-style: [error, unix] + max-len: [error, {code: 80, + ignoreRegExpLiterals: true, + ignoreUrls: true, + tabWidth: 2}] + new-parens: error + no-mixed-spaces-and-tabs: error + no-multiple-empty-lines: [error, {max: 2, maxEOF: 0, maxBOF: 0}] + no-restricted-syntax: [error, { selector: "CallExpression[callee.object.name='assert'][callee.property.name='throws'][arguments.1.type='Literal']:not([arguments.1.regex])", message: "use a regular expression for second argument of assert.throws()" }, { @@ -135,36 +135,36 @@ rules: selector: "CallExpression[callee.object.name='assert'][callee.property.name='fail'][arguments.length=1]", message: "assert.fail() message should be third argument" }] - no-tabs: 2 - no-trailing-spaces: 2 - operator-linebreak: [2, after, {overrides: {'?': ignore, ':': ignore}}] - quotes: [2, single, avoid-escape] - semi: 2 - semi-spacing: 2 - space-before-blocks: [2, always] - space-before-function-paren: [2, { + no-tabs: error + no-trailing-spaces: error + operator-linebreak: [error, after, {overrides: {'?': ignore, ':': ignore}}] + quotes: [error, single, avoid-escape] + semi: error + semi-spacing: error + space-before-blocks: [error, always] + space-before-function-paren: [error, { "anonymous": "never", "named": "never", "asyncArrow": "always" }] - space-in-parens: [2, never] - space-infix-ops: 2 - space-unary-ops: 2 + space-in-parens: [error, never] + space-infix-ops: error + space-unary-ops: error # ECMAScript 6 # http://eslint.org/docs/rules/#ecmascript-6 - arrow-parens: [2, always] - arrow-spacing: [2, {before: true, after: true}] - constructor-super: 2 - no-class-assign: 2 - no-confusing-arrow: 2 - no-const-assign: 2 - no-dupe-class-members: 2 - no-new-symbol: 2 - no-this-before-super: 2 - prefer-const: [2, {ignoreReadBeforeAssign: true}] - rest-spread-spacing: 2 - template-curly-spacing: 2 + arrow-parens: [error, always] + arrow-spacing: [error, {before: true, after: true}] + constructor-super: error + no-class-assign: error + no-confusing-arrow: error + no-const-assign: error + no-dupe-class-members: error + no-new-symbol: error + no-this-before-super: error + prefer-const: [error, {ignoreReadBeforeAssign: true}] + rest-spread-spacing: error + template-curly-spacing: error # Custom rules in tools/eslint-rules diff --git a/doc/.eslintrc.yaml b/doc/.eslintrc.yaml index b4fbf847be7aaf..a0334a79c25cf7 100644 --- a/doc/.eslintrc.yaml +++ b/doc/.eslintrc.yaml @@ -2,11 +2,11 @@ rules: # ease some restrictions in doc examples - no-restricted-properties: 0 - no-undef: 0 - no-unused-vars: 0 - strict: 0 + no-restricted-properties: off + no-undef: off + no-unused-vars: off + strict: off # add new ECMAScript features gradually - no-var: 2 - prefer-const: 2 + no-var: error + prefer-const: error diff --git a/lib/.eslintrc.yaml b/lib/.eslintrc.yaml index d8e34f85b5759d..24f54e682636ee 100644 --- a/lib/.eslintrc.yaml +++ b/lib/.eslintrc.yaml @@ -1,5 +1,5 @@ rules: # Custom rules in tools/eslint-rules - require-buffer: 2 - buffer-constructor: 2 - no-let-in-for-declaration: 2 + require-buffer: error + buffer-constructor: error + no-let-in-for-declaration: error diff --git a/test/.eslintrc.yaml b/test/.eslintrc.yaml index 4fea04d632f2d4..6d2c0ec90d22b0 100644 --- a/test/.eslintrc.yaml +++ b/test/.eslintrc.yaml @@ -3,12 +3,12 @@ rules: # ECMAScript 6 # http://eslint.org/docs/rules/#ecmascript-6 - no-var: 2 - prefer-const: 2 + no-var: error + prefer-const: error # Custom rules in tools/eslint-rules prefer-common-mustnotcall: 2 ## common module is mandatory in tests - required-modules: [2, common] - prefer-assert-methods: 2 + required-modules: [error, common] + prefer-assert-methods: error From 86497f1acc522485003d8b1e4ec43b549c610a5f Mon Sep 17 00:00:00 2001 From: Refael Ackermann Date: Thu, 1 Jun 2017 15:15:09 -0400 Subject: [PATCH 14/92] test: mark inspector-port-zero-cluster as flaky Ref: https://github.com/nodejs/node/issues/13343 --- test/inspector/inspector.status | 1 + 1 file changed, 1 insertion(+) diff --git a/test/inspector/inspector.status b/test/inspector/inspector.status index ed6a782b9031a7..070d817b2c3ab2 100644 --- a/test/inspector/inspector.status +++ b/test/inspector/inspector.status @@ -5,5 +5,6 @@ prefix inspector # sample-test : PASS,FLAKY [true] # This section applies to all platforms +test-inspector-port-zero-cluster : PASS,FLAKY [$system==win32] From e65c9ec7f453565633c978cd2bcd4605cbc5b535 Mon Sep 17 00:00:00 2001 From: Gireesh Punathil Date: Sun, 9 Apr 2017 15:57:19 +0530 Subject: [PATCH 15/92] http: assert parser.consume argument's type MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Unchecked argument conversion in Parser::Consume crashes node in an slightly undesirable manner - 'unreachable code' in parser. Make sure we validate the incoming type at the earliest point. PR-URL: https://github.com/nodejs/node/pull/12288 Fixes: https://github.com/nodejs/node/issues/12178 Reviewed-By: Ben Noordhuis Reviewed-By: Anna Henningsen Reviewed-By: Colin Ihrig Reviewed-By: Alexey Orlenko Reviewed-By: James M Snell Reviewed-By: Santiago Gimeno Reviewed-By: Tobias Nießen Reviewed-By: Refael Ackermann --- src/node_http_parser.cc | 1 + test/abort/test-http-parser-consume.js | 28 ++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 test/abort/test-http-parser-consume.js diff --git a/src/node_http_parser.cc b/src/node_http_parser.cc index bc9b5d953e8ebf..24152e1e119ffc 100644 --- a/src/node_http_parser.cc +++ b/src/node_http_parser.cc @@ -472,6 +472,7 @@ class Parser : public AsyncWrap { static void Consume(const FunctionCallbackInfo& args) { Parser* parser; ASSIGN_OR_RETURN_UNWRAP(&parser, args.Holder()); + CHECK(args[0]->IsExternal()); Local stream_obj = args[0].As(); StreamBase* stream = static_cast(stream_obj->Value()); CHECK_NE(stream, nullptr); diff --git a/test/abort/test-http-parser-consume.js b/test/abort/test-http-parser-consume.js new file mode 100644 index 00000000000000..4a05a299a8e956 --- /dev/null +++ b/test/abort/test-http-parser-consume.js @@ -0,0 +1,28 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); +const spawn = require('child_process').spawn; + +if (process.argv[2] === 'child') { + const server = http.createServer(common.mustCall((req, res) => { + res.end('hello'); + })); + + server.listen(0, common.mustCall((s) => { + const rr = http.get( + { port: server.address().port }, + common.mustCall((d) => { + // This bad input (0) should abort the parser and the process + rr.parser.consume(0); + server.close(); + })); + })); +} else { + const child = spawn(process.execPath, [__filename, 'child'], + { stdio: 'inherit' }); + child.on('exit', common.mustCall((code, signal) => { + assert(common.nodeProcessAborted(code, signal), + 'process should have aborted, but did not'); + })); +} From 594e3c2115d6537420e52cbe3f47c0236b575ace Mon Sep 17 00:00:00 2001 From: Samuel Reed Date: Thu, 3 Nov 2016 11:23:57 -0500 Subject: [PATCH 16/92] doc: add readline.emitKeypressEvents note PR-URL: https://github.com/nodejs/node/pull/9447 Reviewed-By: Anna Henningsen Reviewed-By: Gibson Fahnestock --- doc/api/readline.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/api/readline.md b/doc/api/readline.md index bac425fa37e659..2c6e29088544cb 100644 --- a/doc/api/readline.md +++ b/doc/api/readline.md @@ -452,6 +452,10 @@ autocompletion is disabled when copy-pasted input is detected. If the `stream` is a [TTY][], then it must be in raw mode. +*Note*: This is automatically called by any readline instance on its `input` +if the `input` is a terminal. Closing the `readline` instance does not stop +the `input` from emitting `'keypress'` events. + ```js readline.emitKeypressEvents(process.stdin); if (process.stdin.isTTY) From dcdc9053b46495cbf6a50b7a57d349eaa3aa2328 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Hern=C3=A1ndez=20Cabot?= Date: Wed, 19 Jul 2017 13:49:26 +0200 Subject: [PATCH 17/92] doc: fix typo in stream.md PR-URL: https://github.com/nodejs/node/pull/14364 Fixes: https://github.com/nodejs/node/issues/14362 Reviewed-By: Timothy Gu Reviewed-By: Colin Ihrig Reviewed-By: Vse Mozhet Byt Reviewed-By: Luigi Pinca Reviewed-By: James M Snell Reviewed-By: Matteo Collina --- 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 2a49b4b34f9fb1..205cc440d98ef7 100644 --- a/doc/api/stream.md +++ b/doc/api/stream.md @@ -1922,7 +1922,7 @@ user programs. `transform._transform()` is never called in parallel; streams implement a queue mechanism, and to receive the next chunk, `callback` must be -called, either synchronously or asychronously. +called, either synchronously or asynchronously. #### Class: stream.PassThrough From 3a6392b2836cdcce519213660adc8b97ec59e359 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Mon, 24 Jul 2017 14:36:36 +0200 Subject: [PATCH 18/92] tls: fix empty issuer/subject/infoAccess parsing Also issuerCertificate but that did not fit on the status line. Fixes: https://github.com/nodejs/node/issues/11771 PR-URL: https://github.com/nodejs/node/pull/14473 Reviewed-By: Colin Ihrig Reviewed-By: James M Snell Reviewed-By: Matteo Collina Reviewed-By: Refael Ackermann --- lib/_tls_common.js | 8 +-- .../test-tls-translate-peer-certificate.js | 55 +++++++++++++++++++ 2 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 test/parallel/test-tls-translate-peer-certificate.js diff --git a/lib/_tls_common.js b/lib/_tls_common.js index 669110d826f7bd..5b37c119718c24 100644 --- a/lib/_tls_common.js +++ b/lib/_tls_common.js @@ -149,12 +149,12 @@ exports.translatePeerCertificate = function translatePeerCertificate(c) { if (!c) return null; - if (c.issuer) c.issuer = tls.parseCertString(c.issuer); - if (c.issuerCertificate && c.issuerCertificate !== c) { + if (c.issuer != null) c.issuer = tls.parseCertString(c.issuer); + if (c.issuerCertificate != null && c.issuerCertificate !== c) { c.issuerCertificate = translatePeerCertificate(c.issuerCertificate); } - if (c.subject) c.subject = tls.parseCertString(c.subject); - if (c.infoAccess) { + if (c.subject != null) c.subject = tls.parseCertString(c.subject); + if (c.infoAccess != null) { var info = c.infoAccess; c.infoAccess = {}; diff --git a/test/parallel/test-tls-translate-peer-certificate.js b/test/parallel/test-tls-translate-peer-certificate.js new file mode 100644 index 00000000000000..537c00a009697a --- /dev/null +++ b/test/parallel/test-tls-translate-peer-certificate.js @@ -0,0 +1,55 @@ +'use strict'; +const common = require('../common'); + +if (!common.hasCrypto) + common.skip('missing crypto'); + +const { strictEqual, deepStrictEqual } = require('assert'); +const { translatePeerCertificate } = require('_tls_common'); + +const certString = 'A=1\nB=2\nC=3'; +const certObject = { A: '1', B: '2', C: '3' }; + +strictEqual(translatePeerCertificate(null), null); +strictEqual(translatePeerCertificate(undefined), null); + +strictEqual(translatePeerCertificate(0), null); +strictEqual(translatePeerCertificate(1), 1); + +deepStrictEqual(translatePeerCertificate({}), {}); + +deepStrictEqual(translatePeerCertificate({ issuer: '' }), + { issuer: {} }); +deepStrictEqual(translatePeerCertificate({ issuer: null }), + { issuer: null }); +deepStrictEqual(translatePeerCertificate({ issuer: certString }), + { issuer: certObject }); + +deepStrictEqual(translatePeerCertificate({ subject: '' }), + { subject: {} }); +deepStrictEqual(translatePeerCertificate({ subject: null }), + { subject: null }); +deepStrictEqual(translatePeerCertificate({ subject: certString }), + { subject: certObject }); + +deepStrictEqual(translatePeerCertificate({ issuerCertificate: '' }), + { issuerCertificate: null }); +deepStrictEqual(translatePeerCertificate({ issuerCertificate: null }), + { issuerCertificate: null }); +deepStrictEqual( + translatePeerCertificate({ issuerCertificate: { subject: certString } }), + { issuerCertificate: { subject: certObject } }); + +{ + const cert = {}; + cert.issuerCertificate = cert; + deepStrictEqual(translatePeerCertificate(cert), { issuerCertificate: cert }); +} + +deepStrictEqual(translatePeerCertificate({ infoAccess: '' }), + { infoAccess: {} }); +deepStrictEqual(translatePeerCertificate({ infoAccess: null }), + { infoAccess: null }); +deepStrictEqual( + translatePeerCertificate({ infoAccess: 'OCSP - URI:file:///etc/passwd' }), + { infoAccess: { 'OCSP - URI': ['file:///etc/passwd'] } }); From 8b9a05c04bbe00aedf063754b13a1915caba68ca Mon Sep 17 00:00:00 2001 From: Bartosz Sosnowski Date: Wed, 2 Aug 2017 15:05:52 +0200 Subject: [PATCH 19/92] test: read proper inspector message size Fix a bug when messages bigger than 64kb where incorrectly parsed by the inspector-helper. PR-URL: https://github.com/nodejs/node/pull/14596 Fixes: https://github.com/nodejs/node/issues/14507 Reviewed-By: Luigi Pinca Reviewed-By: Eugene Ostroukhov Reviewed-By: Refael Ackermann Reviewed-By: Colin Ihrig Reviewed-By: James M Snell --- test/inspector/inspector-helper.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/inspector/inspector-helper.js b/test/inspector/inspector-helper.js index 53b9ebdca75b54..17842ffd98961a 100644 --- a/test/inspector/inspector-helper.js +++ b/test/inspector/inspector-helper.js @@ -48,6 +48,7 @@ function send(socket, message, id, callback) { } function parseWSFrame(buffer, handler) { + // Protocol described in https://tools.ietf.org/html/rfc6455#section-5 if (buffer.length < 2) return 0; assert.strictEqual(0x81, buffer[0]); @@ -59,7 +60,8 @@ function parseWSFrame(buffer, handler) { dataLen = buffer.readUInt16BE(2); bodyOffset = 4; } else if (dataLen === 127) { - dataLen = buffer.readUInt32BE(2); + assert(buffer[2] === 0 && buffer[3] === 0, 'Inspector message too big'); + dataLen = buffer.readUIntBE(4, 6); bodyOffset = 10; } if (buffer.length < bodyOffset + dataLen) From 860c6198c0b3cb76c502beb0b2d8a0aa6c97778f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Lal?= Date: Tue, 1 Aug 2017 10:45:34 +0200 Subject: [PATCH 20/92] test: use ciphers supported by shared OpenSSL On Debian with OpenSSL 1.1 CLI, the ciphers used in those tests were unknown. PR-URL: https://github.com/nodejs/node/pull/14566 Reviewed-By: Ben Noordhuis Reviewed-By: Colin Ihrig Reviewed-By: James M Snell --- test/parallel/test-tls-ecdh-disable.js | 2 +- test/parallel/test-tls-set-ciphers.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/parallel/test-tls-ecdh-disable.js b/test/parallel/test-tls-ecdh-disable.js index a44ce2cedbe6b1..9921ccd1a11f75 100644 --- a/test/parallel/test-tls-ecdh-disable.js +++ b/test/parallel/test-tls-ecdh-disable.js @@ -14,7 +14,7 @@ const fs = require('fs'); const options = { key: fs.readFileSync(`${common.fixturesDir}/keys/agent2-key.pem`), cert: fs.readFileSync(`${common.fixturesDir}/keys/agent2-cert.pem`), - ciphers: 'ECDHE-RSA-RC4-SHA', + ciphers: 'ECDHE-RSA-AES128-SHA', ecdhCurve: false }; diff --git a/test/parallel/test-tls-set-ciphers.js b/test/parallel/test-tls-set-ciphers.js index d53029e4cc9511..e6e14bcf87a507 100644 --- a/test/parallel/test-tls-set-ciphers.js +++ b/test/parallel/test-tls-set-ciphers.js @@ -15,7 +15,7 @@ const fs = require('fs'); const options = { key: fs.readFileSync(`${common.fixturesDir}/keys/agent2-key.pem`), cert: fs.readFileSync(`${common.fixturesDir}/keys/agent2-cert.pem`), - ciphers: 'DES-CBC3-SHA' + ciphers: 'AES256-SHA' }; const reply = 'I AM THE WALRUS'; // something recognizable From c88f99f1f3a181e4f9cf6cacd4864e22f5fe9d8a Mon Sep 17 00:00:00 2001 From: James M Snell Date: Fri, 14 Jul 2017 15:05:24 -0700 Subject: [PATCH 21/92] test: improvements to various http tests * Add common/countdown utility * Numerous improvements to http tests PR-URL: https://github.com/nodejs/node/pull/14315 Reviewed-By: Benjamin Gruenbaum --- test/common/README.md | 36 +++++++++ test/common/countdown.js | 27 +++++++ test/parallel/test-common-countdown.js | 15 ++++ test/parallel/test-http-abort-client.js | 37 +++------- test/parallel/test-http-abort-queued.js | 35 ++++----- test/parallel/test-http-after-connect.js | 50 +++++-------- .../test-http-agent-destroyed-socket.js | 69 +++++++----------- .../parallel/test-http-agent-error-on-idle.js | 34 ++++----- test/parallel/test-http-agent-false.js | 20 ++--- test/parallel/test-http-agent-keepalive.js | 73 ++++++++----------- ...test-http-agent-maxsockets-regress-4050.js | 28 ++++--- test/parallel/test-http-agent-maxsockets.js | 42 +++++------ test/parallel/test-http-agent-no-protocol.js | 8 +- test/parallel/test-http-agent-null.js | 8 +- test/parallel/test-http-automatic-headers.js | 18 ++--- test/parallel/test-http-blank-header.js | 29 +++----- test/parallel/test-http-buffer-sanity.js | 44 ++++------- test/parallel/test-http-chunked.js | 34 ++++----- test/parallel/test-http-client-abort.js | 64 ++++++---------- test/parallel/test-http-client-abort2.js | 17 +++-- test/parallel/test-http-client-agent.js | 27 +++---- .../test-http-client-default-headers-exist.js | 23 +++--- test/parallel/test-http-client-encoding.js | 26 +++---- test/parallel/test-http-client-parse-error.js | 45 +++++------- 24 files changed, 370 insertions(+), 439 deletions(-) create mode 100644 test/common/countdown.js create mode 100644 test/parallel/test-common-countdown.js diff --git a/test/common/README.md b/test/common/README.md index ca8613796f3f49..c84acaba390500 100644 --- a/test/common/README.md +++ b/test/common/README.md @@ -280,6 +280,42 @@ The realpath of the 'tmp' directory. Name of the temp directory used by tests. +## Countdown Module + +The `Countdown` module provides a simple countdown mechanism for tests that +require a particular action to be taken after a given number of completed +tasks (for instance, shutting down an HTTP server after a specific number of +requests). + + +```js +const Countdown = require('../common/countdown'); + +function doSomething() { + console.log('.'); +} + +const countdown = new Countdown(2, doSomething); +countdown.dec(); +countdown.dec(); +``` + +### new Countdown(limit, callback) + +* `limit` {number} +* `callback` {function} + +Creates a new `Countdown` instance. + +### Countdown.prototype.dec() + +Decrements the `Countdown` counter. + +### Coutndown.prototype.remaining + +Specifies the remaining number of times `Countdown.prototype.dec()` must be +called before the callback is invoked. + ## WPT Module The wpt.js module is a port of parts of diff --git a/test/common/countdown.js b/test/common/countdown.js new file mode 100644 index 00000000000000..6a22be0a07eb0b --- /dev/null +++ b/test/common/countdown.js @@ -0,0 +1,27 @@ +/* eslint-disable required-modules */ +'use strict'; + +const assert = require('assert'); +const kLimit = Symbol('limit'); +const kCallback = Symbol('callback'); + +class Countdown { + constructor(limit, cb) { + assert.strictEqual(typeof limit, 'number'); + assert.strictEqual(typeof cb, 'function'); + this[kLimit] = limit; + this[kCallback] = cb; + } + + dec() { + assert(this[kLimit] > 0, 'Countdown expired'); + if (--this[kLimit] === 0) + this[kCallback](); + } + + get remaining() { + return this[kLimit]; + } +} + +module.exports = Countdown; diff --git a/test/parallel/test-common-countdown.js b/test/parallel/test-common-countdown.js new file mode 100644 index 00000000000000..ec0543f36fec74 --- /dev/null +++ b/test/parallel/test-common-countdown.js @@ -0,0 +1,15 @@ +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const Countdown = require('../common/countdown'); + +let done = ''; + +const countdown = new Countdown(2, common.mustCall(() => done = true)); +assert.strictEqual(countdown.remaining, 2); +countdown.dec(); +assert.strictEqual(countdown.remaining, 1); +countdown.dec(); +assert.strictEqual(countdown.remaining, 0); +assert.strictEqual(done, true); diff --git a/test/parallel/test-http-abort-client.js b/test/parallel/test-http-abort-client.js index c44681cf9a9884..b50b72f4bb91af 100644 --- a/test/parallel/test-http-abort-client.js +++ b/test/parallel/test-http-abort-client.js @@ -2,42 +2,27 @@ const common = require('../common'); const http = require('http'); -const server = http.Server(function(req, res) { - console.log('Server accepted request.'); +let serverRes; +const server = http.Server((req, res) => { + serverRes = res; res.writeHead(200); res.write('Part of my res.'); res.destroy(); }); -server.listen(0, common.mustCall(function() { +server.listen(0, common.mustCall(() => { http.get({ - port: this.address().port, + port: server.address().port, headers: { connection: 'keep-alive' } - }, common.mustCall(function(res) { + }, common.mustCall((res) => { server.close(); + serverRes.destroy(); - console.log(`Got res: ${res.statusCode}`); - console.dir(res.headers); - - res.on('data', function(chunk) { - console.log(`Read ${chunk.length} bytes`); - console.log(' chunk=%j', chunk.toString()); - }); - - res.on('end', function() { - console.log('Response ended.'); - }); - - res.on('aborted', function() { - console.log('Response aborted.'); - }); - - res.socket.on('close', function() { - console.log('socket closed, but not res'); - }); - - // it would be nice if this worked: + res.resume(); + res.on('end', common.mustCall()); + res.on('aborted', common.mustCall()); res.on('close', common.mustCall()); + res.socket.on('close', common.mustCall()); })); })); diff --git a/test/parallel/test-http-abort-queued.js b/test/parallel/test-http-abort-queued.js index 5f7259f7db968c..28fb2a78311201 100644 --- a/test/parallel/test-http-abort-queued.js +++ b/test/parallel/test-http-abort-queued.js @@ -1,11 +1,11 @@ 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const http = require('http'); let complete; -const server = http.createServer(function(req, res) { +const server = http.createServer((req, res) => { // We should not see the queued /thatotherone request within the server // as it should be aborted before it is sent. assert.strictEqual(req.url, '/'); @@ -19,10 +19,8 @@ const server = http.createServer(function(req, res) { }); -server.listen(0, function() { - console.log('listen', server.address().port); - - const agent = new http.Agent({maxSockets: 1}); +server.listen(0, () => { + const agent = new http.Agent({ maxSockets: 1 }); assert.strictEqual(Object.keys(agent.sockets).length, 0); const options = { @@ -34,7 +32,7 @@ server.listen(0, function() { }; const req1 = http.request(options); - req1.on('response', function(res1) { + req1.on('response', (res1) => { assert.strictEqual(Object.keys(agent.sockets).length, 1); assert.strictEqual(Object.keys(agent.requests).length, 0); @@ -48,7 +46,9 @@ server.listen(0, function() { assert.strictEqual(Object.keys(agent.sockets).length, 1); assert.strictEqual(Object.keys(agent.requests).length, 1); - req2.on('error', function(err) { + // TODO(jasnell): This event does not appear to currently be triggered. + // is this handler actually required? + req2.on('error', (err) => { // This is expected in response to our explicit abort call assert.strictEqual(err.code, 'ECONNRESET'); }); @@ -59,25 +59,16 @@ server.listen(0, function() { assert.strictEqual(Object.keys(agent.sockets).length, 1); assert.strictEqual(Object.keys(agent.requests).length, 1); - console.log(`Got res: ${res1.statusCode}`); - console.dir(res1.headers); - - res1.on('data', function(chunk) { - console.log(`Read ${chunk.length} bytes`); - console.log(' chunk=%j', chunk.toString()); - complete(); - }); + res1.on('data', (chunk) => complete()); - res1.on('end', function() { - console.log('Response ended.'); - - setTimeout(function() { + res1.on('end', common.mustCall(() => { + setTimeout(common.mustCall(() => { assert.strictEqual(Object.keys(agent.sockets).length, 0); assert.strictEqual(Object.keys(agent.requests).length, 0); server.close(); - }, 100); - }); + }), 100); + })); }); req1.end(); diff --git a/test/parallel/test-http-after-connect.js b/test/parallel/test-http-after-connect.js index 8be887c58082da..dfabbc092b6149 100644 --- a/test/parallel/test-http-after-connect.js +++ b/test/parallel/test-http-after-connect.js @@ -2,61 +2,51 @@ const common = require('../common'); const assert = require('assert'); const http = require('http'); +const Countdown = require('../common/countdown'); -let clientResponses = 0; - -const server = http.createServer(common.mustCall(function(req, res) { - console.error('Server got GET request'); +const server = http.createServer(common.mustCall((req, res) => { req.resume(); res.writeHead(200); res.write(''); - setTimeout(function() { - res.end(req.url); - }, 50); + setTimeout(() => res.end(req.url), 50); }, 2)); -server.on('connect', common.mustCall(function(req, socket) { - console.error('Server got CONNECT request'); + +const countdown = new Countdown(2, common.mustCall(() => server.close())); + +server.on('connect', common.mustCall((req, socket) => { socket.write('HTTP/1.1 200 Connection established\r\n\r\n'); socket.resume(); - socket.on('end', function() { - socket.end(); - }); + socket.on('end', () => socket.end()); })); -server.listen(0, function() { + +server.listen(0, common.mustCall(() => { const req = http.request({ - port: this.address().port, + port: server.address().port, method: 'CONNECT', path: 'google.com:80' }); - req.on('connect', common.mustCall(function(res, socket) { - console.error('Client got CONNECT response'); + req.on('connect', common.mustCall((res, socket) => { socket.end(); - socket.on('end', function() { + socket.on('end', common.mustCall(() => { doRequest(0); doRequest(1); - }); + })); socket.resume(); })); req.end(); -}); +})); function doRequest(i) { http.get({ port: server.address().port, path: `/request${i}` - }, common.mustCall(function(res) { - console.error('Client got GET response'); + }, common.mustCall((res) => { let data = ''; res.setEncoding('utf8'); - res.on('data', function(chunk) { - data += chunk; - }); - res.on('end', function() { + res.on('data', (chunk) => data += chunk); + res.on('end', common.mustCall(() => { assert.strictEqual(data, `/request${i}`); - ++clientResponses; - if (clientResponses === 2) { - server.close(); - } - }); + countdown.dec(); + })); })); } diff --git a/test/parallel/test-http-agent-destroyed-socket.js b/test/parallel/test-http-agent-destroyed-socket.js index 4bb14c2d7e01ce..6dcebd42988589 100644 --- a/test/parallel/test-http-agent-destroyed-socket.js +++ b/test/parallel/test-http-agent-destroyed-socket.js @@ -1,36 +1,31 @@ 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const http = require('http'); +const Countdown = require('../common/countdown'); -const server = http.createServer(function(req, res) { - res.writeHead(200, {'Content-Type': 'text/plain'}); +const server = http.createServer(common.mustCall((req, res) => { + res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('Hello World\n'); -}).listen(0, function() { - const agent = new http.Agent({maxSockets: 1}); +}, 2)).listen(0, common.mustCall(() => { + const agent = new http.Agent({ maxSockets: 1 }); - agent.on('free', function(socket, host, port) { - console.log('freeing socket. destroyed? ', socket.destroyed); - }); + agent.on('free', common.mustCall(3)); const requestOptions = { agent: agent, host: 'localhost', - port: this.address().port, + port: server.address().port, path: '/' }; - const request1 = http.get(requestOptions, function(response) { + const request1 = http.get(requestOptions, common.mustCall((response) => { // assert request2 is queued in the agent const key = agent.getName(requestOptions); assert.strictEqual(agent.requests[key].length, 1); - console.log('got response1'); - request1.socket.on('close', function() { - console.log('request1 socket closed'); - }); - response.pipe(process.stdout); - response.on('end', function() { - console.log('response1 done'); + request1.socket.on('close', common.mustCall()); + response.resume(); + response.on('end', common.mustCall(() => { ///////////////////////////////// // // THE IMPORTANT PART @@ -44,43 +39,29 @@ const server = http.createServer(function(req, res) { // is triggered. request1.socket.destroy(); - response.once('close', function() { + // TODO(jasnell): This close event does not appear to be triggered. + // is it necessary? + response.once('close', () => { // assert request2 was removed from the queue assert(!agent.requests[key]); - console.log("waiting for request2.onSocket's nextTick"); - process.nextTick(function() { + process.nextTick(() => { // assert that the same socket was not assigned to request2, // since it was destroyed. assert.notStrictEqual(request1.socket, request2.socket); assert(!request2.socket.destroyed, 'the socket is destroyed'); }); }); - }); - }); + })); + })); - let request2 = http.get(requestOptions, function(response) { + const request2 = http.get(requestOptions, common.mustCall((response) => { assert(!request2.socket.destroyed); assert(request1.socket.destroyed); // assert not reusing the same socket, since it was destroyed. assert.notStrictEqual(request1.socket, request2.socket); - console.log('got response2'); - let gotClose = false; - let gotResponseEnd = false; - request2.socket.on('close', function() { - console.log('request2 socket closed'); - gotClose = true; - done(); - }); - response.pipe(process.stdout); - response.on('end', function() { - console.log('response2 done'); - gotResponseEnd = true; - done(); - }); - - function done() { - if (gotResponseEnd && gotClose) - server.close(); - } - }); -}); + const countdown = new Countdown(2, common.mustCall(() => server.close())); + request2.socket.on('close', common.mustCall(() => countdown.dec())); + response.on('end', common.mustCall(() => countdown.dec())); + response.resume(); + })); +})); diff --git a/test/parallel/test-http-agent-error-on-idle.js b/test/parallel/test-http-agent-error-on-idle.js index 2f270c0d30ca0b..fce5e8f0324f5c 100644 --- a/test/parallel/test-http-agent-error-on-idle.js +++ b/test/parallel/test-http-agent-error-on-idle.js @@ -1,32 +1,31 @@ 'use strict'; -require('../common'); + +const common = require('../common'); const assert = require('assert'); const http = require('http'); const Agent = http.Agent; -const server = http.createServer(function(req, res) { +const server = http.createServer(common.mustCall((req, res) => { res.end('hello world'); -}); +}, 2)); -server.listen(0, function() { - const agent = new Agent({ - keepAlive: true, - }); +server.listen(0, () => { + const agent = new Agent({ keepAlive: true }); const requestParams = { host: 'localhost', - port: this.address().port, + port: server.address().port, agent: agent, path: '/' }; const socketKey = agent.getName(requestParams); - get(function(res) { + http.get(requestParams, common.mustCall((res) => { assert.strictEqual(res.statusCode, 200); res.resume(); - res.on('end', function() { - process.nextTick(function() { + res.on('end', common.mustCall(() => { + process.nextTick(common.mustCall(() => { const freeSockets = agent.freeSockets[socketKey]; assert.strictEqual(freeSockets.length, 1, `expect a free socket on ${socketKey}`); @@ -35,14 +34,10 @@ server.listen(0, function() { const freeSocket = freeSockets[0]; freeSocket.emit('error', new Error('ECONNRESET: test')); - get(done); - }); - }); - }); - - function get(callback) { - return http.get(requestParams, callback); - } + http.get(requestParams, done); + })); + })); + })); function done() { assert.strictEqual(Object.keys(agent.freeSockets).length, 0, @@ -50,6 +45,5 @@ server.listen(0, function() { agent.destroy(); server.close(); - process.exit(0); } }); diff --git a/test/parallel/test-http-agent-false.js b/test/parallel/test-http-agent-false.js index 5c9907bb706d32..6d5b1b38bf0a9b 100644 --- a/test/parallel/test-http-agent-false.js +++ b/test/parallel/test-http-agent-false.js @@ -1,6 +1,5 @@ 'use strict'; -require('../common'); -const assert = require('assert'); +const common = require('../common'); const http = require('http'); // sending `agent: false` when `port: null` is also passed in (i.e. the result @@ -14,20 +13,13 @@ const opts = { agent: false }; -let good = false; -process.on('exit', function() { - assert(good, 'expected either an "error" or "response" event'); -}); - // we just want an "error" (no local HTTP server on port 80) or "response" // to happen (user happens ot have HTTP server running on port 80). // As long as the process doesn't crash from a C++ assertion then we're good. const req = http.request(opts); -req.on('response', function(res) { - good = true; -}); -req.on('error', function(err) { - // an "error" event is ok, don't crash the process - good = true; -}); + +// Will be called by either the response event or error event, not both +const oneResponse = common.mustCall(); +req.on('response', oneResponse); +req.on('error', oneResponse); req.end(); diff --git a/test/parallel/test-http-agent-keepalive.js b/test/parallel/test-http-agent-keepalive.js index 9ea3fd7677aebe..7f9626d4669ef9 100644 --- a/test/parallel/test-http-agent-keepalive.js +++ b/test/parallel/test-http-agent-keepalive.js @@ -13,19 +13,17 @@ const agent = new Agent({ maxFreeSockets: 5 }); -const server = http.createServer(function(req, res) { +const server = http.createServer(common.mustCall((req, res) => { if (req.url === '/error') { res.destroy(); return; } else if (req.url === '/remote_close') { // cache the socket, close it after a short delay const socket = res.connection; - setImmediate(function() { - socket.end(); - }); + setImmediate(common.mustCall(() => socket.end())); } res.end('hello world'); -}); +}, 4)); function get(path, callback) { return http.get({ @@ -44,82 +42,75 @@ function checkDataAndSockets(body) { function second() { // request second, use the same socket - get('/second', function(res) { + get('/second', common.mustCall((res) => { assert.strictEqual(res.statusCode, 200); res.on('data', checkDataAndSockets); - res.on('end', function() { + res.on('end', common.mustCall(() => { assert.strictEqual(agent.sockets[name].length, 1); assert.strictEqual(agent.freeSockets[name], undefined); - process.nextTick(function() { + process.nextTick(common.mustCall(() => { assert.strictEqual(agent.sockets[name], undefined); assert.strictEqual(agent.freeSockets[name].length, 1); remoteClose(); - }); - }); - }); + })); + })); + })); } function remoteClose() { // mock remote server close the socket - get('/remote_close', function(res) { + get('/remote_close', common.mustCall((res) => { assert.deepStrictEqual(res.statusCode, 200); res.on('data', checkDataAndSockets); - res.on('end', function() { + res.on('end', common.mustCall(() => { assert.strictEqual(agent.sockets[name].length, 1); assert.strictEqual(agent.freeSockets[name], undefined); - process.nextTick(function() { + process.nextTick(common.mustCall(() => { assert.strictEqual(agent.sockets[name], undefined); assert.strictEqual(agent.freeSockets[name].length, 1); // waitting remote server close the socket - setTimeout(function() { + setTimeout(common.mustCall(() => { assert.strictEqual(agent.sockets[name], undefined); assert.strictEqual(agent.freeSockets[name], undefined, 'freeSockets is not empty'); remoteError(); - }, common.platformTimeout(200)); - }); - }); - }); + }), common.platformTimeout(200)); + })); + })); + })); } function remoteError() { // remove server will destroy ths socket - const req = get('/error', function(res) { - throw new Error('should not call this function'); - }); - req.on('error', function(err) { - assert.ok(err); + const req = get('/error', common.mustNotCall()); + req.on('error', common.mustCall((err) => { + assert(err); assert.strictEqual(err.message, 'socket hang up'); assert.strictEqual(agent.sockets[name].length, 1); assert.strictEqual(agent.freeSockets[name], undefined); // Wait socket 'close' event emit - setTimeout(function() { + setTimeout(common.mustCall(() => { assert.strictEqual(agent.sockets[name], undefined); assert.strictEqual(agent.freeSockets[name], undefined); - done(); - }, common.platformTimeout(1)); - }); -} - -function done() { - console.log('http keepalive agent test success.'); - process.exit(0); + server.close(); + }), common.platformTimeout(1)); + })); } -server.listen(0, function() { +server.listen(0, common.mustCall(() => { name = `localhost:${server.address().port}:`; // request first, and keep alive - get('/first', function(res) { + get('/first', common.mustCall((res) => { assert.strictEqual(res.statusCode, 200); res.on('data', checkDataAndSockets); - res.on('end', function() { + res.on('end', common.mustCall(() => { assert.strictEqual(agent.sockets[name].length, 1); assert.strictEqual(agent.freeSockets[name], undefined); - process.nextTick(function() { + process.nextTick(common.mustCall(() => { assert.strictEqual(agent.sockets[name], undefined); assert.strictEqual(agent.freeSockets[name].length, 1); second(); - }); - }); - }); -}); + })); + })); + })); +})); diff --git a/test/parallel/test-http-agent-maxsockets-regress-4050.js b/test/parallel/test-http-agent-maxsockets-regress-4050.js index fd3a8c33f3e39a..57a90e4b05c79f 100644 --- a/test/parallel/test-http-agent-maxsockets-regress-4050.js +++ b/test/parallel/test-http-agent-maxsockets-regress-4050.js @@ -1,7 +1,8 @@ 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const http = require('http'); +const Countdown = require('../common/countdown'); const MAX_SOCKETS = 2; @@ -12,9 +13,11 @@ const agent = new http.Agent({ maxFreeSockets: 2 }); -const server = http.createServer(function(req, res) { +const server = http.createServer(common.mustCall((req, res) => { res.end('hello world'); -}); +}, 6)); + +const countdown = new Countdown(6, common.mustCall(() => server.close())); function get(path, callback) { return http.get({ @@ -25,19 +28,14 @@ function get(path, callback) { }, callback); } -server.listen(0, function() { - let finished = 0; - const num_requests = 6; - for (let i = 0; i < num_requests; i++) { - const request = get('/1', function() { - }); - request.on('response', function() { +server.listen(0, common.mustCall(() => { + for (let i = 0; i < 6; i++) { + const request = get('/1', common.mustCall()); + request.on('response', common.mustCall(() => { request.abort(); const sockets = agent.sockets[Object.keys(agent.sockets)[0]]; assert(sockets.length <= MAX_SOCKETS); - if (++finished === num_requests) { - server.close(); - } - }); + countdown.dec(); + })); } -}); +})); diff --git a/test/parallel/test-http-agent-maxsockets.js b/test/parallel/test-http-agent-maxsockets.js index 513906160048d9..66fffba250513f 100644 --- a/test/parallel/test-http-agent-maxsockets.js +++ b/test/parallel/test-http-agent-maxsockets.js @@ -1,7 +1,8 @@ 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const http = require('http'); +const Countdown = require('../common/countdown'); const agent = new http.Agent({ keepAlive: true, @@ -10,9 +11,9 @@ const agent = new http.Agent({ maxFreeSockets: 2 }); -const server = http.createServer(function(req, res) { +const server = http.createServer(common.mustCall((req, res) => { res.end('hello world'); -}); +}, 2)); function get(path, callback) { return http.get({ @@ -23,32 +24,25 @@ function get(path, callback) { }, callback); } -let count = 0; -function done() { - if (++count !== 2) { - return; - } +const countdown = new Countdown(2, common.mustCall(() => { const freepool = agent.freeSockets[Object.keys(agent.freeSockets)[0]]; assert.strictEqual(freepool.length, 2, `expect keep 2 free sockets, but got ${freepool.length}`); agent.destroy(); server.close(); +})); + +function dec() { + process.nextTick(() => countdown.dec()); } -server.listen(0, function() { - get('/1', function(res) { - assert.strictEqual(res.statusCode, 200); - res.resume(); - res.on('end', function() { - process.nextTick(done); - }); - }); +function onGet(res) { + assert.strictEqual(res.statusCode, 200); + res.resume(); + res.on('end', common.mustCall(dec)); +} - get('/2', function(res) { - assert.strictEqual(res.statusCode, 200); - res.resume(); - res.on('end', function() { - process.nextTick(done); - }); - }); -}); +server.listen(0, common.mustCall(() => { + get('/1', common.mustCall(onGet)); + get('/2', common.mustCall(onGet)); +})); diff --git a/test/parallel/test-http-agent-no-protocol.js b/test/parallel/test-http-agent-no-protocol.js index a11489b6c5bc2b..dd95b6c33769c0 100644 --- a/test/parallel/test-http-agent-no-protocol.js +++ b/test/parallel/test-http-agent-no-protocol.js @@ -3,17 +3,17 @@ const common = require('../common'); const http = require('http'); const url = require('url'); -const server = http.createServer(common.mustCall(function(req, res) { +const server = http.createServer(common.mustCall((req, res) => { res.end(); -})).listen(0, '127.0.0.1', common.mustCall(function() { - const opts = url.parse(`http://127.0.0.1:${this.address().port}/`); +})).listen(0, '127.0.0.1', common.mustCall(() => { + const opts = url.parse(`http://127.0.0.1:${server.address().port}/`); // remove the `protocol` field… the `http` module should fall back // to "http:", as defined by the global, default `http.Agent` instance. opts.agent = new http.Agent(); opts.agent.protocol = null; - http.get(opts, common.mustCall(function(res) { + http.get(opts, common.mustCall((res) => { res.resume(); server.close(); })); diff --git a/test/parallel/test-http-agent-null.js b/test/parallel/test-http-agent-null.js index 9071b88b98997a..475cddc4902eaf 100644 --- a/test/parallel/test-http-agent-null.js +++ b/test/parallel/test-http-agent-null.js @@ -2,14 +2,14 @@ const common = require('../common'); const http = require('http'); -const server = http.createServer(common.mustCall(function(req, res) { +const server = http.createServer(common.mustCall((req, res) => { res.end(); -})).listen(0, common.mustCall(function() { +})).listen(0, common.mustCall(() => { const options = { agent: null, - port: this.address().port + port: server.address().port }; - http.get(options, common.mustCall(function(res) { + http.get(options, common.mustCall((res) => { res.resume(); server.close(); })); diff --git a/test/parallel/test-http-automatic-headers.js b/test/parallel/test-http-automatic-headers.js index 37a5c43901c33d..5a6a8e524c76ee 100644 --- a/test/parallel/test-http-automatic-headers.js +++ b/test/parallel/test-http-automatic-headers.js @@ -1,23 +1,23 @@ 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const http = require('http'); -const server = http.createServer(function(req, res) { +const server = http.createServer(common.mustCall((req, res) => { res.setHeader('X-Date', 'foo'); res.setHeader('X-Connection', 'bar'); res.setHeader('X-Content-Length', 'baz'); res.end(); -}); +})); server.listen(0); -server.on('listening', function() { - const agent = new http.Agent({ port: this.address().port, maxSockets: 1 }); +server.on('listening', common.mustCall(() => { + const agent = new http.Agent({ port: server.address().port, maxSockets: 1 }); http.get({ - port: this.address().port, + port: server.address().port, path: '/hello', agent: agent - }, function(res) { + }, common.mustCall((res) => { assert.strictEqual(res.statusCode, 200); assert.strictEqual(res.headers['x-date'], 'foo'); assert.strictEqual(res.headers['x-connection'], 'bar'); @@ -27,5 +27,5 @@ server.on('listening', function() { assert.strictEqual(res.headers['content-length'], '0'); server.close(); agent.destroy(); - }); -}); + })); +})); diff --git a/test/parallel/test-http-blank-header.js b/test/parallel/test-http-blank-header.js index edd8923fa8e2f7..cc52e35e05a38d 100644 --- a/test/parallel/test-http-blank-header.js +++ b/test/parallel/test-http-blank-header.js @@ -4,34 +4,29 @@ const assert = require('assert'); const http = require('http'); const net = require('net'); -const server = http.createServer(common.mustCall(function(req, res) { +const server = http.createServer(common.mustCall((req, res) => { assert.strictEqual('GET', req.method); assert.strictEqual('/blah', req.url); assert.deepStrictEqual({ - host: 'mapdevel.trolologames.ru:443', - origin: 'http://mapdevel.trolologames.ru', + host: 'example.org:443', + origin: 'http://example.org', cookie: '' }, req.headers); })); -server.listen(0, function() { - const c = net.createConnection(this.address().port); +server.listen(0, common.mustCall(() => { + const c = net.createConnection(server.address().port); - c.on('connect', function() { + c.on('connect', common.mustCall(() => { c.write('GET /blah HTTP/1.1\r\n' + - 'Host: mapdevel.trolologames.ru:443\r\n' + + 'Host: example.org:443\r\n' + 'Cookie:\r\n' + - 'Origin: http://mapdevel.trolologames.ru\r\n' + + 'Origin: http://example.org\r\n' + '\r\n\r\nhello world' ); - }); + })); - c.on('end', function() { - c.end(); - }); - - c.on('close', function() { - server.close(); - }); -}); + c.on('end', common.mustCall(() => c.end())); + c.on('close', common.mustCall(() => server.close())); +})); diff --git a/test/parallel/test-http-buffer-sanity.js b/test/parallel/test-http-buffer-sanity.js index 717ca23ce8bc16..0fadd6c0c07819 100644 --- a/test/parallel/test-http-buffer-sanity.js +++ b/test/parallel/test-http-buffer-sanity.js @@ -11,16 +11,12 @@ for (let i = 0; i < buffer.length; i++) { buffer[i] = i % 256; } - -const web = http.Server(function(req, res) { - web.close(); - - console.log(req.headers); +const server = http.Server(function(req, res) { + server.close(); let i = 0; - req.on('data', function(d) { - process.stdout.write(','); + req.on('data', (d) => { measuredSize += d.length; for (let j = 0; j < d.length; j++) { assert.strictEqual(buffer[i], d[j]); @@ -28,39 +24,27 @@ const web = http.Server(function(req, res) { } }); - - req.on('end', function() { + req.on('end', common.mustCall(() => { + assert.strictEqual(bufferSize, measuredSize); res.writeHead(200); res.write('thanks'); res.end(); - console.log('response with \'thanks\''); - }); - - req.connection.on('error', function(e) { - console.log(`http server-side error: ${e.message}`); - process.exit(1); - }); + })); }); -web.listen(0, common.mustCall(function() { - console.log('Making request'); - +server.listen(0, common.mustCall(() => { const req = http.request({ - port: this.address().port, - method: 'GET', + port: server.address().port, + method: 'POST', path: '/', headers: { 'content-length': buffer.length } - }, common.mustCall(function(res) { - console.log('Got response'); + }, common.mustCall((res) => { res.setEncoding('utf8'); - res.on('data', common.mustCall(function(string) { - assert.strictEqual('thanks', string); + let data = ''; + res.on('data', (chunk) => data += chunk); + res.on('end', common.mustCall(() => { + assert.strictEqual('thanks', data); })); })); req.end(buffer); })); - - -process.on('exit', function() { - assert.strictEqual(bufferSize, measuredSize); -}); diff --git a/test/parallel/test-http-chunked.js b/test/parallel/test-http-chunked.js index b70a704bb7fce4..4fa4f2004a2967 100644 --- a/test/parallel/test-http-chunked.js +++ b/test/parallel/test-http-chunked.js @@ -1,5 +1,5 @@ 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const http = require('http'); @@ -13,31 +13,23 @@ const UTF8_STRING = '南越国是前203年至前111年存在于岭南地区的 '采用封建制和郡县制并存的制度,它的建立保证了秦末乱世岭南地区社会秩序的稳定,' + '有效的改善了岭南地区落后的政治、经济现状。'; -const server = http.createServer(function(req, res) { - res.writeHead(200, {'Content-Type': 'text/plain; charset=utf8'}); +const server = http.createServer(common.mustCall((req, res) => { + res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf8' }); res.end(UTF8_STRING, 'utf8'); -}); -server.listen(0, function() { +})); +server.listen(0, common.mustCall(() => { let data = ''; - const get = http.get({ + http.get({ path: '/', host: 'localhost', - port: this.address().port - }, function(x) { + port: server.address().port + }, common.mustCall((x) => { x.setEncoding('utf8'); - x.on('data', function(c) { data += c; }); - x.on('error', function(e) { - throw e; - }); - x.on('end', function() { + x.on('data', (c) => data += c); + x.on('end', common.mustCall(() => { assert.strictEqual('string', typeof data); - console.log('here is the response:'); assert.strictEqual(UTF8_STRING, data); - console.log(data); server.close(); - }); - }); - get.on('error', function(e) { throw e; }); - get.end(); - -}); + })); + })).end(); +})); diff --git a/test/parallel/test-http-client-abort.js b/test/parallel/test-http-client-abort.js index 68b76d1548de27..a4aa41c328f849 100644 --- a/test/parallel/test-http-client-abort.js +++ b/test/parallel/test-http-client-abort.js @@ -1,55 +1,33 @@ 'use strict'; -require('../common'); -const assert = require('assert'); +const common = require('../common'); const http = require('http'); +const Countdown = require('../common/countdown'); -let clientAborts = 0; +const N = 8; + +const countdown = new Countdown(N, common.mustCall(() => server.close())); -const server = http.Server(function(req, res) { - console.log('Got connection'); +const server = http.Server(common.mustCall((req, res) => { res.writeHead(200); res.write('Working on it...'); + req.on('aborted', common.mustCall(() => countdown.dec())); +}, N)); - // I would expect an error event from req or res that the client aborted - // before completing the HTTP request / response cycle, or maybe a new - // event like "aborted" or something. - req.on('aborted', function() { - clientAborts++; - console.log(`Got abort ${clientAborts}`); - if (clientAborts === N) { - console.log('All aborts detected, you win.'); - server.close(); - } - }); -}); +server.listen(0, common.mustCall(() => { -let responses = 0; -const N = 8; -const requests = []; + const requests = []; + const reqCountdown = new Countdown(N, common.mustCall(() => { + requests.forEach((req) => req.abort()); + })); -server.listen(0, function() { - console.log('Server listening.'); + const options = { port: server.address().port }; for (let i = 0; i < N; i++) { - console.log(`Making client ${i}`); - const options = { port: this.address().port, path: `/?id=${i}` }; - const req = http.get(options, function(res) { - console.log(`Client response code ${res.statusCode}`); - - res.resume(); - if (++responses === N) { - console.log('All clients connected, destroying.'); - requests.forEach(function(outReq) { - console.log('abort'); - outReq.abort(); - }); - } - }); - - requests.push(req); + options.path = `/?id=${i}`; + requests.push( + http.get(options, common.mustCall((res) => { + res.resume(); + reqCountdown.dec(); + }))); } -}); - -process.on('exit', function() { - assert.strictEqual(N, clientAborts); -}); +})); diff --git a/test/parallel/test-http-client-abort2.js b/test/parallel/test-http-client-abort2.js index 7c7be9b530e2d2..174174d849b90a 100644 --- a/test/parallel/test-http-client-abort2.js +++ b/test/parallel/test-http-client-abort2.js @@ -1,16 +1,17 @@ 'use strict'; -require('../common'); +const common = require('../common'); const http = require('http'); -const server = http.createServer(function(req, res) { +const server = http.createServer(common.mustCall((req, res) => { res.end('Hello'); -}); +})); -server.listen(0, function() { - const req = http.get({port: this.address().port}, function(res) { - res.on('data', function(data) { +server.listen(0, common.mustCall(() => { + const options = { port: server.address().port }; + const req = http.get(options, common.mustCall((res) => { + res.on('data', (data) => { req.abort(); server.close(); }); - }); -}); + })); +})); diff --git a/test/parallel/test-http-client-agent.js b/test/parallel/test-http-client-agent.js index 6d30a2236ef485..a24d886c041984 100644 --- a/test/parallel/test-http-client-agent.js +++ b/test/parallel/test-http-client-agent.js @@ -1,5 +1,5 @@ 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const http = require('http'); @@ -7,23 +7,22 @@ let name; const max = 3; let count = 0; -const server = http.Server(function(req, res) { +const server = http.Server(common.mustCall((req, res) => { if (req.url === '/0') { - setTimeout(function() { + setTimeout(common.mustCall(() => { res.writeHead(200); res.end('Hello, World!'); - }, 100); + }), 100); } else { res.writeHead(200); res.end('Hello, World!'); } -}); -server.listen(0, function() { - name = http.globalAgent.getName({ port: this.address().port }); - for (let i = 0; i < max; ++i) { +}, max)); +server.listen(0, common.mustCall(() => { + name = http.globalAgent.getName({ port: server.address().port }); + for (let i = 0; i < max; ++i) request(i); - } -}); +})); function request(i) { const req = http.get({ @@ -31,7 +30,7 @@ function request(i) { path: `/${i}` }, function(res) { const socket = req.socket; - socket.on('close', function() { + socket.on('close', common.mustCall(() => { ++count; if (count < max) { assert.strictEqual(http.globalAgent.sockets[name].includes(socket), @@ -41,11 +40,7 @@ function request(i) { assert(!http.globalAgent.requests.hasOwnProperty(name)); server.close(); } - }); + })); res.resume(); }); } - -process.on('exit', function() { - assert.strictEqual(count, max); -}); diff --git a/test/parallel/test-http-client-default-headers-exist.js b/test/parallel/test-http-client-default-headers-exist.js index 410f83449fc1b6..4efe1c95802fb6 100644 --- a/test/parallel/test-http-client-default-headers-exist.js +++ b/test/parallel/test-http-client-default-headers-exist.js @@ -1,7 +1,8 @@ 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const http = require('http'); +const Countdown = require('../common/countdown'); const expectedHeaders = { 'DELETE': ['host', 'connection'], @@ -14,17 +15,18 @@ const expectedHeaders = { const expectedMethods = Object.keys(expectedHeaders); -let requestCount = 0; +const countdown = + new Countdown(expectedMethods.length, + common.mustCall(() => server.close())); -const server = http.createServer(function(req, res) { - requestCount++; +const server = http.createServer(common.mustCall((req, res) => { res.end(); assert(expectedHeaders.hasOwnProperty(req.method), `${req.method} was an unexpected method`); const requestHeaders = Object.keys(req.headers); - requestHeaders.forEach(function(header) { + requestHeaders.forEach((header) => { assert.strictEqual( expectedHeaders[req.method].includes(header.toLowerCase()), true, @@ -38,15 +40,14 @@ const server = http.createServer(function(req, res) { `some headers were missing for method: ${req.method}` ); - if (expectedMethods.length === requestCount) - server.close(); -}); + countdown.dec(); +}, expectedMethods.length)); -server.listen(0, function() { - expectedMethods.forEach(function(method) { +server.listen(0, common.mustCall(() => { + expectedMethods.forEach((method) => { http.request({ method: method, port: server.address().port }).end(); }); -}); +})); diff --git a/test/parallel/test-http-client-encoding.js b/test/parallel/test-http-client-encoding.js index d2aa8fdcbbac46..57d02802c8438c 100644 --- a/test/parallel/test-http-client-encoding.js +++ b/test/parallel/test-http-client-encoding.js @@ -1,18 +1,18 @@ 'use strict'; -require('../common'); - +const common = require('../common'); +const assert = require('assert'); const http = require('http'); -http.createServer(function(req, res) { - res.end('ok\n'); - this.close(); -}).listen(0, test); - -function test() { +const server = http.createServer((req, res) => { + res.end('ok'); + server.close(); +}).listen(0, common.mustCall(() => { http.request({ - port: this.address().port, + port: server.address().port, encoding: 'utf8' - }, function(res) { - res.pipe(process.stdout); - }).end(); -} + }, common.mustCall((res) => { + let data = ''; + res.on('data', (chunk) => data += chunk); + res.on('end', common.mustCall(() => assert.strictEqual(data, 'ok'))); + })).end(); +})); diff --git a/test/parallel/test-http-client-parse-error.js b/test/parallel/test-http-client-parse-error.js index 77cd2cb193a680..fc022b337770e0 100644 --- a/test/parallel/test-http-client-parse-error.js +++ b/test/parallel/test-http-client-parse-error.js @@ -1,39 +1,30 @@ 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); - const http = require('http'); const net = require('net'); +const Countdown = require('../common/countdown'); + +const countdown = new Countdown(2, common.mustCall(() => server.close())); -let connects = 0; -let parseErrors = 0; +const payloads = [ + 'HTTP/1.1 302 Object Moved\r\nContent-Length: 0\r\n\r\nhi world', + 'bad http = should trigger parse error' +]; // Create a TCP server -net.createServer(function(c) { - console.log('connection'); - if (++connects === 1) { - c.end('HTTP/1.1 302 Object Moved\r\nContent-Length: 0\r\n\r\nhi world'); - } else { - c.end('bad http - should trigger parse error\r\n'); - this.close(); - } -}).listen(0, '127.0.0.1', function() { +const server = + net.createServer(common.mustCall((c) => c.end(payloads.shift()), 2)); + +server.listen(0, common.mustCall(() => { for (let i = 0; i < 2; i++) { - http.request({ - host: '127.0.0.1', - port: this.address().port, - method: 'GET', + http.get({ + port: server.address().port, path: '/' - }).on('error', function(e) { - console.log('got error from client'); + }).on('error', common.mustCall((e) => { assert.ok(e.message.includes('Parse Error')); assert.strictEqual(e.code, 'HPE_INVALID_CONSTANT'); - parseErrors++; - }).end(); + countdown.dec(); + })); } -}); - -process.on('exit', function() { - assert.strictEqual(connects, 2); - assert.strictEqual(parseErrors, 2); -}); +})); From fc49cf41ea4f375d5d8f313a16000ec411d06113 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Thu, 3 Aug 2017 18:08:11 -0700 Subject: [PATCH 22/92] test: improve multiple timers tests PR-URL: https://github.com/nodejs/node/pull/14616 Reviewed-By: Anna Henningsen Reviewed-By: Refael Ackermann --- test/parallel/test-timers-immediate.js | 23 +++---- .../parallel/test-timers-non-integer-delay.js | 12 ++-- ...imeout-removes-other-socket-unref-timer.js | 26 ++++---- test/parallel/test-timers-unref-leak.js | 23 ++----- test/parallel/test-timers-unref.js | 60 +++++++------------ ...test-timers-unrefd-interval-still-fires.js | 23 ++++--- .../test-timers-unrefed-in-beforeexit.js | 21 ++----- test/parallel/test-timers-zero-timeout.js | 14 ++--- 8 files changed, 69 insertions(+), 133 deletions(-) diff --git a/test/parallel/test-timers-immediate.js b/test/parallel/test-timers-immediate.js index 9632022917f152..01e034fa580140 100644 --- a/test/parallel/test-timers-immediate.js +++ b/test/parallel/test-timers-immediate.js @@ -2,10 +2,6 @@ const common = require('../common'); const assert = require('assert'); -let immediateB; -let immediateC; -let immediateD; - let mainFinished = false; setImmediate(common.mustCall(function() { @@ -13,21 +9,16 @@ setImmediate(common.mustCall(function() { clearImmediate(immediateB); })); -immediateB = setImmediate(function() { +let immediateB = setImmediate(function() { common.fail('this immediate should not run'); }); -setImmediate(function(x, y, z) { - immediateC = [x, y, z]; -}, 1, 2, 3); - -setImmediate(function(x, y, z, a, b) { - immediateD = [x, y, z, a, b]; -}, 1, 2, 3, 4, 5); +setImmediate(common.mustCall((...args) => { + assert.deepStrictEqual(args, [1, 2, 3]); +}), 1, 2, 3); -process.on('exit', function() { - assert.deepStrictEqual(immediateC, [1, 2, 3], 'immediateC args should match'); - assert.deepStrictEqual(immediateD, [1, 2, 3, 4, 5], '5 args should match'); -}); +setImmediate(common.mustCall((...args) => { + assert.deepStrictEqual(args, [1, 2, 3, 4, 5]); +}), 1, 2, 3, 4, 5); mainFinished = true; diff --git a/test/parallel/test-timers-non-integer-delay.js b/test/parallel/test-timers-non-integer-delay.js index cd7fa5e661dc81..db50ec0a2cd8ac 100644 --- a/test/parallel/test-timers-non-integer-delay.js +++ b/test/parallel/test-timers-non-integer-delay.js @@ -1,5 +1,5 @@ 'use strict'; -require('../common'); +const common = require('../common'); /* * This test makes sure that non-integer timer delays do not make the process @@ -18,13 +18,11 @@ require('../common'); */ const TIMEOUT_DELAY = 1.1; -const NB_TIMEOUTS_FIRED = 50; +let N = 50; -let nbTimeoutFired = 0; -const interval = setInterval(function() { - ++nbTimeoutFired; - if (nbTimeoutFired === NB_TIMEOUTS_FIRED) { +const interval = setInterval(common.mustCall(() => { + if (--N === 0) { clearInterval(interval); process.exit(0); } -}, TIMEOUT_DELAY); +}, N), TIMEOUT_DELAY); diff --git a/test/parallel/test-timers-socket-timeout-removes-other-socket-unref-timer.js b/test/parallel/test-timers-socket-timeout-removes-other-socket-unref-timer.js index f42144360b6941..4b8bc5fc6fda37 100644 --- a/test/parallel/test-timers-socket-timeout-removes-other-socket-unref-timer.js +++ b/test/parallel/test-timers-socket-timeout-removes-other-socket-unref-timer.js @@ -6,6 +6,7 @@ const common = require('../common'); const net = require('net'); +const Countdown = require('../common/countdown'); const clients = []; @@ -19,7 +20,7 @@ const server = net.createServer(function onClient(client) { * the list of unref timers when traversing it, and exposes the * original issue in joyent/node#8897. */ - clients[0].setTimeout(1, function onTimeout() { + clients[0].setTimeout(1, () => { clients[1].setTimeout(0); clients[0].end(); clients[1].end(); @@ -31,19 +32,16 @@ const server = net.createServer(function onClient(client) { } }); -server.listen(0, common.localhostIPv4, function() { - let nbClientsEnded = 0; +server.listen(0, common.localhostIPv4, common.mustCall(() => { + const countdown = new Countdown(2, common.mustCall(() => server.close())); - function addEndedClient(client) { - ++nbClientsEnded; - if (nbClientsEnded === 2) { - server.close(); - } + { + const client = net.connect({ port: server.address().port }); + client.on('end', () => countdown.dec()); } - const client1 = net.connect({ port: this.address().port }); - client1.on('end', addEndedClient); - - const client2 = net.connect({ port: this.address().port }); - client2.on('end', addEndedClient); -}); + { + const client = net.connect({ port: server.address().port }); + client.on('end', () => countdown.dec()); + } +})); diff --git a/test/parallel/test-timers-unref-leak.js b/test/parallel/test-timers-unref-leak.js index 8eef00dd4ffe92..afecf7f15ce1b5 100644 --- a/test/parallel/test-timers-unref-leak.js +++ b/test/parallel/test-timers-unref-leak.js @@ -1,27 +1,14 @@ 'use strict'; -require('../common'); -const assert = require('assert'); +const common = require('../common'); -let called = 0; -let closed = 0; - -const timeout = setTimeout(function() { - called++; -}, 10); +const timeout = setTimeout(common.mustCall(), 10); timeout.unref(); // Wrap `close` method to check if the handle was closed const close = timeout._handle.close; -timeout._handle.close = function() { - closed++; +timeout._handle.close = common.mustCall(function() { return close.apply(this, arguments); -}; +}); // Just to keep process alive and let previous timer's handle die -setTimeout(function() { -}, 50); - -process.on('exit', function() { - assert.strictEqual(called, 1); - assert.strictEqual(closed, 1); -}); +setTimeout(() => {}, 50); diff --git a/test/parallel/test-timers-unref.js b/test/parallel/test-timers-unref.js index aaa43720f6661c..e4bca54b7d7b03 100644 --- a/test/parallel/test-timers-unref.js +++ b/test/parallel/test-timers-unref.js @@ -1,59 +1,54 @@ 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); -let interval_fired = false; -let timeout_fired = false; let unref_interval = false; let unref_timer = false; -let unref_callbacks = 0; let checks = 0; const LONG_TIME = 10 * 1000; const SHORT_TIME = 100; -assert.doesNotThrow(function() { +assert.doesNotThrow(() => { setTimeout(() => {}, 10).unref().ref().unref(); }, 'ref and unref are chainable'); -assert.doesNotThrow(function() { +assert.doesNotThrow(() => { setInterval(() => {}, 10).unref().ref().unref(); }, 'ref and unref are chainable'); -setInterval(function() { - interval_fired = true; -}, LONG_TIME).unref(); +setInterval(common.mustNotCall('Interval should not fire'), LONG_TIME).unref(); +setTimeout(common.mustNotCall('Timer should not fire'), LONG_TIME).unref(); -setTimeout(function() { - timeout_fired = true; -}, LONG_TIME).unref(); - -const interval = setInterval(function() { +const interval = setInterval(common.mustCall(() => { unref_interval = true; clearInterval(interval); -}, SHORT_TIME); +}), SHORT_TIME); interval.unref(); -setTimeout(function() { +setTimeout(common.mustCall(() => { unref_timer = true; -}, SHORT_TIME).unref(); +}), SHORT_TIME).unref(); -const check_unref = setInterval(function() { +const check_unref = setInterval(() => { if (checks > 5 || (unref_interval && unref_timer)) clearInterval(check_unref); checks += 1; }, 100); -setTimeout(function() { - unref_callbacks++; - this.unref(); -}, SHORT_TIME); +{ + const timeout = + setTimeout(common.mustCall(() => { + timeout.unref(); + }), SHORT_TIME); +} -// Should not timeout the test -setInterval(function() { - this.unref(); -}, SHORT_TIME); +{ + // Should not timeout the test + const timeout = + setInterval(() => timeout.unref(), SHORT_TIME); +} // Should not assert on args.Holder()->InternalFieldCount() > 0. See #4261. { @@ -61,16 +56,3 @@ setInterval(function() { process.nextTick(t.unref.bind({})); process.nextTick(t.unref.bind(t)); } - -process.on('exit', function() { - assert.strictEqual(interval_fired, false, - 'Interval should not fire'); - assert.strictEqual(timeout_fired, false, - 'Timeout should not fire'); - assert.strictEqual(unref_timer, true, - 'An unrefd timeout should still fire'); - assert.strictEqual(unref_interval, true, - 'An unrefd interval should still fire'); - assert.strictEqual(unref_callbacks, 1, - 'Callback should only run once'); -}); diff --git a/test/parallel/test-timers-unrefd-interval-still-fires.js b/test/parallel/test-timers-unrefd-interval-still-fires.js index bf16013f004965..a9e9af84304217 100644 --- a/test/parallel/test-timers-unrefd-interval-still-fires.js +++ b/test/parallel/test-timers-unrefd-interval-still-fires.js @@ -5,23 +5,20 @@ const common = require('../common'); const TEST_DURATION = common.platformTimeout(1000); -const N = 3; -let nbIntervalFired = 0; +let N = 3; -const keepOpen = setTimeout(() => { - console.error('[FAIL] Interval fired %d/%d times.', nbIntervalFired, N); - throw new Error('Test timed out. keepOpen was not canceled.'); -}, TEST_DURATION); +const keepOpen = + setTimeout( + common.mustNotCall('Test timed out. keepOpen was not canceled.'), + TEST_DURATION); -const timer = setInterval(() => { - ++nbIntervalFired; - if (nbIntervalFired === N) { +const timer = setInterval(common.mustCall(() => { + if (--N === 0) { clearInterval(timer); - timer._onTimeout = () => { - throw new Error('Unrefd interval fired after being cleared.'); - }; + timer._onTimeout = + common.mustNotCall('Unrefd interal fired after being cleared'); clearTimeout(keepOpen); } -}, 1); +}, N), 1); timer.unref(); diff --git a/test/parallel/test-timers-unrefed-in-beforeexit.js b/test/parallel/test-timers-unrefed-in-beforeexit.js index 530d97674d8bf7..a38b55bf45d599 100644 --- a/test/parallel/test-timers-unrefed-in-beforeexit.js +++ b/test/parallel/test-timers-unrefed-in-beforeexit.js @@ -1,20 +1,7 @@ 'use strict'; -require('../common'); -const assert = require('assert'); +const common = require('../common'); -let once = 0; - -process.on('beforeExit', () => { - if (once > 1) - throw new RangeError('beforeExit should only have been called once!'); - - setTimeout(() => {}, 1).unref(); - once++; -}); - -process.on('exit', (code) => { - if (code !== 0) return; - - assert.strictEqual(once, 1); -}); +process.on('beforeExit', common.mustCall(() => { + setTimeout(common.mustNotCall(), 1).unref(); +})); diff --git a/test/parallel/test-timers-zero-timeout.js b/test/parallel/test-timers-zero-timeout.js index 9728685c43277b..c835b4abcf0b2e 100644 --- a/test/parallel/test-timers-zero-timeout.js +++ b/test/parallel/test-timers-zero-timeout.js @@ -15,18 +15,14 @@ const assert = require('assert'); } { - let ncalled = 0; + let ncalled = 3; - const iv = setInterval(f, 0, 'foo', 'bar', 'baz'); - - function f(a, b, c) { + const f = common.mustCall((a, b, c) => { assert.strictEqual(a, 'foo'); assert.strictEqual(b, 'bar'); assert.strictEqual(c, 'baz'); - if (++ncalled === 3) clearTimeout(iv); - } + if (--ncalled === 0) clearTimeout(iv); + }, ncalled); - process.on('exit', function() { - assert.strictEqual(ncalled, 3); - }); + const iv = setInterval(f, 0, 'foo', 'bar', 'baz'); } From 28b77d1f8be8a81a0ae53512be963707533ca046 Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Sun, 6 Aug 2017 19:47:32 -0700 Subject: [PATCH 23/92] test: improve check in test-os MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The check for `os.networkInterfaces()` in `test-os.js` may be too strict. It's apparently possible for a machine to be configured with multiple IPv4 loopback interfaces. Increase specificity of filter to check on only the object we expect. PR-URL: https://github.com/nodejs/node/pull/14655 Fixes: https://github.com/nodejs/node/issues/14654 Reviewed-By: Luigi Pinca Reviewed-By: Tobias Nießen Reviewed-By: Colin Ihrig Reviewed-By: Refael Ackermann Reviewed-By: James M Snell --- test/parallel/test-os.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/parallel/test-os.js b/test/parallel/test-os.js index db5a137eb54ef4..f3c0082f553c1d 100644 --- a/test/parallel/test-os.js +++ b/test/parallel/test-os.js @@ -104,7 +104,8 @@ console.error(interfaces); switch (platform) { case 'linux': { - const filter = (e) => e.address === '127.0.0.1'; + const filter = + (e) => e.address === '127.0.0.1' && e.netmask === '255.0.0.0'; const actual = interfaces.lo.filter(filter); const expected = [{ address: '127.0.0.1', netmask: '255.0.0.0', mac: '00:00:00:00:00:00', family: 'IPv4', From 9d8464161e513a2b1e4f23ad57de82aedd7bb589 Mon Sep 17 00:00:00 2001 From: Nick Stanish Date: Tue, 8 Aug 2017 22:48:47 -0500 Subject: [PATCH 24/92] test: fix conversion of microseconds in test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/14706 Fixes: https://github.com/nodejs/node/issues/8728 Reviewed-By: Rich Trott Reviewed-By: Luigi Pinca Reviewed-By: Tobias Nießen Reviewed-By: Colin Ihrig Reviewed-By: Timothy Gu --- test/pummel/test-process-cpuUsage.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/pummel/test-process-cpuUsage.js b/test/pummel/test-process-cpuUsage.js index 20b2fadef9fae0..1d5aa861b64ad8 100644 --- a/test/pummel/test-process-cpuUsage.js +++ b/test/pummel/test-process-cpuUsage.js @@ -17,14 +17,14 @@ while (Date.now() - now < RUN_FOR_MS); // Get a diff reading from when we started. const diff = process.cpuUsage(start); -const MICROSECONDS_PER_SECOND = 1000 * 1000; +const MICROSECONDS_PER_MILLISECOND = 1000; // Diff usages should be >= 0, <= ~RUN_FOR_MS millis. // Let's be generous with the slop factor, defined above, in case other things // are happening on this CPU. The <= check may be invalid if the node process // is making use of multiple CPUs, in which case, just remove it. assert(diff.user >= 0); -assert(diff.user <= SLOP_FACTOR * RUN_FOR_MS * MICROSECONDS_PER_SECOND); +assert(diff.user <= SLOP_FACTOR * RUN_FOR_MS * MICROSECONDS_PER_MILLISECOND); assert(diff.system >= 0); -assert(diff.system <= SLOP_FACTOR * RUN_FOR_MS * MICROSECONDS_PER_SECOND); +assert(diff.system <= SLOP_FACTOR * RUN_FOR_MS * MICROSECONDS_PER_MILLISECOND); From c0e47e4f220a89d34a151b5105d7f76ef435655a Mon Sep 17 00:00:00 2001 From: Daniel Bevenius Date: Mon, 3 Jul 2017 07:56:43 +0200 Subject: [PATCH 25/92] doc: fix order of AtExit callbacks in addons.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The sanity_check AtExit callback needs to come last to verify that the other callbacks have been completed. This was not noticed before as this code was not been executed. PR-URL: https://github.com/nodejs/node/pull/14048 Reviewed-By: Michaël Zasso --- doc/api/addons.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/addons.md b/doc/api/addons.md index 4d29b718ab9dcd..d1c9036f54183d 100644 --- a/doc/api/addons.md +++ b/doc/api/addons.md @@ -1090,10 +1090,10 @@ static void sanity_check(void*) { } void init(Local exports) { - AtExit(sanity_check); AtExit(at_exit_cb2, cookie); AtExit(at_exit_cb2, cookie); AtExit(at_exit_cb1, exports->GetIsolate()); + AtExit(sanity_check); } NODE_MODULE(addon, init) From b5904a20548f71e17d8cb900e02250b3821ce4a2 Mon Sep 17 00:00:00 2001 From: Daniel Bevenius Date: Mon, 3 Jul 2017 06:58:45 +0200 Subject: [PATCH 26/92] doc: remove undef NDEBUG from addons.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When working on commit 0d95a0b60a87533c54b517d132e16401fe28909b ("test: remove undef NDEBUG from at-exit addons test) I searched for usages of undef NDEBUG but did not include the doc directory (but I did include the test directory) and missed this one. Commit 1f02569f8db9cb0101807df4982534738f0161b2 ("tools: fix tools/addon-verify.js") enables the code in the "AtExit" section to be included in the test/addons diretory and this code will again be tested. PR-URL: https://github.com/nodejs/node/pull/14048 Reviewed-By: Michaël Zasso --- doc/api/addons.md | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/api/addons.md b/doc/api/addons.md index d1c9036f54183d..f8f1272c72c068 100644 --- a/doc/api/addons.md +++ b/doc/api/addons.md @@ -1053,7 +1053,6 @@ The following `addon.cc` implements AtExit: ```cpp // addon.cc -#undef NDEBUG #include #include #include From ca61f3bd803691cc75a97d6b77436ba9e0f4199c Mon Sep 17 00:00:00 2001 From: Daniel Bevenius Date: Mon, 3 Jul 2017 06:27:58 +0200 Subject: [PATCH 27/92] tools: fix tools/addon-verify.js MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current implementation of addon-verify.js is including the code for the "Function arguments" section in test/addons/01_callbacks and there is no directory generated or the "Function arguments section". This continues and leads to the last section, "AtExit", code to be excluded. There is an test/addons/07_atexit_hooks but it contains code from the "Passing wrapped objects around" section. This commit modifies addon-verify to associate headers with code and then iterates over the set and generates the files as a separate step. PR-URL: https://github.com/nodejs/node/pull/14048 Reviewed-By: Michaël Zasso --- doc/api/addons.md | 2 +- tools/doc/addon-verify.js | 36 ++++++++++++++++++------------------ 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/doc/api/addons.md b/doc/api/addons.md index f8f1272c72c068..09049e3dbd8477 100644 --- a/doc/api/addons.md +++ b/doc/api/addons.md @@ -1104,7 +1104,7 @@ Test in JavaScript by running: ```js // test.js -const addon = require('./build/Release/addon'); +require('./build/Release/addon'); ``` [bindings]: https://github.com/TooTallNate/node-bindings diff --git a/tools/doc/addon-verify.js b/tools/doc/addon-verify.js index f681b0a90eb2a6..14953be66a6ce3 100644 --- a/tools/doc/addon-verify.js +++ b/tools/doc/addon-verify.js @@ -11,29 +11,29 @@ const verifyDir = path.resolve(rootDir, 'test', 'addons'); const contents = fs.readFileSync(doc).toString(); const tokens = marked.lexer(contents); -let files = null; let id = 0; -// Just to make sure that all examples will be processed -tokens.push({ type: 'heading' }); - -for (var i = 0; i < tokens.length; i++) { - var token = tokens[i]; +let currentHeader; +const addons = {}; +tokens.forEach((token) => { if (token.type === 'heading' && token.text) { - const blockName = token.text; - if (files && Object.keys(files).length !== 0) { - verifyFiles(files, - blockName, - console.log.bind(null, 'wrote'), - function(err) { if (err) throw err; }); - } - files = {}; - } else if (token.type === 'code') { + currentHeader = token.text; + addons[currentHeader] = { + files: {} + }; + } + if (token.type === 'code') { var match = token.text.match(/^\/\/\s+(.*\.(?:cc|h|js))[\r\n]/); - if (match === null) - continue; - files[match[1]] = token.text; + if (match !== null) { + addons[currentHeader].files[match[1]] = token.text; + } } +}); +for (var header in addons) { + verifyFiles(addons[header].files, + header, + console.log.bind(null, 'wrote'), + function(err) { if (err) throw err; }); } function once(fn) { From 67074113dc2d17635408c0e27666f379900521cc Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Fri, 21 Jul 2017 13:26:50 +0200 Subject: [PATCH 28/92] http: reset stream to unconsumed in `unconsume()` Reset the underlying socket of an HTTP stream to be marked as unconsume after the HTTP parser no longer owns it. Fixes: https://github.com/nodejs/node/issues/14407 PR-URL: https://github.com/nodejs/node/pull/14410 Reviewed-By: Ben Noordhuis Reviewed-By: James M Snell Reviewed-By: Colin Ihrig Reviewed-By: Colin Ihrig Reviewed-By: Luigi Pinca --- src/node_http_parser.cc | 1 + src/stream_base.h | 5 ++++ .../test-http-upgrade-reconsume-stream.js | 29 +++++++++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 test/parallel/test-http-upgrade-reconsume-stream.js diff --git a/src/node_http_parser.cc b/src/node_http_parser.cc index 24152e1e119ffc..45d54ab548f862 100644 --- a/src/node_http_parser.cc +++ b/src/node_http_parser.cc @@ -503,6 +503,7 @@ class Parser : public AsyncWrap { stream->set_alloc_cb(parser->prev_alloc_cb_); stream->set_read_cb(parser->prev_read_cb_); + stream->Unconsume(); } parser->prev_alloc_cb_.clear(); diff --git a/src/stream_base.h b/src/stream_base.h index 35929750bfbc54..56cd4129d8a373 100644 --- a/src/stream_base.h +++ b/src/stream_base.h @@ -234,6 +234,11 @@ class StreamBase : public StreamResource { consumed_ = true; } + inline void Unconsume() { + CHECK_EQ(consumed_, true); + consumed_ = false; + } + template inline Outer* Cast() { return static_cast(Cast()); } diff --git a/test/parallel/test-http-upgrade-reconsume-stream.js b/test/parallel/test-http-upgrade-reconsume-stream.js new file mode 100644 index 00000000000000..e712ea647b3ad9 --- /dev/null +++ b/test/parallel/test-http-upgrade-reconsume-stream.js @@ -0,0 +1,29 @@ +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const tls = require('tls'); +const http = require('http'); + +// Tests that, after the HTTP parser stopped owning a socket that emits an +// 'upgrade' event, another C++ stream can start owning it (e.g. a TLSSocket). + +const server = http.createServer(common.mustNotCall()); + +server.on('upgrade', common.mustCall((request, socket, head) => { + // This should not crash. + new tls.TLSSocket(socket); + server.close(); + socket.destroy(); +})); + +server.listen(0, common.mustCall(() => { + http.get({ + port: server.address().port, + headers: { + 'Connection': 'Upgrade', + 'Upgrade': 'websocket' + } + }).on('error', () => {}); +})); From 4fb755c432603ec064cc0cf92f8f6e1838fce9f5 Mon Sep 17 00:00:00 2001 From: Prakash Palaniappan Date: Thu, 27 Jul 2017 09:40:15 -0400 Subject: [PATCH 29/92] test: set module loading error for aix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In test/parallel/test-module-loading-error.js, an attempt is made to load a text file as a native executable. This results in an error message in a platform specific manner. AIX was not included in the list of platforms. This fix introduces the AIX error messages. PR-URL: https://github.com/nodejs/node/pull/14511 Reviewed-By: Tobias Nießen Reviewed-By: James M Snell Reviewed-By: Luigi Pinca Reviewed-By: Colin Ihrig Reviewed-By: Gireesh Punathil Reviewed-By: Gibson Fahnestock --- test/parallel/test-module-loading-error.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/parallel/test-module-loading-error.js b/test/parallel/test-module-loading-error.js index cf6ce7e4bdeee8..80918d5fdb0eb3 100644 --- a/test/parallel/test-module-loading-error.js +++ b/test/parallel/test-module-loading-error.js @@ -8,7 +8,9 @@ const error_desc = { win32: ['%1 is not a valid Win32 application'], linux: ['file too short', 'Exec format error'], sunos: ['unknown file type', 'not an ELF file'], - darwin: ['file too short'] + darwin: ['file too short'], + aix: ['Cannot load module', + 'Cannot run a file that does not have a valid format.'] }; const dlerror_msg = error_desc[process.platform]; From 9ed2c4cb0eb1e25b2c62f97d5434fd73103a10e5 Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Thu, 3 Aug 2017 14:10:37 -0700 Subject: [PATCH 30/92] test: add block scoping to test-readline-interface Use block-scoping in test-readline-interface to avoid side effects and make tests more modular. (Some contain race conditions and will need to be moved to the sequential directory if they can't be refactored to avoid the race condition.) Backport-PR-URL: https://github.com/nodejs/node/pull/14748 Backport-Reviewed-By: Anna Henningsen PR-URL: https://github.com/nodejs/node/pull/14615 Reviewed-By: Colin Ihrig Reviewed-By: Yuta Hiroto Reviewed-By: James M Snell --- test/parallel/test-readline-interface.js | 726 +++++++++++++---------- 1 file changed, 405 insertions(+), 321 deletions(-) diff --git a/test/parallel/test-readline-interface.js b/test/parallel/test-readline-interface.js index c1f1002d3e201e..a042514a9eea21 100644 --- a/test/parallel/test-readline-interface.js +++ b/test/parallel/test-readline-interface.js @@ -63,177 +63,222 @@ function isWarned(emitter) { } [ true, false ].forEach(function(terminal) { - let fi; - let rli; - let called; - // disable history - fi = new FakeInput(); - rli = new readline.Interface({ input: fi, output: fi, terminal: terminal, - historySize: 0 }); - assert.strictEqual(rli.historySize, 0); + { + const fi = new FakeInput(); + const rli = new readline.Interface( + { input: fi, output: fi, terminal: terminal, historySize: 0 } + ); + assert.strictEqual(rli.historySize, 0); - fi.emit('data', 'asdf\n'); - assert.deepStrictEqual(rli.history, terminal ? [] : undefined); - rli.close(); + fi.emit('data', 'asdf\n'); + assert.deepStrictEqual(rli.history, terminal ? [] : undefined); + rli.close(); + } // default history size 30 - fi = new FakeInput(); - rli = new readline.Interface({ input: fi, output: fi, terminal: terminal}); - assert.strictEqual(rli.historySize, 30); + { + const fi = new FakeInput(); + const rli = new readline.Interface( + { input: fi, output: fi, terminal: terminal } + ); + assert.strictEqual(rli.historySize, 30); - fi.emit('data', 'asdf\n'); - assert.deepStrictEqual(rli.history, terminal ? ['asdf'] : undefined); - rli.close(); + fi.emit('data', 'asdf\n'); + assert.deepStrictEqual(rli.history, terminal ? ['asdf'] : undefined); + rli.close(); + } // sending a full line - fi = new FakeInput(); - rli = new readline.Interface({ input: fi, output: fi, terminal: terminal }); - called = false; - rli.on('line', function(line) { - called = true; - assert.strictEqual(line, 'asdf'); - }); - fi.emit('data', 'asdf\n'); - assert.ok(called); + { + const fi = new FakeInput(); + const rli = new readline.Interface( + { input: fi, output: fi, terminal: terminal } + ); + let called = false; + rli.on('line', function(line) { + called = true; + assert.strictEqual(line, 'asdf'); + }); + fi.emit('data', 'asdf\n'); + assert.ok(called); + } // sending a blank line - fi = new FakeInput(); - rli = new readline.Interface({ input: fi, output: fi, terminal: terminal }); - called = false; - rli.on('line', function(line) { - called = true; - assert.strictEqual(line, ''); - }); - fi.emit('data', '\n'); - assert.ok(called); + { + const fi = new FakeInput(); + const rli = new readline.Interface( + { input: fi, output: fi, terminal: terminal } + ); + let called = false; + rli.on('line', function(line) { + called = true; + assert.strictEqual(line, ''); + }); + fi.emit('data', '\n'); + assert.ok(called); + } // sending a single character with no newline - fi = new FakeInput(); - rli = new readline.Interface(fi, {}); - called = false; - rli.on('line', function(line) { - called = true; - }); - fi.emit('data', 'a'); - assert.ok(!called); - rli.close(); + { + const fi = new FakeInput(); + const rli = new readline.Interface(fi, {}); + let called = false; + rli.on('line', function(line) { + called = true; + }); + fi.emit('data', 'a'); + assert.ok(!called); + rli.close(); + } // sending a single character with no newline and then a newline - fi = new FakeInput(); - rli = new readline.Interface({ input: fi, output: fi, terminal: terminal }); - called = false; - rli.on('line', function(line) { - called = true; - assert.strictEqual(line, 'a'); - }); - fi.emit('data', 'a'); - assert.ok(!called); - fi.emit('data', '\n'); - assert.ok(called); - rli.close(); + { + const fi = new FakeInput(); + const rli = new readline.Interface( + { input: fi, output: fi, terminal: terminal } + ); + let called = false; + rli.on('line', function(line) { + called = true; + assert.strictEqual(line, 'a'); + }); + fi.emit('data', 'a'); + assert.ok(!called); + fi.emit('data', '\n'); + assert.ok(called); + rli.close(); + } // sending multiple newlines at once - fi = new FakeInput(); - rli = new readline.Interface({ input: fi, output: fi, terminal: terminal }); - let expectedLines = ['foo', 'bar', 'baz']; - let callCount = 0; - rli.on('line', function(line) { - assert.strictEqual(line, expectedLines[callCount]); - callCount++; - }); - fi.emit('data', `${expectedLines.join('\n')}\n`); - assert.strictEqual(callCount, expectedLines.length); - rli.close(); + { + const fi = new FakeInput(); + const rli = new readline.Interface( + { input: fi, output: fi, terminal: terminal } + ); + const expectedLines = ['foo', 'bar', 'baz']; + let callCount = 0; + rli.on('line', function(line) { + assert.strictEqual(line, expectedLines[callCount]); + callCount++; + }); + fi.emit('data', `${expectedLines.join('\n')}\n`); + assert.strictEqual(callCount, expectedLines.length); + rli.close(); + } // sending multiple newlines at once that does not end with a new line - fi = new FakeInput(); - rli = new readline.Interface({ input: fi, output: fi, terminal: terminal }); - expectedLines = ['foo', 'bar', 'baz', 'bat']; - callCount = 0; - rli.on('line', function(line) { - assert.strictEqual(line, expectedLines[callCount]); - callCount++; - }); - fi.emit('data', expectedLines.join('\n')); - assert.strictEqual(callCount, expectedLines.length - 1); - rli.close(); + { + const fi = new FakeInput(); + const rli = new readline.Interface( + { input: fi, output: fi, terminal: terminal } + ); + const expectedLines = ['foo', 'bar', 'baz', 'bat']; + let callCount = 0; + rli.on('line', function(line) { + assert.strictEqual(line, expectedLines[callCount]); + callCount++; + }); + fi.emit('data', expectedLines.join('\n')); + assert.strictEqual(callCount, expectedLines.length - 1); + rli.close(); + } // sending multiple newlines at once that does not end with a new(empty) // line and a `end` event - fi = new FakeInput(); - rli = new readline.Interface({ input: fi, output: fi, terminal: terminal }); - expectedLines = ['foo', 'bar', 'baz', '']; - callCount = 0; - rli.on('line', function(line) { - assert.strictEqual(line, expectedLines[callCount]); - callCount++; - }); - rli.on('close', function() { - callCount++; - }); - fi.emit('data', expectedLines.join('\n')); - fi.emit('end'); - assert.strictEqual(callCount, expectedLines.length); - rli.close(); + { + const fi = new FakeInput(); + const rli = new readline.Interface( + { input: fi, output: fi, terminal: terminal } + ); + const expectedLines = ['foo', 'bar', 'baz', '']; + let callCount = 0; + rli.on('line', function(line) { + assert.strictEqual(line, expectedLines[callCount]); + callCount++; + }); + rli.on('close', function() { + callCount++; + }); + fi.emit('data', expectedLines.join('\n')); + fi.emit('end'); + assert.strictEqual(callCount, expectedLines.length); + rli.close(); + } // sending multiple newlines at once that does not end with a new line // and a `end` event(last line is) // \r\n should emit one line event, not two - fi = new FakeInput(); - rli = new readline.Interface({ input: fi, output: fi, terminal: terminal }); - expectedLines = ['foo', 'bar', 'baz', 'bat']; - callCount = 0; - rli.on('line', function(line) { - assert.strictEqual(line, expectedLines[callCount]); - callCount++; - }); - fi.emit('data', expectedLines.join('\r\n')); - assert.strictEqual(callCount, expectedLines.length - 1); - rli.close(); + { + const fi = new FakeInput(); + const rli = new readline.Interface( + { input: fi, output: fi, terminal: terminal } + ); + const expectedLines = ['foo', 'bar', 'baz', 'bat']; + let callCount = 0; + rli.on('line', function(line) { + assert.strictEqual(line, expectedLines[callCount]); + callCount++; + }); + fi.emit('data', expectedLines.join('\r\n')); + assert.strictEqual(callCount, expectedLines.length - 1); + rli.close(); + } // \r\n should emit one line event when split across multiple writes. - fi = new FakeInput(); - rli = new readline.Interface({ input: fi, output: fi, terminal: terminal }); - expectedLines = ['foo', 'bar', 'baz', 'bat']; - callCount = 0; - rli.on('line', function(line) { - assert.strictEqual(line, expectedLines[callCount]); - callCount++; - }); - expectedLines.forEach(function(line) { - fi.emit('data', `${line}\r`); - fi.emit('data', '\n'); - }); - assert.strictEqual(callCount, expectedLines.length); - rli.close(); + { + const fi = new FakeInput(); + const rli = new readline.Interface( + { input: fi, output: fi, terminal: terminal } + ); + const expectedLines = ['foo', 'bar', 'baz', 'bat']; + let callCount = 0; + rli.on('line', function(line) { + assert.strictEqual(line, expectedLines[callCount]); + callCount++; + }); + expectedLines.forEach(function(line) { + fi.emit('data', `${line}\r`); + fi.emit('data', '\n'); + }); + assert.strictEqual(callCount, expectedLines.length); + rli.close(); + } // \r should behave like \n when alone - fi = new FakeInput(); - rli = new readline.Interface({ input: fi, output: fi, terminal: true }); - expectedLines = ['foo', 'bar', 'baz', 'bat']; - callCount = 0; - rli.on('line', function(line) { - assert.strictEqual(line, expectedLines[callCount]); - callCount++; - }); - fi.emit('data', expectedLines.join('\r')); - assert.strictEqual(callCount, expectedLines.length - 1); - rli.close(); + { + const fi = new FakeInput(); + const rli = new readline.Interface( + { input: fi, output: fi, terminal: true } + ); + const expectedLines = ['foo', 'bar', 'baz', 'bat']; + let callCount = 0; + rli.on('line', function(line) { + assert.strictEqual(line, expectedLines[callCount]); + callCount++; + }); + fi.emit('data', expectedLines.join('\r')); + assert.strictEqual(callCount, expectedLines.length - 1); + rli.close(); + } // \r at start of input should output blank line - fi = new FakeInput(); - rli = new readline.Interface({ input: fi, output: fi, terminal: true }); - expectedLines = ['', 'foo' ]; - callCount = 0; - rli.on('line', function(line) { - assert.strictEqual(line, expectedLines[callCount]); - callCount++; - }); - fi.emit('data', '\rfoo\r'); - assert.strictEqual(callCount, expectedLines.length); - rli.close(); + { + const fi = new FakeInput(); + const rli = new readline.Interface( + { input: fi, output: fi, terminal: true } + ); + const expectedLines = ['', 'foo' ]; + let callCount = 0; + rli.on('line', function(line) { + assert.strictEqual(line, expectedLines[callCount]); + callCount++; + }); + fi.emit('data', '\rfoo\r'); + assert.strictEqual(callCount, expectedLines.length); + rli.close(); + } // Emit two line events when the delay // between \r and \n exceeds crlfDelay @@ -307,189 +352,221 @@ function isWarned(emitter) { // \t when there is no completer function should behave like an ordinary // character - fi = new FakeInput(); - rli = new readline.Interface({ input: fi, output: fi, terminal: true }); - called = false; - rli.on('line', function(line) { - assert.strictEqual(line, '\t'); - assert.strictEqual(called, false); - called = true; - }); - fi.emit('data', '\t'); - fi.emit('data', '\n'); - assert.ok(called); - rli.close(); + { + const fi = new FakeInput(); + const rli = new readline.Interface( + { input: fi, output: fi, terminal: true } + ); + let called = false; + rli.on('line', function(line) { + assert.strictEqual(line, '\t'); + assert.strictEqual(called, false); + called = true; + }); + fi.emit('data', '\t'); + fi.emit('data', '\n'); + assert.ok(called); + rli.close(); + } // \t does not become part of the input when there is a completer function - fi = new FakeInput(); - const completer = (line) => [[], line]; - rli = new readline.Interface({ - input: fi, - output: fi, - terminal: true, - completer: completer - }); - called = false; - rli.on('line', function(line) { - assert.strictEqual(line, 'foo'); - assert.strictEqual(called, false); - called = true; - }); - for (const character of '\tfo\to\t') { - fi.emit('data', character); + { + const fi = new FakeInput(); + const completer = (line) => [[], line]; + const rli = new readline.Interface({ + input: fi, + output: fi, + terminal: true, + completer: completer + }); + let called = false; + rli.on('line', function(line) { + assert.strictEqual(line, 'foo'); + assert.strictEqual(called, false); + called = true; + }); + for (const character of '\tfo\to\t') { + fi.emit('data', character); + } + fi.emit('data', '\n'); + assert.ok(called); + rli.close(); } - fi.emit('data', '\n'); - assert.ok(called); - rli.close(); // constructor throws if completer is not a function or undefined - fi = new FakeInput(); - assert.throws(function() { - readline.createInterface({ - input: fi, - completer: 'string is not valid' - }); - }, function(err) { - if (err instanceof TypeError) { - if (/Argument "completer" must be a function/.test(err)) { - return true; + { + const fi = new FakeInput(); + assert.throws(function() { + readline.createInterface({ + input: fi, + completer: 'string is not valid' + }); + }, function(err) { + if (err instanceof TypeError) { + if (/Argument "completer" must be a function/.test(err)) { + return true; + } } - } - return false; - }); + return false; + }); + } // duplicate lines are removed from history when // `options.removeHistoryDuplicates` is `true` - fi = new FakeInput(); - rli = new readline.Interface({ - input: fi, - output: fi, - terminal: true, - removeHistoryDuplicates: true - }); - expectedLines = ['foo', 'bar', 'baz', 'bar', 'bat', 'bat']; - callCount = 0; - rli.on('line', function(line) { - assert.strictEqual(line, expectedLines[callCount]); - callCount++; - }); - fi.emit('data', `${expectedLines.join('\n')}\n`); - assert.strictEqual(callCount, expectedLines.length); - fi.emit('keypress', '.', { name: 'up' }); // 'bat' - assert.strictEqual(rli.line, expectedLines[--callCount]); - fi.emit('keypress', '.', { name: 'up' }); // 'bar' - assert.notStrictEqual(rli.line, expectedLines[--callCount]); - assert.strictEqual(rli.line, expectedLines[--callCount]); - fi.emit('keypress', '.', { name: 'up' }); // 'baz' - assert.strictEqual(rli.line, expectedLines[--callCount]); - fi.emit('keypress', '.', { name: 'up' }); // 'foo' - assert.notStrictEqual(rli.line, expectedLines[--callCount]); - assert.strictEqual(rli.line, expectedLines[--callCount]); - assert.strictEqual(callCount, 0); - rli.close(); + { + const fi = new FakeInput(); + const rli = new readline.Interface({ + input: fi, + output: fi, + terminal: true, + removeHistoryDuplicates: true + }); + const expectedLines = ['foo', 'bar', 'baz', 'bar', 'bat', 'bat']; + let callCount = 0; + rli.on('line', function(line) { + assert.strictEqual(line, expectedLines[callCount]); + callCount++; + }); + fi.emit('data', `${expectedLines.join('\n')}\n`); + assert.strictEqual(callCount, expectedLines.length); + fi.emit('keypress', '.', { name: 'up' }); // 'bat' + assert.strictEqual(rli.line, expectedLines[--callCount]); + fi.emit('keypress', '.', { name: 'up' }); // 'bar' + assert.notStrictEqual(rli.line, expectedLines[--callCount]); + assert.strictEqual(rli.line, expectedLines[--callCount]); + fi.emit('keypress', '.', { name: 'up' }); // 'baz' + assert.strictEqual(rli.line, expectedLines[--callCount]); + fi.emit('keypress', '.', { name: 'up' }); // 'foo' + assert.notStrictEqual(rli.line, expectedLines[--callCount]); + assert.strictEqual(rli.line, expectedLines[--callCount]); + assert.strictEqual(callCount, 0); + rli.close(); + } // duplicate lines are not removed from history when // `options.removeHistoryDuplicates` is `false` - fi = new FakeInput(); - rli = new readline.Interface({ - input: fi, - output: fi, - terminal: true, - removeHistoryDuplicates: false - }); - expectedLines = ['foo', 'bar', 'baz', 'bar', 'bat', 'bat']; - callCount = 0; - rli.on('line', function(line) { - assert.strictEqual(line, expectedLines[callCount]); - callCount++; - }); - fi.emit('data', `${expectedLines.join('\n')}\n`); - assert.strictEqual(callCount, expectedLines.length); - fi.emit('keypress', '.', { name: 'up' }); // 'bat' - assert.strictEqual(rli.line, expectedLines[--callCount]); - fi.emit('keypress', '.', { name: 'up' }); // 'bar' - assert.notStrictEqual(rli.line, expectedLines[--callCount]); - assert.strictEqual(rli.line, expectedLines[--callCount]); - fi.emit('keypress', '.', { name: 'up' }); // 'baz' - assert.strictEqual(rli.line, expectedLines[--callCount]); - fi.emit('keypress', '.', { name: 'up' }); // 'bar' - assert.strictEqual(rli.line, expectedLines[--callCount]); - fi.emit('keypress', '.', { name: 'up' }); // 'foo' - assert.strictEqual(rli.line, expectedLines[--callCount]); - assert.strictEqual(callCount, 0); - rli.close(); + { + const fi = new FakeInput(); + const rli = new readline.Interface({ + input: fi, + output: fi, + terminal: true, + removeHistoryDuplicates: false + }); + const expectedLines = ['foo', 'bar', 'baz', 'bar', 'bat', 'bat']; + let callCount = 0; + rli.on('line', function(line) { + assert.strictEqual(line, expectedLines[callCount]); + callCount++; + }); + fi.emit('data', `${expectedLines.join('\n')}\n`); + assert.strictEqual(callCount, expectedLines.length); + fi.emit('keypress', '.', { name: 'up' }); // 'bat' + assert.strictEqual(rli.line, expectedLines[--callCount]); + fi.emit('keypress', '.', { name: 'up' }); // 'bar' + assert.notStrictEqual(rli.line, expectedLines[--callCount]); + assert.strictEqual(rli.line, expectedLines[--callCount]); + fi.emit('keypress', '.', { name: 'up' }); // 'baz' + assert.strictEqual(rli.line, expectedLines[--callCount]); + fi.emit('keypress', '.', { name: 'up' }); // 'bar' + assert.strictEqual(rli.line, expectedLines[--callCount]); + fi.emit('keypress', '.', { name: 'up' }); // 'foo' + assert.strictEqual(rli.line, expectedLines[--callCount]); + assert.strictEqual(callCount, 0); + rli.close(); + } // sending a multi-byte utf8 char over multiple writes - const buf = Buffer.from('☮', 'utf8'); - fi = new FakeInput(); - rli = new readline.Interface({ input: fi, output: fi, terminal: terminal }); - callCount = 0; - rli.on('line', function(line) { - callCount++; - assert.strictEqual(line, buf.toString('utf8')); - }); - [].forEach.call(buf, function(i) { - fi.emit('data', Buffer.from([i])); - }); - assert.strictEqual(callCount, 0); - fi.emit('data', '\n'); - assert.strictEqual(callCount, 1); - rli.close(); + { + const buf = Buffer.from('☮', 'utf8'); + const fi = new FakeInput(); + const rli = new readline.Interface( + { input: fi, output: fi, terminal: terminal } + ); + let callCount = 0; + rli.on('line', function(line) { + callCount++; + assert.strictEqual(line, buf.toString('utf8')); + }); + [].forEach.call(buf, function(i) { + fi.emit('data', Buffer.from([i])); + }); + assert.strictEqual(callCount, 0); + fi.emit('data', '\n'); + assert.strictEqual(callCount, 1); + rli.close(); + } // Regression test for repl freeze, #1968: // check that nothing fails if 'keypress' event throws. - fi = new FakeInput(); - rli = new readline.Interface({ input: fi, output: fi, terminal: true }); - const keys = []; - fi.on('keypress', function(key) { - keys.push(key); - if (key === 'X') { - throw new Error('bad thing happened'); - } - }); - try { - fi.emit('data', 'fooX'); - } catch (e) { } - fi.emit('data', 'bar'); - assert.strictEqual(keys.join(''), 'fooXbar'); - rli.close(); + { + const fi = new FakeInput(); + const rli = new readline.Interface( + { input: fi, output: fi, terminal: true } + ); + const keys = []; + fi.on('keypress', function(key) { + keys.push(key); + if (key === 'X') { + throw new Error('bad thing happened'); + } + }); + try { + fi.emit('data', 'fooX'); + } catch (e) { } + fi.emit('data', 'bar'); + assert.strictEqual(keys.join(''), 'fooXbar'); + rli.close(); + } // calling readline without `new` - fi = new FakeInput(); - rli = readline.Interface({ input: fi, output: fi, terminal: terminal }); - called = false; - rli.on('line', function(line) { - called = true; - assert.strictEqual(line, 'asdf'); - }); - fi.emit('data', 'asdf\n'); - assert.ok(called); - rli.close(); + { + const fi = new FakeInput(); + const rli = readline.Interface( + { input: fi, output: fi, terminal: terminal } + ); + let called = false; + rli.on('line', function(line) { + called = true; + assert.strictEqual(line, 'asdf'); + }); + fi.emit('data', 'asdf\n'); + assert.ok(called); + rli.close(); + } if (terminal) { // question - fi = new FakeInput(); - rli = new readline.Interface({ input: fi, output: fi, terminal: terminal }); - expectedLines = ['foo']; - rli.question(expectedLines[0], function() { + { + const fi = new FakeInput(); + const rli = new readline.Interface( + { input: fi, output: fi, terminal: terminal } + ); + const expectedLines = ['foo']; + rli.question(expectedLines[0], function() { + rli.close(); + }); + const cursorPos = rli._getCursorPos(); + assert.strictEqual(cursorPos.rows, 0); + assert.strictEqual(cursorPos.cols, expectedLines[0].length); rli.close(); - }); - let cursorPos = rli._getCursorPos(); - assert.strictEqual(cursorPos.rows, 0); - assert.strictEqual(cursorPos.cols, expectedLines[0].length); - rli.close(); + } // sending a multi-line question - fi = new FakeInput(); - rli = new readline.Interface({ input: fi, output: fi, terminal: terminal }); - expectedLines = ['foo', 'bar']; - rli.question(expectedLines.join('\n'), function() { + { + const fi = new FakeInput(); + const rli = new readline.Interface( + { input: fi, output: fi, terminal: terminal } + ); + const expectedLines = ['foo', 'bar']; + rli.question(expectedLines.join('\n'), function() { + rli.close(); + }); + const cursorPos = rli._getCursorPos(); + assert.strictEqual(cursorPos.rows, expectedLines.length - 1); + assert.strictEqual(cursorPos.cols, expectedLines.slice(-1)[0].length); rli.close(); - }); - cursorPos = rli._getCursorPos(); - assert.strictEqual(cursorPos.rows, expectedLines.length - 1); - assert.strictEqual(cursorPos.cols, expectedLines.slice(-1)[0].length); - rli.close(); + } } // isFullWidthCodePoint() should return false for non-numeric values @@ -539,7 +616,10 @@ function isWarned(emitter) { assert.strictEqual(readline.getStringWidth('\u001b[31m\u001b[39m'), 0); assert.strictEqual(readline.getStringWidth('> '), 2); - assert.deepStrictEqual(fi.listeners(terminal ? 'keypress' : 'data'), []); + { + const fi = new FakeInput(); + assert.deepStrictEqual(fi.listeners(terminal ? 'keypress' : 'data'), []); + } // check EventEmitter memory leak for (let i = 0; i < 12; i++) { @@ -553,35 +633,39 @@ function isWarned(emitter) { } // can create a new readline Interface with a null output arugument - fi = new FakeInput(); - rli = new readline.Interface({input: fi, output: null, terminal: terminal }); + { + const fi = new FakeInput(); + const rli = new readline.Interface( + { input: fi, output: null, terminal: terminal } + ); - called = false; - rli.on('line', function(line) { - called = true; - assert.strictEqual(line, 'asdf'); - }); - fi.emit('data', 'asdf\n'); - assert.ok(called); + let called = false; + rli.on('line', function(line) { + called = true; + assert.strictEqual(line, 'asdf'); + }); + fi.emit('data', 'asdf\n'); + assert.ok(called); - assert.doesNotThrow(function() { - rli.setPrompt('ddd> '); - }); + assert.doesNotThrow(function() { + rli.setPrompt('ddd> '); + }); - assert.doesNotThrow(function() { - rli.prompt(); - }); + assert.doesNotThrow(function() { + rli.prompt(); + }); - assert.doesNotThrow(function() { - rli.write('really shouldnt be seeing this'); - }); + assert.doesNotThrow(function() { + rli.write('really shouldnt be seeing this'); + }); - assert.doesNotThrow(function() { - rli.question('What do you think of node.js? ', function(answer) { - console.log('Thank you for your valuable feedback:', answer); - rli.close(); + assert.doesNotThrow(function() { + rli.question('What do you think of node.js? ', function(answer) { + console.log('Thank you for your valuable feedback:', answer); + rli.close(); + }); }); - }); + } { const expected = terminal From 91649b913c4beb730fbb3f4e2035f9cf1f60b18e Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Tue, 8 Aug 2017 09:53:55 -0700 Subject: [PATCH 31/92] test: make test-tls-connect checks more strict MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Check the error code on expected errors so that the introduction of different errors in refactoring is caught. While at it, re-order modules alphabetically per test-writing guide. PR-URL: https://github.com/nodejs/node/pull/14695 Reviewed-By: Refael Ackermann Reviewed-By: Tobias Nießen Reviewed-By: Luigi Pinca Reviewed-By: Colin Ihrig --- test/parallel/test-tls-connect.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/test/parallel/test-tls-connect.js b/test/parallel/test-tls-connect.js index b410f86180e00b..1419bd3a5ea427 100644 --- a/test/parallel/test-tls-connect.js +++ b/test/parallel/test-tls-connect.js @@ -1,13 +1,13 @@ 'use strict'; const common = require('../common'); -const assert = require('assert'); if (!common.hasCrypto) common.skip('missing crypto'); -const tls = require('tls'); +const assert = require('assert'); const fs = require('fs'); const path = require('path'); +const tls = require('tls'); // https://github.com/joyent/node/issues/1218 // uncatchable exception on TLS connection error @@ -18,7 +18,10 @@ const path = require('path'); const options = {cert: cert, key: key, port: common.PORT}; const conn = tls.connect(options, common.fail); - conn.on('error', common.mustCall()); + conn.on( + 'error', + common.mustCall((e) => { assert.strictEqual(e.code, 'ECONNREFUSED'); }) + ); } // SSL_accept/SSL_connect error handling @@ -35,5 +38,8 @@ const path = require('path'); assert.ok(false); // callback should never be executed }); - conn.on('error', common.mustCall()); + conn.on( + 'error', + common.mustCall((e) => { assert.strictEqual(e.code, 'ECONNREFUSED'); }) + ); } From 9f330250b5596bdff1cf70196d7c06508b27dec3 Mon Sep 17 00:00:00 2001 From: XadillaX Date: Thu, 10 Aug 2017 20:29:53 +0800 Subject: [PATCH 32/92] test: remove redundant `using` in cctest MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/14739 Reviewed-By: Refael Ackermann Reviewed-By: Daniel Bevenius Reviewed-By: James M Snell Reviewed-By: James M Snell Reviewed-By: Benjamin Gruenbaum Reviewed-By: Luigi Pinca Reviewed-By: Timothy Gu Reviewed-By: Colin Ihrig Reviewed-By: Tobias Nießen Reviewed-By: Alexey Orlenko --- test/cctest/node_test_fixture.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/test/cctest/node_test_fixture.h b/test/cctest/node_test_fixture.h index 59988ba6cb2a3e..e32e7e6dc6b3ba 100644 --- a/test/cctest/node_test_fixture.h +++ b/test/cctest/node_test_fixture.h @@ -8,13 +8,6 @@ #include "v8.h" #include "libplatform/libplatform.h" -using node::Environment; -using node::IsolateData; -using node::CreateIsolateData; -using node::CreateEnvironment; -using node::AtExit; -using node::RunAtExit; - class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator { public: virtual void* Allocate(size_t length) { From d20b7bfb6ef033f949211b490bfed70a73dad01e Mon Sep 17 00:00:00 2001 From: Daniel Bevenius Date: Fri, 11 Aug 2017 10:39:00 +0200 Subject: [PATCH 33/92] src: use local isolate instead of args.GetIsolate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While stepping though SetupPromises I noticed that the environments Isolate is used but not when creating the string "_setupPromises". Is there a reason for using args.GetIsolate() instead of using the environments isolate? I see that GetIsolate() is an inline call, but could there be situations where it returns a different Isolate? If not perhaps using the local isolate variable would be a litte clearer. PR-URL: https://github.com/nodejs/node/pull/14768 Reviewed-By: Anna Henningsen Reviewed-By: Timothy Gu Reviewed-By: Tobias Nießen Reviewed-By: Alexey Orlenko Reviewed-By: Colin Ihrig --- src/node.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node.cc b/src/node.cc index 984c228205378d..33d97a0fcc8664 100644 --- a/src/node.cc +++ b/src/node.cc @@ -1230,7 +1230,7 @@ void SetupPromises(const FunctionCallbackInfo& args) { env->process_object()->Delete( env->context(), - FIXED_ONE_BYTE_STRING(args.GetIsolate(), "_setupPromises")).FromJust(); + FIXED_ONE_BYTE_STRING(isolate, "_setupPromises")).FromJust(); } From 1aac05b087400f707ab6799d6d53fb373b1ede70 Mon Sep 17 00:00:00 2001 From: Oky Antoro Date: Fri, 11 Aug 2017 22:30:03 +0700 Subject: [PATCH 34/92] test: cover all HTTP methods that parser supports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cover all request methods that Node's HTTP parser supports in parallel/test-http-methods. PR-URL: https://github.com/nodejs/node/pull/14773 Refs: https://github.com/nodejs/node/issues/14544 Reviewed-By: Alexey Orlenko Reviewed-By: Tobias Nießen Reviewed-By: Colin Ihrig Reviewed-By: Luigi Pinca Reviewed-By: James M Snell --- test/parallel/test-http-methods.js | 47 +++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/test/parallel/test-http-methods.js b/test/parallel/test-http-methods.js index fb49add6a2ad24..a0105d908265df 100644 --- a/test/parallel/test-http-methods.js +++ b/test/parallel/test-http-methods.js @@ -2,11 +2,44 @@ require('../common'); const assert = require('assert'); const http = require('http'); -const util = require('util'); -assert(Array.isArray(http.METHODS)); -assert(http.METHODS.length > 0); -assert(http.METHODS.includes('GET')); -assert(http.METHODS.includes('HEAD')); -assert(http.METHODS.includes('POST')); -assert.deepStrictEqual(util._extend([], http.METHODS), http.METHODS.sort()); +// This test ensures all http methods from HTTP parser are exposed +// to http library + +const methods = [ + 'DELETE', + 'GET', + 'HEAD', + 'POST', + 'PUT', + 'CONNECT', + 'OPTIONS', + 'TRACE', + 'COPY', + 'LOCK', + 'MKCOL', + 'MOVE', + 'PROPFIND', + 'PROPPATCH', + 'SEARCH', + 'UNLOCK', + 'BIND', + 'REBIND', + 'UNBIND', + 'ACL', + 'REPORT', + 'MKACTIVITY', + 'CHECKOUT', + 'MERGE', + 'M-SEARCH', + 'NOTIFY', + 'SUBSCRIBE', + 'UNSUBSCRIBE', + 'PATCH', + 'PURGE', + 'MKCALENDAR', + 'LINK', + 'UNLINK' +]; + +assert.deepStrictEqual(http.METHODS, methods.sort()); From caeee38b1debb9636e4a161286f38e999a449808 Mon Sep 17 00:00:00 2001 From: Sam Roberts Date: Fri, 14 Jul 2017 11:05:00 -0700 Subject: [PATCH 35/92] net: support passing undefined to listen() For consistency with 4.x and 8.x. This commit also contains a forward port of https://github.com/nodejs/node/pull/14232 to confirm that 4.x and 6.x behave identically with respect to the port argument. Backport-PR-URL: https://github.com/nodejs/node/pull/14234 PR-URL: https://github.com/nodejs/node/pull/14234 Refs: https://github.com/nodejs/node/issues/14205 Reviewed-By: Colin Ihrig Reviewed-By: James M Snell Reviewed-By: Sam Roberts --- lib/net.js | 2 +- test/parallel/test-net-listen-port-option.js | 44 ++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/lib/net.js b/lib/net.js index 4f1395ec2ed73a..094f118cefaa96 100644 --- a/lib/net.js +++ b/lib/net.js @@ -1342,7 +1342,7 @@ Server.prototype.listen = function() { self.once('listening', lastArg); } - var port = toNumber(arguments[0]); + var port = typeof arguments[0] === 'undefined' ? 0 : toNumber(arguments[0]); // The third optional argument is the backlog size. // When the ip is omitted it can be the second argument. diff --git a/test/parallel/test-net-listen-port-option.js b/test/parallel/test-net-listen-port-option.js index c4851bd533dfbe..3f5f69da735108 100644 --- a/test/parallel/test-net-listen-port-option.js +++ b/test/parallel/test-net-listen-port-option.js @@ -26,3 +26,47 @@ net.Server().listen({ port: '' + common.PORT }, close); net.Server().listen({ port: port }, common.fail); }, /invalid listen argument/i); }); + +// Repeat the tests, passing port as an argument, which validates somewhat +// differently. + +net.Server().listen(undefined, close); +net.Server().listen('0', close); + +// 'nan', skip, treated as a path, not a port +//'+Infinity', skip, treated as a path, not a port +//'-Infinity' skip, treated as a path, not a port + +// 4.x treats these as 0, but 6.x treats them as invalid numbers. +[ + -1, + 123.456, + 0x10000, + 1 / 0, + -1 / 0, +].forEach(function(port) { + assert.throws(function() { + net.Server().listen(port, common.fail); + }, /"port" argument must be >= 0 and < 65536/i); +}); + +// null is treated as 0 +net.Server().listen(null, close); + +// false/true are converted to 0/1, arguably a bug, but fixing would be +// semver-major. Note that true fails when port 1 low can't be listened on by +// unprivileged processes (Linux) but the listen does succeed on some Windows +// versions. +net.Server().listen(false, close); + +(function() { + const done = common.mustCall(function(err) { + if (err) + return assert.strictEqual(err.code, 'EACCES'); + + assert.strictEqual(this.address().port, 1); + this.close(); + }); + + net.Server().listen(true).on('error', done).on('listening', done); +})(); From 5a7a49f5057bdd308c8e12bb6a18ecc2c9867752 Mon Sep 17 00:00:00 2001 From: dcharbonnier Date: Thu, 3 Aug 2017 19:37:09 +0200 Subject: [PATCH 36/92] doc: clarify the position argument for fs.read MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit What happen to the file position after a read using a position null or integer was not clear and you can assume that the cursor of the file descriptor is updated even if position is an integer. PR-URL: https://github.com/nodejs/node/pull/14631 Fixes: https://github.com/https://github.com/nodejs/node/issues/8397 Reviewed-By: James M Snell Reviewed-By: Colin Ihrig Reviewed-By: Tobias Nießen --- doc/api/fs.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/api/fs.md b/doc/api/fs.md index 381bf422006b44..5fe3678ca60f0d 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -1309,7 +1309,9 @@ Read data from the file specified by `fd`. `length` is an integer specifying the number of bytes to read. `position` is an integer specifying where to begin reading from in the file. -If `position` is `null`, data will be read from the current file position. +If `position` is `null`, data will be read from the current file position, +and the file position will be updated for subsequent reads. +If `position` is an integer, the file position will remain unchanged. The callback is given the three arguments, `(err, bytesRead, buffer)`. From f8fbac78422f698b36d7509cc1a86d967119646a Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Fri, 4 Aug 2017 09:44:11 -0700 Subject: [PATCH 37/92] doc: improve fs.read() doc text MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/14631 Reviewed-By: James M Snell Reviewed-By: Colin Ihrig Reviewed-By: Tobias Nießen --- doc/api/fs.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/api/fs.md b/doc/api/fs.md index 5fe3678ca60f0d..3f0a0f133070f2 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -1308,9 +1308,9 @@ Read data from the file specified by `fd`. `length` is an integer specifying the number of bytes to read. -`position` is an integer specifying where to begin reading from in the file. -If `position` is `null`, data will be read from the current file position, -and the file position will be updated for subsequent reads. +`position` is an argument specifying where to begin reading from in the file. +If `position` is `null`, data will be read from the current file position, +and the file position will be updated. If `position` is an integer, the file position will remain unchanged. The callback is given the three arguments, `(err, bytesRead, buffer)`. From f35f06d04c8d4eebf50e708a6c510cfecae44e9d Mon Sep 17 00:00:00 2001 From: James M Snell Date: Mon, 24 Jul 2017 12:08:28 -0700 Subject: [PATCH 38/92] test: improve multiple vm tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/14458 Reviewed-By: Anna Henningsen Reviewed-By: Rich Trott Reviewed-By: Michaël Zasso Reviewed-By: Colin Ihrig Reviewed-By: Tobias Nießen Reviewed-By: Franziska Hinkelmann --- test/parallel/test-vm-context-async-script.js | 8 +++---- test/parallel/test-vm-context.js | 22 +++++++++---------- .../test-vm-create-and-run-in-context.js | 12 +++++----- test/parallel/test-vm-function-declaration.js | 2 -- .../test-vm-new-script-new-context.js | 8 +++---- .../test-vm-new-script-this-context.js | 10 ++++----- test/parallel/test-vm-run-in-new-context.js | 14 ++++++------ test/parallel/test-vm-syntax-error-message.js | 14 +++++------- test/parallel/test-vm-syntax-error-stderr.js | 12 ++++------ 9 files changed, 46 insertions(+), 56 deletions(-) diff --git a/test/parallel/test-vm-context-async-script.js b/test/parallel/test-vm-context-async-script.js index 1e9ed629fb114f..2b1e4593ecbc70 100644 --- a/test/parallel/test-vm-context-async-script.js +++ b/test/parallel/test-vm-context-async-script.js @@ -1,14 +1,14 @@ 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const vm = require('vm'); -const sandbox = { setTimeout: setTimeout }; +const sandbox = { setTimeout }; const ctx = vm.createContext(sandbox); vm.runInContext('setTimeout(function() { x = 3; }, 0);', ctx); -setTimeout(function() { +setTimeout(common.mustCall(() => { assert.strictEqual(sandbox.x, 3); assert.strictEqual(ctx.x, 3); -}, 1); +}), 1); diff --git a/test/parallel/test-vm-context.js b/test/parallel/test-vm-context.js index a3b46cb89fa160..33116f52bb08e7 100644 --- a/test/parallel/test-vm-context.js +++ b/test/parallel/test-vm-context.js @@ -6,29 +6,29 @@ const vm = require('vm'); const Script = vm.Script; let script = new Script('"passed";'); -console.error('run in a new empty context'); +// Run in a new empty context let context = vm.createContext(); let result = script.runInContext(context); assert.strictEqual('passed', result); -console.error('create a new pre-populated context'); -context = vm.createContext({'foo': 'bar', 'thing': 'lala'}); +// Create a new pre-populated context +context = vm.createContext({ 'foo': 'bar', 'thing': 'lala' }); assert.strictEqual('bar', context.foo); assert.strictEqual('lala', context.thing); -console.error('test updating context'); +// Test updating context script = new Script('foo = 3;'); result = script.runInContext(context); assert.strictEqual(3, context.foo); assert.strictEqual('lala', context.thing); // Issue GH-227: -assert.throws(function() { +assert.throws(() => { vm.runInNewContext('', null, 'some.js'); }, /^TypeError: sandbox must be an object$/); // Issue GH-1140: -console.error('test runInContext signature'); +// Test runInContext signature let gh1140Exception; try { vm.runInContext('throw new Error()', context, 'expected-filename.js'); @@ -56,8 +56,8 @@ const contextifiedSandboxErrorMsg = }); // Issue GH-693: -console.error('test RegExp as argument to assert.throws'); -script = vm.createScript('var assert = require(\'assert\'); assert.throws(' + +// Test RegExp as argument to assert.throws +script = vm.createScript('const assert = require(\'assert\'); assert.throws(' + 'function() { throw "hello world"; }, /hello/);', 'some.js'); script.runInNewContext({ require: require }); @@ -71,14 +71,14 @@ assert.strictEqual(script.runInContext(ctx), false); // Error on the first line of a module should // have the correct line and column number -assert.throws(function() { +assert.throws(() => { vm.runInContext('throw new Error()', context, { filename: 'expected-filename.js', lineOffset: 32, columnOffset: 123 }); -}, function(err) { - return /expected-filename.js:33:130/.test(err.stack); +}, (err) => { + return /expected-filename\.js:33:130/.test(err.stack); }, 'Expected appearance of proper offset in Error stack'); // https://github.com/nodejs/node/issues/6158 diff --git a/test/parallel/test-vm-create-and-run-in-context.js b/test/parallel/test-vm-create-and-run-in-context.js index 7fd3f1d70436ad..e4f1524969148b 100644 --- a/test/parallel/test-vm-create-and-run-in-context.js +++ b/test/parallel/test-vm-create-and-run-in-context.js @@ -5,24 +5,24 @@ const assert = require('assert'); const vm = require('vm'); -console.error('run in a new empty context'); +// Run in a new empty context let context = vm.createContext(); let result = vm.runInContext('"passed";', context); assert.strictEqual('passed', result); -console.error('create a new pre-populated context'); -context = vm.createContext({'foo': 'bar', 'thing': 'lala'}); +// Create a new pre-populated context +context = vm.createContext({ 'foo': 'bar', 'thing': 'lala' }); assert.strictEqual('bar', context.foo); assert.strictEqual('lala', context.thing); -console.error('test updating context'); +// Test updating context result = vm.runInContext('var foo = 3;', context); assert.strictEqual(3, context.foo); assert.strictEqual('lala', context.thing); // https://github.com/nodejs/node/issues/5768 -console.error('run in contextified sandbox without referencing the context'); -const sandbox = {x: 1}; +// Run in contextified sandbox without referencing the context +const sandbox = { x: 1 }; vm.createContext(sandbox); global.gc(); vm.runInContext('x = 2', sandbox); diff --git a/test/parallel/test-vm-function-declaration.js b/test/parallel/test-vm-function-declaration.js index ff594644c68de0..bb7ebe2aa6d1f6 100644 --- a/test/parallel/test-vm-function-declaration.js +++ b/test/parallel/test-vm-function-declaration.js @@ -21,5 +21,3 @@ assert.strictEqual(res.name, 'b', 'res should be named b'); assert.strictEqual(typeof o.a, 'function', 'a should be function'); assert.strictEqual(typeof o.b, 'function', 'b should be function'); assert.strictEqual(res, o.b, 'result should be global b function'); - -console.log('ok'); diff --git a/test/parallel/test-vm-new-script-new-context.js b/test/parallel/test-vm-new-script-new-context.js index 94d884c4d34df9..0280c24e5b8aec 100644 --- a/test/parallel/test-vm-new-script-new-context.js +++ b/test/parallel/test-vm-new-script-new-context.js @@ -15,14 +15,14 @@ const Script = require('vm').Script; { const script = new Script('throw new Error(\'test\');'); - assert.throws(function() { + assert.throws(() => { script.runInNewContext(); }, /^Error: test$/); } { const script = new Script('foo.bar = 5;'); - assert.throws(function() { + assert.throws(() => { script.runInNewContext(); }, /^ReferenceError: foo is not defined$/); } @@ -73,14 +73,14 @@ const Script = require('vm').Script; script.runInNewContext({ f: f }); assert.strictEqual(f.a, 2); - assert.throws(function() { + assert.throws(() => { script.runInNewContext(); }, /^ReferenceError: f is not defined$/); } { const script = new Script(''); - assert.throws(function() { + assert.throws(() => { script.runInNewContext.call('\'hello\';'); }, /^TypeError: this\.runInContext is not a function$/); } diff --git a/test/parallel/test-vm-new-script-this-context.js b/test/parallel/test-vm-new-script-this-context.js index 62aecfed28af4f..4dcfdda5f1d13a 100644 --- a/test/parallel/test-vm-new-script-this-context.js +++ b/test/parallel/test-vm-new-script-this-context.js @@ -5,14 +5,14 @@ const Script = require('vm').Script; common.globalCheck = false; -console.error('run a string'); +// Run a string let script = new Script('\'passed\';'); const result = script.runInThisContext(script); assert.strictEqual('passed', result); -console.error('thrown error'); +// Thrown error script = new Script('throw new Error(\'test\');'); -assert.throws(function() { +assert.throws(() => { script.runInThisContext(script); }, /^Error: test$/); @@ -22,7 +22,7 @@ script.runInThisContext(script); assert.strictEqual(2, global.hello); -console.error('pass values'); +// Pass values global.code = 'foo = 1;' + 'bar = 2;' + 'if (typeof baz !== "undefined") throw new Error("test fail");'; @@ -34,7 +34,7 @@ assert.strictEqual(0, global.obj.foo); assert.strictEqual(2, global.bar); assert.strictEqual(1, global.foo); -console.error('call a function'); +// Call a function global.f = function() { global.foo = 100; }; script = new Script('f()'); script.runInThisContext(script); diff --git a/test/parallel/test-vm-run-in-new-context.js b/test/parallel/test-vm-run-in-new-context.js index 3f8c632859db0f..95184f1e629f12 100644 --- a/test/parallel/test-vm-run-in-new-context.js +++ b/test/parallel/test-vm-run-in-new-context.js @@ -10,12 +10,12 @@ assert.strictEqual(typeof global.gc, 'function', common.globalCheck = false; -console.error('run a string'); +// Run a string const result = vm.runInNewContext('\'passed\';'); assert.strictEqual('passed', result); -console.error('thrown error'); -assert.throws(function() { +// Thrown error +assert.throws(() => { vm.runInNewContext('throw new Error(\'test\');'); }, /^Error: test$/); @@ -24,7 +24,7 @@ vm.runInNewContext('hello = 2'); assert.strictEqual(5, global.hello); -console.error('pass values in and out'); +// Pass values in and out global.code = 'foo = 1;' + 'bar = 2;' + 'if (baz !== 3) throw new Error(\'test fail\');'; @@ -37,17 +37,17 @@ assert.strictEqual(1, global.obj.foo); assert.strictEqual(2, global.obj.bar); assert.strictEqual(2, global.foo); -console.error('call a function by reference'); +// Call a function by reference function changeFoo() { global.foo = 100; } vm.runInNewContext('f()', { f: changeFoo }); assert.strictEqual(global.foo, 100); -console.error('modify an object by reference'); +// Modify an object by reference const f = { a: 1 }; vm.runInNewContext('f.a = 2', { f: f }); assert.strictEqual(f.a, 2); -console.error('use function in context without referencing context'); +// Use function in context without referencing context const fn = vm.runInNewContext('(function() { obj.p = {}; })', { obj: {} }); global.gc(); fn(); diff --git a/test/parallel/test-vm-syntax-error-message.js b/test/parallel/test-vm-syntax-error-message.js index c0a00d06aa54f8..5a16239f5653e9 100644 --- a/test/parallel/test-vm-syntax-error-message.js +++ b/test/parallel/test-vm-syntax-error-message.js @@ -1,5 +1,5 @@ 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const child_process = require('child_process'); @@ -11,16 +11,12 @@ const p = child_process.spawn(process.execPath, [ 'catch (e) { console.log(e.message); }' ]); -p.stderr.on('data', function(data) { - assert(false, 'Unexpected stderr data: ' + data); -}); +p.stderr.on('data', common.mustNotCall()); let output = ''; -p.stdout.on('data', function(data) { - output += data; -}); +p.stdout.on('data', (data) => output += data); -process.on('exit', function() { +p.stdout.on('end', common.mustCall(() => { assert.strictEqual(output.replace(/[\r\n]+/g, ''), 'boo'); -}); +})); diff --git a/test/parallel/test-vm-syntax-error-stderr.js b/test/parallel/test-vm-syntax-error-stderr.js index 9cba2178e3a0a3..e40edc907c6639 100644 --- a/test/parallel/test-vm-syntax-error-stderr.js +++ b/test/parallel/test-vm-syntax-error-stderr.js @@ -12,18 +12,14 @@ const p = child_process.spawn(process.execPath, [ wrong_script ]); -p.stdout.on('data', function(data) { - common.fail(`Unexpected stdout data: ${data}`); -}); +p.stdout.on('data', common.mustNotCall()); let output = ''; -p.stderr.on('data', function(data) { - output += data; -}); +p.stderr.on('data', (data) => output += data); -process.on('exit', function() { +p.stderr.on('end', common.mustCall(() => { assert(/BEGIN CERT/.test(output)); assert(/^\s+\^/m.test(output)); assert(/Invalid left-hand side expression in prefix operation/.test(output)); -}); +})); From 68cf7f0b30a8f08852698cd41b363dc2dbf465c7 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Mon, 24 Jul 2017 11:21:48 -0700 Subject: [PATCH 39/92] test: improve multiple zlib tests PR-URL: https://github.com/nodejs/node/pull/14455 Reviewed-By: Anna Henningsen --- test/parallel/test-zlib-from-gzip.js | 4 +- test/parallel/test-zlib-from-string.js | 22 +- test/parallel/test-zlib-invalid-input.js | 48 ++-- test/parallel/test-zlib-random-byte-pipes.js | 192 ++++++++-------- test/parallel/test-zlib-sync-no-event.js | 10 +- test/parallel/test-zlib-write-after-flush.js | 25 +-- test/parallel/test-zlib.js | 217 ++++++++----------- 7 files changed, 226 insertions(+), 292 deletions(-) diff --git a/test/parallel/test-zlib-from-gzip.js b/test/parallel/test-zlib-from-gzip.js index 7bd377eb8698fd..bca810e1a75d5f 100644 --- a/test/parallel/test-zlib-from-gzip.js +++ b/test/parallel/test-zlib-from-gzip.js @@ -21,10 +21,10 @@ const inp = fs.createReadStream(fixture); const out = fs.createWriteStream(outputFile); inp.pipe(gunzip).pipe(out); -out.on('close', function() { +out.on('close', common.mustCall(() => { const actual = fs.readFileSync(outputFile); assert.strictEqual(actual.length, expect.length, 'length should match'); for (let i = 0, l = actual.length; i < l; i++) { assert.strictEqual(actual[i], expect[i], `byte[${i}]`); } -}); +})); diff --git a/test/parallel/test-zlib-from-string.js b/test/parallel/test-zlib-from-string.js index ab2f7d023d8bc8..cf24d2a804cc73 100644 --- a/test/parallel/test-zlib-from-string.js +++ b/test/parallel/test-zlib-from-string.js @@ -1,7 +1,7 @@ 'use strict'; // test compressing and uncompressing a string with zlib -require('../common'); +const common = require('../common'); const assert = require('assert'); const zlib = require('zlib'); @@ -33,32 +33,32 @@ const expectedBase64Gzip = 'H4sIAAAAAAAAA11RS05DMQy8yhzg6d2BPSAkJPZu4laWkjiN4' + 'mHo33kJO8xfkckmLjE5XMKBQ4gxIsfvCZ44doUThF2mcZq8q2' + 'sHnHNzRtagj5AQAA'; -zlib.deflate(inputString, function(err, buffer) { +zlib.deflate(inputString, common.mustCall((err, buffer) => { assert.strictEqual(buffer.toString('base64'), expectedBase64Deflate, 'deflate encoded string should match'); -}); +})); -zlib.gzip(inputString, function(err, buffer) { +zlib.gzip(inputString, common.mustCall((err, buffer) => { // Can't actually guarantee that we'll get exactly the same // deflated bytes when we compress a string, since the header // depends on stuff other than the input string itself. // However, decrypting it should definitely yield the same // result that we're expecting, and this should match what we get // from inflating the known valid deflate data. - zlib.gunzip(buffer, function(err, gunzipped) { + zlib.gunzip(buffer, common.mustCall((err, gunzipped) => { assert.strictEqual(gunzipped.toString(), inputString, 'Should get original string after gzip/gunzip'); - }); -}); + })); +})); let buffer = Buffer.from(expectedBase64Deflate, 'base64'); -zlib.unzip(buffer, function(err, buffer) { +zlib.unzip(buffer, common.mustCall((err, buffer) => { assert.strictEqual(buffer.toString(), inputString, 'decoded inflated string should match'); -}); +})); buffer = Buffer.from(expectedBase64Gzip, 'base64'); -zlib.unzip(buffer, function(err, buffer) { +zlib.unzip(buffer, common.mustCall((err, buffer) => { assert.strictEqual(buffer.toString(), inputString, 'decoded gunzipped string should match'); -}); +})); diff --git a/test/parallel/test-zlib-invalid-input.js b/test/parallel/test-zlib-invalid-input.js index 6e87ab8b4f8227..d1d157678bba25 100644 --- a/test/parallel/test-zlib-invalid-input.js +++ b/test/parallel/test-zlib-invalid-input.js @@ -1,14 +1,26 @@ 'use strict'; // test uncompressing invalid input -require('../common'); +const common = require('../common'); const assert = require('assert'); const zlib = require('zlib'); -const nonStringInputs = [1, true, {a: 1}, ['a']]; +const nonStringInputs = [ + 1, + true, + { a: 1 }, + ['a'] +]; -console.error('Doing the non-strings'); -nonStringInputs.forEach(function(input) { +// zlib.Unzip classes need to get valid data, or else they'll throw. +const unzips = [ + zlib.Unzip(), + zlib.Gunzip(), + zlib.Inflate(), + zlib.InflateRaw() +]; + +nonStringInputs.forEach(common.mustCall((input) => { // zlib.gunzip should not throw an error when called with bad input. assert.doesNotThrow(function() { zlib.gunzip(input, function(err, buffer) { @@ -16,30 +28,12 @@ nonStringInputs.forEach(function(input) { assert.ok(err); }); }); -}); +}, nonStringInputs.length)); -console.error('Doing the unzips'); -// zlib.Unzip classes need to get valid data, or else they'll throw. -const unzips = [ zlib.Unzip(), - zlib.Gunzip(), - zlib.Inflate(), - zlib.InflateRaw() ]; -const hadError = []; -unzips.forEach(function(uz, i) { - console.error(`Error for ${uz.constructor.name}`); - uz.on('error', function(er) { - console.error('Error event', er); - hadError[i] = true; - }); - - uz.on('end', function(er) { - throw new Error(`end event should not be emitted ${uz.constructor.name}`); - }); +unzips.forEach(common.mustCall((uz, i) => { + uz.on('error', common.mustCall()); + uz.on('end', common.mustNotCall); // this will trigger error event uz.write('this is not valid compressed data.'); -}); - -process.on('exit', function() { - assert.deepStrictEqual(hadError, [true, true, true, true], 'expect 4 errors'); -}); +}, unzips.length)); diff --git a/test/parallel/test-zlib-random-byte-pipes.js b/test/parallel/test-zlib-random-byte-pipes.js index 143ab526f70a49..5ec5908777c814 100644 --- a/test/parallel/test-zlib-random-byte-pipes.js +++ b/test/parallel/test-zlib-random-byte-pipes.js @@ -6,124 +6,119 @@ if (!common.hasCrypto) const assert = require('assert'); const crypto = require('crypto'); const stream = require('stream'); -const util = require('util'); const zlib = require('zlib'); const Stream = stream.Stream; // emit random bytes, and keep a shasum -function RandomReadStream(opt) { - Stream.call(this); +class RandomReadStream extends Stream { + constructor(opt) { + super(); - this.readable = true; - this._paused = false; - this._processing = false; - - this._hasher = crypto.createHash('sha1'); - opt = opt || {}; - - // base block size. - opt.block = opt.block || 256 * 1024; + this.readable = true; + this._paused = false; + this._processing = false; - // total number of bytes to emit - opt.total = opt.total || 256 * 1024 * 1024; - this._remaining = opt.total; + this._hasher = crypto.createHash('sha1'); + opt = opt || {}; - // how variable to make the block sizes - opt.jitter = opt.jitter || 1024; + // base block size. + opt.block = opt.block || 256 * 1024; - this._opt = opt; + // total number of bytes to emit + opt.total = opt.total || 256 * 1024 * 1024; + this._remaining = opt.total; - this._process = this._process.bind(this); + // how variable to make the block sizes + opt.jitter = opt.jitter || 1024; - process.nextTick(this._process); -} + this._opt = opt; -util.inherits(RandomReadStream, Stream); + this._process = this._process.bind(this); -RandomReadStream.prototype.pause = function() { - this._paused = true; - this.emit('pause'); -}; + process.nextTick(this._process); + } -RandomReadStream.prototype.resume = function() { - // console.error("rrs resume"); - this._paused = false; - this.emit('resume'); - this._process(); -}; + pause() { + this._paused = true; + this.emit('pause'); + } -RandomReadStream.prototype._process = function() { - if (this._processing) return; - if (this._paused) return; + resume() { + // console.error("rrs resume"); + this._paused = false; + this.emit('resume'); + this._process(); + } - this._processing = true; + _process() { + if (this._processing) return; + if (this._paused) return; - if (!this._remaining) { - this._hash = this._hasher.digest('hex').toLowerCase().trim(); - this._processing = false; + this._processing = true; - this.emit('end'); - return; - } + if (!this._remaining) { + this._hash = this._hasher.digest('hex').toLowerCase().trim(); + this._processing = false; - // figure out how many bytes to output - // if finished, then just emit end. - let block = this._opt.block; - const jitter = this._opt.jitter; - if (jitter) { - block += Math.ceil(Math.random() * jitter - (jitter / 2)); - } - block = Math.min(block, this._remaining); - const buf = Buffer.allocUnsafe(block); - for (let i = 0; i < block; i++) { - buf[i] = Math.random() * 256; - } + this.emit('end'); + return; + } - this._hasher.update(buf); + // figure out how many bytes to output + // if finished, then just emit end. + let block = this._opt.block; + const jitter = this._opt.jitter; + if (jitter) { + block += Math.ceil(Math.random() * jitter - (jitter / 2)); + } + block = Math.min(block, this._remaining); + const buf = Buffer.allocUnsafe(block); + for (let i = 0; i < block; i++) { + buf[i] = Math.random() * 256; + } - this._remaining -= block; + this._hasher.update(buf); - console.error('block=%d\nremain=%d\n', block, this._remaining); - this._processing = false; + this._remaining -= block; - this.emit('data', buf); - process.nextTick(this._process); -}; + this._processing = false; + this.emit('data', buf); + process.nextTick(this._process); + } +} // a filter that just verifies a shasum -function HashStream() { - Stream.call(this); +class HashStream extends Stream { + constructor() { + super(); + this.readable = this.writable = true; + this._hasher = crypto.createHash('sha1'); + } - this.readable = this.writable = true; - this._hasher = crypto.createHash('sha1'); -} + write(c) { + // Simulate the way that an fs.ReadStream returns false + // on *every* write, only to resume a moment later. + this._hasher.update(c); + process.nextTick(() => this.resume()); + return false; + } + + resume() { + this.emit('resume'); + process.nextTick(() => this.emit('drain')); + } -util.inherits(HashStream, Stream); - -HashStream.prototype.write = function(c) { - // Simulate the way that an fs.ReadStream returns false - // on *every* write like a jerk, only to resume a - // moment later. - this._hasher.update(c); - process.nextTick(this.resume.bind(this)); - return false; -}; - -HashStream.prototype.resume = function() { - this.emit('resume'); - process.nextTick(this.emit.bind(this, 'drain')); -}; - -HashStream.prototype.end = function(c) { - if (c) { - this.write(c); + end(c) { + if (c) { + this.write(c); + } + this._hash = this._hasher.digest('hex').toLowerCase().trim(); + this.emit('data', this._hash); + this.emit('end'); } - this._hash = this._hasher.digest('hex').toLowerCase().trim(); - this.emit('data', this._hash); - this.emit('end'); -}; +} const inp = new RandomReadStream({ total: 1024, block: 256, jitter: 16 }); @@ -133,23 +128,6 @@ const gunz = zlib.createGunzip(); inp.pipe(gzip).pipe(gunz).pipe(out); -inp.on('data', function(c) { - console.error('inp data', c.length); -}); - -gzip.on('data', function(c) { - console.error('gzip data', c.length); -}); - -gunz.on('data', function(c) { - console.error('gunz data', c.length); -}); - -out.on('data', function(c) { - console.error('out data', c.length); -}); - -out.on('data', common.mustCall(function(c) { - console.error('hash=%s', c); +out.on('data', common.mustCall((c) => { assert.strictEqual(c, inp._hash, 'hashes should match'); })); diff --git a/test/parallel/test-zlib-sync-no-event.js b/test/parallel/test-zlib-sync-no-event.js index 33c0018b6f9108..9defd3d31f4fb0 100644 --- a/test/parallel/test-zlib-sync-no-event.js +++ b/test/parallel/test-zlib-sync-no-event.js @@ -1,20 +1,18 @@ 'use strict'; -require('../common'); +const common = require('../common'); const zlib = require('zlib'); const assert = require('assert'); -const shouldNotBeCalled = () => { throw new Error('unexpected event'); }; - const message = 'Come on, Fhqwhgads.'; +const buffer = Buffer.from(message); const zipper = new zlib.Gzip(); -zipper.on('close', shouldNotBeCalled); +zipper.on('close', common.mustNotCall); -const buffer = Buffer.from(message); const zipped = zipper._processChunk(buffer, zlib.Z_FINISH); const unzipper = new zlib.Gunzip(); -unzipper.on('close', shouldNotBeCalled); +unzipper.on('close', common.mustNotCall); const unzipped = unzipper._processChunk(zipped, zlib.Z_FINISH); assert.notStrictEqual(zipped.toString(), message); diff --git a/test/parallel/test-zlib-write-after-flush.js b/test/parallel/test-zlib-write-after-flush.js index caacc976e51a46..5ab601f7f1d46c 100644 --- a/test/parallel/test-zlib-write-after-flush.js +++ b/test/parallel/test-zlib-write-after-flush.js @@ -1,5 +1,5 @@ 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const zlib = require('zlib'); @@ -11,23 +11,14 @@ gzip.pipe(gunz); let output = ''; const input = 'A line of data\n'; gunz.setEncoding('utf8'); -gunz.on('data', function(c) { - output += c; -}); - -process.on('exit', function() { +gunz.on('data', (c) => output += c); +gunz.on('end', common.mustCall(() => { assert.strictEqual(output, input); - - // Make sure that the flush flag was set back to normal assert.strictEqual(gzip._flushFlag, zlib.Z_NO_FLUSH); - - console.log('ok'); -}); +})); // make sure that flush/write doesn't trigger an assert failure -gzip.flush(); write(); -function write() { - gzip.write(input); - gzip.end(); - gunz.read(0); -} +gzip.flush(); +gzip.write(input); +gzip.end(); +gunz.read(0); diff --git a/test/parallel/test-zlib.js b/test/parallel/test-zlib.js index 468b5f346f04ee..dbd437e500b10f 100644 --- a/test/parallel/test-zlib.js +++ b/test/parallel/test-zlib.js @@ -4,7 +4,6 @@ const assert = require('assert'); const zlib = require('zlib'); const path = require('path'); const fs = require('fs'); -const util = require('util'); const stream = require('stream'); let zlibPairs = [ @@ -48,105 +47,104 @@ if (process.env.FAST) { } const tests = {}; -testFiles.forEach(function(file) { +testFiles.forEach(common.mustCall((file) => { tests[file] = fs.readFileSync(path.resolve(common.fixturesDir, file)); -}); +}, testFiles.length)); // stream that saves everything -function BufferStream() { - this.chunks = []; - this.length = 0; - this.writable = true; - this.readable = true; +class BufferStream extends stream.Stream { + constructor() { + super(); + this.chunks = []; + this.length = 0; + this.writable = true; + this.readable = true; + } + + write(c) { + this.chunks.push(c); + this.length += c.length; + return true; + } + + end(c) { + if (c) this.write(c); + // flatten + const buf = Buffer.allocUnsafe(this.length); + let i = 0; + this.chunks.forEach((c) => { + c.copy(buf, i); + i += c.length; + }); + this.emit('data', buf); + this.emit('end'); + return true; + } } -util.inherits(BufferStream, stream.Stream); - -BufferStream.prototype.write = function(c) { - this.chunks.push(c); - this.length += c.length; - return true; -}; - -BufferStream.prototype.end = function(c) { - if (c) this.write(c); - // flatten - const buf = Buffer.allocUnsafe(this.length); - let i = 0; - this.chunks.forEach(function(c) { - c.copy(buf, i); - i += c.length; - }); - this.emit('data', buf); - this.emit('end'); - return true; -}; - - -function SlowStream(trickle) { - this.trickle = trickle; - this.offset = 0; - this.readable = this.writable = true; +class SlowStream extends stream.Stream { + constructor(trickle) { + super(); + this.trickle = trickle; + this.offset = 0; + this.readable = this.writable = true; + } + + write() { + throw new Error('not implemented, just call ss.end(chunk)'); + } + + pause() { + this.paused = true; + this.emit('pause'); + } + + resume() { + const emit = () => { + if (this.paused) return; + if (this.offset >= this.length) { + this.ended = true; + return this.emit('end'); + } + const end = Math.min(this.offset + this.trickle, this.length); + const c = this.chunk.slice(this.offset, end); + this.offset += c.length; + this.emit('data', c); + process.nextTick(emit); + }; + + if (this.ended) return; + this.emit('resume'); + if (!this.chunk) return; + this.paused = false; + emit(); + } + + end(chunk) { + // walk over the chunk in blocks. + this.chunk = chunk; + this.length = chunk.length; + this.resume(); + return this.ended; + } } -util.inherits(SlowStream, stream.Stream); - -SlowStream.prototype.write = function() { - throw new Error('not implemented, just call ss.end(chunk)'); -}; - -SlowStream.prototype.pause = function() { - this.paused = true; - this.emit('pause'); -}; - -SlowStream.prototype.resume = function() { - const emit = () => { - if (this.paused) return; - if (this.offset >= this.length) { - this.ended = true; - return this.emit('end'); - } - const end = Math.min(this.offset + this.trickle, this.length); - const c = this.chunk.slice(this.offset, end); - this.offset += c.length; - this.emit('data', c); - process.nextTick(emit); - }; - - if (this.ended) return; - this.emit('resume'); - if (!this.chunk) return; - this.paused = false; - emit(); -}; - -SlowStream.prototype.end = function(chunk) { - // walk over the chunk in blocks. - this.chunk = chunk; - this.length = chunk.length; - this.resume(); - return this.ended; -}; - // for each of the files, make sure that compressing and // decompressing results in the same data, for every combination // of the options set above. -let failures = 0; -let total = 0; -let done = 0; -Object.keys(tests).forEach(function(file) { +const testKeys = Object.keys(tests); +testKeys.forEach(common.mustCall((file) => { const test = tests[file]; - chunkSize.forEach(function(chunkSize) { - trickle.forEach(function(trickle) { - windowBits.forEach(function(windowBits) { - level.forEach(function(level) { - memLevel.forEach(function(memLevel) { - strategy.forEach(function(strategy) { - zlibPairs.forEach(function(pair) { + chunkSize.forEach(common.mustCall((chunkSize) => { + trickle.forEach(common.mustCall((trickle) => { + windowBits.forEach(common.mustCall((windowBits) => { + level.forEach(common.mustCall((level) => { + memLevel.forEach(common.mustCall((memLevel) => { + strategy.forEach(common.mustCall((strategy) => { + zlibPairs.forEach(common.mustCall((pair) => { const Def = pair[0]; const Inf = pair[1]; const opts = { level: level, @@ -154,57 +152,32 @@ Object.keys(tests).forEach(function(file) { memLevel: memLevel, strategy: strategy }; - total++; - const def = new Def(opts); const inf = new Inf(opts); const ss = new SlowStream(trickle); const buf = new BufferStream(); // verify that the same exact buffer comes out the other end. - buf.on('data', function(c) { + buf.on('data', common.mustCall((c) => { const msg = `${file} ${chunkSize} ${ JSON.stringify(opts)} ${Def.name} -> ${Inf.name}`; - let ok = true; - const testNum = ++done; let i; for (i = 0; i < Math.max(c.length, test.length); i++) { if (c[i] !== test[i]) { - ok = false; - failures++; + assert.fail(null, null, msg); break; } } - if (ok) { - console.log(`ok ${testNum} ${msg}`); - } else { - console.log(`not ok ${testNum} msg`); - console.log(' ...'); - console.log(` testfile: ${file}`); - console.log(` type: ${Def.name} -> ${Inf.name}`); - console.log(` position: ${i}`); - console.log(` options: ${JSON.stringify(opts)}`); - console.log(` expect: ${test[i]}`); - console.log(` actual: ${c[i]}`); - console.log(` chunkSize: ${chunkSize}`); - console.log(' ---'); - } - }); + })); // the magic happens here. ss.pipe(def).pipe(inf).pipe(buf); ss.end(test); - }); - }); - }); - }); - }); - }); - }); -}); - -process.on('exit', function(code) { - console.log(`1..${done}`); - assert.strictEqual(done, total, `${total - done} tests left unfinished`); - assert.strictEqual(failures, 0, 'some test failures'); -}); + }, zlibPairs.length)); + }, strategy.length)); + }, memLevel.length)); + }, level.length)); + }, windowBits.length)); + }, trickle.length)); + }, chunkSize.length)); +}, testKeys.length)); From 32260b91f2ab59c7adec3c32129badb5dff7e0f1 Mon Sep 17 00:00:00 2001 From: Daniel Bevenius Date: Wed, 9 Aug 2017 07:28:28 +0200 Subject: [PATCH 40/92] test: check crypto before requiring tls module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit test-tls-session-cache currently fails if built --without-ssl: internal/util.js:82 throw new errors.Error('ERR_NO_CRYPTO'); ^ Error [ERR_NO_CRYPTO]: Node.js is not compiled with OpenSSL crypto support at Object.assertCrypto (internal/util.js:82:11) at tls.js:26:14 at NativeModule.compile (bootstrap_node.js:586:7) at Function.NativeModule.require (bootstrap_node.js:531:18) at Function.Module._load (module.js:449:25) at Module.require (module.js:517:17) at require (internal/module.js:11:18) at Object. (/node/test/parallel/test-tls-session-cache.js:26:13) at Module._compile (module.js:573:30) at Object.Module._extensions..js (module.js:584:10) The test has a crypto check but it come after the require of the tls module. This commit moves the crypto check to come before the require of tls and allows the test to pass. PR-URL: https://github.com/nodejs/node/pull/14708 Reviewed-By: Rich Trott Reviewed-By: Sakthipriyan Vairamani Reviewed-By: David Cai Reviewed-By: Richard Lau Reviewed-By: Luigi Pinca Reviewed-By: Tobias Nießen Reviewed-By: Colin Ihrig Reviewed-By: James M Snell --- test/parallel/test-tls-session-cache.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/parallel/test-tls-session-cache.js b/test/parallel/test-tls-session-cache.js index 69ad1074e586fa..a1e6a615ae662f 100644 --- a/test/parallel/test-tls-session-cache.js +++ b/test/parallel/test-tls-session-cache.js @@ -1,12 +1,12 @@ 'use strict'; const common = require('../common'); -if (!common.opensslCli) - common.skip('node compiled without OpenSSL CLI.'); - if (!common.hasCrypto) common.skip('missing crypto'); +if (!common.opensslCli) + common.skip('node compiled without OpenSSL CLI.'); + const assert = require('assert'); const tls = require('tls'); const fs = require('fs'); From a284ee6129d47f13940f701f2cf5a0b2b3e6ad81 Mon Sep 17 00:00:00 2001 From: Griffith Tchenpan Date: Sat, 17 Sep 2016 19:00:53 +1000 Subject: [PATCH 41/92] test: invoke callback with common.mustCall() * invoke callback with `common.mustCall()` in test-crypto-hash * order module declarations aphabetically per test-writing-guide PR-URL: https://github.com/nodejs/node/pull/8597 Reviewed-By: Colin Ihrig Reviewed-By: James M Snell Reviewed-By: Rich Trott --- test/parallel/test-crypto-domain.js | 2 +- test/parallel/test-crypto-hash.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/parallel/test-crypto-domain.js b/test/parallel/test-crypto-domain.js index eda01b95b562e4..072cf80f7f9c05 100644 --- a/test/parallel/test-crypto-domain.js +++ b/test/parallel/test-crypto-domain.js @@ -4,8 +4,8 @@ if (!common.hasCrypto) common.skip('missing crypto'); const assert = require('assert'); -const domain = require('domain'); const crypto = require('crypto'); +const domain = require('domain'); function test(fn) { const ex = new Error('BAM'); diff --git a/test/parallel/test-crypto-hash.js b/test/parallel/test-crypto-hash.js index 1d36753738e95f..1ac00216fd67b3 100644 --- a/test/parallel/test-crypto-hash.js +++ b/test/parallel/test-crypto-hash.js @@ -80,11 +80,11 @@ const fileStream = fs.createReadStream(fn); fileStream.on('data', function(data) { sha1Hash.update(data); }); -fileStream.on('close', function() { +fileStream.on('close', common.mustCall(function() { assert.strictEqual(sha1Hash.digest('hex'), '22723e553129a336ad96e10f6aecdf0f45e4149e', 'Test SHA1 of sample.png'); -}); +})); // Issue #2227: unknown digest method should throw an error. assert.throws(function() { From 4fb4fbea1c4894dafa6a2751fd33c446e20732bd Mon Sep 17 00:00:00 2001 From: Beth Griggs Date: Sat, 12 Aug 2017 13:04:46 +0100 Subject: [PATCH 42/92] test: add missing console.error to exec-maxBuffer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the missing console.error to test-child-process-exec-maxBuffer PR-URL: https://github.com/nodejs/node/pull/14796 Reviewed-By: Anna Henningsen Reviewed-By: Vse Mozhet Byt Reviewed-By: Gibson Fahnestock Reviewed-By: David Cai Reviewed-By: Colin Ihrig Reviewed-By: Rich Trott Reviewed-By: Alexey Orlenko Reviewed-By: Tobias Nießen --- test/parallel/test-child-process-exec-maxBuffer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/parallel/test-child-process-exec-maxBuffer.js b/test/parallel/test-child-process-exec-maxBuffer.js index 714e029d728b1e..2b6b9473d64367 100644 --- a/test/parallel/test-child-process-exec-maxBuffer.js +++ b/test/parallel/test-child-process-exec-maxBuffer.js @@ -25,7 +25,7 @@ const unicode = '中文测试'; // length = 4, byte length = 12 } { - const cmd = `"${process.execPath}" -e "console.('${unicode}');"`; + const cmd = `"${process.execPath}" -e "console.error('${unicode}');"`; cp.exec(cmd, {maxBuffer: 10}, checkFactory('stderr')); } From a63cd820038dc3a12cf86013994a69386f078f09 Mon Sep 17 00:00:00 2001 From: Saad Quadri Date: Sun, 13 Aug 2017 12:20:17 -0400 Subject: [PATCH 43/92] doc: fix word wrapping for api stability boxes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/14809 Fixes: https://github.com/nodejs/nodejs.org/issues/1337 Reviewed-By: Gibson Fahnestock Reviewed-By: Luigi Pinca Reviewed-By: Refael Ackermann Reviewed-By: James M Snell Reviewed-By: Daijiro Wachi Reviewed-By: Roman Reiss Reviewed-By: Tobias Nießen --- doc/api_assets/style.css | 3 ++- tools/doc/html.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/api_assets/style.css b/doc/api_assets/style.css index 55dfbb187f18d0..a9989e9fdcca84 100644 --- a/doc/api_assets/style.css +++ b/doc/api_assets/style.css @@ -93,7 +93,8 @@ em code { color: white !important; margin: 0 0 1em 0; font-family: "Lato", "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Verdana, Tahoma, sans-serif; - font-weight: 700; + padding: 1em; + line-height: 1.5; } .api_stability * { diff --git a/tools/doc/html.js b/tools/doc/html.js index 7f22769e633dd3..bc968f4152155b 100644 --- a/tools/doc/html.js +++ b/tools/doc/html.js @@ -349,7 +349,7 @@ function parseAPIHeader(text) { text = text.replace( STABILITY_TEXT_REG_EXP, - `
$1 $2$3
` + `` ); return text; } From debea1c53128ebf406166097f65619ccd7cb9342 Mon Sep 17 00:00:00 2001 From: phisixersai Date: Sat, 15 Jul 2017 22:16:42 +0900 Subject: [PATCH 44/92] tools: delete an unused argument MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/14251 Reviewed-By: Yuta Hiroto Reviewed-By: Rich Trott Reviewed-By: Vse Mozhet Byt Reviewed-By: Colin Ihrig Reviewed-By: Luigi Pinca Reviewed-By: Tobias Nießen Reviewed-By: James M Snell --- tools/jslint.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/jslint.js b/tools/jslint.js index 245a5c570b7a90..a8f4d498ed5ab1 100644 --- a/tools/jslint.js +++ b/tools/jslint.js @@ -120,7 +120,7 @@ if (cluster.isMaster) { if (showProgress) { // Start the progress display update timer when the first worker is ready - cluster.once('online', function(worker) { + cluster.once('online', function() { startTime = process.hrtime(); setInterval(printProgress, 1000).unref(); printProgress(); From d75e9b7d44e64b560dfb6e0dabea232c9f92a13a Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Wed, 16 Aug 2017 13:24:17 -0300 Subject: [PATCH 45/92] doc: add BridgeAR to collaborators MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/14862 Reviewed-By: Rich Trott Reviewed-By: Tobias Nießen Reviewed-By: Sakthipriyan Vairamani Reviewed-By: Vse Mozhet Byt Reviewed-By: James M Snell --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index b3f3e7784af374..0761b7a16275eb 100644 --- a/README.md +++ b/README.md @@ -263,6 +263,8 @@ more information about the governance of the Node.js project, see **Ben Noordhuis** <info@bnoordhuis.nl> * [brendanashworth](https://github.com/brendanashworth) - **Brendan Ashworth** <brendan.ashworth@me.com> +* [BridgeAR](https://github.com/BridgeAR) - +**Ruben Bridgewater** <ruben@bridgewater.de> * [bzoz](https://github.com/bzoz) - **Bartosz Sosnowski** <bartosz@janeasystems.com> * [calvinmetcalf](https://github.com/calvinmetcalf) - From 855d7ae326004a22d34abc49bac9de5877b08c34 Mon Sep 17 00:00:00 2001 From: Sebastian Murphy Date: Sun, 7 May 2017 14:20:23 -0400 Subject: [PATCH 46/92] benchmark: convert var to es6 const MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Converted var variable to es6 const to maintain consistency with other benchmark files. Also clean up the types array to make the files more succinct. PR-URL: https://github.com/nodejs/node/pull/12886 Reviewed-By: Refael Ackermann Reviewed-By: Luigi Pinca Reviewed-By: Sakthipriyan Vairamani Reviewed-By: Tobias Nießen --- benchmark/arrays/var-int.js | 36 ++++++++++++++++------------------ benchmark/arrays/zero-float.js | 36 ++++++++++++++++------------------ benchmark/arrays/zero-int.js | 36 ++++++++++++++++------------------ 3 files changed, 51 insertions(+), 57 deletions(-) diff --git a/benchmark/arrays/var-int.js b/benchmark/arrays/var-int.js index 36b0a908a59a4f..b284074e6e712a 100644 --- a/benchmark/arrays/var-int.js +++ b/benchmark/arrays/var-int.js @@ -1,28 +1,26 @@ 'use strict'; -var common = require('../common.js'); +const common = require('../common.js'); -var types = [ - 'Array', - 'Buffer', - 'Int8Array', - 'Uint8Array', - 'Int16Array', - 'Uint16Array', - 'Int32Array', - 'Uint32Array', - 'Float32Array', - 'Float64Array' -]; - -var bench = common.createBenchmark(main, { - type: types, +const bench = common.createBenchmark(main, { + type: [ + 'Array', + 'Buffer', + 'Int8Array', + 'Uint8Array', + 'Int16Array', + 'Uint16Array', + 'Int32Array', + 'Uint32Array', + 'Float32Array', + 'Float64Array' + ], n: [25] }); function main(conf) { - var type = conf.type; - var clazz = global[type]; - var n = +conf.n; + const type = conf.type; + const clazz = global[type]; + const n = +conf.n; bench.start(); var arr = new clazz(n * 1e6); diff --git a/benchmark/arrays/zero-float.js b/benchmark/arrays/zero-float.js index 047e179234f33a..5df9ddaa739423 100644 --- a/benchmark/arrays/zero-float.js +++ b/benchmark/arrays/zero-float.js @@ -1,28 +1,26 @@ 'use strict'; -var common = require('../common.js'); +const common = require('../common.js'); -var types = [ - 'Array', - 'Buffer', - 'Int8Array', - 'Uint8Array', - 'Int16Array', - 'Uint16Array', - 'Int32Array', - 'Uint32Array', - 'Float32Array', - 'Float64Array' -]; - -var bench = common.createBenchmark(main, { - type: types, +const bench = common.createBenchmark(main, { + type: [ + 'Array', + 'Buffer', + 'Int8Array', + 'Uint8Array', + 'Int16Array', + 'Uint16Array', + 'Int32Array', + 'Uint32Array', + 'Float32Array', + 'Float64Array' + ], n: [25] }); function main(conf) { - var type = conf.type; - var clazz = global[type]; - var n = +conf.n; + const type = conf.type; + const clazz = global[type]; + const n = +conf.n; bench.start(); var arr = new clazz(n * 1e6); diff --git a/benchmark/arrays/zero-int.js b/benchmark/arrays/zero-int.js index 4e5c97e8af0b9c..62583e0965d3b8 100644 --- a/benchmark/arrays/zero-int.js +++ b/benchmark/arrays/zero-int.js @@ -1,28 +1,26 @@ 'use strict'; -var common = require('../common.js'); +const common = require('../common.js'); -var types = [ - 'Array', - 'Buffer', - 'Int8Array', - 'Uint8Array', - 'Int16Array', - 'Uint16Array', - 'Int32Array', - 'Uint32Array', - 'Float32Array', - 'Float64Array' -]; - -var bench = common.createBenchmark(main, { - type: types, +const bench = common.createBenchmark(main, { + type: [ + 'Array', + 'Buffer', + 'Int8Array', + 'Uint8Array', + 'Int16Array', + 'Uint16Array', + 'Int32Array', + 'Uint32Array', + 'Float32Array', + 'Float64Array' + ], n: [25] }); function main(conf) { - var type = conf.type; - var clazz = global[type]; - var n = +conf.n; + const type = conf.type; + const clazz = global[type]; + const n = +conf.n; bench.start(); var arr = new clazz(n * 1e6); From 27b6737d85e268f0d4a0a229300a0abbf9a80820 Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Tue, 15 Aug 2017 21:30:38 -0700 Subject: [PATCH 47/92] doc: explain what to do if git push is rejected MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In COLLABORATOR_GUIDE.md, explain what to do if `git push upstream master` is rejected. PR-URL: https://github.com/nodejs/node/pull/14848 Fixes: https://github.com/nodejs/node/issues/12628 Reviewed-By: James M Snell Reviewed-By: Yuta Hiroto Reviewed-By: Michaël Zasso --- COLLABORATOR_GUIDE.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/COLLABORATOR_GUIDE.md b/COLLABORATOR_GUIDE.md index 116624a79aefd0..bb012ba90e06ae 100644 --- a/COLLABORATOR_GUIDE.md +++ b/COLLABORATOR_GUIDE.md @@ -512,6 +512,33 @@ your pull request shows the purple merged status then you should still add the "Landed in .." comment if you added multiple commits. +### Troubleshooting + +Sometimes, when running `git push upstream master`, you may get an error message +like this: + +```console +To https://github.com/nodejs/node + ! [rejected] master -> master (fetch first) +error: failed to push some refs to 'https://github.com/nodejs/node' +hint: Updates were rejected because the remote contains work that you do +hint: not have locally. This is usually caused by another repository pushing +hint: to the same ref. You may want to first integrate the remote changes +hint: (e.g., 'git pull ...') before pushing again. +hint: See the 'Note about fast-forwards' in 'git push --help' for details. +``` + +That means a commit has landed since your last rebase against `upstream/master`. +To fix this, fetch, rebase, run the tests again (to make sure no interactions +between your changes and the new changes cause any problems), and push again: + +```sh +git fetch upstream +git rebase upstream/master +make -j4 test +git push upstream master +``` + ### I Just Made a Mistake * Ping a CTC member. From cac4beb7649a36326fbe194c4a0d1c5b62530c72 Mon Sep 17 00:00:00 2001 From: Myles Borins Date: Wed, 16 Aug 2017 00:03:45 -0700 Subject: [PATCH 48/92] tools: fix update-eslint.sh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The script currently assumes that there is a package.json in `eslint-tmp`. If there isn't the logic of the script fails. This adds a call to `npm init --yes` ensuring there is a package.json and that the script can do it's thing. PR-URL: https://github.com/nodejs/node/pull/14850 Reviewed-By: Rich Trott Reviewed-By: Colin Ihrig Reviewed-By: Michaël Zasso --- tools/update-eslint.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/update-eslint.sh b/tools/update-eslint.sh index 0c9d3758dca973..ec0e4858cfba25 100755 --- a/tools/update-eslint.sh +++ b/tools/update-eslint.sh @@ -11,6 +11,7 @@ cd "$( dirname "${BASH_SOURCE[0]}" )" rm -rf eslint mkdir eslint-tmp cd eslint-tmp +npm init --yes npm install --global-style --no-binlinks --production eslint@latest cd node_modules/eslint From c76a54f318a81eb1526ab066ba75602a42040f3c Mon Sep 17 00:00:00 2001 From: Jon Moss Date: Fri, 18 Aug 2017 14:36:33 -0400 Subject: [PATCH 49/92] doc: add missing word PR-URL: https://github.com/nodejs/node/pull/14924 Reviewed-By: Anna Henningsen Reviewed-By: Luigi Pinca Reviewed-By: Rich Trott Reviewed-By: Colin Ihrig Reviewed-By: James M Snell --- BUILDING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BUILDING.md b/BUILDING.md index f000720c3f13ae..a2b53d943307a1 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -135,7 +135,7 @@ This will build Node.js first (if necessary) and then use it to build the docs: $ make doc ``` -If you have an existing Node.js you can build just the docs with: +If you have an existing Node.js build, you can build just the docs with: ```console $ NODE=/path/to/node make doc-only From 724508295d0ea16328fcff99f6693ff9e226789b Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Mon, 14 Aug 2017 15:38:28 -0700 Subject: [PATCH 50/92] test: make timers-blocking-callback more reliable test-timers-blocking-callback may fail erroneously on resource-constrained machines due to the timing nature of the test. There is likely no way around the timing issue. This change tries to decrease the probability of the test failing erroneously by having it retry a small number of times on failure. Tested on 0.10.38 (which has a bug that this test was written for) and (modifying the test slightly to remove ES6 stuff) the test still seems to fail 100% of the time there, which is what we want/expect. PR-URL: https://github.com/nodejs/node/pull/14831 Fixes: https://github.com/nodejs/node/issues/14792 Reviewed-By: Refael Ackermann Reviewed-By: Jeremiah Senkpiel Reviewed-By: James M Snell --- .../test-timers-blocking-callback.js | 70 ++++++++++++++----- 1 file changed, 52 insertions(+), 18 deletions(-) diff --git a/test/sequential/test-timers-blocking-callback.js b/test/sequential/test-timers-blocking-callback.js index 73b0f13997716d..d500b813af0026 100644 --- a/test/sequential/test-timers-blocking-callback.js +++ b/test/sequential/test-timers-blocking-callback.js @@ -1,8 +1,9 @@ 'use strict'; /* - * This is a regression test for https://github.com/joyent/node/issues/15447 - * and https://github.com/joyent/node/issues/9333. + * This is a regression test for + * https://github.com/nodejs/node-v0.x-archive/issues/15447 and + * and https://github.com/nodejs/node-v0.x-archive/issues/9333. * * When a timer is added in another timer's callback, its underlying timer * handle was started with a timeout that was actually incorrect. @@ -28,9 +29,15 @@ const Timer = process.binding('timer_wrap').Timer; const TIMEOUT = 100; -let nbBlockingCallbackCalls = 0; -let latestDelay = 0; -let timeCallbackScheduled = 0; +let nbBlockingCallbackCalls; +let latestDelay; +let timeCallbackScheduled; + +// These tests are timing dependent so they may fail even when the bug is +// not present (if the host is sufficiently busy that the timers are delayed +// significantly). However, they fail 100% of the time when the bug *is* +// present, so to increase reliability, allow for a small number of retries. +let retries = 2; function initTest() { nbBlockingCallbackCalls = 0; @@ -38,7 +45,7 @@ function initTest() { timeCallbackScheduled = 0; } -function blockingCallback(callback) { +function blockingCallback(retry, callback) { ++nbBlockingCallbackCalls; if (nbBlockingCallbackCalls > 1) { @@ -47,8 +54,15 @@ function blockingCallback(callback) { // to fire, they shouldn't generally be more than 100% late in this case. // But they are guaranteed to be at least 100ms late given the bug in // https://github.com/nodejs/node-v0.x-archive/issues/15447 and - // https://github.com/nodejs/node-v0.x-archive/issues/9333.. - assert(latestDelay < TIMEOUT * 2); + // https://github.com/nodejs/node-v0.x-archive/issues/9333. + if (latestDelay >= TIMEOUT * 2) { + if (retries > 0) { + retries--; + return retry(callback); + } + assert.fail(null, null, + `timeout delayed by more than 100% (${latestDelay}ms)`); + } if (callback) return callback(); } else { @@ -56,25 +70,45 @@ function blockingCallback(callback) { common.busyLoop(TIMEOUT); timeCallbackScheduled = Timer.now(); - setTimeout(blockingCallback.bind(null, callback), TIMEOUT); + setTimeout(blockingCallback.bind(null, retry, callback), TIMEOUT); } } -const testAddingTimerToEmptyTimersList = common.mustCall(function(callback) { +function testAddingTimerToEmptyTimersList(callback) { initTest(); // Call setTimeout just once to make sure the timers list is // empty when blockingCallback is called. - setTimeout(blockingCallback.bind(null, callback), TIMEOUT); -}); + setTimeout( + blockingCallback.bind(null, testAddingTimerToEmptyTimersList, callback), + TIMEOUT + ); +} + +function testAddingTimerToNonEmptyTimersList() { + // If both timers fail and attempt a retry, only actually do anything for one + // of them. + let retryOK = true; + const retry = () => { + if (retryOK) + testAddingTimerToNonEmptyTimersList(); + retryOK = false; + }; -const testAddingTimerToNonEmptyTimersList = common.mustCall(function() { initTest(); // Call setTimeout twice with the same timeout to make // sure the timers list is not empty when blockingCallback is called. - setTimeout(blockingCallback, TIMEOUT); - setTimeout(blockingCallback, TIMEOUT); -}); + setTimeout( + blockingCallback.bind(null, retry), + TIMEOUT + ); + setTimeout( + blockingCallback.bind(null, retry), + TIMEOUT + ); +} // Run the test for the empty timers list case, and then for the non-empty -// timers list one -testAddingTimerToEmptyTimersList(testAddingTimerToNonEmptyTimersList); +// timers list one. +testAddingTimerToEmptyTimersList( + common.mustCall(testAddingTimerToNonEmptyTimersList) +); From b2112f8d36c6199f9243365462ba86256f764b27 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Wed, 16 Aug 2017 11:46:55 +0200 Subject: [PATCH 51/92] src: detect nul bytes in InternalModuleReadFile() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Throw an exception when the path contains nul bytes, don't abort. Fixes: https://github.com/nodejs/node/issues/13787 PR-URL: https://github.com/nodejs/node/pull/14854 Reviewed-By: James M Snell Reviewed-By: Tobias Nießen Reviewed-By: Timothy Gu Reviewed-By: Colin Ihrig Reviewed-By: Anna Henningsen --- src/node_file.cc | 3 +++ test/parallel/test-require-nul.js | 9 +++++++++ 2 files changed, 12 insertions(+) create mode 100644 test/parallel/test-require-nul.js diff --git a/src/node_file.cc b/src/node_file.cc index 90c88e5cb33e8b..af3ebdb1214816 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -571,6 +571,9 @@ static void InternalModuleReadFile(const FunctionCallbackInfo& args) { CHECK(args[0]->IsString()); node::Utf8Value path(env->isolate(), args[0]); + if (strlen(*path) != path.length()) + return; // Contains a nul byte. + uv_fs_t open_req; const int fd = uv_fs_open(loop, &open_req, *path, O_RDONLY, 0, nullptr); uv_fs_req_cleanup(&open_req); diff --git a/test/parallel/test-require-nul.js b/test/parallel/test-require-nul.js new file mode 100644 index 00000000000000..0c5cb7018d47fc --- /dev/null +++ b/test/parallel/test-require-nul.js @@ -0,0 +1,9 @@ +'use strict'; + +require('../common'); +const assert = require('assert'); + +// Nul bytes should throw, not abort. +assert.throws(() => require('\u0000ab'), /Cannot find module '\u0000ab'/); +assert.throws(() => require('a\u0000b'), /Cannot find module 'a\u0000b'/); +assert.throws(() => require('ab\u0000'), /Cannot find module 'ab\u0000'/); From 55dc14ec61502b8ad9f425046e16311203aa93f7 Mon Sep 17 00:00:00 2001 From: Julien Gilli Date: Tue, 22 Aug 2017 14:40:28 -0700 Subject: [PATCH 52/92] doc: remove misterdjules from the CTC members list PR-URL: https://github.com/nodejs/node/pull/1498 Reviewed-By: Colin Ihrig Reviewed-By: Rich Trott --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 0761b7a16275eb..76c3fd37d92b29 100644 --- a/README.md +++ b/README.md @@ -205,8 +205,6 @@ more information about the governance of the Node.js project, see **Matteo Collina** <matteo.collina@gmail.com> (he/him) * [mhdawson](https://github.com/mhdawson) - **Michael Dawson** <michael_dawson@ca.ibm.com> (he/him) -* [misterdjules](https://github.com/misterdjules) - -**Julien Gilli** <jgilli@nodejs.org> * [mscdex](https://github.com/mscdex) - **Brian White** <mscdex@mscdex.net> * [MylesBorins](https://github.com/MylesBorins) - From 915b56b9630677819e09f3267c16155fb067057e Mon Sep 17 00:00:00 2001 From: Ankit Parashar Date: Fri, 18 Aug 2017 14:40:53 +0530 Subject: [PATCH 53/92] test: remove unused arguments from function Removed the unused arguments of functions defined in file test/parallel/test-http-parser.js. PR-URL: https://github.com/nodejs/node/pull/14931 Reviewed-By: Rich Trott Reviewed-By: Yuta Hiroto Reviewed-By: Refael Ackermann Reviewed-By: Luigi Pinca Reviewed-By: Colin Ihrig Reviewed-By: James M Snell Reviewed-By: Alexey Orlenko --- test/parallel/test-http-parser.js | 45 +++++++++++-------------------- 1 file changed, 16 insertions(+), 29 deletions(-) diff --git a/test/parallel/test-http-parser.js b/test/parallel/test-http-parser.js index 92ff0c9dbde436..7b2d08a82b8608 100644 --- a/test/parallel/test-http-parser.js +++ b/test/parallel/test-http-parser.js @@ -32,7 +32,7 @@ function newParser(type) { parser.url += url; }; - parser[kOnHeadersComplete] = function(info) { + parser[kOnHeadersComplete] = function() { }; parser[kOnBody] = function(b, start, len) { @@ -76,8 +76,7 @@ function expectBody(expected) { const request = Buffer.from(`GET /hello HTTP/1.1${CRLF}${CRLF}`); const onHeadersComplete = (versionMajor, versionMinor, headers, - method, url, statusCode, statusMessage, - upgrade, shouldKeepAlive) => { + method, url) => { assert.strictEqual(versionMajor, 1); assert.strictEqual(versionMinor, 1); assert.strictEqual(method, methods.indexOf('GET')); @@ -93,7 +92,7 @@ function expectBody(expected) { // thrown from parser.execute() // - parser[kOnHeadersComplete] = function(info) { + parser[kOnHeadersComplete] = function() { throw new Error('hello world'); }; @@ -117,8 +116,7 @@ function expectBody(expected) { 'pong'); const onHeadersComplete = (versionMajor, versionMinor, headers, - method, url, statusCode, statusMessage, - upgrade, shouldKeepAlive) => { + method, url, statusCode, statusMessage) => { assert.strictEqual(method, undefined); assert.strictEqual(versionMajor, 1); assert.strictEqual(versionMinor, 1); @@ -146,8 +144,7 @@ function expectBody(expected) { `HTTP/1.0 200 Connection established${CRLF}${CRLF}`); const onHeadersComplete = (versionMajor, versionMinor, headers, - method, url, statusCode, statusMessage, - upgrade, shouldKeepAlive) => { + method, url, statusCode, statusMessage) => { assert.strictEqual(versionMajor, 1); assert.strictEqual(versionMinor, 0); assert.strictEqual(method, undefined); @@ -179,15 +176,14 @@ function expectBody(expected) { let seen_body = false; - const onHeaders = (headers, url) => { + const onHeaders = (headers) => { assert.ok(seen_body); // trailers should come after the body assert.deepStrictEqual(headers, ['Vary', '*', 'Content-Type', 'text/plain']); }; const onHeadersComplete = (versionMajor, versionMinor, headers, - method, url, statusCode, statusMessage, - upgrade, shouldKeepAlive) => { + method, url) => { assert.strictEqual(method, methods.indexOf('POST')); assert.strictEqual(url || parser.url, '/it'); assert.strictEqual(versionMajor, 1); @@ -221,8 +217,7 @@ function expectBody(expected) { CRLF); const onHeadersComplete = (versionMajor, versionMinor, headers, - method, url, statusCode, statusMessage, - upgrade, shouldKeepAlive) => { + method) => { assert.strictEqual(method, methods.indexOf('GET')); assert.strictEqual(versionMajor, 1); assert.strictEqual(versionMinor, 0); @@ -250,8 +245,7 @@ function expectBody(expected) { CRLF); const onHeadersComplete = (versionMajor, versionMinor, headers, - method, url, statusCode, statusMessage, - upgrade, shouldKeepAlive) => { + method, url) => { assert.strictEqual(method, methods.indexOf('GET')); assert.strictEqual(url || parser.url, '/foo/bar/baz?quux=42#1337'); assert.strictEqual(versionMajor, 1); @@ -284,8 +278,7 @@ function expectBody(expected) { 'foo=42&bar=1337'); const onHeadersComplete = (versionMajor, versionMinor, headers, - method, url, statusCode, statusMessage, - upgrade, shouldKeepAlive) => { + method, url) => { assert.strictEqual(method, methods.indexOf('POST')); assert.strictEqual(url || parser.url, '/it'); assert.strictEqual(versionMajor, 1); @@ -322,8 +315,7 @@ function expectBody(expected) { '0' + CRLF); const onHeadersComplete = (versionMajor, versionMinor, headers, - method, url, statusCode, statusMessage, - upgrade, shouldKeepAlive) => { + method, url) => { assert.strictEqual(method, methods.indexOf('POST')); assert.strictEqual(url || parser.url, '/it'); assert.strictEqual(versionMajor, 1); @@ -360,8 +352,7 @@ function expectBody(expected) { '123456' + CRLF); const onHeadersComplete = (versionMajor, versionMinor, headers, - method, url, statusCode, statusMessage, - upgrade, shouldKeepAlive) => { + method, url) => { assert.strictEqual(method, methods.indexOf('POST')); assert.strictEqual(url || parser.url, '/it'); assert.strictEqual(versionMajor, 1); @@ -418,8 +409,7 @@ function expectBody(expected) { function test(a, b) { const onHeadersComplete = (versionMajor, versionMinor, headers, - method, url, statusCode, statusMessage, - upgrade, shouldKeepAlive) => { + method, url) => { assert.strictEqual(method, methods.indexOf('POST')); assert.strictEqual(url || parser.url, '/helpme'); assert.strictEqual(versionMajor, 1); @@ -475,8 +465,7 @@ function expectBody(expected) { '0' + CRLF); const onHeadersComplete = (versionMajor, versionMinor, headers, - method, url, statusCode, statusMessage, - upgrade, shouldKeepAlive) => { + method, url) => { assert.strictEqual(method, methods.indexOf('POST')); assert.strictEqual(url || parser.url, '/it'); assert.strictEqual(versionMajor, 1); @@ -527,8 +516,7 @@ function expectBody(expected) { 'pong'); const onHeadersComplete1 = (versionMajor, versionMinor, headers, - method, url, statusCode, statusMessage, - upgrade, shouldKeepAlive) => { + method, url) => { assert.strictEqual(method, methods.indexOf('PUT')); assert.strictEqual(url, '/this'); assert.strictEqual(versionMajor, 1); @@ -539,8 +527,7 @@ function expectBody(expected) { }; const onHeadersComplete2 = (versionMajor, versionMinor, headers, - method, url, statusCode, statusMessage, - upgrade, shouldKeepAlive) => { + method, url) => { assert.strictEqual(method, methods.indexOf('POST')); assert.strictEqual(url, '/that'); assert.strictEqual(versionMajor, 1); From 70e9a6ece37eb30b1a4f99b741d7d56c783a0a38 Mon Sep 17 00:00:00 2001 From: James Kyle Date: Tue, 22 Aug 2017 09:39:17 +1000 Subject: [PATCH 54/92] doc: link to correct "OS Constants" heading in docs PR-URL: https://github.com/nodejs/node/pull/14969 Reviewed-By: Anna Henningsen Reviewed-By: James M Snell Reviewed-By: Colin Ihrig Reviewed-By: Luigi Pinca --- doc/api/os.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/os.md b/doc/api/os.md index 84cb2ba3ff6b7c..e13e3ae4217dd3 100644 --- a/doc/api/os.md +++ b/doc/api/os.md @@ -46,7 +46,7 @@ added: v6.3.0 Returns an object containing commonly used operating system specific constants for error codes, process signals, and so on. The specific constants currently -defined are described in [OS Constants][]. +defined are described in [OS Constants](#os_os_constants_1). ## os.cpus() Use OpenSSL's default CA store or use bundled Mozilla CA store as supplied by -current NodeJS version. The default store is selectable at build-time. +current Node.js version. The default store is selectable at build-time. Using OpenSSL store allows for external modifications of the store. For most Linux and BSD distributions, this store is maintained by the distribution maintainers and system administrators. OpenSSL CA store location is dependent on configuration of the OpenSSL library but this can be altered at runtime using -environmental variables. +environment variables. -The bundled CA store, as supplied by NodeJS, is a snapshot of Mozilla CA store +The bundled CA store, as supplied by Node.js, is a snapshot of Mozilla CA store that is fixed at release time. It is identical on all supported platforms. See `SSL_CERT_DIR` and `SSL_CERT_FILE`. diff --git a/doc/api/intl.md b/doc/api/intl.md index 8939dddbdd57b2..075d02879fe719 100644 --- a/doc/api/intl.md +++ b/doc/api/intl.md @@ -103,7 +103,7 @@ at runtime so that the JS methods would work for all ICU locales. Assuming the data file is stored at `/some/directory`, it can be made available to ICU through either: -* The [`NODE_ICU_DATA`][] environmental variable: +* The [`NODE_ICU_DATA`][] environment variable: ```shell env NODE_ICU_DATA=/some/directory node diff --git a/doc/api/repl.md b/doc/api/repl.md index ed1425350d19f1..a9d56c5378ab3e 100644 --- a/doc/api/repl.md +++ b/doc/api/repl.md @@ -487,7 +487,7 @@ by the `NODE_REPL_HISTORY` variable, as documented in the ### Using the Node.js REPL with advanced line-editors -For advanced line-editors, start Node.js with the environmental variable +For advanced line-editors, start Node.js with the environment variable `NODE_NO_READLINE=1`. This will start the main and debugger REPL in canonical terminal settings which will allow you to use with `rlwrap`. diff --git a/doc/node.1 b/doc/node.1 index 5ce4b7f2daef91..2167f245216e04 100644 --- a/doc/node.1 +++ b/doc/node.1 @@ -175,15 +175,15 @@ used to enable FIPS-compliant crypto if Node.js is built with .TP .BR \-\-use\-openssl\-ca,\-\-use\-bundled\-ca Use OpenSSL's default CA store or use bundled Mozilla CA store as supplied by -current NodeJS version. The default store is selectable at build-time. +current Node.js version. The default store is selectable at build-time. Using OpenSSL store allows for external modifications of the store. For most Linux and BSD distributions, this store is maintained by the distribution maintainers and system administrators. OpenSSL CA store location is dependent on configuration of the OpenSSL library but this can be altered at runtime using -environmental variables. +environment variables. -The bundled CA store, as supplied by NodeJS, is a snapshot of Mozilla CA store +The bundled CA store, as supplied by Node.js, is a snapshot of Mozilla CA store that is fixed at release time. It is identical on all supported platforms. See \fBSSL_CERT_DIR\fR and \fBSSL_CERT_FILE\fR. From 6540e995475b469eb70f5eaee91b1623ec0fa257 Mon Sep 17 00:00:00 2001 From: Jon Moss Date: Fri, 18 Aug 2017 16:59:10 -0400 Subject: [PATCH 67/92] test: simplify test-tls-client-default-ciphers PR-URL: https://github.com/nodejs/node/pull/14928 Ref: https://github.com/nodejs/node/issues/12376 Reviewed-By: James M Snell Reviewed-By: Rich Trott Reviewed-By: Refael Ackermann Reviewed-By: Colin Ihrig Reviewed-By: Luigi Pinca --- test/parallel/test-tls-client-default-ciphers.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/test/parallel/test-tls-client-default-ciphers.js b/test/parallel/test-tls-client-default-ciphers.js index 91a0a86b1b7c53..5de7f8cf8a8ba2 100644 --- a/test/parallel/test-tls-client-default-ciphers.js +++ b/test/parallel/test-tls-client-default-ciphers.js @@ -16,11 +16,8 @@ function test1() { throw new Done(); }; - try { - tls.connect(common.PORT); - } catch (e) { - assert(e instanceof Done); - } + assert.throws(tls.connect, Done); + assert.strictEqual(ciphers, tls.DEFAULT_CIPHERS); } test1(); From 4c26913dab7e9201154a15a90f29161468b3ad2a Mon Sep 17 00:00:00 2001 From: Sam Roberts Date: Wed, 23 Aug 2017 14:04:33 -0700 Subject: [PATCH 68/92] doc: crypto.randomBytes does not block when async It may not return random bytes right away, but when called asynchronously it will not block. PR-URL: https://github.com/nodejs/node/pull/14993 Reviewed-By: James M Snell Reviewed-By: Ben Noordhuis Reviewed-By: Luigi Pinca Reviewed-By: Colin Ihrig --- doc/api/crypto.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/api/crypto.md b/doc/api/crypto.md index a40178db22e6ab..79c7a3c733e90a 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -1540,7 +1540,8 @@ console.log( `${buf.length} bytes of random data: ${buf.toString('hex')}`); ``` -The `crypto.randomBytes()` method will block until there is sufficient entropy. +The `crypto.randomBytes()` method will not complete until there is +sufficient entropy available. This should normally never take longer than a few milliseconds. The only time when generating the random bytes may conceivably block for a longer period of time is right after boot, when the whole system is still low on entropy. From f0328f631aeebc1f64a038f5fdf50bab9d233881 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Sch=C3=A4r?= Date: Thu, 24 Aug 2017 16:45:19 +0200 Subject: [PATCH 69/92] doc,stream: remove wrong remark on readable.read The returned chunk is *never* longer than `size`. PR-URL: https://github.com/nodejs/node/pull/15014 Reviewed-By: Matteo Collina Reviewed-By: James M Snell Reviewed-By: Luigi Pinca --- 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 205cc440d98ef7..f7176106f3d295 100644 --- a/doc/api/stream.md +++ b/doc/api/stream.md @@ -863,7 +863,7 @@ in object mode. The optional `size` argument specifies a specific number of bytes to read. If `size` bytes are not available to be read, `null` will be returned *unless* the stream has ended, in which case all of the data remaining in the internal -buffer will be returned (*even if it exceeds `size` bytes*). +buffer will be returned. If the `size` argument is not specified, all of the data contained in the internal buffer will be returned. From 66187fa0445019cee8a4684870a7ea76e93de6df Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Sat, 19 Aug 2017 18:29:25 +0200 Subject: [PATCH 70/92] stream: fix Writable instanceof for subclasses The current custom instanceof for `Writable` subclasses previously returned false positives for instances of *other* subclasses of `Writable` because it was inherited by these subclasses. Fixes: https://github.com/nodejs/node/issues/14943 PR-URL: https://github.com/nodejs/node/pull/14945 Reviewed-By: Benjamin Gruenbaum Reviewed-By: Refael Ackermann Reviewed-By: Timothy Gu Reviewed-By: Colin Ihrig Reviewed-By: Ruben Bridgewater Reviewed-By: Evan Lucas Reviewed-By: James M Snell --- lib/_stream_writable.js | 2 ++ test/parallel/test-stream-inheritance.js | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/lib/_stream_writable.js b/lib/_stream_writable.js index 6cf7390b841a33..8251e8e219a519 100644 --- a/lib/_stream_writable.js +++ b/lib/_stream_writable.js @@ -144,6 +144,8 @@ if (typeof Symbol === 'function' && Symbol.hasInstance) { value: function(object) { if (realHasInstance.call(this, object)) return true; + if (this !== Writable) + return false; return object && object._writableState instanceof WritableState; } diff --git a/test/parallel/test-stream-inheritance.js b/test/parallel/test-stream-inheritance.js index 2c6daed0385d4a..aefb39af512646 100644 --- a/test/parallel/test-stream-inheritance.js +++ b/test/parallel/test-stream-inheritance.js @@ -49,3 +49,8 @@ Object.setPrototypeOf(CustomWritable.prototype, Writable.prototype); new CustomWritable(); assert.throws(CustomWritable, /AssertionError: undefined does not inherit from CustomWritable/); + +class OtherCustomWritable extends Writable {} + +assert(!(new OtherCustomWritable() instanceof CustomWritable)); +assert(!(new CustomWritable() instanceof OtherCustomWritable)); From 25be2a3be39481add3496f57cc927a0c4b5fff14 Mon Sep 17 00:00:00 2001 From: solebox Date: Sun, 9 Oct 2016 20:00:13 +0300 Subject: [PATCH 71/92] crypto: naming anonymous functions. Ref: https://github.com/nodejs/node/issues/8913 PR-URL: https://github.com/nodejs/node/pull/8993 --- lib/crypto.js | 50 ++++++++++++++++++++++++++------------------------ 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/lib/crypto.js b/lib/crypto.js index 439a446ac2219d..f2dede115487b0 100644 --- a/lib/crypto.js +++ b/lib/crypto.js @@ -59,24 +59,24 @@ function Hash(algorithm, options) { util.inherits(Hash, LazyTransform); -Hash.prototype._transform = function(chunk, encoding, callback) { +Hash.prototype._transform = function _transform(chunk, encoding, callback) { this._handle.update(chunk, encoding); callback(); }; -Hash.prototype._flush = function(callback) { +Hash.prototype._flush = function _flush(callback) { this.push(this._handle.digest()); callback(); }; -Hash.prototype.update = function(data, encoding) { +Hash.prototype.update = function update(data, encoding) { encoding = encoding || exports.DEFAULT_ENCODING; this._handle.update(data, encoding); return this; }; -Hash.prototype.digest = function(outputEncoding) { +Hash.prototype.digest = function digest(outputEncoding) { outputEncoding = outputEncoding || exports.DEFAULT_ENCODING; // Explicit conversion for backward compatibility. return this._handle.digest(`${outputEncoding}`); @@ -123,12 +123,12 @@ function Cipher(cipher, password, options) { util.inherits(Cipher, LazyTransform); -Cipher.prototype._transform = function(chunk, encoding, callback) { +Cipher.prototype._transform = function _transform(chunk, encoding, callback) { this.push(this._handle.update(chunk, encoding)); callback(); }; -Cipher.prototype._flush = function(callback) { +Cipher.prototype._flush = function _flush(callback) { try { this.push(this._handle.final()); } catch (e) { @@ -138,7 +138,7 @@ Cipher.prototype._flush = function(callback) { callback(); }; -Cipher.prototype.update = function(data, inputEncoding, outputEncoding) { +Cipher.prototype.update = function update(data, inputEncoding, outputEncoding) { inputEncoding = inputEncoding || exports.DEFAULT_ENCODING; outputEncoding = outputEncoding || exports.DEFAULT_ENCODING; @@ -153,7 +153,7 @@ Cipher.prototype.update = function(data, inputEncoding, outputEncoding) { }; -Cipher.prototype.final = function(outputEncoding) { +Cipher.prototype.final = function final(outputEncoding) { outputEncoding = outputEncoding || exports.DEFAULT_ENCODING; var ret = this._handle.final(); @@ -166,22 +166,22 @@ Cipher.prototype.final = function(outputEncoding) { }; -Cipher.prototype.setAutoPadding = function(ap) { +Cipher.prototype.setAutoPadding = function setAutoPadding(ap) { this._handle.setAutoPadding(ap); return this; }; -Cipher.prototype.getAuthTag = function() { +Cipher.prototype.getAuthTag = function getAuthTag() { return this._handle.getAuthTag(); }; -Cipher.prototype.setAuthTag = function(tagbuf) { +Cipher.prototype.setAuthTag = function setAuthTag(tagbuf) { this._handle.setAuthTag(tagbuf); return this; }; -Cipher.prototype.setAAD = function(aadbuf) { +Cipher.prototype.setAAD = function setAAD(aadbuf) { this._handle.setAAD(aadbuf); return this; }; @@ -270,14 +270,14 @@ function Sign(algorithm, options) { util.inherits(Sign, stream.Writable); -Sign.prototype._write = function(chunk, encoding, callback) { +Sign.prototype._write = function _write(chunk, encoding, callback) { this._handle.update(chunk, encoding); callback(); }; Sign.prototype.update = Hash.prototype.update; -Sign.prototype.sign = function(options, encoding) { +Sign.prototype.sign = function sign(options, encoding) { if (!options) throw new Error('No key provided to sign'); @@ -309,7 +309,7 @@ util.inherits(Verify, stream.Writable); Verify.prototype._write = Sign.prototype._write; Verify.prototype.update = Sign.prototype.update; -Verify.prototype.verify = function(object, signature, sigEncoding) { +Verify.prototype.verify = function verify(object, signature, sigEncoding) { sigEncoding = sigEncoding || exports.DEFAULT_ENCODING; return this._handle.verify(toBuf(object), toBuf(signature, sigEncoding)); }; @@ -477,14 +477,14 @@ function dhGetPrivateKey(encoding) { } -DiffieHellman.prototype.setPublicKey = function(key, encoding) { +DiffieHellman.prototype.setPublicKey = function setPublicKey(key, encoding) { encoding = encoding || exports.DEFAULT_ENCODING; this._handle.setPublicKey(toBuf(key, encoding)); return this; }; -DiffieHellman.prototype.setPrivateKey = function(key, encoding) { +DiffieHellman.prototype.setPrivateKey = function setPrivateKey(key, encoding) { encoding = encoding || exports.DEFAULT_ENCODING; this._handle.setPrivateKey(toBuf(key, encoding)); return this; @@ -602,19 +602,21 @@ function Certificate() { } -Certificate.prototype.verifySpkac = function(object) { +Certificate.prototype.verifySpkac = function verifySpkac(object) { return binding.certVerifySpkac(object); }; -Certificate.prototype.exportPublicKey = function(object, encoding) { - return binding.certExportPublicKey(toBuf(object, encoding)); -}; +Certificate.prototype.exportPublicKey = + function exportPublicKey(object, encoding) { + return binding.certExportPublicKey(toBuf(object, encoding)); + }; -Certificate.prototype.exportChallenge = function(object, encoding) { - return binding.certExportChallenge(toBuf(object, encoding)); -}; +Certificate.prototype.exportChallenge = + function exportChallenge(object, encoding) { + return binding.certExportChallenge(toBuf(object, encoding)); + }; exports.setEngine = function setEngine(id, flags) { From 8b045747e03a49d696b814843dbe39eed99d5f39 Mon Sep 17 00:00:00 2001 From: Jeremiah Senkpiel Date: Tue, 18 Apr 2017 12:22:19 -0400 Subject: [PATCH 72/92] test: pipe some error output if npm fails This test now prints out some child error output if the npm child proc fails, allowing us to debug easier. PR-URL: https://github.com/nodejs/node/pull/12490 Refs: https://github.com/nodejs/node/pull/12480 Reviewed-By: James M Snell Reviewed-By: Colin Ihrig --- test/parallel/test-npm-install.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/test/parallel/test-npm-install.js b/test/parallel/test-npm-install.js index 315f7885e840d6..46aa6c763e90fc 100644 --- a/test/parallel/test-npm-install.js +++ b/test/parallel/test-npm-install.js @@ -2,7 +2,7 @@ const common = require('../common'); const path = require('path'); -const spawn = require('child_process').spawn; +const exec = require('child_process').exec; const assert = require('assert'); const fs = require('fs'); @@ -22,11 +22,6 @@ const npmPath = path.join( 'npm-cli.js' ); -const args = [ - npmPath, - 'install' -]; - const pkgContent = JSON.stringify({ dependencies: { 'package-name': `${common.fixturesDir}/packages/main` @@ -43,17 +38,22 @@ env['NPM_CONFIG_PREFIX'] = path.join(npmSandbox, 'npm-prefix'); env['NPM_CONFIG_TMP'] = path.join(npmSandbox, 'npm-tmp'); env['HOME'] = path.join(npmSandbox, 'home'); -const proc = spawn(process.execPath, args, { +exec(`${process.execPath} ${npmPath} install`, { cwd: installDir, env: env -}); +}, common.mustCall(handleExit)); + +function handleExit(error, stdout, stderr) { + const code = error ? error.code : 0; + const signalCode = error ? error.signal : null; + + if (code !== 0) { + process.stderr.write(stderr); + } -function handleExit(code, signalCode) { assert.strictEqual(code, 0, `npm install got error code ${code}`); assert.strictEqual(signalCode, null, `unexpected signal: ${signalCode}`); assert.doesNotThrow(function() { fs.accessSync(`${installDir}/node_modules/package-name`); }); } - -proc.on('exit', common.mustCall(handleExit)); From 8b3ac4b2a2e483cd168d74a5c5ae4942b26302ea Mon Sep 17 00:00:00 2001 From: Ruslan Bekenev Date: Thu, 20 Jul 2017 21:16:43 +0300 Subject: [PATCH 73/92] tools: add custom private key option Add -i option for release.sh that allows users to specify non-default private key for ssh and scp commands. Change argument parsing to getopts. PR-URL: https://github.com/nodejs/node/pull/14401 Reviewed-By: Jeremiah Senkpiel Reviewed-By: Gibson Fahnestock --- tools/release.sh | 45 ++++++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/tools/release.sh b/tools/release.sh index 988a2c19b6d39d..fcb5ef124261a1 100755 --- a/tools/release.sh +++ b/tools/release.sh @@ -13,7 +13,28 @@ webuser=dist promotablecmd=dist-promotable promotecmd=dist-promote signcmd=dist-sign - +customsshkey="" # let ssh and scp use default key +signversion="" + +while getopts ":i:s:" option; do + case "${option}" in + i) + customsshkey="-i ${OPTARG}" + ;; + s) + signversion="${OPTARG}" + ;; + \?) + echo "Invalid option -$OPTARG." + exit 1 + ;; + :) + echo "Option -$OPTARG takes a parameter." + exit 1 + ;; + esac +done +shift $((OPTIND-1)) ################################################################################ ## Select a GPG key to use @@ -81,7 +102,7 @@ function sign { exit 1 fi - shapath=$(ssh ${webuser}@${webhost} $signcmd nodejs $version) + shapath=$(ssh ${customsshkey} ${webuser}@${webhost} $signcmd nodejs $version) if ! [[ ${shapath} =~ ^/.+/SHASUMS256.txt$ ]]; then echo 'Error: No SHASUMS file returned by sign!' @@ -96,7 +117,7 @@ function sign { mkdir -p $tmpdir - scp ${webuser}@${webhost}:${shapath} ${tmpdir}/${shafile} + scp ${customsshkey} ${webuser}@${webhost}:${shapath} ${tmpdir}/${shafile} gpg --default-key $gpgkey --clearsign --digest-algo SHA256 ${tmpdir}/${shafile} gpg --default-key $gpgkey --detach-sign --digest-algo SHA256 ${tmpdir}/${shafile} @@ -119,7 +140,7 @@ function sign { fi if [ "X${yorn}" == "Xy" ]; then - scp ${tmpdir}/${shafile} ${tmpdir}/${shafile}.asc ${tmpdir}/${shafile}.sig ${webuser}@${webhost}:${shadir}/ + scp ${customsshkey} ${tmpdir}/${shafile} ${tmpdir}/${shafile}.asc ${tmpdir}/${shafile}.sig ${webuser}@${webhost}:${shadir}/ break fi done @@ -128,17 +149,11 @@ function sign { } -if [ "X${1}" == "X-s" ]; then - if [ "X${2}" == "X" ]; then - echo "Please supply a version string to sign" - exit 1 - fi - - sign $2 - exit 0 +if [ -n "${signversion}" ]; then + sign ${signversion} + exit 0 fi - # else: do a normal release & promote ################################################################################ @@ -146,7 +161,7 @@ fi echo -e "\n# Checking for releases ..." -promotable=$(ssh ${webuser}@${webhost} $promotablecmd nodejs) +promotable=$(ssh ${customsshkey} ${webuser}@${webhost} $promotablecmd nodejs) if [ "X${promotable}" == "X" ]; then echo "No releases to promote!" @@ -179,7 +194,7 @@ for version in $versions; do echo -e "\n# Promoting ${version}..." - ssh ${webuser}@${webhost} $promotecmd nodejs $version + ssh ${customsshkey} ${webuser}@${webhost} $promotecmd nodejs $version sign $version From 4ee066eabaf553d32eb367ecba767d73d5810b42 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Thu, 24 Aug 2017 15:23:33 -0700 Subject: [PATCH 74/92] meta: considerations for new core modules PR-URL: https://github.com/nodejs/node/pull/15022 Reviewed-By: Rich Trott Reviewed-By: Colin Ihrig Reviewed-By: Anna Henningsen Reviewed-By: Luigi Pinca Reviewed-By: Ruben Bridgewater Reviewed-By: Matteo Collina Reviewed-By: Yuta Hiroto Reviewed-By: Andreas Madsen --- COLLABORATOR_GUIDE.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/COLLABORATOR_GUIDE.md b/COLLABORATOR_GUIDE.md index bb012ba90e06ae..cad067dd330798 100644 --- a/COLLABORATOR_GUIDE.md +++ b/COLLABORATOR_GUIDE.md @@ -263,6 +263,32 @@ multiple commits. Commit metadata and the reason for the revert should be appended. Commit message rules about line length and subsystem can be ignored. A Pull Request should be raised and approved like any other change. +### Introducing New Modules + +Semver-minor commits that introduce new core modules should be treated with +extra care. + +The name of the new core module should not conflict with any existing +module in the ecosystem unless a written agreement with the owner of those +modules is reached to transfer ownership. + +If the new module name is free, a Collaborator should register a placeholder +in the module registry as soon as possible, linking to the pull request that +introduces the new core module. + +Pull requests introducing new core modules: + +* Must be left open for at least one week for review. +* Must be labeled using the `ctc-review` label. +* Must have signoff from at least two CTC members. + +New core modules must be landed with a [Stability Index][] of Experimental, +and must remain Experimental until a semver-major release. + +For new modules that involve significant effort, non-trivial additions to +Node.js or significant new capabilities, an [Enhancement Proposal][] is +recommended but not required. + ### Deprecations Deprecation refers to the identification of Public APIs that should no longer @@ -642,3 +668,5 @@ release. This process of making a release will be a collaboration between the LTS working group and the Release team. [backporting guide]: doc/guides/backporting-to-release-lines.md +[Stability Index]: https://github.com/nodejs/node/pull/doc/api/documentation.md#stability-index +[Enhancement Proposal]: https://github.com/nodejs/node-eps From e0141783624bd85296b420d4288680f9920ab4ce Mon Sep 17 00:00:00 2001 From: James M Snell Date: Mon, 21 Aug 2017 22:44:50 -0700 Subject: [PATCH 75/92] meta: merge TSC and CTC back into a single body PR-URL: https://github.com/nodejs/node/pull/14973 Reviewed-By: Gireesh Punathil Reviewed-By: Matteo Collina Reviewed-By: Evan Lucas Reviewed-By: Rich Trott Reviewed-By: Myles Borins Reviewed-By: Ali Ijaz Sheikh Reviewed-By: Shigeki Ohtsu Reviewed-By: Fedor Indutny --- COLLABORATOR_GUIDE.md | 48 +++++++-------- GOVERNANCE.md | 132 ++++++++++++++---------------------------- README.md | 20 ++++--- doc/onboarding.md | 6 +- src/node_revert.h | 2 +- 5 files changed, 82 insertions(+), 126 deletions(-) diff --git a/COLLABORATOR_GUIDE.md b/COLLABORATOR_GUIDE.md index cad067dd330798..5aa0fb49cd68a6 100644 --- a/COLLABORATOR_GUIDE.md +++ b/COLLABORATOR_GUIDE.md @@ -8,7 +8,7 @@ - [Internal vs. Public API](#internal-vs-public-api) - [Breaking Changes](#breaking-changes) - [Deprecations](#deprecations) - - [Involving the CTC](#involving-the-ctc) + - [Involving the TSC](#involving-the-TSC) * [Landing Pull Requests](#landing-pull-requests) - [Technical HOWTO](#technical-howto) - [I Just Made a Mistake](#i-just-made-a-mistake) @@ -30,7 +30,7 @@ pull requests to the Node.js project. Collaborators should feel free to take full responsibility for managing issues and pull requests they feel qualified to handle, as long as this is done while being mindful of these guidelines, the -opinions of other Collaborators and guidance of the CTC. +opinions of other Collaborators and guidance of the TSC. Collaborators may **close** any issue or pull request they believe is not relevant for the future of the Node.js project. Where this is @@ -46,7 +46,7 @@ necessary. All modifications to the Node.js code and documentation should be performed via GitHub pull requests, including modifications by -Collaborators and CTC members. +Collaborators and TSC members. All pull requests must be reviewed and accepted by a Collaborator with sufficient expertise who is able to take full responsibility for the @@ -70,16 +70,16 @@ For non-breaking changes, if there is no disagreement amongst Collaborators, a pull request may be landed given appropriate review. Where there is discussion amongst Collaborators, consensus should be sought if possible. The lack of consensus may indicate the need to -elevate discussion to the CTC for resolution (see below). +elevate discussion to the TSC for resolution (see below). Breaking changes (that is, pull requests that require an increase in the major version number, known as `semver-major` changes) must be -elevated for review by the CTC. This does not necessarily mean that the -PR must be put onto the CTC meeting agenda. If multiple CTC members +elevated for review by the TSC. This does not necessarily mean that the +PR must be put onto the TSC meeting agenda. If multiple TSC members approve (`LGTM`) the PR and no Collaborators oppose the PR, it can be -landed. Where there is disagreement among CTC members or objections +landed. Where there is disagreement among TSC members or objections from one or more Collaborators, `semver-major` pull requests should be -put on the CTC meeting agenda. +put on the TSC meeting agenda. All bugfixes require a test case which demonstrates the defect. The test should *fail* before the change, and *pass* after the change. @@ -150,7 +150,7 @@ Exception to each of these points can be made if use or behavior of a given internal API can be demonstrated to be sufficiently relied upon by the Node.js ecosystem such that any changes would cause too much breakage. The threshold for what qualifies as "too much breakage" is to be decided on a case-by-case -basis by the CTC. +basis by the TSC. If it is determined that a currently undocumented object, property, method, argument, or event *should* be documented, then a pull request adding the @@ -171,7 +171,7 @@ making and reviewing such changes. Before landing such commits, an effort must be made to determine the potential impact of the change in the ecosystem by analyzing current use and by validating such changes through ecosystem testing using the [Canary in the Goldmine](https://github.com/nodejs/citgm) -tool. If a change cannot be made without ecosystem breakage, then CTC review is +tool. If a change cannot be made without ecosystem breakage, then TSC review is required before landing the change as anything less than semver-major. If a determination is made that a particular internal API (for instance, an @@ -183,7 +183,7 @@ breaking changes are made. ### Breaking Changes Backwards-incompatible changes may land on the master branch at any time after -sufficient review by collaborators and approval of at least two CTC members. +sufficient review by collaborators and approval of at least two TSC members. Examples of breaking changes include, but are not necessarily limited to, removal or redefinition of existing API arguments, changing return values @@ -209,7 +209,7 @@ Exception to this rule is given in the following cases: Such changes *must* be handled as semver-major changes but MAY be landed without a [Deprecation cycle](#deprecation-cycle). -From time-to-time, in particularly exceptional cases, the CTC may be asked to +From time-to-time, in particularly exceptional cases, the TSC may be asked to consider and approve additional exceptions to this rule. Purely additive changes (e.g. adding new events to EventEmitter @@ -244,7 +244,7 @@ Specifically: * Resolving critical security issues. * Fixing a critical bug (e.g. fixing a memory leak) requires a breaking change. - * There is CTC consensus that the change is required. + * There is TSC consensus that the change is required. * If a breaking commit does accidentally land in a Current or LTS branch, an attempt to fix the issue will be made before the next release; If no fix is provided then the commit will be reverted. @@ -320,7 +320,7 @@ operation of running code and therefore should not be viewed as breaking changes. Runtime Deprecations and End-of-life APIs (internal or public) *must* be -handled as semver-major changes unless there is CTC consensus to land the +handled as semver-major changes unless there is TSC consensus to land the deprecation as a semver-minor. All Documentation-Only and Runtime deprecations will be assigned a unique @@ -346,10 +346,10 @@ request adding the deprecation lands in master). All deprecations included in a Node.js release should be listed prominently in the "Notable Changes" section of the release notes. -### Involving the CTC +### Involving the TSC -Collaborators may opt to elevate pull requests or issues to the CTC for -discussion by assigning the `ctc-review` label. This should be done +Collaborators may opt to elevate pull requests or issues to the TSC for +discussion by assigning the `tsc-review` label. This should be done where a pull request: - has a significant impact on the codebase, @@ -357,7 +357,7 @@ where a pull request: - has failed to reach consensus amongst the Collaborators who are actively participating in the discussion. -The CTC should serve as the final arbiter where required. +The TSC should serve as the final arbiter where required. ## Landing Pull Requests @@ -567,7 +567,7 @@ git push upstream master ### I Just Made a Mistake -* Ping a CTC member. +* Ping a TSC member. * `#node-dev` on freenode * With `git`, there's a way to override remote trees by force pushing (`git push -f`). This should generally be seen as forbidden (since @@ -596,9 +596,9 @@ Once a Current branch enters LTS, changes in that branch are limited to bug fixes, security updates, possible npm updates, documentation updates, and certain performance improvements that can be demonstrated to not break existing applications. Semver-minor changes are only permitted if required for bug fixes -and then only on a case-by-case basis with LTS WG and possibly Core Technical -Committee (CTC) review. Semver-major changes are permitted only if required for -security related fixes. +and then only on a case-by-case basis with LTS WG and possibly Technical +Steering Committee (TSC) review. Semver-major changes are permitted only if +required for security related fixes. Once a Current branch moves into Maintenance mode, only **critical** bugs, **critical** security fixes, and documentation updates will be permitted. @@ -606,7 +606,7 @@ Once a Current branch moves into Maintenance mode, only **critical** bugs, #### Landing semver-minor commits in LTS The default policy is to not land semver-minor or higher commits in any LTS -branch. However, the LTS WG or CTC can evaluate any individual semver-minor +branch. However, the LTS WG or TSC can evaluate any individual semver-minor commit and decide whether a special exception ought to be made. It is expected that such exceptions would be evaluated, in part, on the scope and impact of the changes on the code, the risk to ecosystem stability @@ -616,7 +616,7 @@ commit will have for the ecosystem. Any collaborator who feels a semver-minor commit should be landed in an LTS branch should attach the `lts-agenda` label to the pull request. The LTS WG will discuss the issue and, if necessary, will escalate the issue up to the -CTC for further discussion. +TSC for further discussion. #### How are LTS Branches Managed? diff --git a/GOVERNANCE.md b/GOVERNANCE.md index 27c0372ac3e0d0..20b75bd9718be2 100644 --- a/GOVERNANCE.md +++ b/GOVERNANCE.md @@ -1,14 +1,15 @@ # Node.js Project Governance -The Node.js project is governed by its Collaborators, including a Core Technical -Committee (CTC) which is responsible for high-level guidance of the project. +The Node.js project is governed by its Collaborators, including a Technical +Steering Committee (TSC) which is responsible for high-level guidance of the +project. ## Collaborators The [nodejs/node](https://github.com/nodejs/node) GitHub repository is -maintained by Collaborators who are added by the CTC on an ongoing basis. +maintained by Collaborators who are added by the TSC on an ongoing basis. -Individuals identified by the CTC as making significant and valuable +Individuals identified by the TSC as making significant and valuable contributions across any Node.js repository may be made Collaborators and given commit access to the project. Activities taken into consideration include (but are not limited to) the quality of: @@ -22,7 +23,7 @@ are not limited to) the quality of: * other participation in the wider Node.js community If individuals making valuable contributions do not believe they have been -considered for commit access, they may log an issue or contact a CTC member +considered for commit access, they may log an issue or contact a TSC member directly. Modifications of the contents of the nodejs/node repository are made on @@ -40,13 +41,13 @@ be accepted unless: * Discussions and/or additional changes result in no Collaborators objecting to the change. Previously-objecting Collaborators do not necessarily have to sign-off on the change, but they should not be opposed to it. -* The change is escalated to the CTC and the CTC votes to approve the change. +* The change is escalated to the TSC and the TSC votes to approve the change. This should only happen if disagreements between Collaborators cannot be resolved through discussion. Collaborators may opt to elevate significant or controversial modifications to -the CTC by assigning the `ctc-review` label to a pull request or issue. The -CTC should serve as the final arbiter where required. +the TSC by assigning the `tsc-review` label to a pull request or issue. The +TSC should serve as the final arbiter where required. * [Current list of Collaborators](./README.md#current-project-team-members) * [A guide for Collaborators](./COLLABORATOR_GUIDE.md) @@ -61,13 +62,13 @@ Typical activities of a Collaborator include: * participation in working groups * merging pull requests -The CTC periodically reviews the Collaborator list to identify inactive +The TSC periodically reviews the Collaborator list to identify inactive Collaborators. Past Collaborators are typically given _Emeritus_ status. Emeriti -may request that the CTC restore them to active status. +may request that the TSC restore them to active status. -## Core Technical Committee +## Technical Steering Committee -The Core Technical Committee (CTC) has final authority over this project +The Technical Steering Committee (TSC) has final authority over this project including: * Technical direction @@ -77,59 +78,19 @@ including: * Conduct guidelines * Maintaining the list of additional Collaborators -* [Current list of CTC members](./README.md#current-project-team-members) +* [Current list of TSC members](./README.md#current-project-team-members) -## CTC Membership +The operations of the TSC are governed by the [TSC Charter][] as approved by +the Node.js Foundation Board of Directors. -CTC seats are not time-limited. There is no fixed size of the CTC. The CTC -should be of such a size as to ensure adequate coverage of important areas of -expertise balanced with the ability to make decisions efficiently. +### TSC Meetings -There is no specific set of requirements or qualifications for CTC -membership beyond these rules. - -The CTC may add additional members to the CTC by a standard CTC motion. - -When a CTC member's participation in [CTC activities](#ctc-activities) has -become minimal for a sustained period of time, the CTC will request that the -member either indicate an intention to increase participation or voluntarily -resign. - -CTC members may only be removed by voluntary resignation or through a standard -CTC motion. - -Changes to CTC membership should be posted in the agenda, and may be -suggested as any other agenda item (see [CTC Meetings](#ctc-meetings) below). - -No more than 1/3 of the CTC members may be affiliated with the same -employer. If removal or resignation of a CTC member, or a change of -employment by a CTC member, creates a situation where more than 1/3 of -the CTC membership shares an employer, then the situation must be -immediately remedied by the resignation or removal of one or more CTC -members affiliated with the over-represented employer(s). - -### CTC Activities - -Typical activities of a CTC member include: - -* attending the weekly meeting -* commenting on the weekly CTC meeting issue and issues labeled `ctc-review` -* participating in CTC email threads -* volunteering for tasks that arise from CTC meetings and related discussions -* other activities (beyond those typical of Collaborators) that facilitate the - smooth day-to-day operation of the Node.js project - -Note that CTC members are also Collaborators and therefore typically perform -Collaborator activities as well. - -### CTC Meetings - -The CTC meets weekly in a voice conference call. The meeting is run by a -designated meeting chair approved by the CTC. Each meeting is streamed on +The TSC meets regularly in a voice conference call. The meeting is run by a +designated meeting chair approved by the TSC. Each meeting is streamed on YouTube. -Items are added to the CTC agenda which are considered contentious or -are modifications of governance, contribution policy, CTC membership, +Items are added to the TSC agenda which are considered contentious or +are modifications of governance, contribution policy, TSC membership, or release process. The intention of the agenda is not to approve or review all patches. @@ -137,49 +98,40 @@ That should happen continuously on GitHub and be handled by the larger group of Collaborators. Any community member or contributor can ask that something be reviewed -by the CTC by logging a GitHub issue. Any Collaborator, CTC member, or the -meeting chair can bring the issue to the CTC's attention by applying the -`ctc-review` label. If consensus-seeking among CTC members fails for a -particular issue, it may be added to the CTC meeting agenda by adding the -`ctc-agenda` label. - -Prior to each CTC meeting, the meeting chair will share the agenda with -members of the CTC. CTC members can also add items to the agenda at the -beginning of each meeting. The meeting chair and the CTC cannot veto or remove +by the TSC by logging a GitHub issue. Any Collaborator, TSC member, or the +meeting chair can bring the issue to the TSC's attention by applying the +`tsc-review` label. If consensus-seeking among TSC members fails for a +particular issue, it may be added to the TSC meeting agenda by adding the +`tsc-agenda` label. + +Prior to each TSC meeting, the meeting chair will share the agenda with +members of the TSC. TSC members can also add items to the agenda at the +beginning of each meeting. The meeting chair and the TSC cannot veto or remove items. -The CTC may invite persons or representatives from certain projects to -participate in a non-voting capacity. +The TSC may invite additional persons to participate in a non-voting capacity. The meeting chair is responsible for ensuring that minutes are taken and that a pull request with the minutes is submitted after the meeting. Due to the challenges of scheduling a global meeting with participants in -several timezones, the CTC will seek to resolve as many agenda items as possible +several timezones, the TSC will seek to resolve as many agenda items as possible outside of meetings using -[the CTC issue tracker](https://github.com/nodejs/CTC/issues). The process in +[the TSC issue tracker](https://github.com/nodejs/TSC/issues). The process in the issue tracker is: -* A CTC member opens an issue explaining the proposal/issue and @-mentions - @nodejs/ctc. -* After 72 hours, if there are two or more `LGTM`s from other CTC members and no - explicit opposition from other CTC members, then the proposal is approved. -* If there are any CTC members objecting, then a conversation ensues until +* A TSC member opens an issue explaining the proposal/issue and @-mentions + @nodejs/tsc. +* After 72 hours, if there are two or more `LGTM`s from other TSC members and no + explicit opposition from other TSC members, then the proposal is approved. +* If there are any TSC members objecting, then a conversation ensues until either the proposal is dropped or the objecting members are persuaded. If there is an extended impasse, a motion for a vote may be made. ## Consensus Seeking Process -The CTC follows a -[Consensus Seeking](http://en.wikipedia.org/wiki/Consensus-seeking_decision-making) -decision making model. - -When an agenda item has appeared to reach a consensus, the meeting chair will -ask "Does anyone object?" as a final call for dissent from the consensus. +The TSC follows a [Consensus Seeking][] decision making model as described by +the [TSC Charter][]. -If an agenda item cannot reach a consensus, a CTC member can call for either a -closing vote or a vote to table the issue to the next meeting. All votes -(including votes to close or table) pass if and only if more than 50% of the CTC -members (excluding individuals who explicitly abstain) vote in favor. For -example, if there are 20 CTC members, and 5 of those members indicate that they -abstain, then 8 votes in favor are required for a resolution to pass. +[TSC Charter]: https://github.com/nodejs/TSC/blob/master/TSC-Charter.md +[Consensus Seeking]: http://en.wikipedia.org/wiki/Consensus-seeking_decision-making diff --git a/README.md b/README.md index 76c3fd37d92b29..09c90397618220 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ If you need help using or installing Node.js, please use the * [Building Node.js](#building-nodejs) * [Security](#security) * [Current Project Team Members](#current-project-team-members) - * [CTC (Core Technical Committee)](#ctc-core-technical-committee) + * [TSC (Technical Steering Committee)](#tsc-technical-steering-committee) * [Collaborators](#collaborators) * [Release Team](#release-team) @@ -55,9 +55,9 @@ If you need help using or installing Node.js, please use the channel. _Please note that unofficial resources are neither managed by (nor necessarily -endorsed by) the Node.js TSC/CTC. Specifically, such resources are not +endorsed by) the Node.js TSC. Specifically, such resources are not currently covered by the [Node.js Moderation Policy][] and the selection and -actions of resource operators/moderators are not subject to TSC/CTC oversight._ +actions of resource operators/moderators are not subject to TSC oversight._ ## Release Types @@ -175,11 +175,11 @@ handling your report. ## Current Project Team Members The Node.js project team comprises a group of core collaborators and a sub-group -that forms the _Core Technical Committee_ (CTC) which governs the project. For -more information about the governance of the Node.js project, see +that forms the _Technical Steering Committee_ (TSC) which governs the project. +For more information about the governance of the Node.js project, see [GOVERNANCE.md](./GOVERNANCE.md). -### CTC (Core Technical Committee) +### TSC (Technical Steering Committee) * [addaleax](https://github.com/addaleax) - **Anna Henningsen** <anna@addaleax.net> (she/her) @@ -199,6 +199,8 @@ more information about the governance of the Node.js project, see **Fedor Indutny** <fedor.indutny@gmail.com> * [jasnell](https://github.com/jasnell) - **James M Snell** <jasnell@gmail.com> (he/him) +* [joshgav](https://github.com/joshgav) - +**Josh Gavant** <josh.gavant@outlook.com> * [joyeecheung](https://github.com/joyeecheung) - **Joyee Cheung** <joyeec9h3@gmail.com> (she/her) * [mcollina](https://github.com/mcollina) - @@ -224,7 +226,7 @@ more information about the governance of the Node.js project, see * [Trott](https://github.com/Trott) - **Rich Trott** <rtrott@gmail.com> (he/him) -### CTC Emeriti +### TSC Emeriti * [chrisdickinson](https://github.com/chrisdickinson) - **Chris Dickinson** <christopher.s.dickinson@gmail.com> @@ -234,6 +236,8 @@ more information about the governance of the Node.js project, see **Alexis Campailla** <orangemocha@nodejs.org> * [piscisaureus](https://github.com/piscisaureus) - **Bert Belder** <bertbelder@gmail.com> +* [nebrius](https://github.com/nebrius) - +**Bryan Hughes** <bryan@nebri.us> ### Collaborators @@ -509,7 +513,7 @@ Previous releases may also have been signed with one of the following GPG keys: ### Working Groups Information on the current Node.js Working Groups can be found in the -[CTC repository](https://github.com/nodejs/CTC/blob/master/WORKING_GROUPS.md). +[TSC repository](https://github.com/nodejs/TSC/blob/master/WORKING_GROUPS.md). [npm]: https://www.npmjs.com [Website]: https://nodejs.org/en/ diff --git a/doc/onboarding.md b/doc/onboarding.md index e1e10d88b30243..2702c9b993768d 100644 --- a/doc/onboarding.md +++ b/doc/onboarding.md @@ -43,7 +43,7 @@ onboarding session. * Use [https://github.com/notifications](https://github.com/notifications) or set up email * Watching the main repo will flood your inbox (several hundred notifications on typical weekdays), so be prepared - * `#node-dev` on [webchat.freenode.net](https://webchat.freenode.net/) is the best place to interact with the CTC / other Collaborators + * `#node-dev` on [webchat.freenode.net](https://webchat.freenode.net/) is the best place to interact with the TSC / other Collaborators * If there are any questions after the session, a good place to ask is there! * Presence is not mandatory, but please drop a note there if force-pushing to `master` @@ -67,7 +67,7 @@ onboarding session. * [**See "Labels"**](./onboarding-extras.md#labels) * There is [a bot](https://github.com/nodejs-github-bot/github-bot) that applies subsystem labels (for example, `doc`, `test`, `assert`, or `buffer`) so that we know what parts of the code base the pull request modifies. It is not perfect, of course. Feel free to apply relevant labels and remove irrelevant labels from pull requests and issues. - * Use the `ctc-review` label if a topic is controversial or isn't coming to + * Use the `tsc-review` label if a topic is controversial or isn't coming to a conclusion after an extended time. * `semver-{minor,major}`: * If a change has the remote *chance* of breaking something, use the `semver-major` label @@ -166,7 +166,7 @@ onboarding session. * Almost any mistake you could make can be fixed or reverted. * The existing Collaborators trust you and are grateful for your help! * Other repositories: - * [https://github.com/nodejs/CTC](https://github.com/nodejs/CTC) + * [https://github.com/nodejs/TSC](https://github.com/nodejs/TSC) * [https://github.com/nodejs/build](https://github.com/nodejs/build) * [https://github.com/nodejs/nodejs.org](https://github.com/nodejs/nodejs.org) * [https://github.com/nodejs/readable-stream](https://github.com/nodejs/readable-stream) diff --git a/src/node_revert.h b/src/node_revert.h index b4c3633e947a6e..e76c08f58f3950 100644 --- a/src/node_revert.h +++ b/src/node_revert.h @@ -8,7 +8,7 @@ /** * Note that it is expected for this list to vary across specific LTS and * Stable versions! Only CVE's whose fixes require *breaking* changes within - * a given LTS or Stable may be added to this list, and only with CTC + * a given LTS or Stable may be added to this list, and only with TSC * consensus. * * For *master* this list should always be empty! From 5696223534542fd0818f7f67c3a6e75a7b6d1863 Mon Sep 17 00:00:00 2001 From: AJ Jordan Date: Sat, 26 Aug 2017 18:20:34 -0400 Subject: [PATCH 76/92] doc: clarify http.get data consumption requirement With the previous wording, I read this sentence as meaning, "you _must_ use the http.get callback mechanism and cannot register a listener on the returned http.ClientRequest object." This is obviously not the intention, so adjust the sentence to make this clearer. PR-URL: https://github.com/nodejs/node/pull/15049 Reviewed-By: Luigi Pinca Reviewed-By: James M Snell --- doc/api/http.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/api/http.md b/doc/api/http.md index 94f2ec75529278..eab2e2721bd60b 100644 --- a/doc/api/http.md +++ b/doc/api/http.md @@ -1476,8 +1476,8 @@ added: v0.3.6 Since most requests are GET requests without bodies, Node.js provides this convenience method. The only difference between this method and [`http.request()`][] is that it sets the method to GET and calls `req.end()` -automatically. Note that response data must be consumed in the callback -for reasons stated in [`http.ClientRequest`][] section. +automatically. Note that the callback must take care to consume the response +data for reasons stated in [`http.ClientRequest`][] section. The `callback` is invoked with a single argument that is an instance of [`http.IncomingMessage`][] From 4e717820a0ab01ec2567d8de9500ed173dafed60 Mon Sep 17 00:00:00 2001 From: Jackson Tian Date: Thu, 11 Aug 2016 10:47:58 +0800 Subject: [PATCH 77/92] lib: clean up usage of threw Use try/catch to instead of threw. PR-URL: https://github.com/nodejs/node/pull/10534 Reviewed-By: Ruben Bridgewater Reviewed-By: James M Snell Reviewed-By: Colin Ihrig --- lib/internal/bootstrap_node.js | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/lib/internal/bootstrap_node.js b/lib/internal/bootstrap_node.js index de215dc2dce62b..310dc9dd029375 100644 --- a/lib/internal/bootstrap_node.js +++ b/lib/internal/bootstrap_node.js @@ -317,20 +317,14 @@ } function tryGetCwd(path) { - var threw = true; - var cwd; try { - cwd = process.cwd(); - threw = false; - } finally { - if (threw) { - // getcwd(3) can fail if the current working directory has been deleted. - // Fall back to the directory name of the (absolute) executable path. - // It's not really correct but what are the alternatives? - return path.dirname(process.execPath); - } + return process.cwd(); + } catch (ex) { + // getcwd(3) can fail if the current working directory has been deleted. + // Fall back to the directory name of the (absolute) executable path. + // It's not really correct but what are the alternatives? + return path.dirname(process.execPath); } - return cwd; } function evalScript(name) { From 6a7e46ed9cd94e6c5e105544fdf3b66514adfef6 Mon Sep 17 00:00:00 2001 From: Roy Marples Date: Sun, 16 Jul 2017 21:44:11 +0100 Subject: [PATCH 78/92] build: add NetBSD support to opensslconf.h Simplify the BSD list by defining OPENSSL_BSD if using a matching BSD platform. Add NetBSD to the list and update documentation. PR-URL: https://github.com/nodejs/node/pull/14313 Reviewed-By: Ben Noordhuis Reviewed-By: James M Snell --- deps/openssl/config/opensslconf.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/deps/openssl/config/opensslconf.h b/deps/openssl/config/opensslconf.h index 9b20fb6485aa84..1c89babcf6c864 100644 --- a/deps/openssl/config/opensslconf.h +++ b/deps/openssl/config/opensslconf.h @@ -37,6 +37,8 @@ | solaris | x64 | solaris64-x86_64-gcc | o | | freebsd | ia32 | BSD-x86 | o | | freebsd | x64 | BSD-x86_64 | o | + | netbsd | ia32 | BSD-x86 | o | + | netbsd | x64 | BSD-x86_64 | o | | openbsd | ia32 | BSD-x86 | - | | openbsd | x64 | BSD-x86_64 | - | | others | others | linux-elf | - | @@ -51,6 +53,7 @@ | mac | __APPLE__ && __MACH__ | | solaris | __sun | | freebsd | __FreeBSD__ | + | netbsd | __NetBSD__ | | openbsd | __OpenBSD__ | | linux (not andorid)| __linux__ && !__ANDROID__ | | android | __ANDROID__ | @@ -94,6 +97,11 @@ # define OPENSSL_LINUX 1 #endif +#undef OPENSSL_BSD +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) +# define OPENSSL_BSD 1 +#endif + #if defined(OPENSSL_LINUX) && defined(__i386__) # include "./archs/linux-elf/opensslconf.h" #elif defined(OPENSSL_LINUX) && defined(__ILP32__) @@ -112,9 +120,9 @@ # include "./archs/VC-WIN32/opensslconf.h" #elif defined(_WIN32) && defined(_M_X64) # include "./archs/VC-WIN64A/opensslconf.h" -#elif (defined(__FreeBSD__) || defined(__OpenBSD__)) && defined(__i386__) +#elif defined(OPENSSL_BSD) && defined(__i386__) # include "./archs/BSD-x86/opensslconf.h" -#elif (defined(__FreeBSD__) || defined(__OpenBSD__)) && defined(__x86_64__) +#elif defined(OPENSSL_BSD) && defined(__x86_64__) # include "./archs/BSD-x86_64/opensslconf.h" #elif defined(__sun) && defined(__i386__) # include "./archs/solaris-x86-gcc/opensslconf.h" From 1b0e660c255c71236c66ceca7539513275463e4a Mon Sep 17 00:00:00 2001 From: Jon Moss Date: Wed, 30 Aug 2017 15:12:31 -0400 Subject: [PATCH 79/92] doc: /s/SHASUM256/SHASUMS256 As an example, `curl https://nodejs.org/dist/v8.4.0/SHASUM256.txt` will return a 404 right now. PR-URL: https://github.com/nodejs/node/pull/15101 Reviewed-By: Benjamin Gruenbaum Reviewed-By: James M Snell Reviewed-By: Ruben Bridgewater Reviewed-By: Luigi Pinca Reviewed-By: Refael Ackermann --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 09c90397618220..cf3f3dd98cfedd 100644 --- a/README.md +++ b/README.md @@ -114,11 +114,11 @@ documentation of the latest stable version. ### Verifying Binaries -Current, LTS and Nightly download directories all contain a _SHASUM256.txt_ +Current, LTS and Nightly download directories all contain a _SHASUMS256.txt_ file that lists the SHA checksums for each file available for download. -The _SHASUM256.txt_ can be downloaded using curl. +The _SHASUMS256.txt_ can be downloaded using curl. ```console $ curl -O https://nodejs.org/dist/vx.y.z/SHASUMS256.txt @@ -135,10 +135,10 @@ _(Where "node-vx.y.z.tar.gz" is the name of the file you have downloaded)_ Additionally, Current and LTS releases (not Nightlies) have GPG signed -copies of SHASUM256.txt files available as SHASUM256.txt.asc. You can use +copies of SHASUMS256.txt files available as SHASUMS256.txt.asc. You can use `gpg` to verify that the file has not been tampered with. -To verify a SHASUM256.txt.asc, you will first need to import all of +To verify a SHASUMS256.txt.asc, you will first need to import all of the GPG keys of individuals authorized to create releases. They are listed at the bottom of this README under [Release Team](#release-team). Use a command such as this to import the keys: From a260190717fcbdd39bd1e508c68e9be7669a990b Mon Sep 17 00:00:00 2001 From: Simon Brewster Date: Tue, 5 Sep 2017 00:10:05 +0200 Subject: [PATCH 80/92] doc: instructions for generating coverage reports Add instructions for generating code coverage reports to BUILDING.md PR-URL: https://github.com/nodejs/node/pull/15190 Reviewed-By: Timothy Gu Reviewed-By: Luigi Pinca Reviewed-By: Michael Dawson Reviewed-By: James M Snell --- BUILDING.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/BUILDING.md b/BUILDING.md index 1e871cba6d567b..e6579f3e4ef2c1 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -129,6 +129,25 @@ To run the tests: $ make test ``` +To run the tests and generate code coverage reports: + +```console +$ ./configure --coverage +$ make coverage +``` + +This will generate coverage reports for both JavaScript and C++ tests (if you +only want to run the JavaScript tests then you do not need to run the first +command `./configure --coverage`). + +The `make coverage` command downloads some tools to the project root directory +and overwrites the `lib/` directory. To clean up after generating the coverage +reports: + +```console +make coverage-clean +``` + To build the documentation: This will build Node.js first (if necessary) and then use it to build the docs: From 2babae4cd4313e7a14e4a8f2cfe33ea9b58347b1 Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Sun, 3 Sep 2017 11:09:13 -0700 Subject: [PATCH 81/92] test: refactor test-fs-readfile-unlink MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Use tmp directory instead of mutating the fixtures directory. * Add comment explaining that the unlinkSync() at the end of the test is part of the test. Otherwise it may be tempting to remove it as unnecessary tmp directory cleanup. PR-URL: https://github.com/nodejs/node/pull/15173 Reviewed-By: Yuta Hiroto Reviewed-By: Michaël Zasso Reviewed-By: Benjamin Gruenbaum Reviewed-By: Daniel Bevenius Reviewed-By: Luigi Pinca Reviewed-By: Colin Ihrig Reviewed-By: James M Snell --- test/parallel/test-fs-readfile-unlink.js | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/test/parallel/test-fs-readfile-unlink.js b/test/parallel/test-fs-readfile-unlink.js index 5b1cbd14f9c4a4..203ea681e5a079 100644 --- a/test/parallel/test-fs-readfile-unlink.js +++ b/test/parallel/test-fs-readfile-unlink.js @@ -3,16 +3,11 @@ const common = require('../common'); const assert = require('assert'); const fs = require('fs'); const path = require('path'); -const dirName = path.resolve(common.fixturesDir, 'test-readfile-unlink'); -const fileName = path.resolve(dirName, 'test.bin'); +const fileName = path.resolve(common.tmpDir, 'test.bin'); + const buf = Buffer.alloc(512 * 1024, 42); -try { - fs.mkdirSync(dirName); -} catch (e) { - // Ignore if the directory already exists. - if (e.code !== 'EEXIST') throw e; -} +common.refreshTmpDir(); fs.writeFileSync(fileName, buf); @@ -21,6 +16,7 @@ fs.readFile(fileName, function(err, data) { assert.strictEqual(data.length, buf.length); assert.strictEqual(buf[0], 42); + // Unlink should not throw. This is part of the test. It used to throw on + // Windows due to a bug. fs.unlinkSync(fileName); - fs.rmdirSync(dirName); }); From 33fdbb541753955328b222e5ec66242fc24ad4f0 Mon Sep 17 00:00:00 2001 From: Sam Roberts Date: Tue, 25 Jul 2017 12:52:49 -0700 Subject: [PATCH 82/92] doc: describe what security issues are PR-URL: https://github.com/nodejs/node/pull/14485 Reviewed-By: Gibson Fahnestock Reviewed-By: Michael Dawson --- README.md | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/README.md b/README.md index cf3f3dd98cfedd..03c725bdcd13c1 100644 --- a/README.md +++ b/README.md @@ -172,6 +172,51 @@ Your email will be acknowledged within 24 hours, and you’ll receive a more detailed response to your email within 48 hours indicating the next steps in handling your report. +There are no hard and fast rules to determine if a bug is worth reporting as +a security issue. The general rule is any issue worth reporting +must allow an attacker to compromise the confidentiality, integrity +or availability of the Node.js application or its system for which the attacker +does not already have the capability. + +To illustrate the point, here are some examples of past issues and what the +Security Reponse Team thinks of them. When in doubt, however, please do send +us a report nonetheless. + + +### Public disclosure preferred + +- [#14519](https://github.com/nodejs/node/issues/14519): _Internal domain + function can be used to cause segfaults_. Causing program termination using + either the public Javascript APIs or the private bindings layer APIs requires + the ability to execute arbitrary Javascript code, which is already the highest + level of privilege possible. + +- [#12141](https://github.com/nodejs/node/pull/12141): _buffer: zero fill + Buffer(num) by default_. The buffer constructor behaviour was documented, + but found to be prone to [mis-use](https://snyk.io/blog/exploiting-buffer/). + It has since been changed, but despite much debate, was not considered misuse + prone enough to justify fixing in older release lines and breaking our + API stability contract. + +### Private disclosure preferred + +- [CVE-2016-7099](https://nodejs.org/en/blog/vulnerability/september-2016-security-releases/): + _Fix invalid wildcard certificate validation check_. This is a high severity + defect that would allow a malicious TLS server to serve an invalid wildcard + certificate for its hostname and be improperly validated by a Node.js client. + +- [#5507](https://github.com/nodejs/node/pull/5507): _Fix a defect that makes + the CacheBleed Attack possible_. Many, though not all, OpenSSL vulnerabilities + in the TLS/SSL protocols also effect Node.js. + +- [CVE-2016-2216](https://nodejs.org/en/blog/vulnerability/february-2016-security-releases/): + _Fix defects in HTTP header parsing for requests and responses that can allow + response splitting_. While the impact of this vulnerability is application and + network dependent, it is remotely exploitable in the HTTP protocol. + +When in doubt, please do send us a report. + + ## Current Project Team Members The Node.js project team comprises a group of core collaborators and a sub-group From feb6863a5c72ced96be0fd1a59ea32fbbafa1232 Mon Sep 17 00:00:00 2001 From: Jessica Quynh Tran Date: Sat, 3 Jun 2017 16:11:32 -0400 Subject: [PATCH 83/92] doc: document bytes to chars after setEncoding This commit documents and edge-case behavior in readable streams. It is expected that non-object streams are measured in bytes against the highWaterMark. However, it was discovered in issue thereafter begin to measure the buffer's length in characters. PR-URL: https://github.com/nodejs/node/pull/13442 Refs: https://github.com/nodejs/node/issues/6798 Reviewed-By: James M Snell Reviewed-By: Vse Mozhet Byt Reviewed-By: Ruben Bridgewater --- doc/api/stream.md | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/doc/api/stream.md b/doc/api/stream.md index f7176106f3d295..d78bd3e8817ccb 100644 --- a/doc/api/stream.md +++ b/doc/api/stream.md @@ -66,8 +66,8 @@ buffer that can be retrieved using `writable._writableState.getBuffer()` or The amount of data potentially buffered depends on the `highWaterMark` option passed into the streams constructor. For normal streams, the `highWaterMark` -option specifies a total number of bytes. For streams operating in object mode, -the `highWaterMark` specifies a total number of objects. +option specifies a [total number of bytes][hwm-gotcha]. For streams operating +in object mode, the `highWaterMark` specifies a total number of objects. Data is buffered in Readable streams when the implementation calls [`stream.push(chunk)`][stream-push]. If the consumer of the Stream does not @@ -1415,9 +1415,9 @@ constructor and implement the `readable._read()` method. #### new stream.Readable([options]) * `options` {Object} - * `highWaterMark` {number} The maximum number of bytes to store in - the internal buffer before ceasing to read from the underlying - resource. Defaults to `16384` (16kb), or `16` for `objectMode` streams + * `highWaterMark` {number} The maximum [number of bytes][hwm-gotcha] to store + in the internal buffer before ceasing to read from the underlying resource. + Defaults to `16384` (16kb), or `16` for `objectMode` streams * `encoding` {string} If specified, then buffers will be decoded to strings using the specified encoding. Defaults to `null` * `objectMode` {boolean} Whether this stream should behave @@ -2031,6 +2031,19 @@ has an interesting side effect. Because it *is* a call to However, because the argument is an empty string, no data is added to the readable buffer so there is nothing for a user to consume. +### `highWaterMark` discrepency after calling `readable.setEncoding()` + +The use of `readable.setEncoding()` will change the behavior of how the +`highWaterMark` operates in non-object mode. + +Typically, the size of the current buffer is measured against the +`highWaterMark` in _bytes_. However, after `setEncoding()` is called, the +comparison function will begin to measure the buffer's size in _characters_. + +This is not a problem in common cases with `latin1` or `ascii`. But it is +advised to be mindful about this behavior when working with strings that could +contain multi-byte characters. + [`'data'`]: #stream_event_data [`'drain'`]: #stream_event_drain [`'end'`]: #stream_event_end @@ -2065,6 +2078,8 @@ readable buffer so there is nothing for a user to consume. [http-incoming-message]: http.html#http_class_http_incomingmessage [Readable]: #stream_class_stream_readable [zlib]: zlib.html +[hwm-gotcha]: #stream_highWaterMark_discrepency_after_calling_readable_setencoding +[Readable]: #stream_class_stream_readable [stream-_flush]: #stream_transform_flush_callback [stream-_read]: #stream_readable_read_size_1 [stream-_transform]: #stream_transform_transform_chunk_encoding_callback From 8e003155067a8a97a2104ef379e663e243a089a0 Mon Sep 17 00:00:00 2001 From: Daniel Bevenius Date: Thu, 15 Jun 2017 13:29:30 +0200 Subject: [PATCH 84/92] test: check zlib version for createDeflateRaw We are currenly builing Node with --shared-zlib which happens to be version 1.2.8. The test for zlib.createDeflateRaw is expected to fail but does not when using version 1.2.8. As far as I can tell the fix referred to in the comments was introduced in version 1.2.9: - Reject a window size of 256 bytes if not using the zlib wrapper This commit suggests adding a check for the version and skipping this assert if the version is less than 1.2.9. Refs: http://zlib.net/ChangeLog.txt Backport-PR-URL: https://github.com/nodejs/node/pull/15478 PR-URL: https://github.com/nodejs/node/pull/13697 Reviewed-By: Benjamin Gruenbaum Reviewed-By: Colin Ihrig Reviewed-By: James M Snell Reviewed-By: Luigi Pinca Reviewed-By: Anna Henningsen Reviewed-By: Richard Lau --- test/parallel/test-zlib-failed-init.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/parallel/test-zlib-failed-init.js b/test/parallel/test-zlib-failed-init.js index afc2c82ddfca8e..0ca70ad92d50b9 100644 --- a/test/parallel/test-zlib-failed-init.js +++ b/test/parallel/test-zlib-failed-init.js @@ -1,10 +1,15 @@ 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const zlib = require('zlib'); +if (process.config.variables.node_shared_zlib && + /^1\.2\.[0-8]$/.test(process.versions.zlib)) { + common.skip("older versions of shared zlib don't throw on create"); +} + // For raw deflate encoding, requests for 256-byte windows are rejected as // invalid by zlib. // (http://zlib.net/manual.html#Advanced) From 0c670e0339c742130d622ba4c10bb5acd225ce11 Mon Sep 17 00:00:00 2001 From: Evan Torrie Date: Tue, 13 Dec 2016 12:09:56 -0800 Subject: [PATCH 85/92] http: eliminate capture of ClientRequest in Agent Keepalive sockets that are returned to the agent's freesocket pool were previously capturing a reference to the ClientRequest that initiated the request. This commit eliminates that by moving the installation of the socket listeners to a different function. Backport-PR-URL: https://github.com/nodejs/node/pull/15500 PR-URL: https://github.com/nodejs/node/pull/10134 Reviewed-By: Colin Ihrig Reviewed-By: Ben Noordhuis Reviewed-By: Evan Lucas Reviewed-By: James M Snell --- lib/_http_agent.js | 58 +++++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/lib/_http_agent.js b/lib/_http_agent.js index 6ea801c3ed2af6..8b79d14ff12166 100644 --- a/lib/_http_agent.js +++ b/lib/_http_agent.js @@ -206,37 +206,41 @@ Agent.prototype.createSocket = function(req, options, cb) { } self.sockets[name].push(s); debug('sockets', name, self.sockets[name].length); - - function onFree() { - self.emit('free', s, options); - } - s.on('free', onFree); - - function onClose(err) { - debug('CLIENT socket onClose'); - // This is the only place where sockets get removed from the Agent. - // If you want to remove a socket from the pool, just close it. - // All socket errors end in a close event anyway. - self.removeSocket(s, options); - } - s.on('close', onClose); - - function onRemove() { - // We need this function for cases like HTTP 'upgrade' - // (defined by WebSockets) where we need to remove a socket from the - // pool because it'll be locked up indefinitely - debug('CLIENT socket onRemove'); - self.removeSocket(s, options); - s.removeListener('close', onClose); - s.removeListener('free', onFree); - s.removeListener('agentRemove', onRemove); - } - s.on('agentRemove', onRemove); + installListeners(self, s, options); cb(null, s); } }; -Agent.prototype.removeSocket = function(s, options) { +function installListeners(agent, s, options) { + function onFree() { + debug('CLIENT socket onFree'); + agent.emit('free', s, options); + } + s.on('free', onFree); + + function onClose(err) { + debug('CLIENT socket onClose'); + // This is the only place where sockets get removed from the Agent. + // If you want to remove a socket from the pool, just close it. + // All socket errors end in a close event anyway. + agent.removeSocket(s, options); + } + s.on('close', onClose); + + function onRemove() { + // We need this function for cases like HTTP 'upgrade' + // (defined by WebSockets) where we need to remove a socket from the + // pool because it'll be locked up indefinitely + debug('CLIENT socket onRemove'); + agent.removeSocket(s, options); + s.removeListener('close', onClose); + s.removeListener('free', onFree); + s.removeListener('agentRemove', onRemove); + } + s.on('agentRemove', onRemove); +} + +Agent.prototype.removeSocket = function removeSocket(s, options) { var name = this.getName(options); debug('removeSocket', name, 'writable:', s.writable); var sets = [this.sockets]; From 73416b46e4a3595bad2dea0c4e9c7f8970966bad Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Tue, 27 Jun 2017 06:00:35 +0200 Subject: [PATCH 86/92] assert: refactor the code 1. Rename private functions 2. Use destructuring 3. Remove obsolete comments Backport-PR-URL: https://github.com/nodejs/node/pull/15516 PR-URL: https://github.com/nodejs/node/pull/13862 Reviewed-By: Refael Ackermann Reviewed-By: Joyee Cheung --- lib/assert.js | 84 +++++++++++-------------------- test/parallel/test-assert-fail.js | 10 ++++ 2 files changed, 40 insertions(+), 54 deletions(-) create mode 100644 test/parallel/test-assert-fail.js diff --git a/lib/assert.js b/lib/assert.js index 219842f953a12c..cfc7addbcb0fcc 100644 --- a/lib/assert.js +++ b/lib/assert.js @@ -20,8 +20,7 @@ 'use strict'; -// UTILITY -const compare = process.binding('buffer').compare; +const { compare } = process.binding('buffer'); const util = require('util'); const Buffer = require('buffer').Buffer; const pToString = (obj) => Object.prototype.toString.call(obj); @@ -49,7 +48,7 @@ assert.AssertionError = function AssertionError(options) { this.message = getMessage(this); this.generatedMessage = true; } - var stackStartFunction = options.stackStartFunction || fail; + const stackStartFunction = options.stackStartFunction || fail; Error.captureStackTrace(this, stackStartFunction); }; @@ -73,7 +72,7 @@ function getMessage(self) { // All of the following functions must throw an AssertionError // when a corresponding condition is not met, with a message that -// may be undefined if not provided. All assertion methods provide +// may be undefined if not provided. All assertion methods provide // both the actual and expected values to the assertion error for // display purposes. @@ -86,25 +85,16 @@ function fail(actual, expected, message, operator, stackStartFunction) { stackStartFunction: stackStartFunction }); } - -// EXTENSION! allows for well behaved errors defined elsewhere. assert.fail = fail; // Pure assertion tests whether a value is truthy, as determined -// by !!guard. -// assert.ok(guard, message_opt); -// This statement is equivalent to assert.equal(true, !!guard, -// message_opt);. To test strictly for the value true, use -// assert.strictEqual(true, guard, message_opt);. - +// by !!value. function ok(value, message) { - if (!value) fail(value, true, message, '==', assert.ok); + if (!value) fail(value, true, message, '==', ok); } assert.ok = ok; -// The equality assertion tests shallow, coercive equality with -// ==. -// assert.equal(actual, expected, message_opt); +// The equality assertion tests shallow, coercive equality with ==. /* eslint-disable no-restricted-properties */ assert.equal = function equal(actual, expected, message) { if (actual != expected) fail(actual, expected, message, '==', assert.equal); @@ -112,31 +102,27 @@ assert.equal = function equal(actual, expected, message) { // The non-equality assertion tests for whether two objects are not // equal with !=. -// assert.notEqual(actual, expected, message_opt); - assert.notEqual = function notEqual(actual, expected, message) { if (actual == expected) { - fail(actual, expected, message, '!=', assert.notEqual); + fail(actual, expected, message, '!=', notEqual); } }; // The equivalence assertion tests a deep equality relation. -// assert.deepEqual(actual, expected, message_opt); - assert.deepEqual = function deepEqual(actual, expected, message) { - if (!_deepEqual(actual, expected, false)) { - fail(actual, expected, message, 'deepEqual', assert.deepEqual); + if (!innerDeepEqual(actual, expected, false)) { + fail(actual, expected, message, 'deepEqual', deepEqual); } }; /* eslint-enable */ assert.deepStrictEqual = function deepStrictEqual(actual, expected, message) { - if (!_deepEqual(actual, expected, true)) { - fail(actual, expected, message, 'deepStrictEqual', assert.deepStrictEqual); + if (!innerDeepEqual(actual, expected, true)) { + fail(actual, expected, message, 'deepStrictEqual', deepStrictEqual); } }; -function _deepEqual(actual, expected, strict, memos) { +function innerDeepEqual(actual, expected, strict, memos) { // All identical values are equivalent, as determined by ===. if (actual === expected) { return true; @@ -247,45 +233,40 @@ function objEquiv(a, b, strict, actualVisitedObjects) { // Possibly expensive deep test: for (i = ka.length - 1; i >= 0; i--) { key = ka[i]; - if (!_deepEqual(a[key], b[key], strict, actualVisitedObjects)) + if (!innerDeepEqual(a[key], b[key], strict, actualVisitedObjects)) return false; } return true; } // The non-equivalence assertion tests for any deep inequality. -// assert.notDeepEqual(actual, expected, message_opt); - assert.notDeepEqual = function notDeepEqual(actual, expected, message) { - if (_deepEqual(actual, expected, false)) { - fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); + if (innerDeepEqual(actual, expected, false)) { + fail(actual, expected, message, 'notDeepEqual', notDeepEqual); } }; assert.notDeepStrictEqual = notDeepStrictEqual; function notDeepStrictEqual(actual, expected, message) { - if (_deepEqual(actual, expected, true)) { - fail(actual, expected, message, 'notDeepStrictEqual', notDeepStrictEqual); + if (innerDeepEqual(actual, expected, true)) { + fail(actual, expected, message, 'notDeepStrictEqual', + notDeepStrictEqual); } } // The strict equality assertion tests strict equality, as determined by ===. -// assert.strictEqual(actual, expected, message_opt); - assert.strictEqual = function strictEqual(actual, expected, message) { if (actual !== expected) { - fail(actual, expected, message, '===', assert.strictEqual); + fail(actual, expected, message, '===', strictEqual); } }; // The strict non-equality assertion tests for strict inequality, as // determined by !==. -// assert.notStrictEqual(actual, expected, message_opt); - assert.notStrictEqual = function notStrictEqual(actual, expected, message) { if (actual === expected) { - fail(actual, expected, message, '!==', assert.notStrictEqual); + fail(actual, expected, message, '!==', notStrictEqual); } }; @@ -314,7 +295,7 @@ function expectedException(actual, expected) { return expected.call({}, actual) === true; } -function _tryBlock(block) { +function tryBlock(block) { var error; try { block(); @@ -324,9 +305,7 @@ function _tryBlock(block) { return error; } -function _throws(shouldThrow, block, expected, message) { - var actual; - +function innerThrows(shouldThrow, block, expected, message) { if (typeof block !== 'function') { throw new TypeError('"block" argument must be a function'); } @@ -336,13 +315,13 @@ function _throws(shouldThrow, block, expected, message) { expected = null; } - actual = _tryBlock(block); + const actual = tryBlock(block); message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + (message ? ' ' + message : '.'); if (shouldThrow && !actual) { - fail(actual, expected, 'Missing expected exception' + message); + fail(actual, expected, 'Missing expected exception' + message, fail); } const userProvidedMessage = typeof message === 'string'; @@ -353,7 +332,7 @@ function _throws(shouldThrow, block, expected, message) { userProvidedMessage && expectedException(actual, expected)) || isUnexpectedException) { - fail(actual, expected, 'Got unwanted exception' + message); + fail(actual, expected, 'Got unwanted exception' + message, fail); } if ((shouldThrow && actual && expected && @@ -363,15 +342,12 @@ function _throws(shouldThrow, block, expected, message) { } // Expected to throw an error. -// assert.throws(block, Error_opt, message_opt); - -assert.throws = function(block, /*optional*/error, /*optional*/message) { - _throws(true, block, error, message); +assert.throws = function throws(block, error, message) { + innerThrows(true, block, error, message); }; -// EXTENSION! This is annoying to write outside this module. -assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) { - _throws(false, block, error, message); +assert.doesNotThrow = function doesNotThrow(block, error, message) { + innerThrows(false, block, error, message); }; -assert.ifError = function(err) { if (err) throw err; }; +assert.ifError = function ifError(err) { if (err) throw err; }; diff --git a/test/parallel/test-assert-fail.js b/test/parallel/test-assert-fail.js new file mode 100644 index 00000000000000..0423b35ec4d901 --- /dev/null +++ b/test/parallel/test-assert-fail.js @@ -0,0 +1,10 @@ +'use strict'; + +require('../common'); +const assert = require('assert'); + +// The stackFrameFunction should exclude the foo frame +assert.throws( + function foo() { assert.fail('first', 'second', 'message', '!==', foo); }, + (err) => !/foo/m.test(err.stack) +); From abf6355936ee49489f3224c36743e4868edec010 Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Sun, 2 Jul 2017 18:06:35 +0200 Subject: [PATCH 87/92] doc,assert: document stackStartFunction in fail Backport-PR-URL: https://github.com/nodejs/node/pull/15516 PR-URL: https://github.com/nodejs/node/pull/13862 Reviewed-By: Refael Ackermann Reviewed-By: Joyee Cheung --- doc/api/assert.md | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/doc/api/assert.md b/doc/api/assert.md index 2adc5549efb959..6628a6b71df364 100644 --- a/doc/api/assert.md +++ b/doc/api/assert.md @@ -192,7 +192,7 @@ If the values are not equal, an `AssertionError` is thrown with a `message` property set equal to the value of the `message` parameter. If the `message` parameter is undefined, a default error message is assigned. -## assert.fail(actual, expected, message, operator) +## assert.fail(actual, expected[, message[, operator[, stackStartFunction]]]) @@ -200,10 +200,13 @@ added: v0.1.21 * `expected` {any} * `message` {any} * `operator` {string} +* `stackStartFunction` {function} (default: `assert.fail`) Throws an `AssertionError`. If `message` is falsy, the error message is set as the values of `actual` and `expected` separated by the provided `operator`. Otherwise, the error message is the value of `message`. +If `stackStartFunction` is provided, all stack frames above that function will +be removed from stacktrace (see [`Error.captureStackTrace`]). ```js const assert = require('assert'); @@ -211,10 +214,25 @@ const assert = require('assert'); assert.fail(1, 2, undefined, '>'); // AssertionError: 1 > 2 +assert.fail(1, 2, 'fail'); +// AssertionError: fail + assert.fail(1, 2, 'whoops', '>'); // AssertionError: whoops ``` +Example use of `stackStartFunction` for truncating the exception's stacktrace: +```js +function suppressFrame() { + assert.fail('a', 'b', undefined, '!==', suppressFrame); +} +suppressFrame(); +// AssertionError: 'a' !== 'b' +// at repl:1:1 +// at ContextifyScript.Script.runInThisContext (vm.js:44:33) +// ... +``` + ## assert.ifError(value) + Node.js Addons are dynamically-linked shared objects, written in C or C++, that can be loaded into Node.js using the [`require()`][require] function, and used just as if they were an ordinary Node.js module. They are used primarily to diff --git a/doc/api/assert.md b/doc/api/assert.md index 6628a6b71df364..a0eb8d7a4a188e 100644 --- a/doc/api/assert.md +++ b/doc/api/assert.md @@ -1,5 +1,7 @@ # Assert + + > Stability: 2 - Stable The `assert` module provides a simple set of assertion tests that can be used to diff --git a/doc/api/buffer.md b/doc/api/buffer.md index 1f8e8b5becef62..eb2447f4cfff04 100644 --- a/doc/api/buffer.md +++ b/doc/api/buffer.md @@ -1,5 +1,7 @@ # Buffer + + > Stability: 2 - Stable Prior to the introduction of [`TypedArray`] in ECMAScript 2015 (ES6), the diff --git a/doc/api/child_process.md b/doc/api/child_process.md index 6bea59ebac3f12..d04f756eb7f140 100644 --- a/doc/api/child_process.md +++ b/doc/api/child_process.md @@ -1,5 +1,7 @@ # Child Process + + > Stability: 2 - Stable The `child_process` module provides the ability to spawn child processes in diff --git a/doc/api/cli.md b/doc/api/cli.md index 52ad3b324cc492..650e0cdbdb607e 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -1,5 +1,6 @@ # Command Line Options + Node.js comes with a variety of CLI options. These options expose built-in diff --git a/doc/api/cluster.md b/doc/api/cluster.md index 1d605503848963..a846ef0b55d2a0 100644 --- a/doc/api/cluster.md +++ b/doc/api/cluster.md @@ -1,5 +1,7 @@ # Cluster + + > Stability: 2 - Stable A single instance of Node.js runs in a single thread. To take advantage of diff --git a/doc/api/console.md b/doc/api/console.md index f3652a56561316..93ac3bd81ea4de 100644 --- a/doc/api/console.md +++ b/doc/api/console.md @@ -1,5 +1,7 @@ # Console + + > Stability: 2 - Stable The `console` module provides a simple debugging console that is similar to the diff --git a/doc/api/crypto.md b/doc/api/crypto.md index 79c7a3c733e90a..7d94ffd6c77f72 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -1,5 +1,7 @@ # Crypto + + > Stability: 2 - Stable The `crypto` module provides cryptographic functionality that includes a set of diff --git a/doc/api/debugger.md b/doc/api/debugger.md index 1c9b1049e82491..a24437021b7bea 100644 --- a/doc/api/debugger.md +++ b/doc/api/debugger.md @@ -1,5 +1,7 @@ # Debugger + + > Stability: 2 - Stable diff --git a/doc/api/dgram.md b/doc/api/dgram.md index 2aec4abb254643..73e86baa0e175d 100644 --- a/doc/api/dgram.md +++ b/doc/api/dgram.md @@ -1,5 +1,7 @@ # UDP / Datagram Sockets + + > Stability: 2 - Stable diff --git a/doc/api/dns.md b/doc/api/dns.md index 457559d0ce692c..0a34f6efa8052d 100644 --- a/doc/api/dns.md +++ b/doc/api/dns.md @@ -1,5 +1,7 @@ # DNS + + > Stability: 2 - Stable The `dns` module contains functions belonging to two different categories: diff --git a/doc/api/documentation.md b/doc/api/documentation.md index f4b0c876c057c1..8109206ae2f055 100644 --- a/doc/api/documentation.md +++ b/doc/api/documentation.md @@ -1,5 +1,6 @@ # About this Documentation + The goal of this documentation is to comprehensively explain the Node.js diff --git a/doc/api/domain.md b/doc/api/domain.md index e98ccc87a0e346..08d6edc7d8cb24 100644 --- a/doc/api/domain.md +++ b/doc/api/domain.md @@ -1,5 +1,7 @@ # Domain + + > Stability: 0 - Deprecated **This module is pending deprecation**. Once a replacement API has been diff --git a/doc/api/errors.md b/doc/api/errors.md index 10a930ddd73c4b..49b4bac595a6dc 100644 --- a/doc/api/errors.md +++ b/doc/api/errors.md @@ -1,5 +1,6 @@ # Errors + Applications running in Node.js will generally experience four categories of diff --git a/doc/api/events.md b/doc/api/events.md index 7462902e09479a..1cffb5e2d5855f 100644 --- a/doc/api/events.md +++ b/doc/api/events.md @@ -1,5 +1,7 @@ # Events + + > Stability: 2 - Stable diff --git a/doc/api/fs.md b/doc/api/fs.md index 3f0a0f133070f2..7e446f28dcd6e4 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -1,5 +1,7 @@ # File System + + > Stability: 2 - Stable diff --git a/doc/api/globals.md b/doc/api/globals.md index b0467cdacde3a5..054bc2300bd411 100644 --- a/doc/api/globals.md +++ b/doc/api/globals.md @@ -1,5 +1,6 @@ # Global Objects + These objects are available in all modules. Some of these objects aren't diff --git a/doc/api/http.md b/doc/api/http.md index eab2e2721bd60b..2f087d39b36767 100644 --- a/doc/api/http.md +++ b/doc/api/http.md @@ -1,5 +1,7 @@ # HTTP + + > Stability: 2 - Stable To use the HTTP server and client one must `require('http')`. diff --git a/doc/api/https.md b/doc/api/https.md index ea99d8bcdb99b0..6f2a385b270434 100644 --- a/doc/api/https.md +++ b/doc/api/https.md @@ -1,5 +1,7 @@ # HTTPS + + > Stability: 2 - Stable HTTPS is the HTTP protocol over TLS/SSL. In Node.js this is implemented as a diff --git a/doc/api/modules.md b/doc/api/modules.md index 480f9e10ea57be..7e89a94924ba48 100644 --- a/doc/api/modules.md +++ b/doc/api/modules.md @@ -1,5 +1,7 @@ # Modules + + > Stability: 2 - Stable diff --git a/doc/api/net.md b/doc/api/net.md index 5a566dc7cb89c8..3308fc27f0edef 100644 --- a/doc/api/net.md +++ b/doc/api/net.md @@ -1,5 +1,7 @@ # Net + + > Stability: 2 - Stable The `net` module provides you with an asynchronous network wrapper. It contains diff --git a/doc/api/os.md b/doc/api/os.md index e13e3ae4217dd3..3dc2561ad72626 100644 --- a/doc/api/os.md +++ b/doc/api/os.md @@ -1,5 +1,7 @@ # OS + + > Stability: 2 - Stable The `os` module provides a number of operating system-related utility methods. diff --git a/doc/api/path.md b/doc/api/path.md index dfe68f1d3cfcb6..807cf9b88c9869 100644 --- a/doc/api/path.md +++ b/doc/api/path.md @@ -1,5 +1,7 @@ # Path + + > Stability: 2 - Stable The `path` module provides utilities for working with file and directory paths. diff --git a/doc/api/process.md b/doc/api/process.md index 0e8c17af7e605c..885569a4ad48f6 100644 --- a/doc/api/process.md +++ b/doc/api/process.md @@ -1,5 +1,6 @@ # Process + The `process` object is a `global` that provides information about, and control diff --git a/doc/api/punycode.md b/doc/api/punycode.md index 87d1c7d80ad431..f1aedc0cb86cc6 100644 --- a/doc/api/punycode.md +++ b/doc/api/punycode.md @@ -1,5 +1,7 @@ # Punycode + + > Stability: 0 - Deprecated **The version of the punycode module bundled in Node.js is being deprecated**. diff --git a/doc/api/querystring.md b/doc/api/querystring.md index f1f48fadd5fc29..6d39bebbc83b0a 100644 --- a/doc/api/querystring.md +++ b/doc/api/querystring.md @@ -1,5 +1,7 @@ # Query String + + > Stability: 2 - Stable diff --git a/doc/api/readline.md b/doc/api/readline.md index 2c6e29088544cb..bccee609ed3e8e 100644 --- a/doc/api/readline.md +++ b/doc/api/readline.md @@ -1,5 +1,7 @@ # Readline + + > Stability: 2 - Stable The `readline` module provides an interface for reading data from a [Readable][] diff --git a/doc/api/repl.md b/doc/api/repl.md index a9d56c5378ab3e..3cac76497a0a47 100644 --- a/doc/api/repl.md +++ b/doc/api/repl.md @@ -1,5 +1,7 @@ # REPL + + > Stability: 2 - Stable The `repl` module provides a Read-Eval-Print-Loop (REPL) implementation that diff --git a/doc/api/stream.md b/doc/api/stream.md index d78bd3e8817ccb..c4378a2f8ac7af 100644 --- a/doc/api/stream.md +++ b/doc/api/stream.md @@ -1,5 +1,7 @@ # Stream + + > Stability: 2 - Stable A stream is an abstract interface for working with streaming data in Node.js. diff --git a/doc/api/string_decoder.md b/doc/api/string_decoder.md index 17bacf33cbfb9b..2b47317cf0e036 100644 --- a/doc/api/string_decoder.md +++ b/doc/api/string_decoder.md @@ -1,5 +1,7 @@ # String Decoder + + > Stability: 2 - Stable The `string_decoder` module provides an API for decoding `Buffer` objects into diff --git a/doc/api/synopsis.md b/doc/api/synopsis.md index 5e4e22a38b9375..3a9c871d5d5cdc 100644 --- a/doc/api/synopsis.md +++ b/doc/api/synopsis.md @@ -1,5 +1,6 @@ # Usage + `node [options] [v8 options] [script.js | -e "script"] [arguments]` diff --git a/doc/api/timers.md b/doc/api/timers.md index df48905001e19b..010809032c5542 100644 --- a/doc/api/timers.md +++ b/doc/api/timers.md @@ -1,5 +1,7 @@ # Timers + + > Stability: 2 - Stable The `timer` module exposes a global API for scheduling functions to diff --git a/doc/api/tls.md b/doc/api/tls.md index b7e5c8f15e2bf4..12e27959c1c047 100644 --- a/doc/api/tls.md +++ b/doc/api/tls.md @@ -1,5 +1,7 @@ # TLS (SSL) + + > Stability: 2 - Stable The `tls` module provides an implementation of the Transport Layer Security diff --git a/doc/api/tty.md b/doc/api/tty.md index 963de892cbc0fd..2950eb6db1a396 100644 --- a/doc/api/tty.md +++ b/doc/api/tty.md @@ -1,5 +1,7 @@ # TTY + + > Stability: 2 - Stable The `tty` module provides the `tty.ReadStream` and `tty.WriteStream` classes. diff --git a/doc/api/url.md b/doc/api/url.md index 1cb3e2f89f0fd8..6d0911da81d899 100644 --- a/doc/api/url.md +++ b/doc/api/url.md @@ -1,5 +1,7 @@ # URL + + > Stability: 2 - Stable The `url` module provides utilities for URL resolution and parsing. It can be diff --git a/doc/api/util.md b/doc/api/util.md index 0ab3ba0390bc9d..e44d38706f2c37 100644 --- a/doc/api/util.md +++ b/doc/api/util.md @@ -1,5 +1,7 @@ # Util + + > Stability: 2 - Stable The `util` module is primarily designed to support the needs of Node.js' own diff --git a/doc/api/v8.md b/doc/api/v8.md index 0941596084aea1..234835376bd3e0 100644 --- a/doc/api/v8.md +++ b/doc/api/v8.md @@ -1,5 +1,7 @@ # V8 + + The `v8` module exposes APIs that are specific to the version of [V8][] built into the Node.js binary. It can be accessed using: diff --git a/doc/api/vm.md b/doc/api/vm.md index 7d04cbd4d1689d..cd47bc04ea85f6 100644 --- a/doc/api/vm.md +++ b/doc/api/vm.md @@ -1,5 +1,7 @@ # VM (Executing JavaScript) + + > Stability: 2 - Stable diff --git a/doc/api/zlib.md b/doc/api/zlib.md index 17a1464b159de3..9edcc7eae37d88 100644 --- a/doc/api/zlib.md +++ b/doc/api/zlib.md @@ -1,5 +1,7 @@ # Zlib + + > Stability: 2 - Stable The `zlib` module provides compression functionality implemented using Gzip and diff --git a/doc/api_assets/style.css b/doc/api_assets/style.css index a9989e9fdcca84..559245c7cef5a4 100644 --- a/doc/api_assets/style.css +++ b/doc/api_assets/style.css @@ -81,6 +81,61 @@ em code { #gtoc { font-size: .8em; + margin-bottom: 1em; +} + +#gtoc ul { + list-style: none; + margin-left: 0; +} + +#gtoc li { + display: inline; +} + +li.version-picker { + position: relative; +} + +li.version-picker:hover > ol { + display: block; +} + +li.version-picker a span { + font-size: .7em; +} + +ol.version-picker { + background: #fff; + border: 1px #43853d solid; + border-radius: 2px; + display: none; + list-style: none; + position: absolute; + right: -2px; + width: 101%; +} + +#gtoc ol.version-picker li { + display: block; +} + +ol.version-picker li a { + border-radius: 0; + display: block; + margin: 0; + padding: .1em; + padding-left: 1em; +} + +ol.version-picker li:first-child a { + border-top-right-radius: 1px; + border-top-left-radius: 1px; +} + +ol.version-picker li:last-child a { + border-bottom-right-radius: 1px; + border-bottom-left-radius: 1px; } .line { @@ -496,6 +551,9 @@ th > *:last-child, td > *:last-child { #content { font-size: 3.5em; } + #gtoc { + font-size: 0.6em; + } } @media print { diff --git a/doc/template.html b/doc/template.html index 572197beff44fe..d65b56ca5e80ad 100644 --- a/doc/template.html +++ b/doc/template.html @@ -23,11 +23,21 @@

Node.js __VERSION__ Documentation

-

- Index | - View on single page | - View as JSON -

+

diff --git a/tools/doc/html.js b/tools/doc/html.js index bc968f4152155b..49be0ce36fe6fd 100644 --- a/tools/doc/html.js +++ b/tools/doc/html.js @@ -10,6 +10,7 @@ const typeParser = require('./type-parser.js'); module.exports = toHTML; const STABILITY_TEXT_REG_EXP = /(.*:)\s*(\d)([\s\S]*)/; +const DOC_CREATED_REG_EXP = //; // customized heading without id attribute var renderer = new marked.Renderer(); @@ -31,6 +32,8 @@ var gtocPath = path.resolve(path.join( )); var gtocLoading = null; var gtocData = null; +var docCreated = null; +var nodeVersion = null; /** * opts: input, filename, template, nodeVersion. @@ -39,6 +42,8 @@ function toHTML(opts, cb) { var template = opts.template; var nodeVersion = opts.nodeVersion || process.version; + docCreated = opts.input.match(DOC_CREATED_REG_EXP); + if (gtocData) { return onGtocLoaded(); } @@ -136,6 +141,8 @@ function render(opts, cb) { ); } + template = template.replace(/__ALTDOCS__/, altDocs(filename)); + // content has to be the last thing we do with // the lexed tokens, because it's destructive. const content = marked.parser(lexed); @@ -167,6 +174,50 @@ function replaceInText(text) { return linkJsTypeDocs(linkManPages(text)); } +function altDocs(filename) { + let html = ''; + + if (!docCreated) { + console.error(`Failed to add alternative version links to ${filename}`); + return html; + } + + function lte(v) { + const ns = v.num.split('.'); + if (docCreated[1] > +ns[0]) + return false; + if (docCreated[1] < +ns[0]) + return true; + return docCreated[2] <= +ns[1]; + } + + const versions = [ + { num: '8.x' }, + { num: '7.x' }, + { num: '6.x', lts: true }, + { num: '5.x' }, + { num: '4.x', lts: true }, + { num: '0.12.x' }, + { num: '0.10.x' } + ]; + + const host = 'https://nodejs.org'; + const href = (v) => `${host}/docs/latest-v${v.num}/api/${filename}.html`; + + function li(v, i) { + let html = `
  • ${v.num}`; + + if (v.lts) + html += ' LTS'; + + return html + '
  • '; + } + + const lis = (vs) => vs.filter(lte).map(li).join('\n'); + + return `
      ${lis(versions)}
    `; +} + // handle general body-text replacements // for example, link man page references to the actual page function parseText(lexed) { From 37dd2adbacad81d9aa6f091806566d97b0e894c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Mon, 28 Aug 2017 16:57:33 +0200 Subject: [PATCH 90/92] tools: fix linter error in html.js Backport-PR-URL: https://github.com/nodejs/node/pull/15670 PR-URL: https://github.com/nodejs/node/pull/15063 Reviewed-By: Colin Ihrig Reviewed-By: Rich Trott Reviewed-By: Yuta Hiroto --- tools/doc/html.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tools/doc/html.js b/tools/doc/html.js index 49be0ce36fe6fd..9b6d93b7a7bb1c 100644 --- a/tools/doc/html.js +++ b/tools/doc/html.js @@ -175,11 +175,9 @@ function replaceInText(text) { } function altDocs(filename) { - let html = ''; - if (!docCreated) { console.error(`Failed to add alternative version links to ${filename}`); - return html; + return ''; } function lte(v) { From a13ac69ff9157648b191b33d3dc0282444b7e84d Mon Sep 17 00:00:00 2001 From: Chris Young Date: Wed, 13 Sep 2017 17:37:32 -0700 Subject: [PATCH 91/92] doc: prevent displaying empty version picker Backport-PR-URL: https://github.com/nodejs/node/pull/15670 PR-URL: https://github.com/nodejs/node/pull/15420 Fixes: https://github.com/nodejs/node/issues/15396 Reviewed-By: James M Snell Reviewed-By: Refael Ackermann Reviewed-By: Evan Lucas Reviewed-By: Ruben Bridgewater --- doc/api_assets/style.css | 12 ++++++++++++ doc/template.html | 11 ++++------- tools/doc/html.js | 13 ++++++++++--- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/doc/api_assets/style.css b/doc/api_assets/style.css index 559245c7cef5a4..53e6f0aa8624a3 100644 --- a/doc/api_assets/style.css +++ b/doc/api_assets/style.css @@ -91,6 +91,15 @@ em code { #gtoc li { display: inline; + border-right: 1px #000 solid; + margin-right: 0.4em; + padding-right: 0.4em; +} + +#gtoc li:last-child { + border-right: none; + margin-right: 0; + padding-right: 0; } li.version-picker { @@ -118,6 +127,9 @@ ol.version-picker { #gtoc ol.version-picker li { display: block; + border-right: 0; + margin-right: 0; + width: 100%; } ol.version-picker li a { diff --git a/doc/template.html b/doc/template.html index d65b56ca5e80ad..165e47022c8124 100644 --- a/doc/template.html +++ b/doc/template.html @@ -25,18 +25,15 @@

    Node.js __VERSION__ Documentation


    diff --git a/tools/doc/html.js b/tools/doc/html.js index 9b6d93b7a7bb1c..c4ed0b0eda7bbe 100644 --- a/tools/doc/html.js +++ b/tools/doc/html.js @@ -33,7 +33,6 @@ var gtocPath = path.resolve(path.join( var gtocLoading = null; var gtocData = null; var docCreated = null; -var nodeVersion = null; /** * opts: input, filename, template, nodeVersion. @@ -211,9 +210,17 @@ function altDocs(filename) { return html + ''; } - const lis = (vs) => vs.filter(lte).map(li).join('\n'); + const lis = versions.filter(lte).map(li).join('\n'); - return `
      ${lis(versions)}
    `; + if (!lis.length) + return ''; + + return ` +
  • + View another version +
      ${lis}
    +
  • + `; } // handle general body-text replacements From 8691fdfea58aece4e235203511ebe15ad8db3760 Mon Sep 17 00:00:00 2001 From: Myles Borins Date: Wed, 20 Sep 2017 17:23:45 -0400 Subject: [PATCH 92/92] 2017-10-03, Version 6.11.4 'Boron' (LTS) Notable Changes: * net: - support passing undefined to listen() to match behavior in v4.x and v8.x (Sam Roberts) https://github.com/nodejs/node/pull/14234 PR-URL: https://github.com/nodejs/node/pull/15506 --- CHANGELOG.md | 3 +- doc/changelogs/CHANGELOG_V6.md | 106 +++++++++++++++++++++++++++++++++ src/node_version.h | 2 +- 3 files changed, 109 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b159dc31727017..3652dd6a5e8d59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,7 +26,8 @@ release. -6.11.3
    +6.11.4
    +6.11.3
    6.11.2
    6.11.1
    6.11.0
    diff --git a/doc/changelogs/CHANGELOG_V6.md b/doc/changelogs/CHANGELOG_V6.md index 3e4e22bd321b29..2134efa73c23da 100644 --- a/doc/changelogs/CHANGELOG_V6.md +++ b/doc/changelogs/CHANGELOG_V6.md @@ -7,6 +7,7 @@ +6.11.4
    6.11.3
    6.11.2
    6.11.1
    @@ -52,6 +53,111 @@ [Node.js Long Term Support Plan](https://github.com/nodejs/LTS) and will be supported actively until April 2018 and maintained until April 2019. + +## 2017-10-03, Version 6.11.4 'Boron' (LTS), @MylesBorins + +This LTS release comes with 91 commits. This includes 29 which are test related, +28 which are doc related, 11 which are build / tool related and 3 commits which are updates to dependencies. + +### Notable Changes + +* **net**: + - support passing undefined to listen() to match behavior in v4.x and v8.x (Sam Roberts) [#14234](https://github.com/nodejs/node/pull/14234) + +### Commits + +* [[`73416b46e4`](https://github.com/nodejs/node/commit/73416b46e4)] - **assert**: refactor the code (Ruben Bridgewater) [#13862](https://github.com/nodejs/node/pull/13862) +* [[`a8b917ee2f`](https://github.com/nodejs/node/commit/a8b917ee2f)] - **benchmark**: fix dgram/bind-params.js benchmark (Rich Trott) [#14948](https://github.com/nodejs/node/pull/14948) +* [[`855d7ae326`](https://github.com/nodejs/node/commit/855d7ae326)] - **benchmark**: convert var to es6 const (Sebastian Murphy) [#12886](https://github.com/nodejs/node/pull/12886) +* [[`6a7e46ed9c`](https://github.com/nodejs/node/commit/6a7e46ed9c)] - **build**: add NetBSD support to opensslconf.h (Roy Marples) [#14313](https://github.com/nodejs/node/pull/14313) +* [[`66dd898be8`](https://github.com/nodejs/node/commit/66dd898be8)] - **build**: better support for python3 systems (Ben Noordhuis) [#14737](https://github.com/nodejs/node/pull/14737) +* [[`14cc1abb56`](https://github.com/nodejs/node/commit/14cc1abb56)] - **build**: split up cpplint to avoid long cmd lines (Kyle Farnung) [#14116](https://github.com/nodejs/node/pull/14116) +* [[`c9ae894277`](https://github.com/nodejs/node/commit/c9ae894277)] - **build**: add lint option to vcbuild.bat help (Morgan Brenner) [#11992](https://github.com/nodejs/node/pull/11992) +* [[`66cdcd9d5b`](https://github.com/nodejs/node/commit/66cdcd9d5b)] - **build**: add cpp linting to windows build (liusi) [#11856](https://github.com/nodejs/node/pull/11856) +* [[`25be2a3be3`](https://github.com/nodejs/node/commit/25be2a3be3)] - **crypto**: naming anonymous functions. (solebox) [#8993](https://github.com/nodejs/node/pull/8993) +* [[`4e1a50a079`](https://github.com/nodejs/node/commit/4e1a50a079)] - **deps**: backport 0353a1e from V8 upstream (jBarz) [#15287](https://github.com/nodejs/node/pull/15287) +* [[`921876dcd1`](https://github.com/nodejs/node/commit/921876dcd1)] - **deps**: backport 071b655 from V8 upstream (Michaël Zasso) [#15215](https://github.com/nodejs/node/pull/15215) +* [[`a13ac69ff9`](https://github.com/nodejs/node/commit/a13ac69ff9)] - **doc**: prevent displaying empty version picker (Chris Young) [#15420](https://github.com/nodejs/node/pull/15420) +* [[`ecea33b277`](https://github.com/nodejs/node/commit/ecea33b277)] - **doc**: add links to alternative versions of doc (Chris Young) [#10958](https://github.com/nodejs/node/pull/10958) +* [[`feb6863a5c`](https://github.com/nodejs/node/commit/feb6863a5c)] - **doc**: document bytes to chars after setEncoding (Jessica Quynh Tran) [#13442](https://github.com/nodejs/node/pull/13442) +* [[`33fdbb5417`](https://github.com/nodejs/node/commit/33fdbb5417)] - **doc**: describe what security issues are (Sam Roberts) [#14485](https://github.com/nodejs/node/pull/14485) +* [[`a260190717`](https://github.com/nodejs/node/commit/a260190717)] - **doc**: instructions for generating coverage reports (Simon Brewster) [#15190](https://github.com/nodejs/node/pull/15190) +* [[`1b0e660c25`](https://github.com/nodejs/node/commit/1b0e660c25)] - **doc**: /s/SHASUM256/SHASUMS256 (Jon Moss) [#15101](https://github.com/nodejs/node/pull/15101) +* [[`5696223534`](https://github.com/nodejs/node/commit/5696223534)] - **doc**: clarify http.get data consumption requirement (AJ Jordan) [#15049](https://github.com/nodejs/node/pull/15049) +* [[`4c26913dab`](https://github.com/nodejs/node/commit/4c26913dab)] - **doc**: crypto.randomBytes does not block when async (Sam Roberts) [#14993](https://github.com/nodejs/node/pull/14993) +* [[`605a02b613`](https://github.com/nodejs/node/commit/605a02b613)] - **doc**: environmental-\>environment & NodeJS-\>Node.js (Rod Vagg) [#14974](https://github.com/nodejs/node/pull/14974) +* [[`b10bc31030`](https://github.com/nodejs/node/commit/b10bc31030)] - **doc**: fix typo in Buffer.from(string, \[encoding\]) (Michał Wadas) [#15013](https://github.com/nodejs/node/pull/15013) +* [[`29de000938`](https://github.com/nodejs/node/commit/29de000938)] - **doc**: add note for Windows build path (Kyle Lamse) [#14354](https://github.com/nodejs/node/pull/14354) +* [[`7546eef262`](https://github.com/nodejs/node/commit/7546eef262)] - **doc**: rephrase text of child_process.execSync() (hafiz) [#14953](https://github.com/nodejs/node/pull/14953) +* [[`70e9a6ece3`](https://github.com/nodejs/node/commit/70e9a6ece3)] - **doc**: link to correct "OS Constants" heading in docs (James Kyle) [#14969](https://github.com/nodejs/node/pull/14969) +* [[`55dc14ec61`](https://github.com/nodejs/node/commit/55dc14ec61)] - **doc**: remove misterdjules from the CTC members list (Julien Gilli) [#1498](https://github.com/nodejs/node/pull/1498) +* [[`c76a54f318`](https://github.com/nodejs/node/commit/c76a54f318)] - **doc**: add missing word (Jon Moss) [#14924](https://github.com/nodejs/node/pull/14924) +* [[`27b6737d85`](https://github.com/nodejs/node/commit/27b6737d85)] - **doc**: explain what to do if git push is rejected (Rich Trott) [#14848](https://github.com/nodejs/node/pull/14848) +* [[`d75e9b7d44`](https://github.com/nodejs/node/commit/d75e9b7d44)] - **doc**: add BridgeAR to collaborators (Ruben Bridgewater) [#14862](https://github.com/nodejs/node/pull/14862) +* [[`a63cd82003`](https://github.com/nodejs/node/commit/a63cd82003)] - **doc**: fix word wrapping for api stability boxes (Saad Quadri) [#14809](https://github.com/nodejs/node/pull/14809) +* [[`f8fbac7842`](https://github.com/nodejs/node/commit/f8fbac7842)] - **doc**: improve fs.read() doc text (Rich Trott) [#14631](https://github.com/nodejs/node/pull/14631) +* [[`5a7a49f505`](https://github.com/nodejs/node/commit/5a7a49f505)] - **doc**: clarify the position argument for fs.read (dcharbonnier) [#14631](https://github.com/nodejs/node/pull/14631) +* [[`b5904a2054`](https://github.com/nodejs/node/commit/b5904a2054)] - **doc**: remove undef NDEBUG from addons.md (Daniel Bevenius) [#14048](https://github.com/nodejs/node/pull/14048) +* [[`c0e47e4f22`](https://github.com/nodejs/node/commit/c0e47e4f22)] - **doc**: fix order of AtExit callbacks in addons.md (Daniel Bevenius) [#14048](https://github.com/nodejs/node/pull/14048) +* [[`dcdc9053b4`](https://github.com/nodejs/node/commit/dcdc9053b4)] - **doc**: fix typo in stream.md (Marc Hernández Cabot) [#14364](https://github.com/nodejs/node/pull/14364) +* [[`594e3c2115`](https://github.com/nodejs/node/commit/594e3c2115)] - **doc**: add readline.emitKeypressEvents note (Samuel Reed) [#9447](https://github.com/nodejs/node/pull/9447) +* [[`90fcccd7a3`](https://github.com/nodejs/node/commit/90fcccd7a3)] - **doc**: add documentation on ICU (Timothy Gu) [#13916](https://github.com/nodejs/node/pull/13916) +* [[`38ae5c4e34`](https://github.com/nodejs/node/commit/38ae5c4e34)] - **doc, lib, test**: do not re-require needlessly (Vse Mozhet Byt) [#14244](https://github.com/nodejs/node/pull/14244) +* [[`abf6355936`](https://github.com/nodejs/node/commit/abf6355936)] - **doc,assert**: document stackStartFunction in fail (Ruben Bridgewater) [#13862](https://github.com/nodejs/node/pull/13862) +* [[`f0328f631a`](https://github.com/nodejs/node/commit/f0328f631a)] - **doc,stream**: remove wrong remark on readable.read (Jan Schär) [#15014](https://github.com/nodejs/node/pull/15014) +* [[`0c670e0339`](https://github.com/nodejs/node/commit/0c670e0339)] - **http**: eliminate capture of ClientRequest in Agent (Evan Torrie) [#10134](https://github.com/nodejs/node/pull/10134) +* [[`67074113dc`](https://github.com/nodejs/node/commit/67074113dc)] - **http**: reset stream to unconsumed in `unconsume()` (Anna Henningsen) [#14410](https://github.com/nodejs/node/pull/14410) +* [[`e65c9ec7f4`](https://github.com/nodejs/node/commit/e65c9ec7f4)] - **http**: assert parser.consume argument's type (Gireesh Punathil) [#12288](https://github.com/nodejs/node/pull/12288) +* [[`4e717820a0`](https://github.com/nodejs/node/commit/4e717820a0)] - **lib**: clean up usage of threw (Jackson Tian) [#10534](https://github.com/nodejs/node/pull/10534) +* [[`e014178362`](https://github.com/nodejs/node/commit/e014178362)] - **meta**: merge TSC and CTC back into a single body (James M Snell) [#14973](https://github.com/nodejs/node/pull/14973) +* [[`4ee066eaba`](https://github.com/nodejs/node/commit/4ee066eaba)] - **meta**: considerations for new core modules (James M Snell) [#15022](https://github.com/nodejs/node/pull/15022) +* [[`948a7d70e7`](https://github.com/nodejs/node/commit/948a7d70e7)] - **meta**: improve definition of a collaborator (James M Snell) [#14981](https://github.com/nodejs/node/pull/14981) +* [[`caeee38b1d`](https://github.com/nodejs/node/commit/caeee38b1d)] - **net**: support passing undefined to listen() (Sam Roberts) [#14234](https://github.com/nodejs/node/pull/14234) +* [[`792acc17bf`](https://github.com/nodejs/node/commit/792acc17bf)] - **net**: fix abort on bad address input (Ruben Bridgewater) [#13726](https://github.com/nodejs/node/pull/13726) +* [[`8604772960`](https://github.com/nodejs/node/commit/8604772960)] - **readline**: remove max limit of crlfDelay (Azard) [#13497](https://github.com/nodejs/node/pull/13497) +* [[`362a7c0d8b`](https://github.com/nodejs/node/commit/362a7c0d8b)] - **repl**: do not consider `...` as a REPL command (Shivanth MP) [#14467](https://github.com/nodejs/node/pull/14467) +* [[`968121bbfe`](https://github.com/nodejs/node/commit/968121bbfe)] - **src**: remove unnecessary helper function (Brian White) [#14959](https://github.com/nodejs/node/pull/14959) +* [[`b2112f8d36`](https://github.com/nodejs/node/commit/b2112f8d36)] - **src**: detect nul bytes in InternalModuleReadFile() (Ben Noordhuis) [#14854](https://github.com/nodejs/node/pull/14854) +* [[`d20b7bfb6e`](https://github.com/nodejs/node/commit/d20b7bfb6e)] - **src**: use local isolate instead of args.GetIsolate (Daniel Bevenius) [#14768](https://github.com/nodejs/node/pull/14768) +* [[`66187fa044`](https://github.com/nodejs/node/commit/66187fa044)] - **stream**: fix Writable instanceof for subclasses (Anna Henningsen) [#14945](https://github.com/nodejs/node/pull/14945) +* [[`2c8fe9748c`](https://github.com/nodejs/node/commit/2c8fe9748c)] - **test**: remove envPlus, use Object.assign everywhere (Gibson Fahnestock) [#14845](https://github.com/nodejs/node/pull/14845) +* [[`8e00315506`](https://github.com/nodejs/node/commit/8e00315506)] - **test**: check zlib version for createDeflateRaw (Daniel Bevenius) [#13697](https://github.com/nodejs/node/pull/13697) +* [[`2babae4cd4`](https://github.com/nodejs/node/commit/2babae4cd4)] - **test**: refactor test-fs-readfile-unlink (Rich Trott) [#15173](https://github.com/nodejs/node/pull/15173) +* [[`8b045747e0`](https://github.com/nodejs/node/commit/8b045747e0)] - **test**: pipe some error output if npm fails (Jeremiah Senkpiel) [#12490](https://github.com/nodejs/node/pull/12490) +* [[`6540e99547`](https://github.com/nodejs/node/commit/6540e99547)] - **test**: simplify test-tls-client-default-ciphers (Jon Moss) [#14928](https://github.com/nodejs/node/pull/14928) +* [[`ad1d745498`](https://github.com/nodejs/node/commit/ad1d745498)] - **test**: extend async addon test (Anna Henningsen) [#14922](https://github.com/nodejs/node/pull/14922) +* [[`1e231ba8c7`](https://github.com/nodejs/node/commit/1e231ba8c7)] - **test**: add known issue for vm module (Franziska Hinkelmann) [#14661](https://github.com/nodejs/node/pull/14661) +* [[`644d9905a0`](https://github.com/nodejs/node/commit/644d9905a0)] - **test**: do not modify fixtures in test-fs-chmod (Rich Trott) [#14926](https://github.com/nodejs/node/pull/14926) +* [[`168f73c5f4`](https://github.com/nodejs/node/commit/168f73c5f4)] - **test**: improve assertion fail messages (Refael Ackermann) [#14949](https://github.com/nodejs/node/pull/14949) +* [[`915b56b963`](https://github.com/nodejs/node/commit/915b56b963)] - **test**: remove unused arguments from function (Ankit Parashar) [#14931](https://github.com/nodejs/node/pull/14931) +* [[`724508295d`](https://github.com/nodejs/node/commit/724508295d)] - **test**: make timers-blocking-callback more reliable (Rich Trott) [#14831](https://github.com/nodejs/node/pull/14831) +* [[`4fb4fbea1c`](https://github.com/nodejs/node/commit/4fb4fbea1c)] - **test**: add missing console.error to exec-maxBuffer (Beth Griggs) [#14796](https://github.com/nodejs/node/pull/14796) +* [[`a284ee6129`](https://github.com/nodejs/node/commit/a284ee6129)] - **test**: invoke callback with common.mustCall() (Griffith Tchenpan) [#8597](https://github.com/nodejs/node/pull/8597) +* [[`32260b91f2`](https://github.com/nodejs/node/commit/32260b91f2)] - **test**: check crypto before requiring tls module (Daniel Bevenius) [#14708](https://github.com/nodejs/node/pull/14708) +* [[`68cf7f0b30`](https://github.com/nodejs/node/commit/68cf7f0b30)] - **test**: improve multiple zlib tests (James M Snell) [#14455](https://github.com/nodejs/node/pull/14455) +* [[`f35f06d04c`](https://github.com/nodejs/node/commit/f35f06d04c)] - **test**: improve multiple vm tests (James M Snell) [#14458](https://github.com/nodejs/node/pull/14458) +* [[`1aac05b087`](https://github.com/nodejs/node/commit/1aac05b087)] - **test**: cover all HTTP methods that parser supports (Oky Antoro) [#14773](https://github.com/nodejs/node/pull/14773) +* [[`9f330250b5`](https://github.com/nodejs/node/commit/9f330250b5)] - **test**: remove redundant `using` in cctest (XadillaX) [#14739](https://github.com/nodejs/node/pull/14739) +* [[`91649b913c`](https://github.com/nodejs/node/commit/91649b913c)] - **test**: make test-tls-connect checks more strict (Rich Trott) [#14695](https://github.com/nodejs/node/pull/14695) +* [[`9ed2c4cb0e`](https://github.com/nodejs/node/commit/9ed2c4cb0e)] - **test**: add block scoping to test-readline-interface (Rich Trott) [#14615](https://github.com/nodejs/node/pull/14615) +* [[`4fb755c432`](https://github.com/nodejs/node/commit/4fb755c432)] - **test**: set module loading error for aix (Prakash Palaniappan) [#14511](https://github.com/nodejs/node/pull/14511) +* [[`9d8464161e`](https://github.com/nodejs/node/commit/9d8464161e)] - **test**: fix conversion of microseconds in test (Nick Stanish) [#14706](https://github.com/nodejs/node/pull/14706) +* [[`28b77d1f8b`](https://github.com/nodejs/node/commit/28b77d1f8b)] - **test**: improve check in test-os (Rich Trott) [#14655](https://github.com/nodejs/node/pull/14655) +* [[`fc49cf41ea`](https://github.com/nodejs/node/commit/fc49cf41ea)] - **test**: improve multiple timers tests (James M Snell) [#14616](https://github.com/nodejs/node/pull/14616) +* [[`c88f99f1f3`](https://github.com/nodejs/node/commit/c88f99f1f3)] - **test**: improvements to various http tests (James M Snell) [#14315](https://github.com/nodejs/node/pull/14315) +* [[`860c6198c0`](https://github.com/nodejs/node/commit/860c6198c0)] - **test**: use ciphers supported by shared OpenSSL (Jérémy Lal) [#14566](https://github.com/nodejs/node/pull/14566) +* [[`8b9a05c04b`](https://github.com/nodejs/node/commit/8b9a05c04b)] - **test**: read proper inspector message size (Bartosz Sosnowski) [#14596](https://github.com/nodejs/node/pull/14596) +* [[`86497f1acc`](https://github.com/nodejs/node/commit/86497f1acc)] - **test**: mark inspector-port-zero-cluster as flaky (Refael Ackermann) +* [[`8dfc2838c8`](https://github.com/nodejs/node/commit/8dfc2838c8)] - **test**: fix test-readline-interface (Azard) [#14677](https://github.com/nodejs/node/pull/14677) +* [[`3a6392b283`](https://github.com/nodejs/node/commit/3a6392b283)] - **tls**: fix empty issuer/subject/infoAccess parsing (Ben Noordhuis) [#14473](https://github.com/nodejs/node/pull/14473) +* [[`37dd2adbac`](https://github.com/nodejs/node/commit/37dd2adbac)] - **tools**: fix linter error in html.js (Michaël Zasso) [#15063](https://github.com/nodejs/node/pull/15063) +* [[`8b3ac4b2a2`](https://github.com/nodejs/node/commit/8b3ac4b2a2)] - **tools**: add custom private key option (Ruslan Bekenev) [#14401](https://github.com/nodejs/node/pull/14401) +* [[`cac4beb764`](https://github.com/nodejs/node/commit/cac4beb764)] - **tools**: fix update-eslint.sh (Myles Borins) [#14850](https://github.com/nodejs/node/pull/14850) +* [[`debea1c531`](https://github.com/nodejs/node/commit/debea1c531)] - **tools**: delete an unused argument (phisixersai) [#14251](https://github.com/nodejs/node/pull/14251) +* [[`ca61f3bd80`](https://github.com/nodejs/node/commit/ca61f3bd80)] - **tools**: fix tools/addon-verify.js (Daniel Bevenius) [#14048](https://github.com/nodejs/node/pull/14048) +* [[`f7b6d198b9`](https://github.com/nodejs/node/commit/f7b6d198b9)] - **tools**: eslint - use `error` and `off` (Refael Ackermann) [#14061](https://github.com/nodejs/node/pull/14061) +* [[`f8b85e16cd`](https://github.com/nodejs/node/commit/f8b85e16cd)] - **tools**: replace assert-throw-arguments custom lint (Rich Trott) [#14547](https://github.com/nodejs/node/pull/14547) + ## 2017-09-05, Version 6.11.3 'Boron' (LTS), @MylesBorins diff --git a/src/node_version.h b/src/node_version.h index 903b0b55c4ff48..b03e541b4d0537 100644 --- a/src/node_version.h +++ b/src/node_version.h @@ -8,7 +8,7 @@ #define NODE_VERSION_IS_LTS 1 #define NODE_VERSION_LTS_CODENAME "Boron" -#define NODE_VERSION_IS_RELEASE 0 +#define NODE_VERSION_IS_RELEASE 1 #ifndef NODE_STRINGIFY #define NODE_STRINGIFY(n) NODE_STRINGIFY_HELPER(n)