From fe5b71028dcdb666fafafc4e1cbdd26c7310aed1 Mon Sep 17 00:00:00 2001 From: "julien.waechter" Date: Tue, 12 Jan 2016 09:21:46 +0100 Subject: [PATCH 01/33] build: add option to select VS version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This changes vcbuild.bat to accept a new parameter (vc2015 or vc2013) to select the version of Visual Studio to use. PR-URL: https://github.com/nodejs/node/pull/4645 Reviewed-By: João Reis --- vcbuild.bat | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/vcbuild.bat b/vcbuild.bat index e33f8cb652a536..260a86000b436d 100644 --- a/vcbuild.bat +++ b/vcbuild.bat @@ -15,6 +15,7 @@ if /i "%1"=="/?" goto help set config=Release set target=Build set target_arch=x86 +set target_env= set noprojgen= set nobuild= set nosign= @@ -44,6 +45,8 @@ if /i "%1"=="clean" set target=Clean&goto arg-ok if /i "%1"=="ia32" set target_arch=x86&goto arg-ok if /i "%1"=="x86" set target_arch=x86&goto arg-ok if /i "%1"=="x64" set target_arch=x64&goto arg-ok +if /i "%1"=="vc2013" set target_env=vc2013&goto arg-ok +if /i "%1"=="vc2015" set target_env=vc2015&goto arg-ok if /i "%1"=="noprojgen" set noprojgen=1&goto arg-ok if /i "%1"=="nobuild" set nobuild=1&goto arg-ok if /i "%1"=="nosign" set nosign=1&goto arg-ok @@ -110,6 +113,7 @@ call :getnodeversion || exit /b 1 @rem Set environment for msbuild +if defined target_env if "%target_env%" NEQ "vc2015" goto vc-set-2013 @rem Look for Visual Studio 2015 echo Looking for Visual Studio 2015 if not defined VS140COMNTOOLS goto vc-set-2013 @@ -133,6 +137,7 @@ set PLATFORM_TOOLSET=v140 goto msbuild-found :vc-set-2013 +if defined target_env if "%target_env%" NEQ "vc2013" goto msbuild-not-found @rem Look for Visual Studio 2013 echo Looking for Visual Studio 2013 if not defined VS120COMNTOOLS goto msbuild-not-found @@ -262,7 +267,7 @@ echo Failed to create vc project files. goto exit :help -echo vcbuild.bat [debug/release] [msi] [test-all/test-uv/test-internet/test-pummel/test-simple/test-message] [clean] [noprojgen] [small-icu/full-icu/intl-none] [nobuild] [nosign] [x86/x64] [download-all] [enable-vtune] +echo vcbuild.bat [debug/release] [msi] [test-all/test-uv/test-internet/test-pummel/test-simple/test-message] [clean] [noprojgen] [small-icu/full-icu/intl-none] [nobuild] [nosign] [x86/x64] [vc2013/vc2015] [download-all] [enable-vtune] echo Examples: echo vcbuild.bat : builds release build echo vcbuild.bat debug : builds debug build From 8bf5b3301971f21efb50ee663ebc25533373cb90 Mon Sep 17 00:00:00 2001 From: Fedor Indutny Date: Thu, 14 Jan 2016 04:35:04 -0500 Subject: [PATCH 02/33] crypto: clear error stack in ECDH::Initialize Clean up OpenSSL error stack in `ECDH::Initialize`, some curves have faulty implementations that are leaving dangling errors after initializing the curve. Fix: #4686 PR-URL: https://github.com/nodejs/node/pull/4689 Reviewed-By: Sakthipriyan Vairamani Reviewed-By: Shigeki Ohtsu --- src/node_crypto.cc | 2 ++ test/parallel/test-crypto-dh.js | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 35a0687b9f95ec..700e658417d2aa 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -4678,6 +4678,8 @@ void ECDH::Initialize(Environment* env, Local target) { void ECDH::New(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); + MarkPopErrorOnReturn mark_pop_error_on_return; + // TODO(indutny): Support raw curves? CHECK(args[0]->IsString()); node::Utf8Value curve(env->isolate(), args[0]); diff --git a/test/parallel/test-crypto-dh.js b/test/parallel/test-crypto-dh.js index a1e8fb1d7da4ac..68394dd9bcaff9 100644 --- a/test/parallel/test-crypto-dh.js +++ b/test/parallel/test-crypto-dh.js @@ -159,6 +159,11 @@ secret2 = ecdh2.computeSecret(key1, 'binary', 'buffer'); assert.equal(secret1, secret2.toString('base64')); +// Oakley curves do not clean up ERR stack, it was causing unexpected failure +// when accessing other OpenSSL APIs afterwards. +crypto.createECDH('Oakley-EC2N-3'); +crypto.createHash('sha256'); + // Point formats assert.equal(ecdh1.getPublicKey('buffer', 'uncompressed')[0], 4); let firstByte = ecdh1.getPublicKey('buffer', 'compressed')[0]; From 0d0a5ed8166634cf2712a84f6e0bd6b700a3a6fa Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Mon, 11 Jan 2016 15:38:38 -0800 Subject: [PATCH 03/33] debugger: remove variable redeclarations Some variables are declared with var more than once in the same scope. This change reduces the declarations to one per scope. PR-URL: https://github.com/nodejs/node/pull/4633 Reviewed-By: jasnell - James M Snell Reviewed-By: Colin Ihrig --- lib/_debugger.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/_debugger.js b/lib/_debugger.js index 58dc6dbb849751..9637d4ca03488b 100644 --- a/lib/_debugger.js +++ b/lib/_debugger.js @@ -462,7 +462,7 @@ Client.prototype.setBreakpoint = function(req, cb) { }; Client.prototype.clearBreakpoint = function(req, cb) { - var req = { + req = { command: 'clearbreakpoint', arguments: req }; @@ -1352,9 +1352,10 @@ Interface.prototype.setBreakpoint = function(script, line, return; } + let req; if (/\(\)$/.test(script)) { // setBreakpoint('functionname()'); - var req = { + req = { type: 'function', target: script.replace(/\(\)$/, ''), condition: condition @@ -1380,7 +1381,6 @@ Interface.prototype.setBreakpoint = function(script, line, if (ambiguous) return this.error('Script name is ambiguous'); if (line <= 0) return this.error('Line should be a positive value'); - var req; if (scriptId) { req = { type: 'scriptId', @@ -1651,7 +1651,7 @@ Interface.prototype.trySpawn = function(cb) { var isRemote = false; if (this.args.length === 2) { - var match = this.args[1].match(/^([^:]+):(\d+)$/); + const match = this.args[1].match(/^([^:]+):(\d+)$/); if (match) { // Connecting to remote debugger @@ -1675,7 +1675,7 @@ Interface.prototype.trySpawn = function(cb) { } isRemote = true; } else { - var match = this.args[1].match(/^--port=(\d+)$/); + const match = this.args[1].match(/^--port=(\d+)$/); if (match) { // Start debugger on custom port // `node debug --port=5858 app.js` From dcaf6fd80b9dc391ac3ca607dfe01e01cfeaa8ae Mon Sep 17 00:00:00 2001 From: cjihrig Date: Fri, 15 Jan 2016 11:45:49 -0500 Subject: [PATCH 04/33] doc: clarify protocol default in http.request() The previously listed default of 'http' is incorrect, and causes an error to be thrown. This commit changes it to the correct value of 'http:' Fixes: https://github.com/nodejs/node/issues/4712 PR-URL: https://github.com/nodejs/node/pull/4714 Reviewed-By: James M Snell --- doc/api/http.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/http.markdown b/doc/api/http.markdown index 010427ef921592..717651aacb8867 100644 --- a/doc/api/http.markdown +++ b/doc/api/http.markdown @@ -992,7 +992,7 @@ automatically parsed with [`url.parse()`][]. Options: -- `protocol`: Protocol to use. Defaults to `'http'`. +- `protocol`: Protocol to use. Defaults to `'http:'`. - `host`: A domain name or IP address of the server to issue the request to. Defaults to `'localhost'`. - `hostname`: Alias for `host`. To support [`url.parse()`][] `hostname` is From 43dfd03d2cb8c5e780095e246a4f2ccf6a5805b4 Mon Sep 17 00:00:00 2001 From: Rod Vagg Date: Fri, 15 Jan 2016 00:10:04 +1100 Subject: [PATCH 05/33] doc: update branch-diff arguments in release doc PR-URL: https://github.com/nodejs/node/pull/4691 Reviewed-By: Colin Ihrig Reviewed-By: Evan Lucas Reviewed-By: Jeremiah Senkpiel --- doc/releases.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/releases.md b/doc/releases.md index daa325b0bce351..c41241de0ef717 100644 --- a/doc/releases.md +++ b/doc/releases.md @@ -57,7 +57,7 @@ Create a new branch named _"vx.y.z-proposal"_, or something similar. Using `git For a list of commits that could be landed in a patch release on v5.x ``` -$ branch-diff v5.x master --exclude-label semver-major,semver-minor,dont-land-on-v5.x --simple +$ branch-diff v5.x master --exclude-label=semver-major,semver-minor,dont-land-on-v5.x --filter-release --format=simple ``` Carefully review the list of commits looking for errors (incorrect `PR-URL`, incorrect semver, etc.). Commits labeled as semver minor or semver major should only be cherry-picked when appropriate for the type of release being made. Previous release commits and version bumps do not need to be cherry-picked. From 01bdafe5e0c81e5f149593c5fd091e26ce6eb64d Mon Sep 17 00:00:00 2001 From: Michael Theriot Date: Thu, 14 Jan 2016 23:56:17 -0600 Subject: [PATCH 06/33] doc: fix named anchors in addons.markdown and http.markdown PR-URL: https://github.com/nodejs/node/pull/4708 Reviewed-By: Colin Ihrig Reviewed-By: James M Snell --- doc/api/addons.markdown | 2 +- doc/api/http.markdown | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/api/addons.markdown b/doc/api/addons.markdown index ed2c5058a49288..845b20c2bdb2b1 100644 --- a/doc/api/addons.markdown +++ b/doc/api/addons.markdown @@ -1018,5 +1018,5 @@ Test in JavaScript by running: [Native Abstrations for Node.js]: https://github.com/nodejs/nan [examples]: https://github.com/nodejs/nan/tree/master/examples/ [bindings]: https://github.com/TooTallNate/node-bindings -[Linking to Node.js' own dependencies]: #linking-to-node-js-own-dependencies +[Linking to Node.js' own dependencies]: #linking-to-nodejs-own-dependencies [installation instructions]: https://github.com/nodejs/node-gyp#installation diff --git a/doc/api/http.markdown b/doc/api/http.markdown index 717651aacb8867..4da2b32448581e 100644 --- a/doc/api/http.markdown +++ b/doc/api/http.markdown @@ -1096,7 +1096,7 @@ There are a few special headers that should be noted. [`http.Agent`]: #http_class_http_agent [`http.ClientRequest`]: #http_class_http_clientrequest [`http.globalAgent`]: #http_http_globalagent -[`http.IncomingMessage`]: #http_http_incomingmessage +[`http.IncomingMessage`]: #http_class_http_incomingmessage [`http.request()`]: #http_http_request_options_callback [`http.Server`]: #http_class_http_server [`http.ServerResponse`]: #http_class_http_serverresponse From a6c242f341a12c9436ee0274552054bb0fb60780 Mon Sep 17 00:00:00 2001 From: Claudio Rodriguez Date: Sun, 20 Dec 2015 14:15:54 -0300 Subject: [PATCH 07/33] doc: add path property to Write/ReadStream in fs.markdown Documents the "path" property on fs.WriteStream and fs.ReadStream. See #4327 PR-URL: https://github.com/nodejs/node/pull/4368 Reviewed-By: James M Snell --- doc/api/fs.markdown | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/api/fs.markdown b/doc/api/fs.markdown index 42e347f43aa34c..3d60e5ac1c6dfb 100644 --- a/doc/api/fs.markdown +++ b/doc/api/fs.markdown @@ -116,6 +116,10 @@ Stop watching for changes on the given `fs.FSWatcher`. Emitted when the ReadStream's file is opened. +### readStream.path + +The path to the file the stream is reading from. + ## Class: fs.Stats Objects returned from [`fs.stat()`][], [`fs.lstat()`][] and [`fs.fstat()`][] and their @@ -196,6 +200,10 @@ Emitted when the WriteStream's file is opened. The number of bytes written so far. Does not include data that is still queued for writing. +### writeStream.path + +The path to the file the stream is writing to. + ## fs.access(path[, mode], callback) Tests a user's permissions for the file specified by `path`. `mode` is an From 056b07806c246f9c68213130e9823a549ec13cf8 Mon Sep 17 00:00:00 2001 From: Vitor Cortez Date: Thu, 10 Dec 2015 18:32:13 -0300 Subject: [PATCH 08/33] doc: clarify explanation of first stream section The last sentence of the explanation for the first stream section seemed a bit confusing. I tried to change the sentence to clarify it. Additionally, the sections were turned into a numbered list to be more clear about which section is being described, and improve readability. PR-URL: https://github.com/nodejs/node/pull/4234 Reviewed-By: James M Snell --- doc/api/stream.markdown | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/doc/api/stream.markdown b/doc/api/stream.markdown index dcb64c17dd6650..554ddc222d6f48 100644 --- a/doc/api/stream.markdown +++ b/doc/api/stream.markdown @@ -11,19 +11,17 @@ You can load the Stream base classes by doing `require('stream')`. There are base classes provided for [Readable][] streams, [Writable][] streams, [Duplex][] streams, and [Transform][] streams. -This document is split up into 3 sections. The first explains the -parts of the API that you need to be aware of to use streams in your -programs. If you never implement a streaming API yourself, you can -stop there. - -The second section explains the parts of the API that you need to use -if you implement your own custom streams yourself. The API is -designed to make this easy for you to do. - -The third section goes into more depth about how streams work, -including some of the internal mechanisms and functions that you -should probably not modify unless you definitely know what you are -doing. +This document is split up into 3 sections: + +1. The first section explains the parts of the API that you need to be + aware of to use streams in your programs. +2. The second section explains the parts of the API that you need to + use if you implement your own custom streams yourself. The API is + designed to make this easy for you to do. +3. The third section goes into more depth about how streams work, + including some of the internal mechanisms and functions that you + should probably not modify unless you definitely know what you are + doing. ## API for Stream Consumers From a8330f73ab1437dfdc13e40bb02b0144c2ea7933 Mon Sep 17 00:00:00 2001 From: Dave Date: Wed, 30 Dec 2015 00:20:33 -0800 Subject: [PATCH 09/33] events: make sure console functions exist If there's no global console cached, initialize it. Fixes: https://github.com/nodejs/node/issues/4467 PR-URL: https://github.com/nodejs/node/pull/4479 Reviewed-By: Roman Reiss Reviewed-By: James M Snell --- lib/events.js | 15 ++++++++- test/parallel/test-global-console-exists.js | 36 +++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 test/parallel/test-global-console-exists.js diff --git a/lib/events.js b/lib/events.js index ea3f2831eb3bbc..ab76d990e16f6e 100644 --- a/lib/events.js +++ b/lib/events.js @@ -18,7 +18,20 @@ EventEmitter.prototype._maxListeners = undefined; // By default EventEmitters will print a warning if more than 10 listeners are // added to it. This is a useful default which helps finding memory leaks. -EventEmitter.defaultMaxListeners = 10; +var defaultMaxListeners = 10; + +Object.defineProperty(EventEmitter, 'defaultMaxListeners', { + enumerable: true, + get: function() { + return defaultMaxListeners; + }, + set: function(arg) { + // force global console to be compiled. + // see https://github.com/nodejs/node/issues/4467 + console; + defaultMaxListeners = arg; + } +}); EventEmitter.init = function() { this.domain = null; diff --git a/test/parallel/test-global-console-exists.js b/test/parallel/test-global-console-exists.js new file mode 100644 index 00000000000000..1a13ffec29c23b --- /dev/null +++ b/test/parallel/test-global-console-exists.js @@ -0,0 +1,36 @@ +/* eslint-disable required-modules */ +// ordinarily test files must require('common') but that action causes +// the global console to be compiled, defeating the purpose of this test + +'use strict'; + +const assert = require('assert'); +const EventEmitter = require('events'); +const leak_warning = /EventEmitter memory leak detected\. 2 hello listeners/; + +var write_calls = 0; +process.stderr.write = function(data) { + if (write_calls === 0) + assert.ok(data.match(leak_warning)); + else if (write_calls === 1) + assert.ok(data.match(/Trace/)); + else + assert.ok(false, 'stderr.write should be called only twice'); + + write_calls++; +}; + +const old_default = EventEmitter.defaultMaxListeners; +EventEmitter.defaultMaxListeners = 1; + +const e = new EventEmitter(); +e.on('hello', function() {}); +e.on('hello', function() {}); + +// TODO: figure out how to validate console. Currently, +// there is no obvious way of validating that console +// exists here exactly when it should. + +assert.equal(write_calls, 2); + +EventEmitter.defaultMaxListeners = old_default; From 28793958af4e7d4e4d633645369a06daf9c5fa8f Mon Sep 17 00:00:00 2001 From: Saquib Date: Sun, 29 Nov 2015 20:41:19 +0530 Subject: [PATCH 10/33] fs: add autoClose option to fs.createWriteStream Add support to fs.createWriteStream and fs.createWriteStream for an autoClose option that behaves similarly to the autoClose option supported by fs.createReadStream and fs.ReadStream. When an instance of fs.createWriteStream created with autoClose === false finishes, it is not destroyed. Its underlying fd is not closed and it is the responsibility of the user to close it. PR-URL: https://github.com/nodejs/node/pull/3679 Reviewed-By: James M Snell Reviewed-By: Colin Ihrig --- doc/api/fs.markdown | 9 +++- lib/fs.js | 15 ++++-- .../test-fs-write-stream-autoclose-option.js | 52 +++++++++++++++++++ 3 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 test/parallel/test-fs-write-stream-autoclose-option.js diff --git a/doc/api/fs.markdown b/doc/api/fs.markdown index 3d60e5ac1c6dfb..0f2c2575bbe3f4 100644 --- a/doc/api/fs.markdown +++ b/doc/api/fs.markdown @@ -342,13 +342,20 @@ Returns a new [`WriteStream`][] object. (See [Writable Stream][]). { flags: 'w', defaultEncoding: 'utf8', fd: null, - mode: 0o666 } + mode: 0o666, + autoClose: true } `options` may also include a `start` option to allow writing data at some position past the beginning of the file. Modifying a file rather than replacing it may require a `flags` mode of `r+` rather than the default mode `w`. The `defaultEncoding` can be any one of those accepted by [`Buffer`][]. +If `autoClose` is set to true (default behavior) on `error` or `end` +the file descriptor will be closed automatically. If `autoClose` is false, +then the file descriptor won't be closed, even if there's an error. +It is your responsiblity to close it and make sure +there's no file descriptor leak. + Like [`ReadStream`][], if `fd` is specified, `WriteStream` will ignore the `path` argument and will use the specified file descriptor. This means that no `'open'` event will be emitted. Note that `fd` should be blocking; non-blocking diff --git a/lib/fs.js b/lib/fs.js index 74cc9cbf5c81d0..978b8cedf40d8f 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -1886,6 +1886,7 @@ function WriteStream(path, options) { this.mode = options.mode === undefined ? 0o666 : options.mode; this.start = options.start; + this.autoClose = options.autoClose === undefined ? true : !!options.autoClose; this.pos = undefined; this.bytesWritten = 0; @@ -1907,7 +1908,11 @@ function WriteStream(path, options) { this.open(); // dispose on finish. - this.once('finish', this.close); + this.once('finish', function() { + if (this.autoClose) { + this.close(); + } + }); } fs.FileWriteStream = fs.WriteStream; // support the legacy name @@ -1916,7 +1921,9 @@ fs.FileWriteStream = fs.WriteStream; // support the legacy name WriteStream.prototype.open = function() { fs.open(this.path, this.flags, this.mode, function(er, fd) { if (er) { - this.destroy(); + if (this.autoClose) { + this.destroy(); + } this.emit('error', er); return; } @@ -1939,7 +1946,9 @@ WriteStream.prototype._write = function(data, encoding, cb) { var self = this; fs.write(this.fd, data, 0, data.length, this.pos, function(er, bytes) { if (er) { - self.destroy(); + if (self.autoClose) { + self.destroy(); + } return cb(er); } self.bytesWritten += bytes; diff --git a/test/parallel/test-fs-write-stream-autoclose-option.js b/test/parallel/test-fs-write-stream-autoclose-option.js new file mode 100644 index 00000000000000..0706ed6485888b --- /dev/null +++ b/test/parallel/test-fs-write-stream-autoclose-option.js @@ -0,0 +1,52 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const path = require('path'); +const fs = require('fs'); + +const file = path.join(common.tmpDir, 'write-autoclose-opt1.txt'); +common.refreshTmpDir(); +let stream = fs.createWriteStream(file, {flags: 'w+', autoClose: false}); +stream.write('Test1'); +stream.end(); +stream.on('finish', common.mustCall(function() { + process.nextTick(common.mustCall(function() { + assert.strictEqual(stream.closed, undefined); + assert(stream.fd !== null); + next(); + })); +})); + +function next() { + // This will tell us if the fd is usable again or not + stream = fs.createWriteStream(null, {fd: stream.fd, start: 0}); + stream.write('Test2'); + stream.end(); + stream.on('finish', common.mustCall(function() { + assert.strictEqual(stream.closed, true); + assert.strictEqual(stream.fd, null); + process.nextTick(common.mustCall(next2)); + })); +} + +function next2() { + // This will test if after reusing the fd data is written properly + fs.readFile(file, function(err, data) { + assert(!err); + assert.strictEqual(data.toString(), 'Test2'); + process.nextTick(common.mustCall(next3)); + }); +} + +function next3() { + // This is to test success scenario where autoClose is true + const stream = fs.createWriteStream(file, {autoClose: true}); + stream.write('Test3'); + stream.end(); + stream.on('finish', common.mustCall(function() { + process.nextTick(common.mustCall(function() { + assert.strictEqual(stream.closed, true); + assert.strictEqual(stream.fd, null); + })); + })); +} From c1712947b2cdb365c018ab547cac0cf7866a74b9 Mon Sep 17 00:00:00 2001 From: Daniel Sellers Date: Wed, 30 Dec 2015 21:31:25 -0700 Subject: [PATCH 11/33] http: improves expect header handling Now returns a 417 error status or allows for an event listener on the `checkExpectation` event. Before we were ignoring requests that had misspelled `100-continue` values for expect headers. This is a quick port of the work done here: https://github.com/nodejs/node-v0.x-archive/pull/7132 by alFReD-NSH with surrounding discussion here: https://github.com/nodejs/node-v0.x-archive/issues/4651 Also updates all the instances of the deprecated EventEmitter.listenerCount to the current self.listenerCount. Most of these were in the new code ported over but there was another legacy instance. Refs: #2403 PR-URL: https://github.com/nodejs/node/pull/4501 Reviewed-By: James M Snell --- doc/api/http.markdown | 11 +++++ lib/_http_server.js | 26 ++++++---- test/parallel/test-http-expect-handling.js | 55 ++++++++++++++++++++++ 3 files changed, 83 insertions(+), 9 deletions(-) create mode 100644 test/parallel/test-http-expect-handling.js diff --git a/doc/api/http.markdown b/doc/api/http.markdown index 4da2b32448581e..0f3f6c538f4c26 100644 --- a/doc/api/http.markdown +++ b/doc/api/http.markdown @@ -192,6 +192,17 @@ The request implements the [Writable Stream][] interface. This is an Emitted when the request has been aborted by the client. This event is only emitted on the first call to `abort()`. +### Event: 'checkExpectation' + +`function (request, response) { }` + +Emitted each time a request with an http Expect header is received, where the +value is not 100-continue. If this event isn't listened for, the server will +automatically respond with a 417 Expectation Failed as appropriate. + +Note that when this event is emitted and handled, the `request` event will +not be emitted. + ### Event: 'connect' `function (response, socket, head) { }` diff --git a/lib/_http_server.js b/lib/_http_server.js index 3e4e7f4dd89822..62f23e8a3c8846 100644 --- a/lib/_http_server.js +++ b/lib/_http_server.js @@ -2,7 +2,6 @@ const util = require('util'); const net = require('net'); -const EventEmitter = require('events'); const HTTPParser = process.binding('http_parser').HTTPParser; const assert = require('assert').ok; const common = require('_http_common'); @@ -391,7 +390,7 @@ function connectionListener(socket) { parser = null; var eventName = req.method === 'CONNECT' ? 'connect' : 'upgrade'; - if (EventEmitter.listenerCount(self, eventName) > 0) { + if (self.listenerCount(eventName) > 0) { debug('SERVER have listener for %s', eventName); var bodyHead = d.slice(bytesParsed, d.length); @@ -516,14 +515,23 @@ function connectionListener(socket) { } if (req.headers.expect !== undefined && - (req.httpVersionMajor == 1 && req.httpVersionMinor == 1) && - continueExpression.test(req.headers['expect'])) { - res._expect_continue = true; - if (EventEmitter.listenerCount(self, 'checkContinue') > 0) { - self.emit('checkContinue', req, res); + (req.httpVersionMajor == 1 && req.httpVersionMinor == 1)) { + if (continueExpression.test(req.headers.expect)) { + res._expect_continue = true; + + if (self.listenerCount('checkContinue') > 0) { + self.emit('checkContinue', req, res); + } else { + res.writeContinue(); + self.emit('request', req, res); + } } else { - res.writeContinue(); - self.emit('request', req, res); + if (self.listenerCount('checkExpectation') > 0) { + self.emit('checkExpectation', req, res); + } else { + res.writeHead(417); + res.end(); + } } } else { self.emit('request', req, res); diff --git a/test/parallel/test-http-expect-handling.js b/test/parallel/test-http-expect-handling.js new file mode 100644 index 00000000000000..fd88ae0ded6074 --- /dev/null +++ b/test/parallel/test-http-expect-handling.js @@ -0,0 +1,55 @@ +// Spec documentation http://httpwg.github.io/specs/rfc7231.html#header.expect +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); + +const tests = [417, 417]; + +let testsComplete = 0; +let testIdx = 0; + +const s = http.createServer(function(req, res) { + throw new Error('this should never be executed'); +}); + +s.listen(common.PORT, nextTest); + +function nextTest() { + const options = { + port: common.PORT, + headers: { 'Expect': 'meoww' } + }; + + if (testIdx === tests.length) { + return s.close(); + } + + const test = tests[testIdx]; + + if (testIdx > 0) { + s.on('checkExpectation', common.mustCall((req, res) => { + res.statusCode = 417; + res.end(); + })); + } + + http.get(options, function(response) { + console.log('client: expected status: ' + test); + console.log('client: statusCode: ' + response.statusCode); + assert.equal(response.statusCode, test); + assert.equal(response.statusMessage, 'Expectation Failed'); + + response.on('end', function() { + testsComplete++; + testIdx++; + nextTest(); + }); + response.resume(); + }); +} + + +process.on('exit', function() { + assert.equal(2, testsComplete); +}); From 16ef250e2092cccc9fd25c5e082df58754dbb072 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Fri, 15 Jan 2016 09:50:44 +0100 Subject: [PATCH 12/33] tools: enable no-extra-semi rule in eslint PR-URL: https://github.com/nodejs/node/pull/2205 Reviewed-By: Colin Ihrig Reviewed-By: Roman Reiss --- .eslintrc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.eslintrc b/.eslintrc index 2197bf35ccf7be..fec8179aa31f14 100644 --- a/.eslintrc +++ b/.eslintrc @@ -25,6 +25,8 @@ rules: no-dupe-keys: 2 ## check duplicate switch-case no-duplicate-case: 2 + ## disallow superfluous semicolons + no-extra-semi: 2 ## disallow assignment of exceptional params no-ex-assign: 2 ## disallow unreachable code From f0ee088f3ba9c5be9cef6035cf99a7ad5617a113 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Fri, 15 Jan 2016 09:53:11 +0100 Subject: [PATCH 13/33] lib,test: remove extra semicolons PR-URL: https://github.com/nodejs/node/pull/2205 Reviewed-By: Colin Ihrig Reviewed-By: Roman Reiss --- lib/_debugger.js | 4 ++-- lib/events.js | 2 +- lib/net.js | 2 +- lib/tls.js | 2 +- test/common.js | 2 +- test/debugger/helper-debugger-repl.js | 2 +- test/parallel/test-child-process-spawnsync-input.js | 2 +- test/parallel/test-http-1.0-keep-alive.js | 2 +- test/parallel/test-stream-big-packet.js | 4 ++-- test/parallel/test-stream-pipe-without-listenerCount.js | 2 +- .../test-stream-writable-change-default-encoding.js | 2 +- test/parallel/test-stream-writable-decoded-encoding.js | 6 +++--- test/parallel/test-stream2-base64-single-char-read-end.js | 2 +- test/parallel/test-stream3-pause-then-read.js | 2 +- ...imers-socket-timeout-removes-other-socket-unref-timer.js | 2 +- test/parallel/test-tls-alpn-server-client.js | 2 +- test/parallel/test-tls-npn-server-client.js | 2 +- test/parallel/test-tls-sni-option.js | 2 +- test/parallel/test-tls-sni-server-client.js | 2 +- test/parallel/test-url.js | 2 +- test/parallel/test-zlib-flush-drain.js | 2 +- test/pummel/test-tls-server-large-request.js | 2 +- test/sequential/test-child-process-fork-getconnections.js | 4 ++-- test/sequential/test-tcp-wrap-listen.js | 2 +- 24 files changed, 29 insertions(+), 29 deletions(-) diff --git a/lib/_debugger.js b/lib/_debugger.js index 9637d4ca03488b..5339ebbb56fea9 100644 --- a/lib/_debugger.js +++ b/lib/_debugger.js @@ -573,7 +573,7 @@ Client.prototype.mirrorObject = function(handle, depth, cb) { }); cb(null, mirror); } - }; + } }); return; } else if (handle.type === 'function') { @@ -799,7 +799,7 @@ function Interface(stdin, stdout, args) { } else { self.repl.context[key] = fn; } - }; + } // Copy all prototype methods in repl context // Setup them as getters if possible diff --git a/lib/events.js b/lib/events.js index ab76d990e16f6e..d20460720eda2e 100644 --- a/lib/events.js +++ b/lib/events.js @@ -430,7 +430,7 @@ function listenerCount(type) { } return 0; -}; +} // About 1.5x faster than the two-arg version of Array#splice(). function spliceOne(list, index) { diff --git a/lib/net.js b/lib/net.js index ec8f1c470e2dff..7a612096ab45d0 100644 --- a/lib/net.js +++ b/lib/net.js @@ -1186,7 +1186,7 @@ function createServerHandle(address, port, addressType, fd) { } return handle; -}; +} exports._createServerHandle = createServerHandle; diff --git a/lib/tls.js b/lib/tls.js index 1abeb77873692b..245afb6bdc7561 100644 --- a/lib/tls.js +++ b/lib/tls.js @@ -46,7 +46,7 @@ function convertProtocols(protocols) { }, 0); return buff; -}; +} exports.convertNPNProtocols = function(protocols, out) { // If protocols is Array - translate it into buffer diff --git a/test/common.js b/test/common.js index 133294d91e15e1..b91044ec4b6ff9 100644 --- a/test/common.js +++ b/test/common.js @@ -337,7 +337,7 @@ function leakedGlobals() { leaked.push(val); return leaked; -}; +} exports.leakedGlobals = leakedGlobals; // Turn this off if the test should not check for global leaks. diff --git a/test/debugger/helper-debugger-repl.js b/test/debugger/helper-debugger-repl.js index 714a22c2a22fdc..20cd341165042d 100644 --- a/test/debugger/helper-debugger-repl.js +++ b/test/debugger/helper-debugger-repl.js @@ -103,7 +103,7 @@ function addTest(input, output) { } else { quit(); } - }; + } expected.push({input: input, lines: output, callback: next}); } diff --git a/test/parallel/test-child-process-spawnsync-input.js b/test/parallel/test-child-process-spawnsync-input.js index 338b4277fb1982..0116f092920a8b 100644 --- a/test/parallel/test-child-process-spawnsync-input.js +++ b/test/parallel/test-child-process-spawnsync-input.js @@ -23,7 +23,7 @@ var ret; function checkSpawnSyncRet(ret) { assert.strictEqual(ret.status, 0); assert.strictEqual(ret.error, undefined); -}; +} function verifyBufOutput(ret) { checkSpawnSyncRet(ret); diff --git a/test/parallel/test-http-1.0-keep-alive.js b/test/parallel/test-http-1.0-keep-alive.js index 516a02031ef247..fa49707c24a8d5 100644 --- a/test/parallel/test-http-1.0-keep-alive.js +++ b/test/parallel/test-http-1.0-keep-alive.js @@ -122,7 +122,7 @@ function check(tests) { current++; if (ctx.expectClose) return; conn.removeListener('close', onclose); - conn.removeListener('data', ondata);; + conn.removeListener('data', ondata); connected(); } conn.on('data', ondata); diff --git a/test/parallel/test-stream-big-packet.js b/test/parallel/test-stream-big-packet.js index 67bb32847bd7f7..e64f4aa34fd481 100644 --- a/test/parallel/test-stream-big-packet.js +++ b/test/parallel/test-stream-big-packet.js @@ -8,7 +8,7 @@ var passed = false; function PassThrough() { stream.Transform.call(this); -}; +} util.inherits(PassThrough, stream.Transform); PassThrough.prototype._transform = function(chunk, encoding, done) { this.push(chunk); @@ -17,7 +17,7 @@ PassThrough.prototype._transform = function(chunk, encoding, done) { function TestStream() { stream.Transform.call(this); -}; +} util.inherits(TestStream, stream.Transform); TestStream.prototype._transform = function(chunk, encoding, done) { if (!passed) { diff --git a/test/parallel/test-stream-pipe-without-listenerCount.js b/test/parallel/test-stream-pipe-without-listenerCount.js index d7a6a6b653a6bf..872be6d7be5ce8 100644 --- a/test/parallel/test-stream-pipe-without-listenerCount.js +++ b/test/parallel/test-stream-pipe-without-listenerCount.js @@ -16,4 +16,4 @@ r.on('error', common.mustCall(noop)); w.on('error', common.mustCall(noop)); r.pipe(w); -function noop() {}; +function noop() {} diff --git a/test/parallel/test-stream-writable-change-default-encoding.js b/test/parallel/test-stream-writable-change-default-encoding.js index d8193123d6f3af..d1d4af5b824baf 100644 --- a/test/parallel/test-stream-writable-change-default-encoding.js +++ b/test/parallel/test-stream-writable-change-default-encoding.js @@ -8,7 +8,7 @@ var util = require('util'); function MyWritable(fn, options) { stream.Writable.call(this, options); this.fn = fn; -}; +} util.inherits(MyWritable, stream.Writable); diff --git a/test/parallel/test-stream-writable-decoded-encoding.js b/test/parallel/test-stream-writable-decoded-encoding.js index b5f1b4f6b73f49..75d5d424766323 100644 --- a/test/parallel/test-stream-writable-decoded-encoding.js +++ b/test/parallel/test-stream-writable-decoded-encoding.js @@ -8,7 +8,7 @@ var util = require('util'); function MyWritable(fn, options) { stream.Writable.call(this, options); this.fn = fn; -}; +} util.inherits(MyWritable, stream.Writable); @@ -17,7 +17,7 @@ MyWritable.prototype._write = function(chunk, encoding, callback) { callback(); }; -;(function decodeStringsTrue() { +(function decodeStringsTrue() { var m = new MyWritable(function(isBuffer, type, enc) { assert(isBuffer); assert.equal(type, 'object'); @@ -28,7 +28,7 @@ MyWritable.prototype._write = function(chunk, encoding, callback) { m.end(); })(); -;(function decodeStringsFalse() { +(function decodeStringsFalse() { var m = new MyWritable(function(isBuffer, type, enc) { assert(!isBuffer); assert.equal(type, 'string'); diff --git a/test/parallel/test-stream2-base64-single-char-read-end.js b/test/parallel/test-stream2-base64-single-char-read-end.js index 900e090921b712..0f9f56b3e70730 100644 --- a/test/parallel/test-stream2-base64-single-char-read-end.js +++ b/test/parallel/test-stream2-base64-single-char-read-end.js @@ -17,7 +17,7 @@ src._read = function(n) { src.push(new Buffer('1')); src.push(null); }); - }; + } }; dst._write = function(chunk, enc, cb) { diff --git a/test/parallel/test-stream3-pause-then-read.js b/test/parallel/test-stream3-pause-then-read.js index e4e33738b33206..0aee70f6832c7f 100644 --- a/test/parallel/test-stream3-pause-then-read.js +++ b/test/parallel/test-stream3-pause-then-read.js @@ -42,7 +42,7 @@ function read100() { function readn(n, then) { console.error('read %d', n); expectEndingData -= n; - ;(function read() { + (function read() { var c = r.read(n); if (!c) r.once('readable', read); 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 c9ca3eafd64ebf..a26b548385e5f6 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 @@ -39,7 +39,7 @@ server.listen(common.PORT, common.localhostIPv4, function() { if (nbClientsEnded === 2) { server.close(); } - }; + } const client1 = net.connect({ port: common.PORT }); client1.on('end', addEndedClient); diff --git a/test/parallel/test-tls-alpn-server-client.js b/test/parallel/test-tls-alpn-server-client.js index e5d809d1489aee..a9fe0b84d4ca5f 100644 --- a/test/parallel/test-tls-alpn-server-client.js +++ b/test/parallel/test-tls-alpn-server-client.js @@ -66,7 +66,7 @@ function runTest(clientsOptions, serverOptions, cb) { cb(results); } }); - }; + } } diff --git a/test/parallel/test-tls-npn-server-client.js b/test/parallel/test-tls-npn-server-client.js index 211cfc7ed35067..d74d65c8b03bd7 100644 --- a/test/parallel/test-tls-npn-server-client.js +++ b/test/parallel/test-tls-npn-server-client.js @@ -85,7 +85,7 @@ function startTest() { callback(); }); - }; + } connectClient(clientsOptions[0], function() { connectClient(clientsOptions[1], function() { diff --git a/test/parallel/test-tls-sni-option.js b/test/parallel/test-tls-sni-option.js index 510b929ae2a17b..83e62133363677 100644 --- a/test/parallel/test-tls-sni-option.js +++ b/test/parallel/test-tls-sni-option.js @@ -146,7 +146,7 @@ function startTest() { else connectClient(i + 1, callback); } - }; + } connectClient(0, function() { server.close(); diff --git a/test/parallel/test-tls-sni-server-client.js b/test/parallel/test-tls-sni-server-client.js index 8eb80b50e41540..733713c8e72df8 100644 --- a/test/parallel/test-tls-sni-server-client.js +++ b/test/parallel/test-tls-sni-server-client.js @@ -103,7 +103,7 @@ function startTest() { // Continue start(); }); - }; + } start(); } diff --git a/test/parallel/test-url.js b/test/parallel/test-url.js index 9fa087261e0127..20e6138b268b5c 100644 --- a/test/parallel/test-url.js +++ b/test/parallel/test-url.js @@ -1569,6 +1569,6 @@ var throws = [ ]; for (var i = 0; i < throws.length; i++) { assert.throws(function() { url.format(throws[i]); }, TypeError); -}; +} assert(url.format('') === ''); assert(url.format({}) === ''); diff --git a/test/parallel/test-zlib-flush-drain.js b/test/parallel/test-zlib-flush-drain.js index f04dac9f0699ac..14a42e76cc3874 100644 --- a/test/parallel/test-zlib-flush-drain.js +++ b/test/parallel/test-zlib-flush-drain.js @@ -33,7 +33,7 @@ deflater.flush(function(err) { }); deflater.on('drain', function() { - drainCount++;; + drainCount++; }); process.once('exit', function() { diff --git a/test/pummel/test-tls-server-large-request.js b/test/pummel/test-tls-server-large-request.js index d7663e936de78a..cb740c63ed7d68 100644 --- a/test/pummel/test-tls-server-large-request.js +++ b/test/pummel/test-tls-server-large-request.js @@ -24,7 +24,7 @@ var options = { function Mediator() { stream.Writable.call(this); this.buf = ''; -}; +} util.inherits(Mediator, stream.Writable); Mediator.prototype._write = function write(data, enc, cb) { diff --git a/test/sequential/test-child-process-fork-getconnections.js b/test/sequential/test-child-process-fork-getconnections.js index a7521f1635fb39..f7bb9f5eea216f 100644 --- a/test/sequential/test-child-process-fork-getconnections.js +++ b/test/sequential/test-child-process-fork-getconnections.js @@ -11,7 +11,7 @@ if (process.argv[2] === 'child') { process.on('message', function(m, socket) { function sendClosed(id) { process.send({ id: id, status: 'closed'}); - }; + } if (m.cmd === 'new') { assert(socket); @@ -82,7 +82,7 @@ if (process.argv[2] === 'child') { }); sent++; child.send({ id: i, cmd: 'close' }); - }; + } let closeEmitted = false; server.on('close', function() { diff --git a/test/sequential/test-tcp-wrap-listen.js b/test/sequential/test-tcp-wrap-listen.js index 44254c3d3f39aa..d16069f25dbeab 100644 --- a/test/sequential/test-tcp-wrap-listen.js +++ b/test/sequential/test-tcp-wrap-listen.js @@ -65,7 +65,7 @@ server.onconnection = function(err, client) { writeCount++; console.log('write ' + writeCount); maybeCloseClient(); - }; + } sliceCount++; } else { From c6ac464dbcfc270d0cd4586fc3dd3f3da69a8119 Mon Sep 17 00:00:00 2001 From: Brian White Date: Wed, 13 Jan 2016 14:52:03 -0500 Subject: [PATCH 14/33] querystring: improve parse() performance MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These changes improve parse() performance from ~11-30% on all of the existing querystring benchmarks. PR-URL: https://github.com/nodejs/node/pull/4675 Reviewed-By: Johan Bergström Reviewed-By: Colin Ihrig Reviewed-By: James M Snell --- benchmark/querystring/querystring-parse.js | 5 ++-- lib/querystring.js | 30 +++++++++++++++++++--- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/benchmark/querystring/querystring-parse.js b/benchmark/querystring/querystring-parse.js index 3d88bed07d63da..6a4d9f5e6169f4 100644 --- a/benchmark/querystring/querystring-parse.js +++ b/benchmark/querystring/querystring-parse.js @@ -3,7 +3,7 @@ var querystring = require('querystring'); var v8 = require('v8'); var bench = common.createBenchmark(main, { - type: ['noencode', 'encodemany', 'encodelast'], + type: ['noencode', 'encodemany', 'encodelast', 'multivalue'], n: [1e6], }); @@ -14,7 +14,8 @@ function main(conf) { var inputs = { noencode: 'foo=bar&baz=quux&xyzzy=thud', encodemany: '%66%6F%6F=bar&%62%61%7A=quux&xyzzy=%74h%75d', - encodelast: 'foo=bar&baz=quux&xyzzy=thu%64' + encodelast: 'foo=bar&baz=quux&xyzzy=thu%64', + multivalue: 'foo=bar&foo=baz&foo=quux&quuy=quuz' }; var input = inputs[type]; diff --git a/lib/querystring.js b/lib/querystring.js index 5f8df93038921f..b034635668faa8 100644 --- a/lib/querystring.js +++ b/lib/querystring.js @@ -209,7 +209,6 @@ QueryString.parse = QueryString.decode = function(qs, sep, eq, options) { return obj; } - var regexp = /\+/g; qs = qs.split(sep); var maxKeys = 1000; @@ -230,7 +229,9 @@ QueryString.parse = QueryString.decode = function(qs, sep, eq, options) { var keys = []; for (var i = 0; i < len; ++i) { - const x = qs[i].replace(regexp, '%20'); + // replacePlus() is used instead of a regexp because it is ~15-30% faster + // with v8 4.7 + const x = replacePlus(qs[i]); const idx = x.indexOf(eq); var k, v; @@ -242,10 +243,14 @@ QueryString.parse = QueryString.decode = function(qs, sep, eq, options) { v = ''; } + // Use a key array lookup instead of using hasOwnProperty(), which is slower if (keys.indexOf(k) === -1) { obj[k] = v; keys.push(k); - } else if (Array.isArray(obj[k])) { + } else if (obj[k] instanceof Array) { + // `instanceof Array` is used instead of Array.isArray() because it is + // ~15-20% faster with v8 4.7 and is safe to use because we are using it + // with values being created within this function obj[k].push(v); } else { obj[k] = [obj[k], v]; @@ -256,6 +261,25 @@ QueryString.parse = QueryString.decode = function(qs, sep, eq, options) { }; +function replacePlus(str) { + var ret = ''; + var start = 0; + var i = -1; + while ((i = str.indexOf('+', i + 1)) !== -1) { + ret += str.slice(start, i); + ret += '%20'; + start = i + 1; + } + if (start === 0) + return str; + if (start < str.length) + ret += str.slice(start); + return ret; +} + + +// v8 does not optimize functions with try-catch blocks, so we isolate them here +// to minimize the damage function decodeStr(s, decoder) { try { return decoder(s); From 8104d9d8753a5e2485a0465a32e40774ba49d307 Mon Sep 17 00:00:00 2001 From: Evan Lucas Date: Tue, 5 Jan 2016 06:28:27 -0600 Subject: [PATCH 15/33] repl: make sure historyPath is trimmed If one were to set NODE_REPL_HISTORY to a string that contains only a space (" "), then the history file would be created with that name which can cause problems are certain systems. PR-URL: https://github.com/nodejs/node/pull/4539 Reviewed-By: Sakthipriyan Vairamani Reviewed-By: James M Snell Reviewed-By: Colin Ihrig Reviewed-By: Jeremiah Senkpiel --- doc/api/repl.markdown | 2 +- lib/internal/repl.js | 13 ++++++++++++- test/parallel/test-repl-persistent-history.js | 5 +++++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/doc/api/repl.markdown b/doc/api/repl.markdown index b9d706beef0295..d045d7c4332c60 100644 --- a/doc/api/repl.markdown +++ b/doc/api/repl.markdown @@ -37,7 +37,7 @@ via the following environment variables: - `NODE_REPL_HISTORY` - When a valid path is given, persistent REPL history will be saved to the specified file rather than `.node_repl_history` in the user's home directory. Setting this value to `""` will disable persistent - REPL history. + REPL history. Whitespace will be trimmed from the value. - `NODE_REPL_HISTORY_SIZE` - defaults to `1000`. Controls how many lines of history will be persisted if history is available. Must be a positive number. - `NODE_REPL_MODE` - may be any of `sloppy`, `strict`, or `magic`. Defaults diff --git a/lib/internal/repl.js b/lib/internal/repl.js index e6b41fbdd89b65..371446a83bd4fd 100644 --- a/lib/internal/repl.js +++ b/lib/internal/repl.js @@ -55,15 +55,26 @@ function createRepl(env, opts, cb) { } const repl = REPL.start(opts); - if (opts.terminal && env.NODE_REPL_HISTORY !== '') { + if (opts.terminal) { return setupHistory(repl, env.NODE_REPL_HISTORY, env.NODE_REPL_HISTORY_FILE, cb); } + repl._historyPrev = _replHistoryMessage; cb(null, repl); } function setupHistory(repl, historyPath, oldHistoryPath, ready) { + // Empty string disables persistent history. + + if (typeof historyPath === 'string') + historyPath = historyPath.trim(); + + if (historyPath === '') { + repl._historyPrev = _replHistoryMessage; + return ready(null, repl); + } + if (!historyPath) { try { historyPath = path.join(os.homedir(), '.node_repl_history'); diff --git a/test/parallel/test-repl-persistent-history.js b/test/parallel/test-repl-persistent-history.js index 81e728974f179d..387cef7e97a794 100644 --- a/test/parallel/test-repl-persistent-history.js +++ b/test/parallel/test-repl-persistent-history.js @@ -85,6 +85,11 @@ const tests = [ test: [UP], expected: [prompt, replDisabled, prompt] }, + { + env: { NODE_REPL_HISTORY: ' ' }, + test: [UP], + expected: [prompt, replDisabled, prompt] + }, { env: { NODE_REPL_HISTORY: '', NODE_REPL_HISTORY_FILE: enoentHistoryPath }, From 6988d2edb361502dc452c488fa0c3a9650416c72 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Sun, 17 Jan 2016 17:18:37 +0100 Subject: [PATCH 16/33] src: don't check failure with ERR_peek_error() It's possible there is already an existing error on OpenSSL's error stack that is unrelated to the EVP_DigestInit_ex() operation we just executed. Fixes: https://github.com/nodejs/node/issues/4221 PR-URL: https://github.com/nodejs/node/pull/4731 Reviewed-By: Colin Ihrig Reviewed-By: Fedor Indutny --- src/node_crypto.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 700e658417d2aa..a27f97dc7407fe 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -3611,8 +3611,7 @@ bool Hash::HashInit(const char* hash_type) { if (md_ == nullptr) return false; EVP_MD_CTX_init(&mdctx_); - EVP_DigestInit_ex(&mdctx_, md_, nullptr); - if (0 != ERR_peek_error()) { + if (EVP_DigestInit_ex(&mdctx_, md_, nullptr) <= 0) { return false; } initialised_ = true; From 848b04bf78296ca7199788b7ba967ae2312b55fe Mon Sep 17 00:00:00 2001 From: Evan Lucas Date: Thu, 14 Jan 2016 10:54:04 -0600 Subject: [PATCH 17/33] node: allow preload modules with -i This gives us the ability to preload when using the node repl. This can be useful for doing things like creating aliases. Fixes: https://github.com/nodejs/node/issues/4661 PR-URL: https://github.com/nodejs/node/pull/4696 Reviewed-By: Colin Ihrig Reviewed-By: James M Snell --- src/node.js | 1 + test/fixtures/define-global.js | 1 + test/parallel/test-preload.js | 15 ++++++++++++++- 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/define-global.js diff --git a/src/node.js b/src/node.js index 993e596ba6140d..726820fb1ea70b 100644 --- a/src/node.js +++ b/src/node.js @@ -140,6 +140,7 @@ } } else { + startup.preloadModules(); // If -i or --interactive were passed, or stdin is a TTY. if (process._forceRepl || NativeModule.require('tty').isatty(0)) { // REPL diff --git a/test/fixtures/define-global.js b/test/fixtures/define-global.js new file mode 100644 index 00000000000000..82b6a5a72cc99b --- /dev/null +++ b/test/fixtures/define-global.js @@ -0,0 +1 @@ +global.a = 'test'; diff --git a/test/parallel/test-preload.js b/test/parallel/test-preload.js index f94a7eae942493..e7d89d124c798c 100644 --- a/test/parallel/test-preload.js +++ b/test/parallel/test-preload.js @@ -1,5 +1,5 @@ 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const path = require('path'); const child_process = require('child_process'); @@ -21,6 +21,7 @@ var fixture = function(name) { var fixtureA = fixture('printA.js'); var fixtureB = fixture('printB.js'); var fixtureC = fixture('printC.js'); +const fixtureD = fixture('define-global.js'); var fixtureThrows = fixture('throws_error4.js'); // test preloading a single module works @@ -73,6 +74,18 @@ child_process.exec(nodeBinary + ' ' assert.equal(stdout, 'A\nB\nhello\n'); }); +// test that preload works with -i +const interactive = child_process.exec(nodeBinary + ' ' + + preloadOption([fixtureD]) + + '-i', + common.mustCall(function(err, stdout, stderr) { + assert.ifError(err); + assert.strictEqual(stdout, `> 'test'\n> `); + })); + +interactive.stdin.write('a\n'); +interactive.stdin.write('process.exit()\n'); + child_process.exec(nodeBinary + ' ' + '--require ' + fixture('cluster-preload.js') + ' ' + fixture('cluster-preload-test.js'), From 4254508fb123e79df1f1c86b3c24cf710903b87e Mon Sep 17 00:00:00 2001 From: Ben Ripkens Date: Tue, 29 Dec 2015 11:54:35 +0100 Subject: [PATCH 18/33] v8,src: expose statistics about heap spaces Provide means to inspect information about the separate heap spaces via a callable API. This is helpful to analyze memory issues. Fixes: https://github.com/nodejs/node/issues/2079 PR-URL: https://github.com/nodejs/node/pull/4463 Reviewed-By: Colin Ihrig Reviewed-By: Trevor Norris Reviewed-By: Ben Noordhuis Reviewed-By: James M Snell --- doc/api/v8.markdown | 49 +++++++++++++++++++ lib/v8.js | 33 ++++++++++++- src/env-inl.h | 12 +++++ src/env.h | 4 ++ src/node_v8.cc | 87 +++++++++++++++++++++++++++++++++- test/parallel/test-v8-stats.js | 19 ++++++++ 6 files changed, 202 insertions(+), 2 deletions(-) diff --git a/doc/api/v8.markdown b/doc/api/v8.markdown index 70abd6c6473f24..c6d760b0d5ff31 100644 --- a/doc/api/v8.markdown +++ b/doc/api/v8.markdown @@ -21,6 +21,55 @@ Returns an object with the following properties } ``` +## getHeapSpaceStatistics() + +Returns statistics about the V8 heap spaces, i.e. the segments which make up +the V8 heap. Order of heap spaces nor availability of a heap space can be +guaranteed as the statistics are provided via the V8 `GetHeapSpaceStatistics` +function. + +Example result: + +``` +[ + { + "space_name": "new_space", + "space_size": 2063872, + "space_used_size": 951112, + "space_available_size": 80824, + "physical_space_size": 2063872 + }, + { + "space_name": "old_space", + "space_size": 3090560, + "space_used_size": 2493792, + "space_available_size": 0, + "physical_space_size": 3090560 + }, + { + "space_name": "code_space", + "space_size": 1260160, + "space_used_size": 644256, + "space_available_size": 960, + "physical_space_size": 1260160 + }, + { + "space_name": "map_space", + "space_size": 1094160, + "space_used_size": 201608, + "space_available_size": 0, + "physical_space_size": 1094160 + }, + { + "space_name": "large_object_space", + "space_size": 0, + "space_used_size": 0, + "space_available_size": 1490980608, + "physical_space_size": 0 + } +] +``` + ## setFlagsFromString(string) Set additional V8 command line flags. Use with care; changing settings diff --git a/lib/v8.js b/lib/v8.js index acadfa64e0650e..551b2ada98526e 100644 --- a/lib/v8.js +++ b/lib/v8.js @@ -16,9 +16,9 @@ const v8binding = process.binding('v8'); +// Properties for heap statistics buffer extraction. const heapStatisticsBuffer = new Uint32Array(v8binding.heapStatisticsArrayBuffer); - const kTotalHeapSizeIndex = v8binding.kTotalHeapSizeIndex; const kTotalHeapSizeExecutableIndex = v8binding.kTotalHeapSizeExecutableIndex; const kTotalPhysicalSizeIndex = v8binding.kTotalPhysicalSizeIndex; @@ -26,6 +26,18 @@ const kTotalAvailableSize = v8binding.kTotalAvailableSize; const kUsedHeapSizeIndex = v8binding.kUsedHeapSizeIndex; const kHeapSizeLimitIndex = v8binding.kHeapSizeLimitIndex; +// Properties for heap space statistics buffer extraction. +const heapSpaceStatisticsBuffer = + new Uint32Array(v8binding.heapSpaceStatisticsArrayBuffer); +const kHeapSpaces = v8binding.kHeapSpaces; +const kNumberOfHeapSpaces = kHeapSpaces.length; +const kHeapSpaceStatisticsPropertiesCount = + v8binding.kHeapSpaceStatisticsPropertiesCount; +const kSpaceSizeIndex = v8binding.kSpaceSizeIndex; +const kSpaceUsedSizeIndex = v8binding.kSpaceUsedSizeIndex; +const kSpaceAvailableSizeIndex = v8binding.kSpaceAvailableSizeIndex; +const kPhysicalSpaceSizeIndex = v8binding.kPhysicalSpaceSizeIndex; + exports.getHeapStatistics = function() { const buffer = heapStatisticsBuffer; @@ -42,3 +54,22 @@ exports.getHeapStatistics = function() { }; exports.setFlagsFromString = v8binding.setFlagsFromString; + +exports.getHeapSpaceStatistics = function() { + const heapSpaceStatistics = new Array(kNumberOfHeapSpaces); + const buffer = heapSpaceStatisticsBuffer; + v8binding.updateHeapSpaceStatisticsArrayBuffer(); + + for (let i = 0; i < kNumberOfHeapSpaces; i++) { + const propertyOffset = i * kHeapSpaceStatisticsPropertiesCount; + heapSpaceStatistics[i] = { + space_name: kHeapSpaces[i], + space_size: buffer[propertyOffset + kSpaceSizeIndex], + space_used_size: buffer[propertyOffset + kSpaceUsedSizeIndex], + space_available_size: buffer[propertyOffset + kSpaceAvailableSizeIndex], + physical_space_size: buffer[propertyOffset + kPhysicalSpaceSizeIndex] + }; + } + + return heapSpaceStatistics; +}; diff --git a/src/env-inl.h b/src/env-inl.h index f73e9c6ba2000a..d2c0e048a6d3e3 100644 --- a/src/env-inl.h +++ b/src/env-inl.h @@ -242,6 +242,7 @@ inline Environment::~Environment() { isolate_data()->Put(); delete[] heap_statistics_buffer_; + delete[] heap_space_statistics_buffer_; delete[] http_parser_buffer_; } @@ -374,6 +375,17 @@ inline void Environment::set_heap_statistics_buffer(uint32_t* pointer) { heap_statistics_buffer_ = pointer; } +inline uint32_t* Environment::heap_space_statistics_buffer() const { + CHECK_NE(heap_space_statistics_buffer_, nullptr); + return heap_space_statistics_buffer_; +} + +inline void Environment::set_heap_space_statistics_buffer(uint32_t* pointer) { + CHECK_EQ(heap_space_statistics_buffer_, nullptr); // Should be set only once. + heap_space_statistics_buffer_ = pointer; +} + + inline char* Environment::http_parser_buffer() const { return http_parser_buffer_; } diff --git a/src/env.h b/src/env.h index 6151c57069ad7b..0431ecab77b3d5 100644 --- a/src/env.h +++ b/src/env.h @@ -461,6 +461,9 @@ class Environment { inline uint32_t* heap_statistics_buffer() const; inline void set_heap_statistics_buffer(uint32_t* pointer); + inline uint32_t* heap_space_statistics_buffer() const; + inline void set_heap_space_statistics_buffer(uint32_t* pointer); + inline char* http_parser_buffer() const; inline void set_http_parser_buffer(char* buffer); @@ -561,6 +564,7 @@ class Environment { int handle_cleanup_waiting_; uint32_t* heap_statistics_buffer_ = nullptr; + uint32_t* heap_space_statistics_buffer_ = nullptr; char* http_parser_buffer_; diff --git a/src/node_v8.cc b/src/node_v8.cc index 9f456daec464ce..a1122e57f13cac 100644 --- a/src/node_v8.cc +++ b/src/node_v8.cc @@ -7,13 +7,16 @@ namespace node { +using v8::Array; using v8::ArrayBuffer; using v8::Context; using v8::Function; using v8::FunctionCallbackInfo; +using v8::HeapSpaceStatistics; using v8::HeapStatistics; using v8::Isolate; using v8::Local; +using v8::NewStringType; using v8::Object; using v8::String; using v8::Uint32; @@ -34,6 +37,21 @@ static const size_t kHeapStatisticsPropertiesCount = HEAP_STATISTICS_PROPERTIES(V); #undef V +#define HEAP_SPACE_STATISTICS_PROPERTIES(V) \ + V(0, space_size, kSpaceSizeIndex) \ + V(1, space_used_size, kSpaceUsedSizeIndex) \ + V(2, space_available_size, kSpaceAvailableSizeIndex) \ + V(3, physical_space_size, kPhysicalSpaceSizeIndex) + +#define V(a, b, c) +1 +static const size_t kHeapSpaceStatisticsPropertiesCount = + HEAP_SPACE_STATISTICS_PROPERTIES(V); +#undef V + +// Will be populated in InitializeV8Bindings. +static size_t number_of_heap_spaces = 0; + + void UpdateHeapStatisticsArrayBuffer(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); HeapStatistics s; @@ -45,6 +63,23 @@ void UpdateHeapStatisticsArrayBuffer(const FunctionCallbackInfo& args) { } +void UpdateHeapSpaceStatisticsBuffer(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + HeapSpaceStatistics s; + Isolate* const isolate = env->isolate(); + uint32_t* buffer = env->heap_space_statistics_buffer(); + + for (size_t i = 0; i < number_of_heap_spaces; i++) { + isolate->GetHeapSpaceStatistics(&s, i); + size_t const property_offset = i * kHeapSpaceStatisticsPropertiesCount; +#define V(index, name, _) buffer[property_offset + index] = \ + static_cast(s.name()); + HEAP_SPACE_STATISTICS_PROPERTIES(V) +#undef V + } +} + + void SetFlagsFromString(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); @@ -62,10 +97,10 @@ void InitializeV8Bindings(Local target, Local unused, Local context) { Environment* env = Environment::GetCurrent(context); + env->SetMethod(target, "updateHeapStatisticsArrayBuffer", UpdateHeapStatisticsArrayBuffer); - env->SetMethod(target, "setFlagsFromString", SetFlagsFromString); env->set_heap_statistics_buffer(new uint32_t[kHeapStatisticsPropertiesCount]); @@ -84,6 +119,56 @@ void InitializeV8Bindings(Local target, HEAP_STATISTICS_PROPERTIES(V) #undef V + + target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), + "kHeapSpaceStatisticsPropertiesCount"), + Uint32::NewFromUnsigned(env->isolate(), + kHeapSpaceStatisticsPropertiesCount)); + + number_of_heap_spaces = env->isolate()->NumberOfHeapSpaces(); + + // Heap space names are extracted once and exposed to JavaScript to + // avoid excessive creation of heap space name Strings. + HeapSpaceStatistics s; + const Local heap_spaces = Array::New(env->isolate(), + number_of_heap_spaces); + for (size_t i = 0; i < number_of_heap_spaces; i++) { + env->isolate()->GetHeapSpaceStatistics(&s, i); + Local heap_space_name = String::NewFromUtf8(env->isolate(), + s.space_name(), + NewStringType::kNormal) + .ToLocalChecked(); + heap_spaces->Set(i, heap_space_name); + } + target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "kHeapSpaces"), + heap_spaces); + + env->SetMethod(target, + "updateHeapSpaceStatisticsArrayBuffer", + UpdateHeapSpaceStatisticsBuffer); + + env->set_heap_space_statistics_buffer( + new uint32_t[kHeapSpaceStatisticsPropertiesCount * number_of_heap_spaces]); + + const size_t heap_space_statistics_buffer_byte_length = + sizeof(*env->heap_space_statistics_buffer()) * + kHeapSpaceStatisticsPropertiesCount * + number_of_heap_spaces; + + target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), + "heapSpaceStatisticsArrayBuffer"), + ArrayBuffer::New(env->isolate(), + env->heap_space_statistics_buffer(), + heap_space_statistics_buffer_byte_length)); + +#define V(i, _, name) \ + target->Set(FIXED_ONE_BYTE_STRING(env->isolate(), #name), \ + Uint32::NewFromUnsigned(env->isolate(), i)); + + HEAP_SPACE_STATISTICS_PROPERTIES(V) +#undef V + + env->SetMethod(target, "setFlagsFromString", SetFlagsFromString); } } // namespace node diff --git a/test/parallel/test-v8-stats.js b/test/parallel/test-v8-stats.js index eb5566fe2bc28f..54140e4110fefe 100644 --- a/test/parallel/test-v8-stats.js +++ b/test/parallel/test-v8-stats.js @@ -15,3 +15,22 @@ assert.deepEqual(Object.keys(s).sort(), keys); keys.forEach(function(key) { assert.equal(typeof s[key], 'number'); }); + + +const expectedHeapSpaces = [ + 'new_space', + 'old_space', + 'code_space', + 'map_space', + 'large_object_space' +]; +const heapSpaceStatistics = v8.getHeapSpaceStatistics(); +const actualHeapSpaceNames = heapSpaceStatistics.map(s => s.space_name); +assert.deepEqual(actualHeapSpaceNames.sort(), expectedHeapSpaces.sort()); +heapSpaceStatistics.forEach(heapSpace => { + assert.strictEqual(typeof heapSpace.space_name, 'string'); + assert.strictEqual(typeof heapSpace.space_size, 'number'); + assert.strictEqual(typeof heapSpace.space_used_size, 'number'); + assert.strictEqual(typeof heapSpace.space_available_size, 'number'); + assert.strictEqual(typeof heapSpace.physical_space_size, 'number'); +}); From f221a43f3ebf842c1f1681e9d13182af928b3112 Mon Sep 17 00:00:00 2001 From: Jackson Tian Date: Mon, 18 Jan 2016 15:08:12 +0800 Subject: [PATCH 19/33] buffer: make byteLength work with Buffer correctly Make the byteLength work correctly when input is Buffer. e.g: ```js // The incomplete unicode string Buffer.byteLength(new Buffer([0xe4, 0xb8, 0xad, 0xe6, 0x96])) ``` The old output: 9 The new output: 5 PR-URL: https://github.com/nodejs/node/pull/4738 Reviewed-By: Ben Noordhuis Reviewed-By: Brian White Reviewed-By: James M Snell Reviewed-By: Colin Ihrig --- lib/buffer.js | 3 +++ test/parallel/test-buffer-bytelength.js | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/lib/buffer.js b/lib/buffer.js index 2daebb5e301e1c..f9214ed89f84cd 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -257,6 +257,9 @@ function base64ByteLength(str, bytes) { function byteLength(string, encoding) { + if (string instanceof Buffer) + return string.length; + if (typeof string !== 'string') string = '' + string; diff --git a/test/parallel/test-buffer-bytelength.js b/test/parallel/test-buffer-bytelength.js index 32ed6dbd67615e..ef68097157b1d8 100644 --- a/test/parallel/test-buffer-bytelength.js +++ b/test/parallel/test-buffer-bytelength.js @@ -10,6 +10,12 @@ assert.equal(Buffer.byteLength(NaN, 'utf8'), 3); assert.equal(Buffer.byteLength({}, 'binary'), 15); assert.equal(Buffer.byteLength(), 9); +// buffer +var incomplete = new Buffer([0xe4, 0xb8, 0xad, 0xe6, 0x96]); +assert.equal(Buffer.byteLength(incomplete), 5); +var ascii = new Buffer('abc'); +assert.equal(Buffer.byteLength(ascii), 3); + // special case: zero length string assert.equal(Buffer.byteLength('', 'ascii'), 0); assert.equal(Buffer.byteLength('', 'HeX'), 0); From d533364a24325c47bd832fc4a8b137aad2823750 Mon Sep 17 00:00:00 2001 From: Kohei TAKATA Date: Fri, 15 Jan 2016 12:49:24 +0900 Subject: [PATCH 20/33] readline: Remove XXX and output debuglog Remove a comment that has a word 'XXX'. And add a line to output debuglog of error. PR-URL: https://github.com/nodejs/node/pull/4690 Reviewed-By: Colin Ihrig Reviewed-By: James M Snell --- lib/readline.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/readline.js b/lib/readline.js index 00d9f8984e6a71..8ee10850e54f89 100644 --- a/lib/readline.js +++ b/lib/readline.js @@ -9,6 +9,7 @@ const kHistorySize = 30; const util = require('util'); +const debug = util.debuglog('readline'); const internalUtil = require('internal/util'); const inherits = util.inherits; const Buffer = require('buffer').Buffer; @@ -375,7 +376,7 @@ Interface.prototype._tabComplete = function() { self.resume(); if (err) { - // XXX Log it somewhere? + debug('tab completion error %j', err); return; } From 3af206d6c1e5565f7860ce9dcb845de0ac7b6ff5 Mon Sep 17 00:00:00 2001 From: cjihrig Date: Fri, 15 Jan 2016 16:54:13 -0500 Subject: [PATCH 21/33] src: return UV_EAI_NODATA on empty lookup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AfterGetAddrInfo() can potentially return an empty array of results without setting an error value. The JavaScript layer expects the array to have at least one value if an error is not returned. This commit sets a UV_EAI_NODATA error when an empty result array is detected. Fixes: https://github.com/nodejs/node/issues/4545 PR-URL: https://github.com/nodejs/node/pull/4715 Reviewed-By: Ben Noordhuis Reviewed-By: Evan Lucas Reviewed-By: Saúl Ibarra Corretgé --- src/cares_wrap.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc index 8f57dfe477cda4..46636c528b7f81 100644 --- a/src/cares_wrap.cc +++ b/src/cares_wrap.cc @@ -983,6 +983,10 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) { address = address->ai_next; } + // No responses were found to return + if (n == 0) { + argv[0] = Integer::New(env->isolate(), UV_EAI_NODATA); + } argv[1] = results; } From 399db043667724b2080a51ad77e8e5d7ae8a7370 Mon Sep 17 00:00:00 2001 From: Santiago Gimeno Date: Sun, 22 Nov 2015 15:12:17 +0100 Subject: [PATCH 22/33] test: fix tls-multi-key race condition In some conditions it can happen that the client-side socket is destroyed before the server-side socket has gracefully closed, thus causing a 'ECONNRESET' error in this socket. To solve this, also close gracefully in the client side. PR-URL: https://github.com/nodejs/node/pull/3966 Reviewed-By: Fedor Indutny Reviewed-By: James M Snell --- test/parallel/test-tls-multi-key.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/parallel/test-tls-multi-key.js b/test/parallel/test-tls-multi-key.js index 4c9fb4285f6ddb..17b409f284dcba 100644 --- a/test/parallel/test-tls-multi-key.js +++ b/test/parallel/test-tls-multi-key.js @@ -35,8 +35,8 @@ var server = tls.createServer(options, function(conn) { rejectUnauthorized: false }, function() { ciphers.push(rsa.getCipher()); - ecdsa.destroy(); - rsa.destroy(); + ecdsa.end(); + rsa.end(); server.close(); }); }); From 14061c6498f591968c601ab1ea359c8aa94d6723 Mon Sep 17 00:00:00 2001 From: Peter Geiss Date: Sat, 16 Jan 2016 01:37:27 -0500 Subject: [PATCH 23/33] buffer: remove unnecessary TODO comments Refs: #4642 PR-URL: #4719 Reviewed-By: Colin Ihrig Reviewed-By: Rich Trott --- lib/buffer.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/buffer.js b/lib/buffer.js index f9214ed89f84cd..3d28bf9a23dc48 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -539,8 +539,6 @@ Buffer.prototype.set = internalUtil.deprecate(function set(offset, v) { }, 'Buffer.set is deprecated. Use array indexes instead.'); -// TODO(trevnorris): fix these checks to follow new standard -// write(string, offset = 0, length = buffer.length, encoding = 'utf8') var writeWarned = false; const writeMsg = 'Buffer.write(string, encoding, offset, length) is ' + 'deprecated. Use write(string[, offset[, length]]' + @@ -633,8 +631,6 @@ Buffer.prototype.toJSON = function() { }; -// TODO(trevnorris): currently works like Array.prototype.slice(), which -// doesn't follow the new standard for throwing on out of range indexes. Buffer.prototype.slice = function slice(start, end) { const buffer = this.subarray(start, end); Object.setPrototypeOf(buffer, Buffer.prototype); From eb2b8c637b34f000e71ca15de80ebbb313215201 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Thu, 7 Jan 2016 22:36:30 +0100 Subject: [PATCH 24/33] module: cache stat() results more aggressively Reduce the number of stat() system calls that require() makes by caching the results more aggressively. To avoid unbounded growth without implementing a LRU cache, scope the cache to the lifetime of the first call to require(). Recursive calls (i.e. require() calls in the included code) transparently profit from the cache. The benchmarked application is the loopback-sample-app[0] and it sees the number of stat calls at start-up go down by 40%, from 4736 to 2810. [0] https://github.com/strongloop/loopback-sample-app PR-URL: https://github.com/nodejs/node/pull/4575 Reviewed-By: Colin Ihrig Reviewed-By: James M Snell --- lib/internal/module.js | 11 +++++++-- lib/module.js | 26 ++++++++++++++++++---- test/fixtures/module-require-depth/one.js | 9 ++++++++ test/fixtures/module-require-depth/two.js | 9 ++++++++ test/parallel/test-module-require-depth.js | 13 +++++++++++ 5 files changed, 62 insertions(+), 6 deletions(-) create mode 100644 test/fixtures/module-require-depth/one.js create mode 100644 test/fixtures/module-require-depth/two.js create mode 100644 test/parallel/test-module-require-depth.js diff --git a/lib/internal/module.js b/lib/internal/module.js index ef55aa64bd5642..29f88999dbf72f 100644 --- a/lib/internal/module.js +++ b/lib/internal/module.js @@ -1,6 +1,8 @@ 'use strict'; -module.exports = { makeRequireFunction, stripBOM }; +exports = module.exports = { makeRequireFunction, stripBOM }; + +exports.requireDepth = 0; // Invoke with makeRequireFunction.call(module) where |module| is the // Module object to use as the context for the require() function. @@ -9,7 +11,12 @@ function makeRequireFunction() { const self = this; function require(path) { - return self.require(path); + try { + exports.requireDepth += 1; + return self.require(path); + } finally { + exports.requireDepth -= 1; + } } require.resolve = function(request) { diff --git a/lib/module.js b/lib/module.js index 02e6cccf77d1eb..7d3f0f6c71d57b 100644 --- a/lib/module.js +++ b/lib/module.js @@ -23,6 +23,20 @@ function hasOwnProperty(obj, prop) { } +function stat(filename) { + filename = path._makeLong(filename); + const cache = stat.cache; + if (cache !== null) { + const result = cache.get(filename); + if (result !== undefined) return result; + } + const result = internalModuleStat(filename); + if (cache !== null) cache.set(filename, result); + return result; +} +stat.cache = null; + + function Module(id, parent) { this.id = id; this.exports = {}; @@ -104,7 +118,7 @@ Module._realpathCache = {}; // check if the file exists and is not a directory function tryFile(requestPath) { - const rc = internalModuleStat(path._makeLong(requestPath)); + const rc = stat(requestPath); return rc === 0 && toRealPath(requestPath); } @@ -141,12 +155,12 @@ Module._findPath = function(request, paths) { // For each path for (var i = 0, PL = paths.length; i < PL; i++) { // Don't search further if path doesn't exist - if (paths[i] && internalModuleStat(path._makeLong(paths[i])) < 1) continue; + if (paths[i] && stat(paths[i]) < 1) continue; var basePath = path.resolve(paths[i], request); var filename; if (!trailingSlash) { - const rc = internalModuleStat(path._makeLong(basePath)); + const rc = stat(basePath); if (rc === 0) { // File. filename = toRealPath(basePath); } else if (rc === 1) { // Directory. @@ -394,7 +408,11 @@ Module.prototype._compile = function(content, filename) { const dirname = path.dirname(filename); const require = internalModule.makeRequireFunction.call(this); const args = [this.exports, require, this, filename, dirname]; - return compiledWrapper.apply(this.exports, args); + const depth = internalModule.requireDepth; + if (depth === 0) stat.cache = new Map(); + const result = compiledWrapper.apply(this.exports, args); + if (depth === 0) stat.cache = null; + return result; }; diff --git a/test/fixtures/module-require-depth/one.js b/test/fixtures/module-require-depth/one.js new file mode 100644 index 00000000000000..5927908b7540ab --- /dev/null +++ b/test/fixtures/module-require-depth/one.js @@ -0,0 +1,9 @@ +// Flags: --expose_internals +'use strict'; +const assert = require('assert'); +const internalModule = require('internal/module'); + +exports.requireDepth = internalModule.requireDepth; +assert.strictEqual(internalModule.requireDepth, 1); +assert.deepStrictEqual(require('./two'), { requireDepth: 2 }); +assert.strictEqual(internalModule.requireDepth, 1); diff --git a/test/fixtures/module-require-depth/two.js b/test/fixtures/module-require-depth/two.js new file mode 100644 index 00000000000000..aea49947d1152d --- /dev/null +++ b/test/fixtures/module-require-depth/two.js @@ -0,0 +1,9 @@ +// Flags: --expose_internals +'use strict'; +const assert = require('assert'); +const internalModule = require('internal/module'); + +exports.requireDepth = internalModule.requireDepth; +assert.strictEqual(internalModule.requireDepth, 2); +assert.deepStrictEqual(require('./one'), { requireDepth: 1 }); +assert.strictEqual(internalModule.requireDepth, 2); diff --git a/test/parallel/test-module-require-depth.js b/test/parallel/test-module-require-depth.js new file mode 100644 index 00000000000000..4d2ddac151be68 --- /dev/null +++ b/test/parallel/test-module-require-depth.js @@ -0,0 +1,13 @@ +// Flags: --expose_internals +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const internalModule = require('internal/module'); + +// Module one loads two too so the expected depth for two is, well, two. +assert.strictEqual(internalModule.requireDepth, 0); +const one = require(common.fixturesDir + '/module-require-depth/one'); +const two = require(common.fixturesDir + '/module-require-depth/two'); +assert.deepStrictEqual(one, { requireDepth: 1 }); +assert.deepStrictEqual(two, { requireDepth: 2 }); +assert.strictEqual(internalModule.requireDepth, 0); From 8f4f5b3ca50c61a17877d4b0d46ced17b420e33a Mon Sep 17 00:00:00 2001 From: Roman Reiss Date: Tue, 19 Jan 2016 03:17:39 +0100 Subject: [PATCH 25/33] tools: enable space-in-parens ESLint rule Ref: http://eslint.org/docs/rules/space-in-parens.html PR-URL: https://github.com/nodejs/node/pull/4753 Reviewed-By: Colin Ihrig Reviewed-By: Evan Lucas --- .eslintrc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.eslintrc b/.eslintrc index fec8179aa31f14..8d9988acef7adc 100644 --- a/.eslintrc +++ b/.eslintrc @@ -67,8 +67,10 @@ rules: eol-last: 2 ## no trailing spaces no-trailing-spaces: 2 - # require space after keywords, eg 'for (..)' + ## require space after keywords, eg 'for (..)' space-after-keywords: 2 + ## no leading/trailing spaces in parens + space-in-parens: [2, "never"] # ECMAScript 6 # list: http://eslint.org/docs/rules/#ecmascript-6 From a39b28bb5a1d70f131c670dc29138f22fc5a0905 Mon Sep 17 00:00:00 2001 From: Roman Reiss Date: Tue, 19 Jan 2016 03:23:07 +0100 Subject: [PATCH 26/33] test: fix issues for space-in-parens ESLint rule PR-URL: https://github.com/nodejs/node/pull/4753 Reviewed-By: Colin Ihrig Reviewed-By: Evan Lucas --- test/parallel/test-beforeexit-event.js | 2 +- test/parallel/test-crypto-hmac.js | 2 +- test/parallel/test-http-client-timeout-agent.js | 2 +- test/parallel/test-process-binding.js | 2 +- test/pummel/test-timers.js | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/parallel/test-beforeexit-event.js b/test/parallel/test-beforeexit-event.js index 8e5d66f5f5d7c7..6bc5ef53ed9518 100644 --- a/test/parallel/test-beforeexit-event.js +++ b/test/parallel/test-beforeexit-event.js @@ -5,7 +5,7 @@ var common = require('../common'); var revivals = 0; var deaths = 0; -process.on('beforeExit', function() { deaths++; } ); +process.on('beforeExit', function() { deaths++; }); process.once('beforeExit', tryImmediate); diff --git a/test/parallel/test-crypto-hmac.js b/test/parallel/test-crypto-hmac.js index c244c9e0dd12c2..7d66f83baaed8e 100644 --- a/test/parallel/test-crypto-hmac.js +++ b/test/parallel/test-crypto-hmac.js @@ -62,7 +62,7 @@ var wikipedia = [ for (var i = 0, l = wikipedia.length; i < l; i++) { for (var hash in wikipedia[i]['hmac']) { // FIPS does not support MD5. - if (common.hasFipsCrypto && hash == 'md5' ) + if (common.hasFipsCrypto && hash == 'md5') continue; var result = crypto.createHmac(hash, wikipedia[i]['key']) .update(wikipedia[i]['data']) diff --git a/test/parallel/test-http-client-timeout-agent.js b/test/parallel/test-http-client-timeout-agent.js index 51bfb8299b13df..6892b38719fb1a 100644 --- a/test/parallel/test-http-client-timeout-agent.js +++ b/test/parallel/test-http-client-timeout-agent.js @@ -17,7 +17,7 @@ var options = { var server = http.createServer(function(req, res) { const m = /\/(.*)/.exec(req.url); const reqid = parseInt(m[1], 10); - if ( reqid % 2 ) { + if (reqid % 2) { // do not reply the request } else { res.writeHead(200, {'Content-Type': 'text/plain'}); diff --git a/test/parallel/test-process-binding.js b/test/parallel/test-process-binding.js index 5350a8c66932cb..722e9333aff60a 100644 --- a/test/parallel/test-process-binding.js +++ b/test/parallel/test-process-binding.js @@ -12,7 +12,7 @@ assert.throws( assert.doesNotThrow(function() { process.binding('buffer'); }, function(err) { - if ( (err instanceof Error) ) { + if (err instanceof Error) { return true; } }, 'unexpected error'); diff --git a/test/pummel/test-timers.js b/test/pummel/test-timers.js index d911beb6b09288..3525c827a9e6b7 100644 --- a/test/pummel/test-timers.js +++ b/test/pummel/test-timers.js @@ -30,7 +30,7 @@ clearTimeout(id); setInterval(function() { interval_count += 1; - var endtime = new Date( ); + var endtime = new Date(); var diff = endtime - starttime; assert.ok(diff > 0); From a347cd793f3e42fdec73d5e83d92dc53f41c40e8 Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Sun, 17 Jan 2016 19:50:09 -0800 Subject: [PATCH 27/33] test: make test-cluster-disconnect-leak reliable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, test-cluster-disconnect-leak had two issues: * Magic numbers: How many times to spawn a worker was determined through empirical experimentation. This means that as new platforms and new CPU/RAM configurations are tested, the magic numbers require more and more refinement. This brings us to... * Non-determinism: The test *seems* to fail all the time when the bug it tests for is present, but it's really a judgment based on sampling. "Oh, with 8 workers per CPU, it fails about 80% of the time. Let's try 16..." This revised version of the test takes a different approach. The fix for the bug that the test was written for means that the `disconnect` event will fire reliably for a single worker. So we check for that and the test still fails when the fix is not in the code base and succeeds when it is. Advantages of this approach include: * The test runs much faster. * The test now works on Windows. The previous version skipped Windows. * The test should be reliable on any new platform regardless of CPU and RAM. Ref: https://github.com/nodejs/node/pull/4674 PR-URL: https://github.com/nodejs/node/pull/4736 Reviewed-By: Ben Noordhuis Reviewed-By: James M Snell Reviewed-By: Johan Bergström --- .../test-cluster-disconnect-leak.js | 46 ++++++------------- 1 file changed, 14 insertions(+), 32 deletions(-) diff --git a/test/sequential/test-cluster-disconnect-leak.js b/test/sequential/test-cluster-disconnect-leak.js index 33476dd427a61a..a4916c95ba4ea7 100644 --- a/test/sequential/test-cluster-disconnect-leak.js +++ b/test/sequential/test-cluster-disconnect-leak.js @@ -1,47 +1,29 @@ 'use strict'; -// Flags: --expose-internals + +// Test fails in Node v5.4.0 and passes in v5.4.1 and newer. const common = require('../common'); -const assert = require('assert'); const net = require('net'); const cluster = require('cluster'); -const handles = require('internal/cluster').handles; -const os = require('os'); -if (common.isWindows) { - console.log('1..0 # Skipped: This test does not apply to Windows.'); - return; -} +const noop = () => {}; cluster.schedulingPolicy = cluster.SCHED_NONE; if (cluster.isMaster) { - const cpus = os.cpus().length; - const tries = cpus > 8 ? 128 : cpus * 16; - - const worker1 = cluster.fork(); - worker1.on('message', common.mustCall(() => { - worker1.disconnect(); - for (let i = 0; i < tries; ++ i) { - const w = cluster.fork(); - w.on('online', common.mustCall(w.disconnect)); - } - })); - - cluster.on('exit', common.mustCall((worker, code) => { - assert.strictEqual(code, 0, 'worker exited with error'); - }, tries + 1)); - - process.on('exit', () => { - assert.deepEqual(Object.keys(cluster.workers), []); - assert.strictEqual(Object.keys(handles).length, 0); - }); + const worker = cluster.fork(); + + // This is the important part of the test: Confirm that `disconnect` fires. + worker.on('disconnect', common.mustCall(noop)); + + // These are just some extra stuff we're checking for good measure... + worker.on('exit', common.mustCall(noop)); + cluster.on('exit', common.mustCall(noop)); + cluster.disconnect(); return; } -var server = net.createServer(); +const server = net.createServer(); -server.listen(common.PORT, function() { - process.send('listening'); -}); +server.listen(common.PORT); From 426ff820f5ee7d5c58ab3e90f28f07a2d568f8c1 Mon Sep 17 00:00:00 2001 From: Evan Lucas Date: Tue, 19 Jan 2016 08:53:38 -0600 Subject: [PATCH 28/33] stream: prevent object map change in ReadableState ReadableState has the resumeScheduled property that helps determine if a stream should be resumed. It was not assigned in the constructor. When stream.resume is called on a readable stream that is not flowing, it is set to true. This changes the property map of the ReadableState which can cause a deopt in onEofChunk and needMoreData. PR-URL: https://github.com/nodejs/node/pull/4761 Reviewed-By: Ben Noordhuis Reviewed-By: Colin Ihrig Reviewed-By: Brian White --- lib/_stream_readable.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/_stream_readable.js b/lib/_stream_readable.js index 7074cd2ca508a5..33a5f0a7733e1f 100644 --- a/lib/_stream_readable.js +++ b/lib/_stream_readable.js @@ -51,6 +51,7 @@ function ReadableState(options, stream) { this.needReadable = false; this.emittedReadable = false; this.readableListening = false; + this.resumeScheduled = false; // Crypto is kind of old and crusty. Historically, its default string // encoding is 'binary' so we have to make this configurable. From 8a11b8c0efb7f414ed3b50399b33771b8fe9a0a5 Mon Sep 17 00:00:00 2001 From: Richard Lau Date: Tue, 19 Jan 2016 10:47:18 -0500 Subject: [PATCH 29/33] doc: restore ICU third-party software licenses PR-URL: https://github.com/nodejs/node/pull/4762 Reviewed-By: Rod Vagg --- LICENSE | 328 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 328 insertions(+) diff --git a/LICENSE b/LICENSE index 78edee8cf32256..0bef5360342062 100644 --- a/LICENSE +++ b/LICENSE @@ -98,6 +98,10 @@ The externally maintained libraries used by Node.js are: - ICU, located at deps/icu, is licensed as follows: """ + ICU License - ICU 1.8.1 and later + + COPYRIGHT AND PERMISSION NOTICE + Copyright (c) 1995-2015 International Business Machines Corporation and others All rights reserved. @@ -124,6 +128,330 @@ The externally maintained libraries used by Node.js are: Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization of the copyright holder. + + All trademarks and registered trademarks mentioned herein are the property of their respective owners. + + Third-Party Software Licenses + This section contains third-party software notices and/or additional terms for licensed + third-party software components included within ICU libraries. + + 1. Unicode Data Files and Software + + COPYRIGHT AND PERMISSION NOTICE + + Copyright © 1991-2015 Unicode, Inc. All rights reserved. + Distributed under the Terms of Use in + http://www.unicode.org/copyright.html. + + Permission is hereby granted, free of charge, to any person obtaining + a copy of the Unicode data files and any associated documentation + (the "Data Files") or Unicode software and any associated documentation + (the "Software") to deal in the Data Files or Software + without restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, and/or sell copies of + the Data Files or Software, and to permit persons to whom the Data Files + or Software are furnished to do so, provided that + (a) this copyright and permission notice appear with all copies + of the Data Files or Software, + (b) this copyright and permission notice appear in associated + documentation, and + (c) there is clear notice in each modified Data File or in the Software + as well as in the documentation associated with the Data File(s) or + Software that the data or software has been modified. + + THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF + ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS + NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL + DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THE DATA FILES OR SOFTWARE. + + Except as contained in this notice, the name of a copyright holder + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in these Data Files or Software without prior + written authorization of the copyright holder. + + 2. Chinese/Japanese Word Break Dictionary Data (cjdict.txt) + + # The Google Chrome software developed by Google is licensed under the BSD license. Other software included in this distribution is provided under other licenses, as set forth below. + # + # The BSD License + # http://opensource.org/licenses/bsd-license.php + # Copyright (C) 2006-2008, Google Inc. + # + # All rights reserved. + # + # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + # + # Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + # Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + # Neither the name of Google Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + # + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + # + # + # The word list in cjdict.txt are generated by combining three word lists listed + # below with further processing for compound word breaking. The frequency is generated + # with an iterative training against Google web corpora. + # + # * Libtabe (Chinese) + # - https://sourceforge.net/project/?group_id=1519 + # - Its license terms and conditions are shown below. + # + # * IPADIC (Japanese) + # - http://chasen.aist-nara.ac.jp/chasen/distribution.html + # - Its license terms and conditions are shown below. + # + # ---------COPYING.libtabe ---- BEGIN-------------------- + # + # /* + # * Copyrighy (c) 1999 TaBE Project. + # * Copyright (c) 1999 Pai-Hsiang Hsiao. + # * All rights reserved. + # * + # * Redistribution and use in source and binary forms, with or without + # * modification, are permitted provided that the following conditions + # * are met: + # * + # * . Redistributions of source code must retain the above copyright + # * notice, this list of conditions and the following disclaimer. + # * . Redistributions in binary form must reproduce the above copyright + # * notice, this list of conditions and the following disclaimer in + # * the documentation and/or other materials provided with the + # * distribution. + # * . Neither the name of the TaBE Project nor the names of its + # * contributors may be used to endorse or promote products derived + # * from this software without specific prior written permission. + # * + # * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + # * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + # * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + # * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + # * REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + # * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + # * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + # * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + # * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + # * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + # * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + # * OF THE POSSIBILITY OF SUCH DAMAGE. + # */ + # + # /* + # * Copyright (c) 1999 Computer Systems and Communication Lab, + # * Institute of Information Science, Academia Sinica. + # * All rights reserved. + # * + # * Redistribution and use in source and binary forms, with or without + # * modification, are permitted provided that the following conditions + # * are met: + # * + # * . Redistributions of source code must retain the above copyright + # * notice, this list of conditions and the following disclaimer. + # * . Redistributions in binary form must reproduce the above copyright + # * notice, this list of conditions and the following disclaimer in + # * the documentation and/or other materials provided with the + # * distribution. + # * . Neither the name of the Computer Systems and Communication Lab + # * nor the names of its contributors may be used to endorse or + # * promote products derived from this software without specific + # * prior written permission. + # * + # * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + # * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + # * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + # * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + # * REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + # * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + # * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + # * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + # * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + # * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + # * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + # * OF THE POSSIBILITY OF SUCH DAMAGE. + # */ + # + # Copyright 1996 Chih-Hao Tsai @ Beckman Institute, University of Illinois + # c-tsai4@uiuc.edu http://casper.beckman.uiuc.edu/~c-tsai4 + # + # ---------------COPYING.libtabe-----END------------------------------------ + # + # + # ---------------COPYING.ipadic-----BEGIN------------------------------------ + # + # Copyright 2000, 2001, 2002, 2003 Nara Institute of Science + # and Technology. All Rights Reserved. + # + # Use, reproduction, and distribution of this software is permitted. + # Any copy of this software, whether in its original form or modified, + # must include both the above copyright notice and the following + # paragraphs. + # + # Nara Institute of Science and Technology (NAIST), + # the copyright holders, disclaims all warranties with regard to this + # software, including all implied warranties of merchantability and + # fitness, in no event shall NAIST be liable for + # any special, indirect or consequential damages or any damages + # whatsoever resulting from loss of use, data or profits, whether in an + # action of contract, negligence or other tortuous action, arising out + # of or in connection with the use or performance of this software. + # + # A large portion of the dictionary entries + # originate from ICOT Free Software. The following conditions for ICOT + # Free Software applies to the current dictionary as well. + # + # Each User may also freely distribute the Program, whether in its + # original form or modified, to any third party or parties, PROVIDED + # that the provisions of Section 3 ("NO WARRANTY") will ALWAYS appear + # on, or be attached to, the Program, which is distributed substantially + # in the same form as set out herein and that such intended + # distribution, if actually made, will neither violate or otherwise + # contravene any of the laws and regulations of the countries having + # jurisdiction over the User or the intended distribution itself. + # + # NO WARRANTY + # + # The program was produced on an experimental basis in the course of the + # research and development conducted during the project and is provided + # to users as so produced on an experimental basis. Accordingly, the + # program is provided without any warranty whatsoever, whether express, + # implied, statutory or otherwise. The term "warranty" used herein + # includes, but is not limited to, any warranty of the quality, + # performance, merchantability and fitness for a particular purpose of + # the program and the nonexistence of any infringement or violation of + # any right of any third party. + # + # Each user of the program will agree and understand, and be deemed to + # have agreed and understood, that there is no warranty whatsoever for + # the program and, accordingly, the entire risk arising from or + # otherwise connected with the program is assumed by the user. + # + # Therefore, neither ICOT, the copyright holder, or any other + # organization that participated in or was otherwise related to the + # development of the program and their respective officials, directors, + # officers and other employees shall be held liable for any and all + # damages, including, without limitation, general, special, incidental + # and consequential damages, arising out of or otherwise in connection + # with the use or inability to use the program or any product, material + # or result produced or otherwise obtained by using the program, + # regardless of whether they have been advised of, or otherwise had + # knowledge of, the possibility of such damages at any time during the + # project or thereafter. Each user will be deemed to have agreed to the + # foregoing by his or her commencement of use of the program. The term + # "use" as used herein includes, but is not limited to, the use, + # modification, copying and distribution of the program and the + # production of secondary products from the program. + # + # In the case where the program, whether in its original form or + # modified, was distributed or delivered to or received by a user from + # any person, organization or entity other than ICOT, unless it makes or + # grants independently of ICOT any specific warranty to the user in + # writing, such person, organization or entity, will also be exempted + # from and not be held liable to the user for any such damages as noted + # above as far as the program is concerned. + # + # ---------------COPYING.ipadic-----END------------------------------------ + + 3. Lao Word Break Dictionary Data (laodict.txt) + + # Copyright (c) 2013 International Business Machines Corporation + # and others. All Rights Reserved. + # + # Project: http://code.google.com/p/lao-dictionary/ + # Dictionary: http://lao-dictionary.googlecode.com/git/Lao-Dictionary.txt + # License: http://lao-dictionary.googlecode.com/git/Lao-Dictionary-LICENSE.txt + # (copied below) + # + # This file is derived from the above dictionary, with slight modifications. + # -------------------------------------------------------------------------------- + # Copyright (C) 2013 Brian Eugene Wilson, Robert Martin Campbell. + # All rights reserved. + # + # Redistribution and use in source and binary forms, with or without modification, + # are permitted provided that the following conditions are met: + # + # Redistributions of source code must retain the above copyright notice, this + # list of conditions and the following disclaimer. Redistributions in binary + # form must reproduce the above copyright notice, this list of conditions and + # the following disclaimer in the documentation and/or other materials + # provided with the distribution. + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + # -------------------------------------------------------------------------------- + + 4. Burmese Word Break Dictionary Data (burmesedict.txt) + + # Copyright (c) 2014 International Business Machines Corporation + # and others. All Rights Reserved. + # + # This list is part of a project hosted at: + # github.com/kanyawtech/myanmar-karen-word-lists + # + # -------------------------------------------------------------------------------- + # Copyright (c) 2013, LeRoy Benjamin Sharon + # All rights reserved. + # + # Redistribution and use in source and binary forms, with or without modification, + # are permitted provided that the following conditions are met: + # + # Redistributions of source code must retain the above copyright notice, this + # list of conditions and the following disclaimer. + # + # Redistributions in binary form must reproduce the above copyright notice, this + # list of conditions and the following disclaimer in the documentation and/or + # other materials provided with the distribution. + # + # Neither the name Myanmar Karen Word Lists, nor the names of its + # contributors may be used to endorse or promote products derived from + # this software without specific prior written permission. + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + # -------------------------------------------------------------------------------- + + 5. Time Zone Database + ICU uses the public domain data and code derived from + Time Zone Database for its time zone support. The ownership of the TZ database is explained + in BCP 175: Procedure for Maintaining the Time Zone + Database section 7. + + 7. Database Ownership + + The TZ database itself is not an IETF Contribution or an IETF + document. Rather it is a pre-existing and regularly updated work + that is in the public domain, and is intended to remain in the public + domain. Therefore, BCPs 78 [RFC5378] and 79 [RFC3979] do not apply + to the TZ Database or contributions that individuals make to it. + Should any claims be made and substantiated against the TZ Database, + the organization that is providing the IANA Considerations defined in + this RFC, under the memorandum of understanding with the IETF, + currently ICANN, may act in accordance with all competent court + orders. No ownership claims will be made by ICANN or the IETF Trust + on the database or the code. Any person making a contribution to the + database or code waives all rights to future claims in that + contribution or in the TZ Database. """ - libuv, located at deps/uv, is licensed as follows: From fe23f4241f32eed474f45b48b6dc170e7ee446b8 Mon Sep 17 00:00:00 2001 From: Richard Lau Date: Tue, 19 Jan 2016 10:41:23 -0500 Subject: [PATCH 30/33] tools: fix license-builder.sh for ICU Modify tools/license-builder.sh to restore the Third-Party Software licenses for ICU. Also fix arguments to tail to work on Linux. rvagg: modified sed command for ICU to replace tabs with spaces and remove whitespace at the end of lines PR-URL: https://github.com/nodejs/node/pull/4762 Reviewed-By: Rod Vagg --- tools/license-builder.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/license-builder.sh b/tools/license-builder.sh index bb350e5a8bc559..5d6b810e1234c3 100755 --- a/tools/license-builder.sh +++ b/tools/license-builder.sh @@ -33,7 +33,8 @@ addlicense "c-ares" "deps/cares" \ "$(sed -e '/^ \*\/$/,$d' -e '/^$/d' -e 's/^[/ ]\* *//' ${rootdir}/deps/cares/src/ares_init.c)" addlicense "HTTP Parser" "deps/http_parser" "$(cat deps/http_parser/LICENSE-MIT)" addlicense "ICU" "deps/icu" \ - "$(sed -e '1,/COPYRIGHT AND PERMISSION NOTICE/d' -e '/^
$//' ${rootdir}/deps/icu/license.html)" + "$(sed -e '1,/ICU License - ICU 1\.8\.1 and later/d' -e :a \ + -e 's/<[^>]*>//g;s/ / /g;s/ +$//;/ Date: Tue, 19 Jan 2016 11:40:13 +0100 Subject: [PATCH 31/33] src: fix negative values in process.hrtime() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix a regression introduced in commit 89f056b ("node: improve performance of hrtime()") where the nanosecond field sometimes had a negative value when calculating the difference between two timestamps. Fixes: https://github.com/nodejs/node/issues/4751 PR-URL: https://github.com/nodejs/node/pull/4757 Reviewed-By: Evan Lucas Reviewed-By: Trevor Norris Reviewed-By: Сковорода Никита Андреевич --- src/node.js | 7 +++---- test/parallel/test-process-hrtime.js | 3 +++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/node.js b/src/node.js index 726820fb1ea70b..67f6cdb5ceda8c 100644 --- a/src/node.js +++ b/src/node.js @@ -193,10 +193,9 @@ if (typeof ar !== 'undefined') { if (Array.isArray(ar)) { - return [ - (hrValues[0] * 0x100000000 + hrValues[1]) - ar[0], - hrValues[2] - ar[1] - ]; + const sec = (hrValues[0] * 0x100000000 + hrValues[1]) - ar[0]; + const nsec = hrValues[2] - ar[1]; + return [nsec < 0 ? sec - 1 : sec, nsec < 0 ? nsec + 1e9 : nsec]; } throw new TypeError('process.hrtime() only accepts an Array tuple'); diff --git a/test/parallel/test-process-hrtime.js b/test/parallel/test-process-hrtime.js index ad186a3507d1e7..db16be0ad9e812 100644 --- a/test/parallel/test-process-hrtime.js +++ b/test/parallel/test-process-hrtime.js @@ -24,3 +24,6 @@ function validateTuple(tuple) { assert(isFinite(v)); }); } + +const diff = process.hrtime([0, 1e9 - 1]); +assert(diff[1] >= 0); // https://github.com/nodejs/node/issues/4751 From dd882563e56652f76e25994d046ab49b1bc5f836 Mon Sep 17 00:00:00 2001 From: Evan Lucas Date: Wed, 20 Jan 2016 15:32:36 -0600 Subject: [PATCH 32/33] 2016-01-20, Version 5.5.0 (Stable) Notable changes: * events: make sure console functions exist (Dave) https://github.com/nodejs/node/pull/4479 * fs: add autoClose option to fs.createWriteStream (Saquib) https://github.com/nodejs/node/pull/3679 * http: improves expect header handling (Daniel Sellers) https://github.com/nodejs/node/pull/4501 * node: allow preload modules with -i (Evan Lucas) https://github.com/nodejs/node/pull/4696 * v8,src: expose statistics about heap spaces (`v8.getHeapSpaceStatistics()`) (Ben Ripkens) https://github.com/nodejs/node/pull/4463 * Minor performance improvements: - lib: Use arrow functions instead of bind where possible (Minwoo Jung) https://github.com/nodejs/node/pull/3622 - module: cache stat() results more aggressively (Ben Noordhuis) https://github.com/nodejs/node/pull/4575 - querystring: improve parse() performance (Brian White) https://github.com/nodejs/node/pull/4675 PR-URL: https://github.com/nodejs/node/pull/4742 --- CHANGELOG.md | 84 ++++++++++++++++++++++++++++++++++++++++++++++ src/node_version.h | 6 ++-- 2 files changed, 87 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 314a2a66ac86e9..74f1bc53b6a9fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,89 @@ # Node.js ChangeLog +## 2016-01-20, Version 5.5.0 (Stable), @evanlucas + +### Notable Changes + +- **events**: make sure console functions exist (Dave) [#4479](https://github.com/nodejs/node/pull/4479) +- **fs**: add autoClose option to fs.createWriteStream (Saquib) [#3679](https://github.com/nodejs/node/pull/3679) +- **http**: improves expect header handling (Daniel Sellers) [#4501](https://github.com/nodejs/node/pull/4501) +- **node**: allow preload modules with -i (Evan Lucas) [#4696](https://github.com/nodejs/node/pull/4696) +- **v8,src**: expose statistics about heap spaces (`v8.getHeapSpaceStatistics()`) (Ben Ripkens) [#4463](https://github.com/nodejs/node/pull/4463) +* Minor performance improvements: + - **lib**: Use arrow functions instead of bind where possible (Minwoo Jung) [#3622](https://github.com/nodejs/node/pull/3622). + - (Mistakenly missing from v5.4.0) + - **module**: cache stat() results more aggressively (Ben Noordhuis) [#4575](https://github.com/nodejs/node/pull/4575) + - **querystring**: improve parse() performance (Brian White) [#4675](https://github.com/nodejs/node/pull/4675) + +### Known issues + +* Surrogate pair in REPL can freeze terminal. [#690](https://github.com/nodejs/node/issues/690) +* Calling `dns.setServers()` while a DNS query is in progress can cause the process to crash on a failed assertion. [#894](https://github.com/nodejs/node/issues/894) +* `url.resolve` may transfer the auth portion of the url when resolving between two full hosts, see [#1435](https://github.com/nodejs/node/issues/1435). +* Unicode characters in filesystem paths are not handled consistently across platforms or Node.js APIs. See [#2088](https://github.com/nodejs/node/issues/2088), [#3401](https://github.com/nodejs/node/issues/3401) and [#3519](https://github.com/nodejs/node/issues/3519). + +### Commits + +* [[`8d0ca10752`](https://github.com/nodejs/node/commit/8d0ca10752)] - **buffer**: make byteLength work with Buffer correctly (Jackson Tian) [#4738](https://github.com/nodejs/node/pull/4738) +* [[`83d2b7707e`](https://github.com/nodejs/node/commit/83d2b7707e)] - **buffer**: remove unnecessary TODO comments (Peter Geiss) [#4719](https://github.com/nodejs/node/pull/4719) +* [[`8182ec094d`](https://github.com/nodejs/node/commit/8182ec094d)] - **build**: add option to select VS version (julien.waechter) [#4645](https://github.com/nodejs/node/pull/4645) +* [[`4383acd9f4`](https://github.com/nodejs/node/commit/4383acd9f4)] - **build**: fix and refactor VTune config in vcbuild.bat (Rod Vagg) [#4192](https://github.com/nodejs/node/pull/4192) +* [[`be0b0b8cb9`](https://github.com/nodejs/node/commit/be0b0b8cb9)] - **build**: minor corrections in VTune configure text (Rod Vagg) [#4192](https://github.com/nodejs/node/pull/4192) +* [[`9571be12f6`](https://github.com/nodejs/node/commit/9571be12f6)] - **cluster**: fix race condition setting suicide prop (Santiago Gimeno) [#4349](https://github.com/nodejs/node/pull/4349) +* [[`ebd9addcd1`](https://github.com/nodejs/node/commit/ebd9addcd1)] - **crypto**: clear error stack in ECDH::Initialize (Fedor Indutny) [#4689](https://github.com/nodejs/node/pull/4689) +* [[`66b9c0d8bd`](https://github.com/nodejs/node/commit/66b9c0d8bd)] - **debugger**: remove variable redeclarations (Rich Trott) [#4633](https://github.com/nodejs/node/pull/4633) +* [[`88b2889679`](https://github.com/nodejs/node/commit/88b2889679)] - **dgram**: prevent disabled optimization of bind() (Brian White) [#4613](https://github.com/nodejs/node/pull/4613) +* [[`d56e3f8b67`](https://github.com/nodejs/node/commit/d56e3f8b67)] - **doc**: restore ICU third-party software licenses (Richard Lau) [#4762](https://github.com/nodejs/node/pull/4762) +* [[`212a44df03`](https://github.com/nodejs/node/commit/212a44df03)] - **doc**: clarify protocol default in http.request() (cjihrig) [#4714](https://github.com/nodejs/node/pull/4714) +* [[`3297036345`](https://github.com/nodejs/node/commit/3297036345)] - **doc**: update branch-diff arguments in release doc (Rod Vagg) [#4691](https://github.com/nodejs/node/pull/4691) +* [[`666c089e68`](https://github.com/nodejs/node/commit/666c089e68)] - **doc**: fix named anchors in addons.markdown and http.markdown (Michael Theriot) [#4708](https://github.com/nodejs/node/pull/4708) +* [[`310530b7ec`](https://github.com/nodejs/node/commit/310530b7ec)] - **doc**: add path property to Write/ReadStream in fs.markdown (Claudio Rodriguez) [#4368](https://github.com/nodejs/node/pull/4368) +* [[`3470574cb6`](https://github.com/nodejs/node/commit/3470574cb6)] - **doc**: clarify explanation of first stream section (Vitor Cortez) [#4234](https://github.com/nodejs/node/pull/4234) +* [[`d91646b9c7`](https://github.com/nodejs/node/commit/d91646b9c7)] - **doc**: rebuild LICENSE using tools/license-builder.sh (Rod Vagg) [#4194](https://github.com/nodejs/node/pull/4194) +* [[`265e2f557b`](https://github.com/nodejs/node/commit/265e2f557b)] - **doc**: fix typo in doc/node.1 (Jérémy Lal) [#4680](https://github.com/nodejs/node/pull/4680) +* [[`4c132fe61e`](https://github.com/nodejs/node/commit/4c132fe61e)] - **doc**: make references clickable (Roman Klauke) [#4654](https://github.com/nodejs/node/pull/4654) +* [[`d139704ff7`](https://github.com/nodejs/node/commit/d139704ff7)] - **doc**: improve child_process.execFile() code example (Ryan Sobol) [#4504](https://github.com/nodejs/node/pull/4504) +* [[`eeb6fdcd0f`](https://github.com/nodejs/node/commit/eeb6fdcd0f)] - **doc**: add docs for more stream options (zoubin) [#4639](https://github.com/nodejs/node/pull/4639) +* [[`b6ab6d2de5`](https://github.com/nodejs/node/commit/b6ab6d2de5)] - **doc**: add branch-diff example to releases.md (Myles Borins) [#4636](https://github.com/nodejs/node/pull/4636) +* [[`287325c5e8`](https://github.com/nodejs/node/commit/287325c5e8)] - **docs**: update gpg key for Myles Borins (Myles Borins) [#4657](https://github.com/nodejs/node/pull/4657) +* [[`65825b79aa`](https://github.com/nodejs/node/commit/65825b79aa)] - **docs**: fix npm command in releases.md (Myles Borins) [#4656](https://github.com/nodejs/node/pull/4656) +* [[`f9a59c1d3b`](https://github.com/nodejs/node/commit/f9a59c1d3b)] - **(SEMVER-MINOR)** **events**: make sure console functions exist (Dave) [#4479](https://github.com/nodejs/node/pull/4479) +* [[`6039a7c1b5`](https://github.com/nodejs/node/commit/6039a7c1b5)] - **(SEMVER-MINOR)** **fs**: add autoClose option to fs.createWriteStream (Saquib) [#3679](https://github.com/nodejs/node/pull/3679) +* [[`ed55169834`](https://github.com/nodejs/node/commit/ed55169834)] - **gitignore**: never ignore debug module (Michaël Zasso) [#2286](https://github.com/nodejs/node/pull/2286) +* [[`d755432fa9`](https://github.com/nodejs/node/commit/d755432fa9)] - **(SEMVER-MINOR)** **http**: improves expect header handling (Daniel Sellers) [#4501](https://github.com/nodejs/node/pull/4501) +* [[`7ce0e04f44`](https://github.com/nodejs/node/commit/7ce0e04f44)] - **lib**: fix style issues after eslint update (Michaël Zasso) [nodejs/io.js#2286](https://github.com/nodejs/io.js/pull/2286) +* [[`ae5bcf9528`](https://github.com/nodejs/node/commit/ae5bcf9528)] - **lib**: use arrow functions instead of bind (Minwoo Jung) [#3622](https://github.com/nodejs/node/pull/3622) +* [[`0ec093cd41`](https://github.com/nodejs/node/commit/0ec093cd41)] - **lib,test**: remove extra semicolons (Michaël Zasso) [#2205](https://github.com/nodejs/node/pull/2205) +* [[`d8f5bd4fe1`](https://github.com/nodejs/node/commit/d8f5bd4fe1)] - **module**: avoid ArgumentsAdaptorTrampoline frame (Ben Noordhuis) [#4575](https://github.com/nodejs/node/pull/4575) +* [[`83f8d98806`](https://github.com/nodejs/node/commit/83f8d98806)] - **module**: cache stat() results more aggressively (Ben Noordhuis) [#4575](https://github.com/nodejs/node/pull/4575) +* [[`ff64a4c395`](https://github.com/nodejs/node/commit/ff64a4c395)] - **(SEMVER-MINOR)** **node**: allow preload modules with -i (Evan Lucas) [#4696](https://github.com/nodejs/node/pull/4696) +* [[`4bc1a47761`](https://github.com/nodejs/node/commit/4bc1a47761)] - **querystring**: improve parse() performance (Brian White) [#4675](https://github.com/nodejs/node/pull/4675) +* [[`ad63d350d4`](https://github.com/nodejs/node/commit/ad63d350d4)] - **readline**: Remove XXX and output debuglog (Kohei TAKATA) [#4690](https://github.com/nodejs/node/pull/4690) +* [[`da550aa063`](https://github.com/nodejs/node/commit/da550aa063)] - **repl**: make sure historyPath is trimmed (Evan Lucas) [#4539](https://github.com/nodejs/node/pull/4539) +* [[`1a6e7d1b52`](https://github.com/nodejs/node/commit/1a6e7d1b52)] - **src**: fix negative values in process.hrtime() (Ben Noordhuis) [#4757](https://github.com/nodejs/node/pull/4757) +* [[`8bad51977a`](https://github.com/nodejs/node/commit/8bad51977a)] - **src**: return UV_EAI_NODATA on empty lookup (cjihrig) [#4715](https://github.com/nodejs/node/pull/4715) +* [[`761cf2bf6a`](https://github.com/nodejs/node/commit/761cf2bf6a)] - **src**: don't check failure with ERR_peek_error() (Ben Noordhuis) [#4731](https://github.com/nodejs/node/pull/4731) +* [[`953f4a3999`](https://github.com/nodejs/node/commit/953f4a3999)] - **stream**: prevent object map change in ReadableState (Evan Lucas) [#4761](https://github.com/nodejs/node/pull/4761) +* [[`e65f1f7954`](https://github.com/nodejs/node/commit/e65f1f7954)] - **test**: fix tls-multi-key race condition (Santiago Gimeno) [#3966](https://github.com/nodejs/node/pull/3966) +* [[`3727ae0d7d`](https://github.com/nodejs/node/commit/3727ae0d7d)] - **test**: use addon.md block headings as test dir names (Rod Vagg) [#4412](https://github.com/nodejs/node/pull/4412) +* [[`47960a07c0`](https://github.com/nodejs/node/commit/47960a07c0)] - **test**: make test-cluster-disconnect-leak reliable (Rich Trott) [#4736](https://github.com/nodejs/node/pull/4736) +* [[`9926b5a25f`](https://github.com/nodejs/node/commit/9926b5a25f)] - **test**: fix issues for space-in-parens ESLint rule (Roman Reiss) [#4753](https://github.com/nodejs/node/pull/4753) +* [[`d1aabd6264`](https://github.com/nodejs/node/commit/d1aabd6264)] - **test**: fix style issues after eslint update (Michaël Zasso) [nodejs/io.js#2286](https://github.com/nodejs/io.js/pull/2286) +* [[`e98bcfa2cb`](https://github.com/nodejs/node/commit/e98bcfa2cb)] - **test**: remove 1 second delay from test (Rich Trott) [#4616](https://github.com/nodejs/node/pull/4616) +* [[`6cfd0b5a32`](https://github.com/nodejs/node/commit/6cfd0b5a32)] - **test**: fix flaky test-net-socket-local-address (cjihrig) [#4650](https://github.com/nodejs/node/pull/4650) +* [[`e22cc6c2eb`](https://github.com/nodejs/node/commit/e22cc6c2eb)] - **test**: fix race in test-net-server-pause-on-connect (Rich Trott) [#4637](https://github.com/nodejs/node/pull/4637) +* [[`9164c00bdb`](https://github.com/nodejs/node/commit/9164c00bdb)] - **test**: move resource intensive tests to sequential (Rich Trott) [#4615](https://github.com/nodejs/node/pull/4615) +* [[`d8ba2c0de4`](https://github.com/nodejs/node/commit/d8ba2c0de4)] - **test**: fix `http-upgrade-client` flakiness (Santiago Gimeno) [#4602](https://github.com/nodejs/node/pull/4602) +* [[`6018fa1f57`](https://github.com/nodejs/node/commit/6018fa1f57)] - **test**: fix `http-upgrade-agent` flakiness (Santiago Gimeno) [#4520](https://github.com/nodejs/node/pull/4520) +* [[`c33f6a87d0`](https://github.com/nodejs/node/commit/c33f6a87d0)] - **tools**: enable space-in-parens ESLint rule (Roman Reiss) [#4753](https://github.com/nodejs/node/pull/4753) +* [[`162e16afdb`](https://github.com/nodejs/node/commit/162e16afdb)] - **tools**: enable no-extra-semi rule in eslint (Michaël Zasso) [#2205](https://github.com/nodejs/node/pull/2205) +* [[`031b87d42d`](https://github.com/nodejs/node/commit/031b87d42d)] - **tools**: add license-builder.sh to construct LICENSE (Rod Vagg) [#4194](https://github.com/nodejs/node/pull/4194) +* [[`ec8e0ae697`](https://github.com/nodejs/node/commit/ec8e0ae697)] - **tools**: fix style issue after eslint update (Michaël Zasso) [nodejs/io.js#2286](https://github.com/nodejs/io.js/pull/2286) +* [[`4d5ee7a512`](https://github.com/nodejs/node/commit/4d5ee7a512)] - **tools**: update eslint config (Michaël Zasso) [nodejs/io.js#2286](https://github.com/nodejs/io.js/pull/2286) +* [[`2d441493a4`](https://github.com/nodejs/node/commit/2d441493a4)] - **tools**: update eslint to v1.10.3 (Michaël Zasso) [nodejs/io.js#2286](https://github.com/nodejs/io.js/pull/2286) +* [[`aba3cc834e`](https://github.com/nodejs/node/commit/aba3cc834e)] - **tools**: fix license-builder.sh for ICU (Richard Lau) [#4762](https://github.com/nodejs/node/pull/4762) +* [[`5f57005ec9`](https://github.com/nodejs/node/commit/5f57005ec9)] - **(SEMVER-MINOR)** **v8,src**: expose statistics about heap spaces (Ben Ripkens) [#4463](https://github.com/nodejs/node/pull/4463) + ## 2016-01-12, Version 5.4.1 (Stable), @TheAlphaNerd ### Notable Changes diff --git a/src/node_version.h b/src/node_version.h index 29e5d0366cc195..b5954a9014050b 100644 --- a/src/node_version.h +++ b/src/node_version.h @@ -2,10 +2,10 @@ #define SRC_NODE_VERSION_H_ #define NODE_MAJOR_VERSION 5 -#define NODE_MINOR_VERSION 4 -#define NODE_PATCH_VERSION 2 +#define NODE_MINOR_VERSION 5 +#define NODE_PATCH_VERSION 0 -#define NODE_VERSION_IS_RELEASE 0 +#define NODE_VERSION_IS_RELEASE 1 #ifndef NODE_STRINGIFY #define NODE_STRINGIFY(n) NODE_STRINGIFY_HELPER(n) From 2d46ea0d93025a48dd27851c28fc678e40efecf5 Mon Sep 17 00:00:00 2001 From: Evan Lucas Date: Wed, 20 Jan 2016 15:37:19 -0600 Subject: [PATCH 33/33] Working on v5.5.1 PR-URL: https://github.com/nodejs/node/pull/4742 --- src/node_version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/node_version.h b/src/node_version.h index b5954a9014050b..b2f753e58195b7 100644 --- a/src/node_version.h +++ b/src/node_version.h @@ -3,9 +3,9 @@ #define NODE_MAJOR_VERSION 5 #define NODE_MINOR_VERSION 5 -#define NODE_PATCH_VERSION 0 +#define NODE_PATCH_VERSION 1 -#define NODE_VERSION_IS_RELEASE 1 +#define NODE_VERSION_IS_RELEASE 0 #ifndef NODE_STRINGIFY #define NODE_STRINGIFY(n) NODE_STRINGIFY_HELPER(n)