From 7e9779aade8d9745f802b8074ab13151d9981e27 Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Thu, 9 Feb 2017 21:29:56 -0800 Subject: [PATCH 001/264] test: refactor test-readline-keys * replace `util._extend()` with `Object.assign()` * extract repeated map function to a single instance * remove unneeded truthiness-check ternary on Objects Backport-PR-URL: https://github.com/nodejs/node/pull/16947 PR-URL: https://github.com/nodejs/node/pull/11281 Reviewed-By: Yuta Hiroto Reviewed-By: Luigi Pinca Reviewed-By: Colin Ihrig Reviewed-By: James M Snell --- test/parallel/test-readline-keys.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/test/parallel/test-readline-keys.js b/test/parallel/test-readline-keys.js index f45bcb97e02d55..68beb89281cb53 100644 --- a/test/parallel/test-readline-keys.js +++ b/test/parallel/test-readline-keys.js @@ -3,7 +3,6 @@ const common = require('../common'); const PassThrough = require('stream').PassThrough; const assert = require('assert'); const inherits = require('util').inherits; -const extend = require('util')._extend; const Interface = require('readline').Interface; @@ -12,6 +11,10 @@ function FakeInput() { } inherits(FakeInput, PassThrough); +function extend(k) { + return Object.assign({ ctrl: false, meta: false, shift: false }, k); +} + const fi = new FakeInput(); const fo = new FakeInput(); @@ -32,9 +35,7 @@ function addTest(sequences, expectedKeys) { expectedKeys = [ expectedKeys ]; } - expectedKeys = expectedKeys.map(function(k) { - return k ? extend({ ctrl: false, meta: false, shift: false }, k) : k; - }); + expectedKeys = expectedKeys.map(extend); keys = []; @@ -65,9 +66,7 @@ const addKeyIntervalTest = (sequences, expectedKeys, interval = 550, expectedKeys = [ expectedKeys ]; } - expectedKeys = expectedKeys.map(function(k) { - return k ? extend({ ctrl: false, meta: false, shift: false }, k) : k; - }); + expectedKeys = expectedKeys.map(extend); const keys = []; fi.on('keypress', (s, k) => keys.push(k)); From 3e6da45ce06540e59c6f460558bee67dbe213d96 Mon Sep 17 00:00:00 2001 From: dicearr Date: Mon, 23 Oct 2017 09:28:52 +0200 Subject: [PATCH 002/264] doc: howto decode buffers extending from Writable Improved stream documentation with an example of how to decode buffers to strings within a custom Writable. Fixes: https://github.com/nodejs/node/issues/15369 PR-URL: https://github.com/nodejs/node/pull/16403 Reviewed-By: Matteo Collina Reviewed-By: Benjamin Gruenbaum Reviewed-By: Gireesh Punathil --- doc/api/stream.md | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/doc/api/stream.md b/doc/api/stream.md index 353cf1b3c15f7c..19c919a4147168 100644 --- a/doc/api/stream.md +++ b/doc/api/stream.md @@ -1407,6 +1407,47 @@ class MyWritable extends Writable { } ``` +#### Decoding buffers in a Writable Stream + +Decoding buffers is a common task, for instance, when using transformers whose +input is a string. This is not a trivial process when using multi-byte +characters encoding, such as UTF-8. The following example shows how to decode +multi-byte strings using `StringDecoder` and [Writable][]. + +```js +const { Writable } = require('stream'); +const { StringDecoder } = require('string_decoder'); + +class StringWritable extends Writable { + constructor(options) { + super(options); + const state = this._writableState; + this._decoder = new StringDecoder(state.defaultEncoding); + this.data = ''; + } + _write(chunk, encoding, callback) { + if (encoding === 'buffer') { + chunk = this._decoder.write(chunk); + } + this.data += chunk; + callback(); + } + _final(callback) { + this.data += this._decoder.end(); + callback(); + } +} + +const euro = [[0xE2, 0x82], [0xAC]].map(Buffer.from); +const w = new StringWritable(); + +w.write('currency: '); +w.write(euro[0]); +w.end(euro[1]); + +console.log(w.data); // currency: € +``` + ### Implementing a Readable Stream The `stream.Readable` class is extended to implement a [Readable][] stream. From 9416dab7acfbedacb05016c84838544694f8bfa6 Mon Sep 17 00:00:00 2001 From: Ken Takagi Date: Fri, 6 Oct 2017 10:11:23 -0700 Subject: [PATCH 003/264] test: use fixtures module in test-https-pfx PR-URL: https://github.com/nodejs/node/pull/15895 Reviewed-By: Daijiro Wachi Reviewed-By: Gireesh Punathil Reviewed-By: Joyee Cheung Reviewed-By: Colin Ihrig --- test/parallel/test-https-pfx.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/parallel/test-https-pfx.js b/test/parallel/test-https-pfx.js index 4f10b907fc4b1f..d787125409c4b6 100644 --- a/test/parallel/test-https-pfx.js +++ b/test/parallel/test-https-pfx.js @@ -1,13 +1,15 @@ 'use strict'; const common = require('../common'); + if (!common.hasCrypto) common.skip('missing crypto'); +const fixtures = require('../common/fixtures'); + const assert = require('assert'); -const fs = require('fs'); const https = require('https'); -const pfx = fs.readFileSync(`${common.fixturesDir}/test_cert.pfx`); +const pfx = fixtures.readSync('test_cert.pfx'); const options = { host: '127.0.0.1', From 826432808733b58cd98f5b3ebe68eae2f2658634 Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Sun, 29 Oct 2017 19:54:45 -0700 Subject: [PATCH 004/264] test,net: remove scatological terminology PR-URL: https://github.com/nodejs/node/pull/16599 Reviewed-By: James M Snell Reviewed-By: Gireesh Punathil Reviewed-By: Luigi Pinca Reviewed-By: Gibson Fahnestock Reviewed-By: Colin Ihrig Reviewed-By: Anna Henningsen Reviewed-By: Anatoli Papirovski --- lib/net.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/net.js b/lib/net.js index 094f118cefaa96..8256838b5bd88a 100644 --- a/lib/net.js +++ b/lib/net.js @@ -256,7 +256,7 @@ function afterShutdown(status, handle, req) { // if the writable side has ended already, then clean everything // up. function onSocketEnd() { - // XXX Should not have to do as much crap in this function. + // XXX Should not have to do as much in this function. // ended should already be true, since this is called *after* // the EOF errno and onread has eof'ed debug('onSocketEnd', this._readableState); From 290df5ac412f47c9fe70bf1d1cd5a21289d41be7 Mon Sep 17 00:00:00 2001 From: Anthony Nandaa Date: Sat, 28 Oct 2017 01:06:52 +0300 Subject: [PATCH 005/264] doc: add details about rss on process.memoryUsage 1. `process.memoryUsage()` returns an object with 4 keys: `rss, heapTotal, headUsed, external`. There were brief explanations for the rest except `rss`. This commit adds this on the docs. 2. A little more clarity on `rss` to help people disambiguate it from the virtual memory size. PR-URL: https://github.com/nodejs/node/pull/16566 Refs: https://github.com/nodejs/node/pull/16566#discussion_r147545405 Reviewed-By: Refael Ackermann Reviewed-By: Gibson Fahnestock Reviewed-By: Gireesh Punathil Reviewed-By: James M Snell Reviewed-By: Luigi Pinca --- doc/api/process.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/doc/api/process.md b/doc/api/process.md index 40b88d574365b2..f4e5e0c06c1387 100644 --- a/doc/api/process.md +++ b/doc/api/process.md @@ -1196,7 +1196,13 @@ Will generate: `heapTotal` and `heapUsed` refer to V8's memory usage. `external` refers to the memory usage of C++ objects bound to JavaScript -objects managed by V8. +objects managed by V8. `rss`, Resident Set Size, is the amount of space +occupied in the main memory device (that is a subset of the total allocated +memory) for the process, which includes the _heap_, _code segment_ and _stack_. + +The _heap_ is where objects, strings and closures are stored. Variables are +stored in the _stack_ and the actual JavaScript code resides in the +_code segment_. ## process.nextTick(callback[, ...args]) +This function is based on a constant-time algorithm. Returns true if `a` is equal to `b`, without leaking timing information that would allow an attacker to guess one of the values. This is suitable for comparing HMAC digests or secret values like authentication cookies or From 1a633e3cd8220fba0eee6371a2c48a775ba146b7 Mon Sep 17 00:00:00 2001 From: Luigi Pinca Date: Sun, 29 Oct 2017 18:35:52 +0100 Subject: [PATCH 007/264] doc: add docs for Zlib#close() PR-URL: https://github.com/nodejs/node/pull/16592 Reviewed-By: James M Snell Reviewed-By: Gibson Fahnestock Reviewed-By: Anna Henningsen Reviewed-By: Gireesh Punathil Reviewed-By: Colin Ihrig --- doc/api/zlib.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/api/zlib.md b/doc/api/zlib.md index a042379fba42c5..e6972c8dad6ea4 100644 --- a/doc/api/zlib.md +++ b/doc/api/zlib.md @@ -363,6 +363,13 @@ added: v0.5.8 Not exported by the `zlib` module. It is documented here because it is the base class of the compressor/decompressor classes. +### zlib.close([callback]) + + +Close the underlying handle. + ### zlib.flush([kind], callback) -* `src` {[Readable][] Stream} The source stream that +* `src` {stream.Readable} The source stream that [unpiped][`stream.unpipe()`] this writable The `'unpipe'` event is emitted when the [`stream.unpipe()`][] method is called From 92b13e455fb750b86ba8da2fb47f5474a710d4c0 Mon Sep 17 00:00:00 2001 From: Andreas Lind Date: Wed, 2 Nov 2016 23:20:12 +0100 Subject: [PATCH 012/264] https: Use secureProtocol in Agent#getName Refs: https://github.com/nodejs/node/issues/9324 PR-URL: https://github.com/nodejs/node/pull/9452 Reviewed-By: Ben Noordhuis Reviewed-By: James M Snell Reviewed-By: Colin Ihrig --- lib/https.js | 4 ++ test/parallel/test-https-agent-getname.js | 4 +- .../test-https-agent-secure-protocol.js | 60 +++++++++++++++++++ 3 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 test/parallel/test-https-agent-secure-protocol.js diff --git a/lib/https.js b/lib/https.js index ef0c8dd04638b8..72d4deb34f1ab8 100644 --- a/lib/https.js +++ b/lib/https.js @@ -146,6 +146,10 @@ Agent.prototype.getName = function(options) { if (options.servername && options.servername !== options.host) name += options.servername; + name += ':'; + if (options.secureProtocol) + name += options.secureProtocol; + return name; }; diff --git a/test/parallel/test-https-agent-getname.js b/test/parallel/test-https-agent-getname.js index 63473775b0e0f6..c89161ab142e58 100644 --- a/test/parallel/test-https-agent-getname.js +++ b/test/parallel/test-https-agent-getname.js @@ -9,7 +9,7 @@ const agent = new https.Agent(); // empty options assert.strictEqual( agent.getName({}), - 'localhost:::::::::' + 'localhost::::::::::' ); // pass all options arguments @@ -28,5 +28,5 @@ const options = { assert.strictEqual( agent.getName(options), - '0.0.0.0:443:192.168.1.1:ca:cert:ciphers:key:pfx:false:localhost' + '0.0.0.0:443:192.168.1.1:ca:cert:ciphers:key:pfx:false:localhost:' ); diff --git a/test/parallel/test-https-agent-secure-protocol.js b/test/parallel/test-https-agent-secure-protocol.js new file mode 100644 index 00000000000000..7cca682101fa0b --- /dev/null +++ b/test/parallel/test-https-agent-secure-protocol.js @@ -0,0 +1,60 @@ +'use strict'; +const assert = require('assert'); +const common = require('../common'); + +if (!common.hasCrypto) { + common.skip('missing crypto'); + return; +} + +const https = require('https'); +const fs = require('fs'); + +const options = { + key: fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'), + cert: fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem'), + ca: fs.readFileSync(common.fixturesDir + '/keys/ca1-cert.pem') +}; + +const server = https.Server(options, function(req, res) { + res.writeHead(200); + res.end('hello world\n'); +}); + +server.listen(0, common.mustCall(function() { + const port = this.address().port; + const globalAgent = https.globalAgent; + globalAgent.keepAlive = true; + https.get({ + path: '/', + port: port, + ca: options.ca, + rejectUnauthorized: true, + servername: 'agent1', + secureProtocol: 'SSLv23_method' + }, common.mustCall(function(res) { + res.resume(); + globalAgent.once('free', common.mustCall(function() { + https.get({ + path: '/', + port: port, + ca: options.ca, + rejectUnauthorized: true, + servername: 'agent1', + secureProtocol: 'TLSv1_method' + }, common.mustCall(function(res) { + res.resume(); + globalAgent.once('free', common.mustCall(function() { + // Verify that two keep-alived connections are created + // due to the different secureProtocol settings: + const keys = Object.keys(globalAgent.freeSockets); + assert.strictEqual(keys.length, 2); + assert.ok(keys[0].includes(':SSLv23_method')); + assert.ok(keys[1].includes(':TLSv1_method')); + globalAgent.destroy(); + server.close(); + })); + })); + })); + })); +})); From 19f3ac9749f80b3cab9d4248d6784dffbdf1a368 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Sat, 10 Sep 2016 16:43:08 +0200 Subject: [PATCH 013/264] src: add Malloc() size param + overflow detection Adds an optional second parameter to `node::Malloc()` and an optional third parameter to `node::Realloc()` giving the size/number of items to be allocated, in the style of `calloc(3)`. Use a proper overflow check using division; the previous `CHECK_GE(n * size, n);` would not detect all cases of overflow (e.g. `size == SIZE_MAX / 2 && n == 3`). Backport-PR-URL: https://github.com/nodejs/node/pull/16587 PR-URL: https://github.com/nodejs/node/pull/8482 Reviewed-By: Ben Noordhuis Reviewed-By: James M Snell Reviewed-By: Michael Dawson Reviewed-By: Ilkka Myller --- src/node_crypto.cc | 5 ++--- src/string_bytes.cc | 2 +- src/util-inl.h | 24 ++++++++++++++++++------ src/util.h | 11 ++++------- 4 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 99ed0ddf0808bb..fefd471c6b7eda 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -5826,11 +5826,10 @@ void GetCurves(const FunctionCallbackInfo& args) { const size_t num_curves = EC_get_builtin_curves(nullptr, 0); Local arr = Array::New(env->isolate(), num_curves); EC_builtin_curve* curves; - size_t alloc_size; if (num_curves) { - alloc_size = sizeof(*curves) * num_curves; - curves = static_cast(node::Malloc(alloc_size)); + curves = static_cast(node::Malloc(sizeof(*curves), + num_curves)); CHECK_NE(curves, nullptr); diff --git a/src/string_bytes.cc b/src/string_bytes.cc index 9d1619d864b495..771ef034004b83 100644 --- a/src/string_bytes.cc +++ b/src/string_bytes.cc @@ -54,7 +54,7 @@ class ExternString: public ResourceType { return scope.Escape(String::Empty(isolate)); TypeName* new_data = - static_cast(node::Malloc(length * sizeof(*new_data))); + static_cast(node::Malloc(length, sizeof(*new_data))); if (new_data == nullptr) { return Local(); } diff --git a/src/util-inl.h b/src/util-inl.h index 27bced48fe2198..8f23a59651b2f7 100644 --- a/src/util-inl.h +++ b/src/util-inl.h @@ -320,6 +320,14 @@ bool StringEqualNoCaseN(const char* a, const char* b, size_t length) { return true; } +inline size_t MultiplyWithOverflowCheck(size_t a, size_t b) { + size_t ret = a * b; + if (a != 0) + CHECK_EQ(b, ret / a); + + return ret; +} + // These should be used in our code as opposed to the native // versions as they abstract out some platform and or // compiler version specific functionality. @@ -327,24 +335,28 @@ bool StringEqualNoCaseN(const char* a, const char* b, size_t length) { // that the standard allows them to either return a unique pointer or a // nullptr for zero-sized allocation requests. Normalize by always using // a nullptr. -void* Realloc(void* pointer, size_t size) { - if (size == 0) { +void* Realloc(void* pointer, size_t n, size_t size) { + size_t full_size = MultiplyWithOverflowCheck(size, n); + + if (full_size == 0) { free(pointer); return nullptr; } - return realloc(pointer, size); + + return realloc(pointer, full_size); } // As per spec realloc behaves like malloc if passed nullptr. -void* Malloc(size_t size) { +void* Malloc(size_t n, size_t size) { + if (n == 0) n = 1; if (size == 0) size = 1; - return Realloc(nullptr, size); + return Realloc(nullptr, n, size); } void* Calloc(size_t n, size_t size) { if (n == 0) n = 1; if (size == 0) size = 1; - CHECK_GE(n * size, n); // Overflow guard. + MultiplyWithOverflowCheck(size, n); return calloc(n, size); } diff --git a/src/util.h b/src/util.h index f415141a58e997..38c17b390e1fab 100644 --- a/src/util.h +++ b/src/util.h @@ -31,9 +31,9 @@ namespace node { // that the standard allows them to either return a unique pointer or a // nullptr for zero-sized allocation requests. Normalize by always using // a nullptr. -inline void* Realloc(void* pointer, size_t size); -inline void* Malloc(size_t size); -inline void* Calloc(size_t n, size_t size); +inline void* Realloc(void* pointer, size_t n, size_t size = 1); +inline void* Malloc(size_t n, size_t size = 1); +inline void* Calloc(size_t n, size_t size = 1); #ifdef __GNUC__ #define NO_RETURN __attribute__((noreturn)) @@ -294,10 +294,7 @@ class MaybeStackBuffer { if (storage <= kStackStorageSize) { buf_ = buf_st_; } else { - // Guard against overflow. - CHECK_LE(storage, sizeof(T) * storage); - - buf_ = static_cast(Malloc(sizeof(T) * storage)); + buf_ = static_cast(Malloc(sizeof(T), storage)); CHECK_NE(buf_, nullptr); } From 4aec8cfcd23abbb0d7be172d63a2dbed1e31fb61 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Sat, 10 Sep 2016 17:50:02 +0200 Subject: [PATCH 014/264] src: pass desired return type to allocators Pass the desired return type directly to the allocation functions, so that the resulting `static_cast` from `void*` becomes unneccessary and the return type can be use as a reasonable default value for the `size` parameter. Backport-PR-URL: https://github.com/nodejs/node/pull/16587 PR-URL: https://github.com/nodejs/node/pull/8482 Reviewed-By: Ben Noordhuis Reviewed-By: James M Snell Reviewed-By: Michael Dawson Reviewed-By: Ilkka Myller --- src/cares_wrap.cc | 17 +++++++---------- src/node.cc | 2 +- src/node_buffer.cc | 20 +++++++++++++------- src/node_crypto.cc | 21 ++++++++++----------- src/stream_wrap.cc | 4 ++-- src/string_bytes.cc | 9 ++++----- src/tls_wrap.cc | 2 +- src/udp_wrap.cc | 4 ++-- src/util-inl.h | 21 +++++++++++---------- src/util.h | 15 +++++++++++---- test/cctest/test_util.cc | 10 ++++++---- 11 files changed, 68 insertions(+), 57 deletions(-) diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc index d40d4b3256f193..86afbd681e0ab8 100644 --- a/src/cares_wrap.cc +++ b/src/cares_wrap.cc @@ -175,8 +175,7 @@ static void ares_poll_close_cb(uv_handle_t* watcher) { /* Allocates and returns a new node_ares_task */ static node_ares_task* ares_task_create(Environment* env, ares_socket_t sock) { - node_ares_task* task = - static_cast(node::Malloc(sizeof(*task))); + auto task = node::Malloc(1); if (task == nullptr) { /* Out of memory. */ @@ -329,11 +328,10 @@ void cares_wrap_hostent_cpy(struct hostent* dest, struct hostent* src) { alias_count++) { } - dest->h_aliases = static_cast(node::Malloc((alias_count + 1) * - sizeof(char*))); + dest->h_aliases = node::Malloc(alias_count + 1); for (size_t i = 0; i < alias_count; i++) { cur_alias_length = strlen(src->h_aliases[i]); - dest->h_aliases[i] = static_cast(node::Malloc(cur_alias_length + 1)); + dest->h_aliases[i] = node::Malloc(cur_alias_length + 1); memcpy(dest->h_aliases[i], src->h_aliases[i], cur_alias_length + 1); } dest->h_aliases[alias_count] = nullptr; @@ -345,10 +343,9 @@ void cares_wrap_hostent_cpy(struct hostent* dest, struct hostent* src) { list_count++) { } - dest->h_addr_list = static_cast(node::Malloc((list_count + 1) * - sizeof(char*))); + dest->h_addr_list = node::Malloc(list_count + 1); for (size_t i = 0; i < list_count; i++) { - dest->h_addr_list[i] = static_cast(node::Malloc(src->h_length)); + dest->h_addr_list[i] = node::Malloc(src->h_length); memcpy(dest->h_addr_list[i], src->h_addr_list[i], src->h_length); } dest->h_addr_list[list_count] = nullptr; @@ -507,7 +504,7 @@ class QueryWrap : public AsyncWrap { unsigned char* buf_copy = nullptr; if (status == ARES_SUCCESS) { - buf_copy = static_cast(node::Malloc(answer_len)); + buf_copy = node::Malloc(answer_len); memcpy(buf_copy, answer_buf, answer_len); } @@ -534,7 +531,7 @@ class QueryWrap : public AsyncWrap { struct hostent* host_copy = nullptr; if (status == ARES_SUCCESS) { - host_copy = static_cast(node::Malloc(sizeof(hostent))); + host_copy = node::Malloc(1); cares_wrap_hostent_cpy(host_copy, host); } diff --git a/src/node.cc b/src/node.cc index f4218ca6795933..731f33495e039c 100644 --- a/src/node.cc +++ b/src/node.cc @@ -1054,7 +1054,7 @@ void* ArrayBufferAllocator::Allocate(size_t size) { if (env_ == nullptr || !env_->array_buffer_allocator_info()->no_zero_fill() || zero_fill_all_buffers) - return node::Calloc(size, 1); + return node::Calloc(size); env_->array_buffer_allocator_info()->reset_fill_flag(); return node::Malloc(size); } diff --git a/src/node_buffer.cc b/src/node_buffer.cc index 9a7ee754d4f532..f06b00318ddaa6 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -48,14 +48,20 @@ THROW_AND_RETURN_IF_OOB(end <= end_max); \ size_t length = end - start; -#define BUFFER_MALLOC(length) \ - zero_fill_all_buffers ? node::Calloc(length, 1) : node::Malloc(length) - namespace node { // if true, all Buffer and SlowBuffer instances will automatically zero-fill bool zero_fill_all_buffers = false; +namespace { + +inline void* BufferMalloc(size_t length) { + return zero_fill_all_buffers ? node::Calloc(length) : + node::Malloc(length); +} + +} // namespace + namespace Buffer { using v8::ArrayBuffer; @@ -234,7 +240,7 @@ MaybeLocal New(Isolate* isolate, char* data = nullptr; if (length > 0) { - data = static_cast(BUFFER_MALLOC(length)); + data = static_cast(BufferMalloc(length)); if (data == nullptr) return Local(); @@ -246,7 +252,7 @@ MaybeLocal New(Isolate* isolate, free(data); data = nullptr; } else if (actual < length) { - data = static_cast(node::Realloc(data, actual)); + data = node::Realloc(data, actual); CHECK_NE(data, nullptr); } } @@ -280,7 +286,7 @@ MaybeLocal New(Environment* env, size_t length) { void* data; if (length > 0) { - data = BUFFER_MALLOC(length); + data = BufferMalloc(length); if (data == nullptr) return Local(); } else { @@ -1063,7 +1069,7 @@ void IndexOfString(const FunctionCallbackInfo& args) { offset, is_forward); } else if (enc == LATIN1) { - uint8_t* needle_data = static_cast(node::Malloc(needle_length)); + uint8_t* needle_data = node::Malloc(needle_length); if (needle_data == nullptr) { return args.GetReturnValue().Set(-1); } diff --git a/src/node_crypto.cc b/src/node_crypto.cc index fefd471c6b7eda..e1ae4d893b2108 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -2386,7 +2386,7 @@ int SSLWrap::TLSExtStatusCallback(SSL* s, void* arg) { size_t len = Buffer::Length(obj); // OpenSSL takes control of the pointer after accepting it - char* data = reinterpret_cast(node::Malloc(len)); + char* data = node::Malloc(len); CHECK_NE(data, nullptr); memcpy(data, resp, len); @@ -3466,7 +3466,7 @@ bool CipherBase::GetAuthTag(char** out, unsigned int* out_len) const { if (initialised_ || kind_ != kCipher || !auth_tag_) return false; *out_len = auth_tag_len_; - *out = static_cast(node::Malloc(auth_tag_len_)); + *out = node::Malloc(auth_tag_len_); CHECK_NE(*out, nullptr); memcpy(*out, auth_tag_, auth_tag_len_); return true; @@ -5138,7 +5138,7 @@ void ECDH::ComputeSecret(const FunctionCallbackInfo& args) { // NOTE: field_size is in bits int field_size = EC_GROUP_get_degree(ecdh->group_); size_t out_len = (field_size + 7) / 8; - char* out = static_cast(node::Malloc(out_len)); + char* out = node::Malloc(out_len); CHECK_NE(out, nullptr); int r = ECDH_compute_key(out, out_len, pub, ecdh->key_, nullptr); @@ -5174,7 +5174,7 @@ void ECDH::GetPublicKey(const FunctionCallbackInfo& args) { if (size == 0) return env->ThrowError("Failed to get public key length"); - unsigned char* out = static_cast(node::Malloc(size)); + unsigned char* out = node::Malloc(size); CHECK_NE(out, nullptr); int r = EC_POINT_point2oct(ecdh->group_, pub, form, out, size, nullptr); @@ -5200,7 +5200,7 @@ void ECDH::GetPrivateKey(const FunctionCallbackInfo& args) { return env->ThrowError("Failed to get ECDH private key"); int size = BN_num_bytes(b); - unsigned char* out = static_cast(node::Malloc(size)); + unsigned char* out = node::Malloc(size); CHECK_NE(out, nullptr); if (size != BN_bn2bin(b, out)) { @@ -5333,7 +5333,7 @@ class PBKDF2Request : public AsyncWrap { saltlen_(saltlen), salt_(salt), keylen_(keylen), - key_(static_cast(node::Malloc(keylen))), + key_(node::Malloc(keylen)), iter_(iter) { if (key() == nullptr) FatalError("node::PBKDF2Request()", "Out of Memory"); @@ -5496,7 +5496,7 @@ void PBKDF2(const FunctionCallbackInfo& args) { THROW_AND_RETURN_IF_NOT_BUFFER(args[1], "Salt"); - pass = static_cast(node::Malloc(passlen)); + pass = node::Malloc(passlen); if (pass == nullptr) { FatalError("node::PBKDF2()", "Out of Memory"); } @@ -5508,7 +5508,7 @@ void PBKDF2(const FunctionCallbackInfo& args) { goto err; } - salt = static_cast(node::Malloc(saltlen)); + salt = node::Malloc(saltlen); if (salt == nullptr) { FatalError("node::PBKDF2()", "Out of Memory"); } @@ -5601,7 +5601,7 @@ class RandomBytesRequest : public AsyncWrap { : AsyncWrap(env, object, AsyncWrap::PROVIDER_CRYPTO), error_(0), size_(size), - data_(static_cast(node::Malloc(size))) { + data_(node::Malloc(size)) { if (data() == nullptr) FatalError("node::RandomBytesRequest()", "Out of Memory"); Wrap(object, this); @@ -5828,8 +5828,7 @@ void GetCurves(const FunctionCallbackInfo& args) { EC_builtin_curve* curves; if (num_curves) { - curves = static_cast(node::Malloc(sizeof(*curves), - num_curves)); + curves = node::Malloc(num_curves); CHECK_NE(curves, nullptr); diff --git a/src/stream_wrap.cc b/src/stream_wrap.cc index 7709e24a6b4d93..f5bc4ad8c4eca3 100644 --- a/src/stream_wrap.cc +++ b/src/stream_wrap.cc @@ -148,7 +148,7 @@ void StreamWrap::OnAlloc(uv_handle_t* handle, void StreamWrap::OnAllocImpl(size_t size, uv_buf_t* buf, void* ctx) { - buf->base = static_cast(node::Malloc(size)); + buf->base = node::Malloc(size); buf->len = size; if (buf->base == nullptr && size > 0) { @@ -204,7 +204,7 @@ void StreamWrap::OnReadImpl(ssize_t nread, return; } - char* base = static_cast(node::Realloc(buf->base, nread)); + char* base = node::Realloc(buf->base, nread); CHECK_LE(static_cast(nread), buf->len); if (pending == UV_TCP) { diff --git a/src/string_bytes.cc b/src/string_bytes.cc index 771ef034004b83..065a8ece15a06c 100644 --- a/src/string_bytes.cc +++ b/src/string_bytes.cc @@ -53,8 +53,7 @@ class ExternString: public ResourceType { if (length == 0) return scope.Escape(String::Empty(isolate)); - TypeName* new_data = - static_cast(node::Malloc(length, sizeof(*new_data))); + TypeName* new_data = node::Malloc(length); if (new_data == nullptr) { return Local(); } @@ -610,7 +609,7 @@ Local StringBytes::Encode(Isolate* isolate, case ASCII: if (contains_non_ascii(buf, buflen)) { - char* out = static_cast(node::Malloc(buflen)); + char* out = node::Malloc(buflen); if (out == nullptr) { return Local(); } @@ -645,7 +644,7 @@ Local StringBytes::Encode(Isolate* isolate, case BASE64: { size_t dlen = base64_encoded_size(buflen); - char* dst = static_cast(node::Malloc(dlen)); + char* dst = node::Malloc(dlen); if (dst == nullptr) { return Local(); } @@ -664,7 +663,7 @@ Local StringBytes::Encode(Isolate* isolate, case HEX: { size_t dlen = buflen * 2; - char* dst = static_cast(node::Malloc(dlen)); + char* dst = node::Malloc(dlen); if (dst == nullptr) { return Local(); } diff --git a/src/tls_wrap.cc b/src/tls_wrap.cc index 1f1e1eeb2d8169..4b8a575d56f2d8 100644 --- a/src/tls_wrap.cc +++ b/src/tls_wrap.cc @@ -663,7 +663,7 @@ void TLSWrap::OnDestructImpl(void* ctx) { void TLSWrap::OnAllocSelf(size_t suggested_size, uv_buf_t* buf, void* ctx) { - buf->base = static_cast(node::Malloc(suggested_size)); + buf->base = node::Malloc(suggested_size); CHECK_NE(buf->base, nullptr); buf->len = suggested_size; } diff --git a/src/udp_wrap.cc b/src/udp_wrap.cc index 6e6c46aad00939..43378199fe0188 100644 --- a/src/udp_wrap.cc +++ b/src/udp_wrap.cc @@ -373,7 +373,7 @@ void UDPWrap::OnSend(uv_udp_send_t* req, int status) { void UDPWrap::OnAlloc(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) { - buf->base = static_cast(node::Malloc(suggested_size)); + buf->base = node::Malloc(suggested_size); buf->len = suggested_size; if (buf->base == nullptr && suggested_size > 0) { @@ -415,7 +415,7 @@ void UDPWrap::OnRecv(uv_udp_t* handle, return; } - char* base = static_cast(node::Realloc(buf->base, nread)); + char* base = node::Realloc(buf->base, nread); argv[2] = Buffer::New(env, base, nread).ToLocalChecked(); argv[3] = AddressToJS(env, addr); wrap->MakeCallback(env->onmessage_string(), arraysize(argv), argv); diff --git a/src/util-inl.h b/src/util-inl.h index 8f23a59651b2f7..7d4eda49152b16 100644 --- a/src/util-inl.h +++ b/src/util-inl.h @@ -335,29 +335,30 @@ inline size_t MultiplyWithOverflowCheck(size_t a, size_t b) { // that the standard allows them to either return a unique pointer or a // nullptr for zero-sized allocation requests. Normalize by always using // a nullptr. -void* Realloc(void* pointer, size_t n, size_t size) { - size_t full_size = MultiplyWithOverflowCheck(size, n); +template +T* Realloc(T* pointer, size_t n) { + size_t full_size = MultiplyWithOverflowCheck(sizeof(T), n); if (full_size == 0) { free(pointer); return nullptr; } - return realloc(pointer, full_size); + return static_cast(realloc(pointer, full_size)); } // As per spec realloc behaves like malloc if passed nullptr. -void* Malloc(size_t n, size_t size) { +template +T* Malloc(size_t n) { if (n == 0) n = 1; - if (size == 0) size = 1; - return Realloc(nullptr, n, size); + return Realloc(nullptr, n); } -void* Calloc(size_t n, size_t size) { +template +T* Calloc(size_t n) { if (n == 0) n = 1; - if (size == 0) size = 1; - MultiplyWithOverflowCheck(size, n); - return calloc(n, size); + MultiplyWithOverflowCheck(sizeof(T), n); + return static_cast(calloc(n, sizeof(T))); } } // namespace node diff --git a/src/util.h b/src/util.h index 38c17b390e1fab..59a26fb8527735 100644 --- a/src/util.h +++ b/src/util.h @@ -31,9 +31,16 @@ namespace node { // that the standard allows them to either return a unique pointer or a // nullptr for zero-sized allocation requests. Normalize by always using // a nullptr. -inline void* Realloc(void* pointer, size_t n, size_t size = 1); -inline void* Malloc(size_t n, size_t size = 1); -inline void* Calloc(size_t n, size_t size = 1); +template +inline T* Realloc(T* pointer, size_t n); +template +inline T* Malloc(size_t n); +template +inline T* Calloc(size_t n); + +// Shortcuts for char*. +inline char* Malloc(size_t n) { return Malloc(n); } +inline char* Calloc(size_t n) { return Calloc(n); } #ifdef __GNUC__ #define NO_RETURN __attribute__((noreturn)) @@ -294,7 +301,7 @@ class MaybeStackBuffer { if (storage <= kStackStorageSize) { buf_ = buf_st_; } else { - buf_ = static_cast(Malloc(sizeof(T), storage)); + buf_ = Malloc(storage); CHECK_NE(buf_, nullptr); } diff --git a/test/cctest/test_util.cc b/test/cctest/test_util.cc index 65a382bd3893fa..7bbf53af13d3c4 100644 --- a/test/cctest/test_util.cc +++ b/test/cctest/test_util.cc @@ -92,14 +92,16 @@ TEST(UtilTest, ToLower) { TEST(UtilTest, Malloc) { using node::Malloc; + EXPECT_NE(nullptr, Malloc(0)); + EXPECT_NE(nullptr, Malloc(1)); EXPECT_NE(nullptr, Malloc(0)); EXPECT_NE(nullptr, Malloc(1)); } TEST(UtilTest, Calloc) { using node::Calloc; - EXPECT_NE(nullptr, Calloc(0, 0)); - EXPECT_NE(nullptr, Calloc(1, 0)); - EXPECT_NE(nullptr, Calloc(0, 1)); - EXPECT_NE(nullptr, Calloc(1, 1)); + EXPECT_NE(nullptr, Calloc(0)); + EXPECT_NE(nullptr, Calloc(1)); + EXPECT_NE(nullptr, Calloc(0)); + EXPECT_NE(nullptr, Calloc(1)); } From 6a0eb9f6cfbe3c76a3508418997de7ab2becd4b5 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Sat, 10 Sep 2016 18:19:24 +0200 Subject: [PATCH 015/264] src: provide allocation + nullptr check shortcuts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Provide shortcut `node::CheckedMalloc()` and friends that replace `node::Malloc()` + `CHECK_NE(·, nullptr);` combinations in a few places. Backport-PR-URL: https://github.com/nodejs/node/pull/16587 PR-URL: https://github.com/nodejs/node/pull/8482 Reviewed-By: Ben Noordhuis Reviewed-By: James M Snell Reviewed-By: Michael Dawson Reviewed-By: Ilkka Myller --- src/cares_wrap.cc | 2 +- src/node.cc | 4 ++-- src/node_buffer.cc | 9 ++++----- src/node_crypto.cc | 17 ----------------- src/node_internals.h | 2 +- src/stream_wrap.cc | 8 +------- src/string_bytes.cc | 8 ++++---- src/tls_wrap.cc | 1 - src/udp_wrap.cc | 7 +------ src/util-inl.h | 29 +++++++++++++++++++++++++---- src/util.cc | 1 + src/util.h | 12 +++++++++++- test/cctest/test_util.cc | 16 ++++++++++++++++ 13 files changed, 67 insertions(+), 49 deletions(-) diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc index 86afbd681e0ab8..638daef76226ca 100644 --- a/src/cares_wrap.cc +++ b/src/cares_wrap.cc @@ -175,7 +175,7 @@ static void ares_poll_close_cb(uv_handle_t* watcher) { /* Allocates and returns a new node_ares_task */ static node_ares_task* ares_task_create(Environment* env, ares_socket_t sock) { - auto task = node::Malloc(1); + auto task = node::UncheckedMalloc(1); if (task == nullptr) { /* Out of memory. */ diff --git a/src/node.cc b/src/node.cc index 731f33495e039c..6345abdb312dda 100644 --- a/src/node.cc +++ b/src/node.cc @@ -1054,9 +1054,9 @@ void* ArrayBufferAllocator::Allocate(size_t size) { if (env_ == nullptr || !env_->array_buffer_allocator_info()->no_zero_fill() || zero_fill_all_buffers) - return node::Calloc(size); + return node::UncheckedCalloc(size); env_->array_buffer_allocator_info()->reset_fill_flag(); - return node::Malloc(size); + return node::UncheckedMalloc(size); } static bool DomainHasErrorHandler(const Environment* env, diff --git a/src/node_buffer.cc b/src/node_buffer.cc index f06b00318ddaa6..5e6de043ee6006 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -56,8 +56,8 @@ bool zero_fill_all_buffers = false; namespace { inline void* BufferMalloc(size_t length) { - return zero_fill_all_buffers ? node::Calloc(length) : - node::Malloc(length); + return zero_fill_all_buffers ? node::UncheckedCalloc(length) : + node::UncheckedMalloc(length); } } // namespace @@ -253,7 +253,6 @@ MaybeLocal New(Isolate* isolate, data = nullptr; } else if (actual < length) { data = node::Realloc(data, actual); - CHECK_NE(data, nullptr); } } @@ -331,7 +330,7 @@ MaybeLocal Copy(Environment* env, const char* data, size_t length) { void* new_data; if (length > 0) { CHECK_NE(data, nullptr); - new_data = node::Malloc(length); + new_data = node::UncheckedMalloc(length); if (new_data == nullptr) return Local(); memcpy(new_data, data, length); @@ -1069,7 +1068,7 @@ void IndexOfString(const FunctionCallbackInfo& args) { offset, is_forward); } else if (enc == LATIN1) { - uint8_t* needle_data = node::Malloc(needle_length); + uint8_t* needle_data = node::UncheckedMalloc(needle_length); if (needle_data == nullptr) { return args.GetReturnValue().Set(-1); } diff --git a/src/node_crypto.cc b/src/node_crypto.cc index e1ae4d893b2108..09002972a94b5f 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -2387,7 +2387,6 @@ int SSLWrap::TLSExtStatusCallback(SSL* s, void* arg) { // OpenSSL takes control of the pointer after accepting it char* data = node::Malloc(len); - CHECK_NE(data, nullptr); memcpy(data, resp, len); if (!SSL_set_tlsext_status_ocsp_resp(s, data, len)) @@ -3467,7 +3466,6 @@ bool CipherBase::GetAuthTag(char** out, unsigned int* out_len) const { return false; *out_len = auth_tag_len_; *out = node::Malloc(auth_tag_len_); - CHECK_NE(*out, nullptr); memcpy(*out, auth_tag_, auth_tag_len_); return true; } @@ -5139,7 +5137,6 @@ void ECDH::ComputeSecret(const FunctionCallbackInfo& args) { int field_size = EC_GROUP_get_degree(ecdh->group_); size_t out_len = (field_size + 7) / 8; char* out = node::Malloc(out_len); - CHECK_NE(out, nullptr); int r = ECDH_compute_key(out, out_len, pub, ecdh->key_, nullptr); EC_POINT_free(pub); @@ -5175,7 +5172,6 @@ void ECDH::GetPublicKey(const FunctionCallbackInfo& args) { return env->ThrowError("Failed to get public key length"); unsigned char* out = node::Malloc(size); - CHECK_NE(out, nullptr); int r = EC_POINT_point2oct(ecdh->group_, pub, form, out, size, nullptr); if (r != size) { @@ -5201,7 +5197,6 @@ void ECDH::GetPrivateKey(const FunctionCallbackInfo& args) { int size = BN_num_bytes(b); unsigned char* out = node::Malloc(size); - CHECK_NE(out, nullptr); if (size != BN_bn2bin(b, out)) { free(out); @@ -5335,8 +5330,6 @@ class PBKDF2Request : public AsyncWrap { keylen_(keylen), key_(node::Malloc(keylen)), iter_(iter) { - if (key() == nullptr) - FatalError("node::PBKDF2Request()", "Out of Memory"); Wrap(object, this); } @@ -5497,9 +5490,6 @@ void PBKDF2(const FunctionCallbackInfo& args) { THROW_AND_RETURN_IF_NOT_BUFFER(args[1], "Salt"); pass = node::Malloc(passlen); - if (pass == nullptr) { - FatalError("node::PBKDF2()", "Out of Memory"); - } memcpy(pass, Buffer::Data(args[0]), passlen); saltlen = Buffer::Length(args[1]); @@ -5509,9 +5499,6 @@ void PBKDF2(const FunctionCallbackInfo& args) { } salt = node::Malloc(saltlen); - if (salt == nullptr) { - FatalError("node::PBKDF2()", "Out of Memory"); - } memcpy(salt, Buffer::Data(args[1]), saltlen); if (!args[2]->IsNumber()) { @@ -5602,8 +5589,6 @@ class RandomBytesRequest : public AsyncWrap { error_(0), size_(size), data_(node::Malloc(size)) { - if (data() == nullptr) - FatalError("node::RandomBytesRequest()", "Out of Memory"); Wrap(object, this); } @@ -5830,8 +5815,6 @@ void GetCurves(const FunctionCallbackInfo& args) { if (num_curves) { curves = node::Malloc(num_curves); - CHECK_NE(curves, nullptr); - if (EC_get_builtin_curves(curves, num_curves)) { for (size_t i = 0; i < num_curves; i++) { arr->Set(i, OneByteString(env->isolate(), OBJ_nid2sn(curves[i].nid))); diff --git a/src/node_internals.h b/src/node_internals.h index adcb7f835a3451..130af5d1c0f97f 100644 --- a/src/node_internals.h +++ b/src/node_internals.h @@ -199,7 +199,7 @@ class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator { virtual void* Allocate(size_t size); // Defined in src/node.cc virtual void* AllocateUninitialized(size_t size) - { return node::Malloc(size); } + { return node::UncheckedMalloc(size); } virtual void Free(void* data, size_t) { free(data); } private: diff --git a/src/stream_wrap.cc b/src/stream_wrap.cc index f5bc4ad8c4eca3..ba03221696a539 100644 --- a/src/stream_wrap.cc +++ b/src/stream_wrap.cc @@ -150,12 +150,6 @@ void StreamWrap::OnAlloc(uv_handle_t* handle, void StreamWrap::OnAllocImpl(size_t size, uv_buf_t* buf, void* ctx) { buf->base = node::Malloc(size); buf->len = size; - - if (buf->base == nullptr && size > 0) { - FatalError( - "node::StreamWrap::DoAlloc(size_t, uv_buf_t*, void*)", - "Out Of Memory"); - } } @@ -204,8 +198,8 @@ void StreamWrap::OnReadImpl(ssize_t nread, return; } - char* base = node::Realloc(buf->base, nread); CHECK_LE(static_cast(nread), buf->len); + char* base = node::Realloc(buf->base, nread); if (pending == UV_TCP) { pending_obj = AcceptHandle(env, wrap); diff --git a/src/string_bytes.cc b/src/string_bytes.cc index 065a8ece15a06c..882ca6e3e89bd3 100644 --- a/src/string_bytes.cc +++ b/src/string_bytes.cc @@ -53,7 +53,7 @@ class ExternString: public ResourceType { if (length == 0) return scope.Escape(String::Empty(isolate)); - TypeName* new_data = node::Malloc(length); + TypeName* new_data = node::UncheckedMalloc(length); if (new_data == nullptr) { return Local(); } @@ -609,7 +609,7 @@ Local StringBytes::Encode(Isolate* isolate, case ASCII: if (contains_non_ascii(buf, buflen)) { - char* out = node::Malloc(buflen); + char* out = node::UncheckedMalloc(buflen); if (out == nullptr) { return Local(); } @@ -644,7 +644,7 @@ Local StringBytes::Encode(Isolate* isolate, case BASE64: { size_t dlen = base64_encoded_size(buflen); - char* dst = node::Malloc(dlen); + char* dst = node::UncheckedMalloc(dlen); if (dst == nullptr) { return Local(); } @@ -663,7 +663,7 @@ Local StringBytes::Encode(Isolate* isolate, case HEX: { size_t dlen = buflen * 2; - char* dst = node::Malloc(dlen); + char* dst = node::UncheckedMalloc(dlen); if (dst == nullptr) { return Local(); } diff --git a/src/tls_wrap.cc b/src/tls_wrap.cc index 4b8a575d56f2d8..813f7ef869ecce 100644 --- a/src/tls_wrap.cc +++ b/src/tls_wrap.cc @@ -664,7 +664,6 @@ void TLSWrap::OnDestructImpl(void* ctx) { void TLSWrap::OnAllocSelf(size_t suggested_size, uv_buf_t* buf, void* ctx) { buf->base = node::Malloc(suggested_size); - CHECK_NE(buf->base, nullptr); buf->len = suggested_size; } diff --git a/src/udp_wrap.cc b/src/udp_wrap.cc index 43378199fe0188..d14eefd64d600a 100644 --- a/src/udp_wrap.cc +++ b/src/udp_wrap.cc @@ -375,11 +375,6 @@ void UDPWrap::OnAlloc(uv_handle_t* handle, uv_buf_t* buf) { buf->base = node::Malloc(suggested_size); buf->len = suggested_size; - - if (buf->base == nullptr && suggested_size > 0) { - FatalError("node::UDPWrap::OnAlloc(uv_handle_t*, size_t, uv_buf_t*)", - "Out Of Memory"); - } } @@ -415,7 +410,7 @@ void UDPWrap::OnRecv(uv_udp_t* handle, return; } - char* base = node::Realloc(buf->base, nread); + char* base = node::UncheckedRealloc(buf->base, nread); argv[2] = Buffer::New(env, base, nread).ToLocalChecked(); argv[3] = AddressToJS(env, addr); wrap->MakeCallback(env->onmessage_string(), arraysize(argv), argv); diff --git a/src/util-inl.h b/src/util-inl.h index 7d4eda49152b16..886b8569d63d2b 100644 --- a/src/util-inl.h +++ b/src/util-inl.h @@ -336,7 +336,7 @@ inline size_t MultiplyWithOverflowCheck(size_t a, size_t b) { // nullptr for zero-sized allocation requests. Normalize by always using // a nullptr. template -T* Realloc(T* pointer, size_t n) { +T* UncheckedRealloc(T* pointer, size_t n) { size_t full_size = MultiplyWithOverflowCheck(sizeof(T), n); if (full_size == 0) { @@ -349,18 +349,39 @@ T* Realloc(T* pointer, size_t n) { // As per spec realloc behaves like malloc if passed nullptr. template -T* Malloc(size_t n) { +T* UncheckedMalloc(size_t n) { if (n == 0) n = 1; - return Realloc(nullptr, n); + return UncheckedRealloc(nullptr, n); } template -T* Calloc(size_t n) { +T* UncheckedCalloc(size_t n) { if (n == 0) n = 1; MultiplyWithOverflowCheck(sizeof(T), n); return static_cast(calloc(n, sizeof(T))); } +template +T* Realloc(T* pointer, size_t n) { + T* ret = UncheckedRealloc(pointer, n); + if (n > 0) CHECK_NE(ret, nullptr); + return ret; +} + +template +T* Malloc(size_t n) { + T* ret = UncheckedMalloc(n); + if (n > 0) CHECK_NE(ret, nullptr); + return ret; +} + +template +T* Calloc(size_t n) { + T* ret = UncheckedCalloc(n); + if (n > 0) CHECK_NE(ret, nullptr); + return ret; +} + } // namespace node #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS diff --git a/src/util.cc b/src/util.cc index 7ce99d5c76aa93..14aa68996f56cc 100644 --- a/src/util.cc +++ b/src/util.cc @@ -1,6 +1,7 @@ #include "util.h" #include "string_bytes.h" #include "node_buffer.h" +#include "node_internals.h" #include namespace node { diff --git a/src/util.h b/src/util.h index 59a26fb8527735..8b2db6f5c321e8 100644 --- a/src/util.h +++ b/src/util.h @@ -32,6 +32,15 @@ namespace node { // nullptr for zero-sized allocation requests. Normalize by always using // a nullptr. template +inline T* UncheckedRealloc(T* pointer, size_t n); +template +inline T* UncheckedMalloc(size_t n); +template +inline T* UncheckedCalloc(size_t n); + +// Same things, but aborts immediately instead of returning nullptr when +// no memory is available. +template inline T* Realloc(T* pointer, size_t n); template inline T* Malloc(size_t n); @@ -41,6 +50,8 @@ inline T* Calloc(size_t n); // Shortcuts for char*. inline char* Malloc(size_t n) { return Malloc(n); } inline char* Calloc(size_t n) { return Calloc(n); } +inline char* UncheckedMalloc(size_t n) { return UncheckedMalloc(n); } +inline char* UncheckedCalloc(size_t n) { return UncheckedCalloc(n); } #ifdef __GNUC__ #define NO_RETURN __attribute__((noreturn)) @@ -302,7 +313,6 @@ class MaybeStackBuffer { buf_ = buf_st_; } else { buf_ = Malloc(storage); - CHECK_NE(buf_, nullptr); } // Remember how much was allocated to check against that in SetLength(). diff --git a/test/cctest/test_util.cc b/test/cctest/test_util.cc index 7bbf53af13d3c4..f1446ae0345153 100644 --- a/test/cctest/test_util.cc +++ b/test/cctest/test_util.cc @@ -105,3 +105,19 @@ TEST(UtilTest, Calloc) { EXPECT_NE(nullptr, Calloc(0)); EXPECT_NE(nullptr, Calloc(1)); } + +TEST(UtilTest, UncheckedMalloc) { + using node::UncheckedMalloc; + EXPECT_NE(nullptr, UncheckedMalloc(0)); + EXPECT_NE(nullptr, UncheckedMalloc(1)); + EXPECT_NE(nullptr, UncheckedMalloc(0)); + EXPECT_NE(nullptr, UncheckedMalloc(1)); +} + +TEST(UtilTest, UncheckedCalloc) { + using node::UncheckedCalloc; + EXPECT_NE(nullptr, UncheckedCalloc(0)); + EXPECT_NE(nullptr, UncheckedCalloc(1)); + EXPECT_NE(nullptr, UncheckedCalloc(0)); + EXPECT_NE(nullptr, UncheckedCalloc(1)); +} From e18df46092624980a0218982af757a0743cf1d98 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Sat, 10 Sep 2016 18:21:20 +0200 Subject: [PATCH 016/264] src: notify V8 for low memory when alloc fails Call `v8::Isolate::GetCurrent()->LowMemoryNotification()` when an allocation fails to give V8 a chance to clean up and return memory before retrying (and possibly giving up). Backport-PR-URL: https://github.com/nodejs/node/pull/16587 PR-URL: https://github.com/nodejs/node/pull/8482 Reviewed-By: Ben Noordhuis Reviewed-By: James M Snell Reviewed-By: Michael Dawson Reviewed-By: Ilkka Myller --- src/node.cc | 3 +++ src/node_internals.h | 3 +++ src/util-inl.h | 10 +++++++++- src/util.cc | 9 +++++++++ src/util.h | 5 +++++ 5 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/node.cc b/src/node.cc index 6345abdb312dda..98fde0dbbe3f65 100644 --- a/src/node.cc +++ b/src/node.cc @@ -198,6 +198,7 @@ bool trace_warnings = false; // that is used by lib/module.js bool config_preserve_symlinks = false; +bool v8_initialized = false; // Set in node.cc by ParseArgs when --expose-internals or --expose_internals is // used. @@ -4895,6 +4896,7 @@ int Start(int argc, char** argv) { v8_platform.Initialize(v8_thread_pool_size); V8::Initialize(); + v8_initialized = true; int exit_code = 1; { @@ -4908,6 +4910,7 @@ int Start(int argc, char** argv) { StartNodeInstance(&instance_data); exit_code = instance_data.exit_code(); } + v8_initialized = false; V8::Dispose(); v8_platform.Dispose(); diff --git a/src/node_internals.h b/src/node_internals.h index 130af5d1c0f97f..9ead8b10377075 100644 --- a/src/node_internals.h +++ b/src/node_internals.h @@ -43,6 +43,9 @@ extern std::string openssl_config; // that is used by lib/module.js extern bool config_preserve_symlinks; +// Tells whether it is safe to call v8::Isolate::GetCurrent(). +extern bool v8_initialized; + // Set in node.cc by ParseArgs when --expose-internals or --expose_internals is // used. // Used in node_config.cc to set a constant on process.binding('config') diff --git a/src/util-inl.h b/src/util-inl.h index 886b8569d63d2b..5ffe5b857f5381 100644 --- a/src/util-inl.h +++ b/src/util-inl.h @@ -344,7 +344,15 @@ T* UncheckedRealloc(T* pointer, size_t n) { return nullptr; } - return static_cast(realloc(pointer, full_size)); + void* allocated = realloc(pointer, full_size); + + if (UNLIKELY(allocated == nullptr)) { + // Tell V8 that memory is low and retry. + LowMemoryNotification(); + allocated = realloc(pointer, full_size); + } + + return static_cast(allocated); } // As per spec realloc behaves like malloc if passed nullptr. diff --git a/src/util.cc b/src/util.cc index 14aa68996f56cc..9fb5c3fd2855d3 100644 --- a/src/util.cc +++ b/src/util.cc @@ -77,4 +77,13 @@ BufferValue::BufferValue(Isolate* isolate, Local value) { } } +void LowMemoryNotification() { + if (v8_initialized) { + auto isolate = v8::Isolate::GetCurrent(); + if (isolate != nullptr) { + isolate->LowMemoryNotification(); + } + } +} + } // namespace node diff --git a/src/util.h b/src/util.h index 8b2db6f5c321e8..4ce25e4622f4b2 100644 --- a/src/util.h +++ b/src/util.h @@ -53,6 +53,11 @@ inline char* Calloc(size_t n) { return Calloc(n); } inline char* UncheckedMalloc(size_t n) { return UncheckedMalloc(n); } inline char* UncheckedCalloc(size_t n) { return UncheckedCalloc(n); } +// Used by the allocation functions when allocation fails. +// Thin wrapper around v8::Isolate::LowMemoryNotification() that checks +// whether V8 is initialized. +void LowMemoryNotification(); + #ifdef __GNUC__ #define NO_RETURN __attribute__((noreturn)) #else From 148a03034525e75602e44c5bb774aae0de675efd Mon Sep 17 00:00:00 2001 From: cjihrig Date: Thu, 15 Jun 2017 18:03:37 -0400 Subject: [PATCH 017/264] test: remove node-tap lookalike This commit removes the small node-tap lookalike from several of the streams2 tests. It's only used by six tests, and is inconsistent with all other tests. Backport-PR-URL: https://github.com/nodejs/node/pull/17024 PR-URL: https://github.com/nodejs/node/pull/13707 Reviewed-By: Anna Henningsen Reviewed-By: Ben Noordhuis Reviewed-By: James M Snell --- test/parallel/test-stream2-basic.js | 282 ++++++--------- test/parallel/test-stream2-objects.js | 176 ++++----- .../test-stream2-readable-from-list.js | 69 +--- test/parallel/test-stream2-set-encoding.js | 146 +++----- test/parallel/test-stream2-transform.js | 338 +++++++----------- test/parallel/test-stream2-writable.js | 254 ++++++------- 6 files changed, 494 insertions(+), 771 deletions(-) diff --git a/test/parallel/test-stream2-basic.js b/test/parallel/test-stream2-basic.js index 1bea98ff136799..58ac2bd1033659 100644 --- a/test/parallel/test-stream2-basic.js +++ b/test/parallel/test-stream2-basic.js @@ -65,42 +65,8 @@ TestWriter.prototype.end = function(c) { this.emit('end', this.received); }; -//////// - -// tiny node-tap lookalike. -const tests = []; -let count = 0; - -function test(name, fn) { - count++; - tests.push([name, fn]); -} - -function run() { - const next = tests.shift(); - if (!next) - return console.error('ok'); - - const name = next[0]; - const fn = next[1]; - console.log('# %s', name); - fn({ - end: function() { - count--; - run(); - } - }); -} - -// ensure all tests have run -process.on('exit', function() { - assert.strictEqual(count, 0); -}); - -process.nextTick(run); - - -test('a most basic test', function(t) { +{ + // Test basic functionality const r = new TestReader(20); const reads = []; @@ -121,10 +87,9 @@ test('a most basic test', function(t) { 'xxxxxxxxxxxxxxxxxxxxxxxxx', 'xxxxxxxxxxxxxxxxxxxxx' ]; - r.on('end', function() { + r.on('end', common.mustCall(function() { assert.deepStrictEqual(reads, expect); - t.end(); - }); + })); let readSize = 1; function flow() { @@ -136,9 +101,10 @@ test('a most basic test', function(t) { } flow(); -}); +} -test('pipe', function(t) { +{ + // Verify pipe const r = new TestReader(5); const expect = [ 'xxxxx', @@ -154,72 +120,64 @@ test('pipe', function(t) { const w = new TestWriter(); - w.on('end', function(received) { + w.on('end', common.mustCall(function(received) { assert.deepStrictEqual(received, expect); - t.end(); - }); + })); r.pipe(w); -}); +} [1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(function(SPLIT) { - test('unpipe', function(t) { - const r = new TestReader(5); + // Verify unpipe + const r = new TestReader(5); - // unpipe after 3 writes, then write to another stream instead. - let expect = [ 'xxxxx', - 'xxxxx', - 'xxxxx', - 'xxxxx', - 'xxxxx', - 'xxxxx', - 'xxxxx', - 'xxxxx', - 'xxxxx', - 'xxxxx' ]; - expect = [ expect.slice(0, SPLIT), expect.slice(SPLIT) ]; - - const w = [ new TestWriter(), new TestWriter() ]; - - let writes = SPLIT; - w[0].on('write', function() { - if (--writes === 0) { - r.unpipe(); - assert.strictEqual(r._readableState.pipes, null); - w[0].end(); - r.pipe(w[1]); - assert.strictEqual(r._readableState.pipes, w[1]); - } - }); + // unpipe after 3 writes, then write to another stream instead. + let expect = [ 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx' ]; + expect = [ expect.slice(0, SPLIT), expect.slice(SPLIT) ]; - let ended = 0; + const w = [ new TestWriter(), new TestWriter() ]; - let ended0 = false; - let ended1 = false; - w[0].on('end', function(results) { - assert.strictEqual(ended0, false); - ended0 = true; - ended++; - assert.deepStrictEqual(results, expect[0]); - }); + let writes = SPLIT; + w[0].on('write', function() { + if (--writes === 0) { + r.unpipe(); + assert.strictEqual(r._readableState.pipes, null); + w[0].end(); + r.pipe(w[1]); + assert.strictEqual(r._readableState.pipes, w[1]); + } + }); - w[1].on('end', function(results) { - assert.strictEqual(ended1, false); - ended1 = true; - ended++; - assert.strictEqual(ended, 2); - assert.deepStrictEqual(results, expect[1]); - t.end(); - }); + let ended = 0; - r.pipe(w[0]); - }); + w[0].on('end', common.mustCall(function(results) { + ended++; + assert.strictEqual(ended, 1); + assert.deepStrictEqual(results, expect[0]); + })); + + w[1].on('end', common.mustCall(function(results) { + ended++; + assert.strictEqual(ended, 2); + assert.deepStrictEqual(results, expect[1]); + })); + + r.pipe(w[0]); }); -// both writers should get the same exact data. -test('multipipe', function(t) { +{ + // Verify both writers get the same data when piping to destinations const r = new TestReader(5); const w = [ new TestWriter(), new TestWriter() ]; @@ -234,69 +192,66 @@ test('multipipe', function(t) { 'xxxxx', 'xxxxx' ]; - let c = 2; - w[0].on('end', function(received) { + w[0].on('end', common.mustCall(function(received) { assert.deepStrictEqual(received, expect, 'first'); - if (--c === 0) t.end(); - }); - w[1].on('end', function(received) { + })); + w[1].on('end', common.mustCall(function(received) { assert.deepStrictEqual(received, expect, 'second'); - if (--c === 0) t.end(); - }); + })); r.pipe(w[0]); r.pipe(w[1]); -}); +} [1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(function(SPLIT) { - test('multi-unpipe', function(t) { - const r = new TestReader(5); - - // unpipe after 3 writes, then write to another stream instead. - let expect = [ 'xxxxx', - 'xxxxx', - 'xxxxx', - 'xxxxx', - 'xxxxx', - 'xxxxx', - 'xxxxx', - 'xxxxx', - 'xxxxx', - 'xxxxx' ]; - expect = [ expect.slice(0, SPLIT), expect.slice(SPLIT) ]; + // Verify multi-unpipe + const r = new TestReader(5); - const w = [ new TestWriter(), new TestWriter(), new TestWriter() ]; + // unpipe after 3 writes, then write to another stream instead. + let expect = [ 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx', + 'xxxxx' ]; + expect = [ expect.slice(0, SPLIT), expect.slice(SPLIT) ]; + + const w = [ new TestWriter(), new TestWriter(), new TestWriter() ]; + + let writes = SPLIT; + w[0].on('write', function() { + if (--writes === 0) { + r.unpipe(); + w[0].end(); + r.pipe(w[1]); + } + }); - let writes = SPLIT; - w[0].on('write', function() { - if (--writes === 0) { - r.unpipe(); - w[0].end(); - r.pipe(w[1]); - } - }); + let ended = 0; - let ended = 0; + w[0].on('end', common.mustCall(function(results) { + ended++; + assert.strictEqual(ended, 1); + assert.deepStrictEqual(results, expect[0]); + })); - w[0].on('end', function(results) { - ended++; - assert.deepStrictEqual(results, expect[0]); - }); + w[1].on('end', common.mustCall(function(results) { + ended++; + assert.strictEqual(ended, 2); + assert.deepStrictEqual(results, expect[1]); + })); - w[1].on('end', function(results) { - ended++; - assert.strictEqual(ended, 2); - assert.deepStrictEqual(results, expect[1]); - t.end(); - }); - - r.pipe(w[0]); - r.pipe(w[2]); - }); + r.pipe(w[0]); + r.pipe(w[2]); }); -test('back pressure respected', function(t) { +{ + // Verify that back pressure is respected const r = new R({ objectMode: true }); r._read = common.mustNotCall(); let counter = 0; @@ -308,7 +263,6 @@ test('back pressure respected', function(t) { const w1 = new R(); w1.write = function(chunk) { - console.error('w1.emit("close")'); assert.strictEqual(chunk[0], 'one'); w1.emit('close'); process.nextTick(function() { @@ -324,7 +278,6 @@ test('back pressure respected', function(t) { let w2 = new R(); w2.write = function(chunk) { - console.error('w2 write', chunk, counter); assert.strictEqual(chunk[0], expected.shift()); assert.strictEqual(counter, 0); @@ -336,7 +289,6 @@ test('back pressure respected', function(t) { setTimeout(function() { counter--; - console.error('w2 drain'); w2.emit('drain'); }, 10); @@ -346,7 +298,6 @@ test('back pressure respected', function(t) { let w3 = new R(); w3.write = function(chunk) { - console.error('w3 write', chunk, counter); assert.strictEqual(chunk[0], expected.shift()); assert.strictEqual(counter, 1); @@ -358,20 +309,19 @@ test('back pressure respected', function(t) { setTimeout(function() { counter--; - console.error('w3 drain'); w3.emit('drain'); }, 50); return false; }; - w3.end = function() { + w3.end = common.mustCall(function() { assert.strictEqual(counter, 2); assert.strictEqual(expected.length, 0); - t.end(); - }; -}); + }); +} -test('read(0) for ended streams', function(t) { +{ + // Verify read(0) behavior for ended streams const r = new R(); let written = false; let ended = false; @@ -392,16 +342,16 @@ test('read(0) for ended streams', function(t) { assert.strictEqual(buffer.toString(), 'foo'); }; - w.end = function() { + w.end = common.mustCall(function() { ended = true; assert.strictEqual(written, true); - t.end(); - }; + }); r.pipe(w); -}); +} -test('sync _read ending', function(t) { +{ + // Verify synchronous _read ending const r = new R(); let called = false; r._read = function(n) { @@ -409,6 +359,7 @@ test('sync _read ending', function(t) { }; r.once('end', function() { + // Verify that this is called before the next tick called = true; }); @@ -416,11 +367,11 @@ test('sync _read ending', function(t) { process.nextTick(function() { assert.strictEqual(called, true); - t.end(); }); -}); +} -test('adding readable triggers data flow', function(t) { +{ + // Verify that adding readable listeners trigger data flow const r = new R({ highWaterMark: 5 }); let onReadable = false; let readCalled = 0; @@ -437,17 +388,16 @@ test('adding readable triggers data flow', function(t) { r.read(); }); - r.on('end', function() { + r.on('end', common.mustCall(function() { assert.strictEqual(readCalled, 3); assert.ok(onReadable); - t.end(); - }); -}); + })); +} -test('chainable', function(t) { +{ + // Verify that streams are chainable const r = new R(); r._read = common.mustCall(); const r2 = r.setEncoding('utf8').pause().resume().pause(); assert.strictEqual(r, r2); - t.end(); -}); +} diff --git a/test/parallel/test-stream2-objects.js b/test/parallel/test-stream2-objects.js index cea3a4845105df..40ba13e4d35715 100644 --- a/test/parallel/test-stream2-objects.js +++ b/test/parallel/test-stream2-objects.js @@ -4,40 +4,6 @@ const Readable = require('_stream_readable'); const Writable = require('_stream_writable'); const assert = require('assert'); -// tiny node-tap lookalike. -const tests = []; -let count = 0; - -function test(name, fn) { - count++; - tests.push([name, fn]); -} - -function run() { - const next = tests.shift(); - if (!next) - return console.error('ok'); - - const name = next[0]; - const fn = next[1]; - console.log('# %s', name); - fn({ - same: assert.deepStrictEqual, - equal: assert.strictEqual, - end: function() { - count--; - run(); - } - }); -} - -// ensure all tests have run -process.on('exit', function() { - assert.strictEqual(count, 0); -}); - -process.nextTick(run); - function toArray(callback) { const stream = new Writable({ objectMode: true }); const list = []; @@ -45,9 +11,9 @@ function toArray(callback) { list.push(chunk); }; - stream.end = function() { + stream.end = common.mustCall(function() { callback(list); - }; + }); return stream; } @@ -63,7 +29,8 @@ function fromArray(list) { return r; } -test('can read objects from stream', function(t) { +{ + // Verify that objects can be read from the stream const r = fromArray([{ one: '1'}, { two: '2' }]); const v1 = r.read(); @@ -73,34 +40,30 @@ test('can read objects from stream', function(t) { assert.deepStrictEqual(v1, { one: '1' }); assert.deepStrictEqual(v2, { two: '2' }); assert.deepStrictEqual(v3, null); +} - t.end(); -}); - -test('can pipe objects into stream', function(t) { +{ + // Verify that objects can be piped into the stream const r = fromArray([{ one: '1'}, { two: '2' }]); - r.pipe(toArray(function(list) { + r.pipe(toArray(common.mustCall(function(list) { assert.deepStrictEqual(list, [ { one: '1' }, { two: '2' } ]); + }))); +} - t.end(); - })); -}); - -test('read(n) is ignored', function(t) { +{ + // Verify that read(n) is ignored const r = fromArray([{ one: '1'}, { two: '2' }]); - const value = r.read(2); assert.deepStrictEqual(value, { one: '1' }); +} - t.end(); -}); - -test('can read objects from _read (sync)', function(t) { +{ + // Verify that objects can be synchronously read const r = new Readable({ objectMode: true }); const list = [{ one: '1'}, { two: '2' }]; r._read = function(n) { @@ -108,17 +71,16 @@ test('can read objects from _read (sync)', function(t) { r.push(item || null); }; - r.pipe(toArray(function(list) { + r.pipe(toArray(common.mustCall(function(list) { assert.deepStrictEqual(list, [ { one: '1' }, { two: '2' } ]); + }))); +} - t.end(); - })); -}); - -test('can read objects from _read (async)', function(t) { +{ + // Verify that objects can be asynchronously read const r = new Readable({ objectMode: true }); const list = [{ one: '1'}, { two: '2' }]; r._read = function(n) { @@ -128,17 +90,16 @@ test('can read objects from _read (async)', function(t) { }); }; - r.pipe(toArray(function(list) { + r.pipe(toArray(common.mustCall(function(list) { assert.deepStrictEqual(list, [ { one: '1' }, { two: '2' } ]); + }))); +} - t.end(); - })); -}); - -test('can read strings as objects', function(t) { +{ + // Verify that strings can be read as objects const r = new Readable({ objectMode: true }); @@ -149,14 +110,13 @@ test('can read strings as objects', function(t) { }); r.push(null); - r.pipe(toArray(function(array) { + r.pipe(toArray(common.mustCall(function(array) { assert.deepStrictEqual(array, list); + }))); +} - t.end(); - })); -}); - -test('read(0) for object streams', function(t) { +{ + // Verify read(0) behavior for object streams const r = new Readable({ objectMode: true }); @@ -165,14 +125,13 @@ test('read(0) for object streams', function(t) { r.push('foobar'); r.push(null); - r.pipe(toArray(function(array) { + r.pipe(toArray(common.mustCall(function(array) { assert.deepStrictEqual(array, ['foobar']); + }))); +} - t.end(); - })); -}); - -test('falsey values', function(t) { +{ + // Verify the behavior of pushing falsey values const r = new Readable({ objectMode: true }); @@ -183,14 +142,13 @@ test('falsey values', function(t) { r.push(''); r.push(null); - r.pipe(toArray(function(array) { + r.pipe(toArray(common.mustCall(function(array) { assert.deepStrictEqual(array, [false, 0, '']); + }))); +} - t.end(); - })); -}); - -test('high watermark _read', function(t) { +{ + // Verify high watermark _read() behavior const r = new Readable({ highWaterMark: 6, objectMode: true @@ -218,11 +176,10 @@ test('high watermark _read', function(t) { assert.strictEqual(v3, '3'); assert.strictEqual(calls, 1); +} - t.end(); -}); - -test('high watermark push', function(t) { +{ + // Verify high watermark push behavior const r = new Readable({ highWaterMark: 6, objectMode: true @@ -232,11 +189,10 @@ test('high watermark push', function(t) { const bool = r.push(i); assert.strictEqual(bool, i !== 5); } +} - t.end(); -}); - -test('can write objects to stream', function(t) { +{ + // Verify that objects can be written to stream const w = new Writable({ objectMode: true }); w._write = function(chunk, encoding, cb) { @@ -244,15 +200,13 @@ test('can write objects to stream', function(t) { cb(); }; - w.on('finish', function() { - t.end(); - }); - + w.on('finish', common.mustCall()); w.write({ foo: 'bar' }); w.end(); -}); +} -test('can write multiple objects to stream', function(t) { +{ + // Verify that multiple objects can be written to stream const w = new Writable({ objectMode: true }); const list = []; @@ -261,11 +215,9 @@ test('can write multiple objects to stream', function(t) { cb(); }; - w.on('finish', function() { + w.on('finish', common.mustCall(function() { assert.deepStrictEqual(list, [0, 1, 2, 3, 4]); - - t.end(); - }); + })); w.write(0); w.write(1); @@ -273,9 +225,10 @@ test('can write multiple objects to stream', function(t) { w.write(3); w.write(4); w.end(); -}); +} -test('can write strings as objects', function(t) { +{ + // Verify that strings can be written as objects const w = new Writable({ objectMode: true }); @@ -286,11 +239,9 @@ test('can write strings as objects', function(t) { process.nextTick(cb); }; - w.on('finish', function() { + w.on('finish', common.mustCall(function() { assert.deepStrictEqual(list, ['0', '1', '2', '3', '4']); - - t.end(); - }); + })); w.write('0'); w.write('1'); @@ -298,9 +249,10 @@ test('can write strings as objects', function(t) { w.write('3'); w.write('4'); w.end(); -}); +} -test('buffers finish until cb is called', function(t) { +{ + // Verify that stream buffers finish until callback is called const w = new Writable({ objectMode: true }); @@ -315,12 +267,10 @@ test('buffers finish until cb is called', function(t) { }); }; - w.on('finish', function() { + w.on('finish', common.mustCall(function() { assert.strictEqual(called, true); - - t.end(); - }); + })); w.write('foo'); w.end(); -}); +} diff --git a/test/parallel/test-stream2-readable-from-list.js b/test/parallel/test-stream2-readable-from-list.js index 54db1d1c182526..99c8cea9ebefa7 100644 --- a/test/parallel/test-stream2-readable-from-list.js +++ b/test/parallel/test-stream2-readable-from-list.js @@ -5,33 +5,6 @@ const assert = require('assert'); const fromList = require('_stream_readable')._fromList; const BufferList = require('internal/streams/BufferList'); -// tiny node-tap lookalike. -const tests = []; -let count = 0; - -function test(name, fn) { - count++; - tests.push([name, fn]); -} - -function run() { - const next = tests.shift(); - if (!next) - return console.error('ok'); - - const name = next[0]; - const fn = next[1]; - console.log('# %s', name); - fn({ - same: assert.deepStrictEqual, - equal: assert.strictEqual, - end: function() { - count--; - run(); - } - }); -} - function bufferListFromArray(arr) { const bl = new BufferList(); for (let i = 0; i < arr.length; ++i) @@ -39,15 +12,8 @@ function bufferListFromArray(arr) { return bl; } -// ensure all tests have run -process.on('exit', function() { - assert.strictEqual(count, 0); -}); - -process.nextTick(run); - - -test('buffers', function(t) { +{ + // Verify behavior with buffers let list = [ Buffer.from('foog'), Buffer.from('bark'), Buffer.from('bazy'), @@ -56,27 +22,26 @@ test('buffers', function(t) { // read more than the first element. let ret = fromList(6, { buffer: list, length: 16 }); - t.equal(ret.toString(), 'foogba'); + assert.strictEqual(ret.toString(), 'foogba'); // read exactly the first element. ret = fromList(2, { buffer: list, length: 10 }); - t.equal(ret.toString(), 'rk'); + assert.strictEqual(ret.toString(), 'rk'); // read less than the first element. ret = fromList(2, { buffer: list, length: 8 }); - t.equal(ret.toString(), 'ba'); + assert.strictEqual(ret.toString(), 'ba'); // read more than we have. ret = fromList(100, { buffer: list, length: 6 }); - t.equal(ret.toString(), 'zykuel'); + assert.strictEqual(ret.toString(), 'zykuel'); // all consumed. - t.same(list, new BufferList()); - - t.end(); -}); + assert.deepStrictEqual(list, new BufferList()); +} -test('strings', function(t) { +{ + // Verify behavior with strings let list = [ 'foog', 'bark', 'bazy', @@ -85,22 +50,20 @@ test('strings', function(t) { // read more than the first element. let ret = fromList(6, { buffer: list, length: 16, decoder: true }); - t.equal(ret, 'foogba'); + assert.strictEqual(ret, 'foogba'); // read exactly the first element. ret = fromList(2, { buffer: list, length: 10, decoder: true }); - t.equal(ret, 'rk'); + assert.strictEqual(ret, 'rk'); // read less than the first element. ret = fromList(2, { buffer: list, length: 8, decoder: true }); - t.equal(ret, 'ba'); + assert.strictEqual(ret, 'ba'); // read more than we have. ret = fromList(100, { buffer: list, length: 6, decoder: true }); - t.equal(ret, 'zykuel'); + assert.strictEqual(ret, 'zykuel'); // all consumed. - t.same(list, new BufferList()); - - t.end(); -}); + assert.deepStrictEqual(list, new BufferList()); +} diff --git a/test/parallel/test-stream2-set-encoding.js b/test/parallel/test-stream2-set-encoding.js index a207168f39a97e..45bc59a5250d02 100644 --- a/test/parallel/test-stream2-set-encoding.js +++ b/test/parallel/test-stream2-set-encoding.js @@ -1,45 +1,9 @@ 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const R = require('_stream_readable'); const util = require('util'); -// tiny node-tap lookalike. -const tests = []; -let count = 0; - -function test(name, fn) { - count++; - tests.push([name, fn]); -} - -function run() { - const next = tests.shift(); - if (!next) - return console.error('ok'); - - const name = next[0]; - const fn = next[1]; - console.log('# %s', name); - fn({ - same: assert.deepStrictEqual, - equal: assert.strictEqual, - end: function() { - count--; - run(); - } - }); -} - -// ensure all tests have run -process.on('exit', function() { - assert.strictEqual(count, 0); -}); - -process.nextTick(run); - -///// - util.inherits(TestReader, R); function TestReader(n, opts) { @@ -68,13 +32,12 @@ TestReader.prototype._read = function(n) { this.pos += n; const ret = Buffer.alloc(n, 'a'); - console.log('this.push(ret)', ret); - return this.push(ret); }.bind(this), 1); }; -test('setEncoding utf8', function(t) { +{ + // Verify utf8 encoding const tr = new TestReader(100); tr.setEncoding('utf8'); const out = []; @@ -96,14 +59,14 @@ test('setEncoding utf8', function(t) { out.push(chunk); }); - tr.on('end', function() { - t.same(out, expect); - t.end(); - }); -}); + tr.on('end', common.mustCall(function() { + assert.deepStrictEqual(out, expect); + })); +} -test('setEncoding hex', function(t) { +{ + // Verify hex encoding const tr = new TestReader(100); tr.setEncoding('hex'); const out = []; @@ -135,13 +98,13 @@ test('setEncoding hex', function(t) { out.push(chunk); }); - tr.on('end', function() { - t.same(out, expect); - t.end(); - }); -}); + tr.on('end', common.mustCall(function() { + assert.deepStrictEqual(out, expect); + })); +} -test('setEncoding hex with read(13)', function(t) { +{ + // Verify hex encoding with read(13) const tr = new TestReader(100); tr.setEncoding('hex'); const out = []; @@ -164,20 +127,18 @@ test('setEncoding hex with read(13)', function(t) { '16161' ]; tr.on('readable', function flow() { - console.log('readable once'); let chunk; while (null !== (chunk = tr.read(13))) out.push(chunk); }); - tr.on('end', function() { - console.log('END'); - t.same(out, expect); - t.end(); - }); -}); + tr.on('end', common.mustCall(function() { + assert.deepStrictEqual(out, expect); + })); +} -test('setEncoding base64', function(t) { +{ + // Verify base64 encoding const tr = new TestReader(100); tr.setEncoding('base64'); const out = []; @@ -203,13 +164,13 @@ test('setEncoding base64', function(t) { out.push(chunk); }); - tr.on('end', function() { - t.same(out, expect); - t.end(); - }); -}); + tr.on('end', common.mustCall(function() { + assert.deepStrictEqual(out, expect); + })); +} -test('encoding: utf8', function(t) { +{ + // Verify utf8 encoding const tr = new TestReader(100, { encoding: 'utf8' }); const out = []; const expect = @@ -230,14 +191,14 @@ test('encoding: utf8', function(t) { out.push(chunk); }); - tr.on('end', function() { - t.same(out, expect); - t.end(); - }); -}); + tr.on('end', common.mustCall(function() { + assert.deepStrictEqual(out, expect); + })); +} -test('encoding: hex', function(t) { +{ + // Verify hex encoding const tr = new TestReader(100, { encoding: 'hex' }); const out = []; const expect = @@ -268,13 +229,13 @@ test('encoding: hex', function(t) { out.push(chunk); }); - tr.on('end', function() { - t.same(out, expect); - t.end(); - }); -}); + tr.on('end', common.mustCall(function() { + assert.deepStrictEqual(out, expect); + })); +} -test('encoding: hex with read(13)', function(t) { +{ + // Verify hex encoding with read(13) const tr = new TestReader(100, { encoding: 'hex' }); const out = []; const expect = @@ -301,13 +262,13 @@ test('encoding: hex with read(13)', function(t) { out.push(chunk); }); - tr.on('end', function() { - t.same(out, expect); - t.end(); - }); -}); + tr.on('end', common.mustCall(function() { + assert.deepStrictEqual(out, expect); + })); +} -test('encoding: base64', function(t) { +{ + // Verify base64 encoding const tr = new TestReader(100, { encoding: 'base64' }); const out = []; const expect = @@ -332,14 +293,13 @@ test('encoding: base64', function(t) { out.push(chunk); }); - tr.on('end', function() { - t.same(out, expect); - t.end(); - }); -}); + tr.on('end', common.mustCall(function() { + assert.deepStrictEqual(out, expect); + })); +} -test('chainable', function(t) { +{ + // Verify chaining behavior const tr = new TestReader(100); - t.equal(tr.setEncoding('utf8'), tr); - t.end(); -}); + assert.deepStrictEqual(tr.setEncoding('utf8'), tr); +} diff --git a/test/parallel/test-stream2-transform.js b/test/parallel/test-stream2-transform.js index 2c4636a4bf71de..e28e615852bec5 100644 --- a/test/parallel/test-stream2-transform.js +++ b/test/parallel/test-stream2-transform.js @@ -1,47 +1,11 @@ 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const PassThrough = require('_stream_passthrough'); const Transform = require('_stream_transform'); -// tiny node-tap lookalike. -const tests = []; -let count = 0; - -function test(name, fn) { - count++; - tests.push([name, fn]); -} - -function run() { - const next = tests.shift(); - if (!next) - return console.error('ok'); - - const name = next[0]; - const fn = next[1]; - console.log('# %s', name); - fn({ - same: assert.deepStrictEqual, - equal: assert.strictEqual, - ok: assert, - end: function() { - count--; - run(); - } - }); -} - -// ensure all tests have run -process.on('exit', function() { - assert.strictEqual(count, 0); -}); - -process.nextTick(run); - -///// - -test('writable side consumption', function(t) { +{ + // Verify writable side consumption const tx = new Transform({ highWaterMark: 10 }); @@ -58,17 +22,16 @@ test('writable side consumption', function(t) { } tx.end(); - t.equal(tx._readableState.length, 10); - t.equal(transformed, 10); - t.equal(tx._transformState.writechunk.length, 5); - t.same(tx._writableState.getBuffer().map(function(c) { + assert.strictEqual(tx._readableState.length, 10); + assert.strictEqual(transformed, 10); + assert.strictEqual(tx._transformState.writechunk.length, 5); + assert.deepStrictEqual(tx._writableState.getBuffer().map(function(c) { return c.chunk.length; }), [6, 7, 8, 9, 10]); +} - t.end(); -}); - -test('passthrough', function(t) { +{ + // Verify passthrough behavior const pt = new PassThrough(); pt.write(Buffer.from('foog')); @@ -77,14 +40,14 @@ test('passthrough', function(t) { pt.write(Buffer.from('kuel')); pt.end(); - t.equal(pt.read(5).toString(), 'foogb'); - t.equal(pt.read(5).toString(), 'arkba'); - t.equal(pt.read(5).toString(), 'zykue'); - t.equal(pt.read(5).toString(), 'l'); - t.end(); -}); + assert.strictEqual(pt.read(5).toString(), 'foogb'); + assert.strictEqual(pt.read(5).toString(), 'arkba'); + assert.strictEqual(pt.read(5).toString(), 'zykue'); + assert.strictEqual(pt.read(5).toString(), 'l'); +} -test('object passthrough', function(t) { +{ + // Verify object passthrough behavior const pt = new PassThrough({ objectMode: true }); pt.write(1); @@ -96,25 +59,24 @@ test('object passthrough', function(t) { pt.write({ a: 'b'}); pt.end(); - t.equal(pt.read(), 1); - t.equal(pt.read(), true); - t.equal(pt.read(), false); - t.equal(pt.read(), 0); - t.equal(pt.read(), 'foo'); - t.equal(pt.read(), ''); - t.same(pt.read(), { a: 'b'}); - t.end(); -}); - -test('passthrough constructor', function(t) { + assert.strictEqual(pt.read(), 1); + assert.strictEqual(pt.read(), true); + assert.strictEqual(pt.read(), false); + assert.strictEqual(pt.read(), 0); + assert.strictEqual(pt.read(), 'foo'); + assert.strictEqual(pt.read(), ''); + assert.deepStrictEqual(pt.read(), { a: 'b'}); +} + +{ + // Verify passthrough constructor behavior const pt = PassThrough(); assert(pt instanceof PassThrough); +} - t.end(); -}); - -test('simple transform', function(t) { +{ + // Perform a simple transform const pt = new Transform(); pt._transform = function(c, e, cb) { const ret = Buffer.alloc(c.length, 'x'); @@ -128,14 +90,14 @@ test('simple transform', function(t) { pt.write(Buffer.from('kuel')); pt.end(); - t.equal(pt.read(5).toString(), 'xxxxx'); - t.equal(pt.read(5).toString(), 'xxxxx'); - t.equal(pt.read(5).toString(), 'xxxxx'); - t.equal(pt.read(5).toString(), 'x'); - t.end(); -}); + assert.strictEqual(pt.read(5).toString(), 'xxxxx'); + assert.strictEqual(pt.read(5).toString(), 'xxxxx'); + assert.strictEqual(pt.read(5).toString(), 'xxxxx'); + assert.strictEqual(pt.read(5).toString(), 'x'); +} -test('simple object transform', function(t) { +{ + // Verify simple object transform const pt = new Transform({ objectMode: true }); pt._transform = function(c, e, cb) { pt.push(JSON.stringify(c)); @@ -151,17 +113,17 @@ test('simple object transform', function(t) { pt.write({ a: 'b'}); pt.end(); - t.equal(pt.read(), '1'); - t.equal(pt.read(), 'true'); - t.equal(pt.read(), 'false'); - t.equal(pt.read(), '0'); - t.equal(pt.read(), '"foo"'); - t.equal(pt.read(), '""'); - t.equal(pt.read(), '{"a":"b"}'); - t.end(); -}); - -test('async passthrough', function(t) { + assert.strictEqual(pt.read(), '1'); + assert.strictEqual(pt.read(), 'true'); + assert.strictEqual(pt.read(), 'false'); + assert.strictEqual(pt.read(), '0'); + assert.strictEqual(pt.read(), '"foo"'); + assert.strictEqual(pt.read(), '""'); + assert.strictEqual(pt.read(), '{"a":"b"}'); +} + +{ + // Verify async passthrough const pt = new Transform(); pt._transform = function(chunk, encoding, cb) { setTimeout(function() { @@ -176,16 +138,16 @@ test('async passthrough', function(t) { pt.write(Buffer.from('kuel')); pt.end(); - pt.on('finish', function() { - t.equal(pt.read(5).toString(), 'foogb'); - t.equal(pt.read(5).toString(), 'arkba'); - t.equal(pt.read(5).toString(), 'zykue'); - t.equal(pt.read(5).toString(), 'l'); - t.end(); - }); -}); + pt.on('finish', common.mustCall(function() { + assert.strictEqual(pt.read(5).toString(), 'foogb'); + assert.strictEqual(pt.read(5).toString(), 'arkba'); + assert.strictEqual(pt.read(5).toString(), 'zykue'); + assert.strictEqual(pt.read(5).toString(), 'l'); + })); +} -test('assymetric transform (expand)', function(t) { +{ + // Verify assymetric transform (expand) const pt = new Transform(); // emit each chunk 2 times. @@ -205,19 +167,19 @@ test('assymetric transform (expand)', function(t) { pt.write(Buffer.from('kuel')); pt.end(); - pt.on('finish', function() { - t.equal(pt.read(5).toString(), 'foogf'); - t.equal(pt.read(5).toString(), 'oogba'); - t.equal(pt.read(5).toString(), 'rkbar'); - t.equal(pt.read(5).toString(), 'kbazy'); - t.equal(pt.read(5).toString(), 'bazyk'); - t.equal(pt.read(5).toString(), 'uelku'); - t.equal(pt.read(5).toString(), 'el'); - t.end(); - }); -}); + pt.on('finish', common.mustCall(function() { + assert.strictEqual(pt.read(5).toString(), 'foogf'); + assert.strictEqual(pt.read(5).toString(), 'oogba'); + assert.strictEqual(pt.read(5).toString(), 'rkbar'); + assert.strictEqual(pt.read(5).toString(), 'kbazy'); + assert.strictEqual(pt.read(5).toString(), 'bazyk'); + assert.strictEqual(pt.read(5).toString(), 'uelku'); + assert.strictEqual(pt.read(5).toString(), 'el'); + })); +} -test('assymetric transform (compress)', function(t) { +{ + // Verify assymetric trasform (compress) const pt = new Transform(); // each output is the first char of 3 consecutive chunks, @@ -262,17 +224,17 @@ test('assymetric transform (compress)', function(t) { pt.end(); // 'abcdeabcdeabcd' - pt.on('finish', function() { - t.equal(pt.read(5).toString(), 'abcde'); - t.equal(pt.read(5).toString(), 'abcde'); - t.equal(pt.read(5).toString(), 'abcd'); - t.end(); - }); -}); + pt.on('finish', common.mustCall(function() { + assert.strictEqual(pt.read(5).toString(), 'abcde'); + assert.strictEqual(pt.read(5).toString(), 'abcde'); + assert.strictEqual(pt.read(5).toString(), 'abcd'); + })); +} // this tests for a stall when data is written to a full stream // that has empty transforms. -test('complex transform', function(t) { +{ + // Verify compex transform behavior let count = 0; let saved = null; const pt = new Transform({highWaterMark: 3}); @@ -293,118 +255,96 @@ test('complex transform', function(t) { pt.once('readable', function() { process.nextTick(function() { pt.write(Buffer.from('d')); - pt.write(Buffer.from('ef'), function() { + pt.write(Buffer.from('ef'), common.mustCall(function() { pt.end(); - t.end(); - }); - t.equal(pt.read().toString(), 'abcdef'); - t.equal(pt.read(), null); + })); + assert.strictEqual(pt.read().toString(), 'abcdef'); + assert.strictEqual(pt.read(), null); }); }); pt.write(Buffer.from('abc')); -}); +} -test('passthrough event emission', function(t) { +{ + // Verify passthrough event emission const pt = new PassThrough(); let emits = 0; pt.on('readable', function() { - console.error('>>> emit readable %d', emits); emits++; }); pt.write(Buffer.from('foog')); - - console.error('need emit 0'); pt.write(Buffer.from('bark')); - console.error('should have emitted readable now 1 === %d', emits); - t.equal(emits, 1); - - t.equal(pt.read(5).toString(), 'foogb'); - t.equal(String(pt.read(5)), 'null'); - - console.error('need emit 1'); + assert.strictEqual(emits, 1); + assert.strictEqual(pt.read(5).toString(), 'foogb'); + assert.strictEqual(String(pt.read(5)), 'null'); pt.write(Buffer.from('bazy')); - console.error('should have emitted, but not again'); pt.write(Buffer.from('kuel')); - console.error('should have emitted readable now 2 === %d', emits); - t.equal(emits, 2); - - t.equal(pt.read(5).toString(), 'arkba'); - t.equal(pt.read(5).toString(), 'zykue'); - t.equal(pt.read(5), null); - - console.error('need emit 2'); + assert.strictEqual(emits, 2); + assert.strictEqual(pt.read(5).toString(), 'arkba'); + assert.strictEqual(pt.read(5).toString(), 'zykue'); + assert.strictEqual(pt.read(5), null); pt.end(); - t.equal(emits, 3); + assert.strictEqual(emits, 3); + assert.strictEqual(pt.read(5).toString(), 'l'); + assert.strictEqual(pt.read(5), null); - t.equal(pt.read(5).toString(), 'l'); - t.equal(pt.read(5), null); - - console.error('should not have emitted again'); - t.equal(emits, 3); - t.end(); -}); + assert.strictEqual(emits, 3); +} -test('passthrough event emission reordered', function(t) { +{ + // Verify passthrough event emission reordering const pt = new PassThrough(); let emits = 0; pt.on('readable', function() { - console.error('emit readable', emits); emits++; }); pt.write(Buffer.from('foog')); - console.error('need emit 0'); pt.write(Buffer.from('bark')); - console.error('should have emitted readable now 1 === %d', emits); - t.equal(emits, 1); - t.equal(pt.read(5).toString(), 'foogb'); - t.equal(pt.read(5), null); - - console.error('need emit 1'); - pt.once('readable', function() { - t.equal(pt.read(5).toString(), 'arkba'); - - t.equal(pt.read(5), null); - - console.error('need emit 2'); - pt.once('readable', function() { - t.equal(pt.read(5).toString(), 'zykue'); - t.equal(pt.read(5), null); - pt.once('readable', function() { - t.equal(pt.read(5).toString(), 'l'); - t.equal(pt.read(5), null); - t.equal(emits, 4); - t.end(); - }); + assert.strictEqual(emits, 1); + assert.strictEqual(pt.read(5).toString(), 'foogb'); + assert.strictEqual(pt.read(5), null); + + pt.once('readable', common.mustCall(function() { + assert.strictEqual(pt.read(5).toString(), 'arkba'); + assert.strictEqual(pt.read(5), null); + + pt.once('readable', common.mustCall(function() { + assert.strictEqual(pt.read(5).toString(), 'zykue'); + assert.strictEqual(pt.read(5), null); + pt.once('readable', common.mustCall(function() { + assert.strictEqual(pt.read(5).toString(), 'l'); + assert.strictEqual(pt.read(5), null); + assert.strictEqual(emits, 4); + })); pt.end(); - }); + })); pt.write(Buffer.from('kuel')); - }); + })); pt.write(Buffer.from('bazy')); -}); +} -test('passthrough facaded', function(t) { - console.error('passthrough facaded'); +{ + // Verify passthrough facade const pt = new PassThrough(); const datas = []; pt.on('data', function(chunk) { datas.push(chunk.toString()); }); - pt.on('end', function() { - t.same(datas, ['foog', 'bark', 'bazy', 'kuel']); - t.end(); - }); + pt.on('end', common.mustCall(function() { + assert.deepStrictEqual(datas, ['foog', 'bark', 'bazy', 'kuel']); + })); pt.write(Buffer.from('foog')); setTimeout(function() { @@ -419,10 +359,10 @@ test('passthrough facaded', function(t) { }, 10); }, 10); }, 10); -}); +} -test('object transform (json parse)', function(t) { - console.error('json parse stream'); +{ + // Verify object transform (JSON parse) const jp = new Transform({ objectMode: true }); jp._transform = function(data, encoding, cb) { try { @@ -450,21 +390,20 @@ test('object transform (json parse)', function(t) { objects.forEach(function(obj) { jp.write(JSON.stringify(obj)); const res = jp.read(); - t.same(res, obj); + assert.deepStrictEqual(res, obj); }); jp.end(); // read one more time to get the 'end' event jp.read(); - process.nextTick(function() { - t.ok(ended); - t.end(); - }); -}); + process.nextTick(common.mustCall(function() { + assert.strictEqual(ended, true); + })); +} -test('object transform (json stringify)', function(t) { - console.error('json parse stream'); +{ + // Verify object transform (JSON stringify) const js = new Transform({ objectMode: true }); js._transform = function(data, encoding, cb) { try { @@ -492,15 +431,14 @@ test('object transform (json stringify)', function(t) { objects.forEach(function(obj) { js.write(obj); const res = js.read(); - t.equal(res, JSON.stringify(obj)); + assert.strictEqual(res, JSON.stringify(obj)); }); js.end(); // read one more time to get the 'end' event js.read(); - process.nextTick(function() { - t.ok(ended); - t.end(); - }); -}); + process.nextTick(common.mustCall(function() { + assert.strictEqual(ended, true); + })); +} diff --git a/test/parallel/test-stream2-writable.js b/test/parallel/test-stream2-writable.js index ebfc61f9f67fa4..d244f06ef0a292 100644 --- a/test/parallel/test-stream2-writable.js +++ b/test/parallel/test-stream2-writable.js @@ -1,5 +1,5 @@ 'use strict'; -require('../common'); +const common = require('../common'); const W = require('_stream_writable'); const D = require('_stream_duplex'); const assert = require('assert'); @@ -27,66 +27,32 @@ for (let i = 0; i < chunks.length; i++) { chunks[i] = new Array(i + 1).join('x'); } -// tiny node-tap lookalike. -const tests = []; -let count = 0; - -function test(name, fn) { - count++; - tests.push([name, fn]); -} - -function run() { - const next = tests.shift(); - if (!next) - return console.error('ok'); - - const name = next[0]; - const fn = next[1]; - console.log('# %s', name); - fn({ - same: assert.deepStrictEqual, - equal: assert.strictEqual, - end: function() { - count--; - run(); - } - }); -} - -// ensure all tests have run -process.on('exit', function() { - assert.strictEqual(count, 0); -}); - -process.nextTick(run); - -test('write fast', function(t) { +{ + // Verify fast writing const tw = new TestWriter({ highWaterMark: 100 }); - tw.on('finish', function() { - t.same(tw.buffer, chunks, 'got chunks in the right order'); - t.end(); - }); + tw.on('finish', common.mustCall(function() { + assert.deepStrictEqual(tw.buffer, chunks, 'got chunks in the right order'); + })); chunks.forEach(function(chunk) { - // screw backpressure. Just buffer it all up. + // Ignore backpressure. Just buffer it all up. tw.write(chunk); }); tw.end(); -}); +} -test('write slow', function(t) { +{ + // Verify slow writing const tw = new TestWriter({ highWaterMark: 100 }); - tw.on('finish', function() { - t.same(tw.buffer, chunks, 'got chunks in the right order'); - t.end(); - }); + tw.on('finish', common.mustCall(function() { + assert.deepStrictEqual(tw.buffer, chunks, 'got chunks in the right order'); + })); let i = 0; (function W() { @@ -96,20 +62,20 @@ test('write slow', function(t) { else tw.end(); })(); -}); +} -test('write backpressure', function(t) { +{ + // Verify write backpressure const tw = new TestWriter({ highWaterMark: 50 }); let drains = 0; - tw.on('finish', function() { - t.same(tw.buffer, chunks, 'got chunks in the right order'); - t.equal(drains, 17); - t.end(); - }); + tw.on('finish', common.mustCall(function() { + assert.deepStrictEqual(tw.buffer, chunks, 'got chunks in the right order'); + assert.strictEqual(drains, 17); + })); tw.on('drain', function() { drains++; @@ -129,9 +95,10 @@ test('write backpressure', function(t) { tw.end(); } })(); -}); +} -test('write bufferize', function(t) { +{ + // Verify write buffersize const tw = new TestWriter({ highWaterMark: 100 }); @@ -151,7 +118,7 @@ test('write bufferize', function(t) { undefined ]; tw.on('finish', function() { - t.same(tw.buffer, chunks, 'got the expected chunks'); + assert.deepStrictEqual(tw.buffer, chunks, 'got the expected chunks'); }); chunks.forEach(function(chunk, i) { @@ -159,10 +126,10 @@ test('write bufferize', function(t) { chunk = Buffer.from(chunk); tw.write(chunk.toString(enc), enc); }); - t.end(); -}); +} -test('write no bufferize', function(t) { +{ + // Verify write with no buffersize const tw = new TestWriter({ highWaterMark: 100, decodeStrings: false @@ -189,7 +156,7 @@ test('write no bufferize', function(t) { undefined ]; tw.on('finish', function() { - t.same(tw.buffer, chunks, 'got the expected chunks'); + assert.deepStrictEqual(tw.buffer, chunks, 'got the expected chunks'); }); chunks.forEach(function(chunk, i) { @@ -197,10 +164,10 @@ test('write no bufferize', function(t) { chunk = Buffer.from(chunk); tw.write(chunk.toString(enc), enc); }); - t.end(); -}); +} -test('write callbacks', function(t) { +{ + // Verify write callbacks const callbacks = chunks.map(function(chunk, i) { return [i, function() { callbacks._called[i] = chunk; @@ -215,118 +182,115 @@ test('write callbacks', function(t) { highWaterMark: 100 }); - tw.on('finish', function() { - process.nextTick(function() { - t.same(tw.buffer, chunks, 'got chunks in the right order'); - t.same(callbacks._called, chunks, 'called all callbacks'); - t.end(); - }); - }); + tw.on('finish', common.mustCall(function() { + process.nextTick(common.mustCall(function() { + assert.deepStrictEqual(tw.buffer, chunks, + 'got chunks in the right order'); + assert.deepStrictEqual(callbacks._called, chunks, 'called all callbacks'); + })); + })); chunks.forEach(function(chunk, i) { tw.write(chunk, callbacks[`callback-${i}`]); }); tw.end(); -}); +} -test('end callback', function(t) { +{ + // Verify end() callback const tw = new TestWriter(); - tw.end(function() { - t.end(); - }); -}); + tw.end(common.mustCall()); +} -test('end callback with chunk', function(t) { +{ + // Verify end() callback with chunk const tw = new TestWriter(); - tw.end(Buffer.from('hello world'), function() { - t.end(); - }); -}); + tw.end(Buffer.from('hello world'), common.mustCall()); +} -test('end callback with chunk and encoding', function(t) { +{ + // Verify end() callback with chunk and encoding const tw = new TestWriter(); - tw.end('hello world', 'ascii', function() { - t.end(); - }); -}); + tw.end('hello world', 'ascii', common.mustCall()); +} -test('end callback after .write() call', function(t) { +{ + // Verify end() callback after write() call const tw = new TestWriter(); tw.write(Buffer.from('hello world')); - tw.end(function() { - t.end(); - }); -}); + tw.end(common.mustCall()); +} -test('end callback called after write callback', function(t) { +{ + // Verify end() callback after write() callback const tw = new TestWriter(); let writeCalledback = false; tw.write(Buffer.from('hello world'), function() { writeCalledback = true; }); - tw.end(function() { - t.equal(writeCalledback, true); - t.end(); - }); -}); + tw.end(common.mustCall(function() { + assert.strictEqual(writeCalledback, true); + })); +} -test('encoding should be ignored for buffers', function(t) { +{ + // Verify encoding is ignored for buffers const tw = new W(); const hex = '018b5e9a8f6236ffe30e31baf80d2cf6eb'; - tw._write = function(chunk) { - t.equal(chunk.toString('hex'), hex); - t.end(); - }; + tw._write = common.mustCall(function(chunk) { + assert.strictEqual(chunk.toString('hex'), hex); + }); const buf = Buffer.from(hex, 'hex'); tw.write(buf, 'latin1'); -}); +} -test('writables are not pipable', function(t) { +{ + // Verify writables cannot be piped const w = new W(); - w._write = () => {}; + w._write = common.mustNotCall(); let gotError = false; w.on('error', function() { gotError = true; }); w.pipe(process.stdout); - assert(gotError); - t.end(); -}); + assert.strictEqual(gotError, true); +} -test('duplexes are pipable', function(t) { +{ + // Verify that duplex streams cannot be piped const d = new D(); - d._read = () => {}; - d._write = () => {}; + d._read = common.mustCall(); + d._write = common.mustNotCall(); let gotError = false; d.on('error', function() { gotError = true; }); d.pipe(process.stdout); - assert(!gotError); - t.end(); -}); + assert.strictEqual(gotError, false); +} -test('end(chunk) two times is an error', function(t) { +{ + // Verify that end(chunk) twice is an error const w = new W(); w._write = () => {}; let gotError = false; w.on('error', function(er) { gotError = true; - t.equal(er.message, 'write after end'); + assert.strictEqual(er.message, 'write after end'); }); w.end('this is the end'); w.end('and so is this'); - process.nextTick(function() { - assert(gotError); - t.end(); - }); -}); + process.nextTick(common.mustCall(function() { + assert.strictEqual(gotError, true); + })); +} -test('dont end while writing', function(t) { +{ + // Verify stream doesn't end while writing const w = new W(); let wrote = false; w._write = function(chunk, e, cb) { - assert(!this.writing); + assert.strictEqual(this.writing, undefined); wrote = true; this.writing = true; setTimeout(function() { @@ -334,15 +298,15 @@ test('dont end while writing', function(t) { cb(); }, 1); }; - w.on('finish', function() { - assert(wrote); - t.end(); - }); + w.on('finish', common.mustCall(function() { + assert.strictEqual(wrote, true); + })); w.write(Buffer.alloc(0)); w.end(); -}); +} -test('finish does not come before write cb', function(t) { +{ + // Verify finish does not come before write() callback const w = new W(); let writeCb = false; w._write = function(chunk, e, cb) { @@ -351,38 +315,36 @@ test('finish does not come before write cb', function(t) { cb(); }, 10); }; - w.on('finish', function() { - assert(writeCb); - t.end(); - }); + w.on('finish', common.mustCall(function() { + assert.strictEqual(writeCb, true); + })); w.write(Buffer.alloc(0)); w.end(); -}); +} -test('finish does not come before sync _write cb', function(t) { +{ + // Verify finish does not come before synchronous _write() callback const w = new W(); let writeCb = false; w._write = function(chunk, e, cb) { cb(); }; - w.on('finish', function() { - assert(writeCb); - t.end(); - }); + w.on('finish', common.mustCall(function() { + assert.strictEqual(writeCb, true); + })); w.write(Buffer.alloc(0), function() { writeCb = true; }); w.end(); -}); +} -test('finish is emitted if last chunk is empty', function(t) { +{ + // Verify finish is emitted if the last chunk is empty const w = new W(); w._write = function(chunk, e, cb) { process.nextTick(cb); }; - w.on('finish', function() { - t.end(); - }); + w.on('finish', common.mustCall()); w.write(Buffer.allocUnsafe(1)); w.end(Buffer.alloc(0)); -}); +} From 7115079c4f1d155895d0294f8af1ff03c2f41622 Mon Sep 17 00:00:00 2001 From: Shigeki Ohtsu Date: Tue, 20 Jun 2017 23:44:53 +0900 Subject: [PATCH 018/264] crypto: warn if counter mode used in createCipher MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `crypto.createCipher()` sets the fixed IV derived from password and it leads to a security risk of nonce reuse when counter mode is used. A warning is emitted when CTR, GCM or CCM is used in `crypto.createCipher()` to notify users to avoid nonce reuse. Backport-PR-URL: https://github.com/nodejs/node/pull/16583 Fixes: https://github.com/nodejs/node/issues/13801 PR-URL: https://github.com/nodejs/node/pull/13821 Reviewed-By: Ben Noordhuis Reviewed-By: Fedor Indutny Reviewed-By: James M Snell Reviewed-By: Tobias Nießen --- doc/api/crypto.md | 7 ++++++- src/node_crypto.cc | 8 ++++++++ test/parallel/test-crypto-cipher-decipher.js | 4 ++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/doc/api/crypto.md b/doc/api/crypto.md index 19fdaa4dd6ad19..4a7488ba6f2f70 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -1102,7 +1102,11 @@ rapidly. In line with OpenSSL's recommendation to use pbkdf2 instead of [`EVP_BytesToKey`][] it is recommended that developers derive a key and IV on their own using [`crypto.pbkdf2()`][] and to use [`crypto.createCipheriv()`][] -to create the `Cipher` object. +to create the `Cipher` object. Users should not use ciphers with counter mode +(e.g. CTR, GCM or CCM) in `crypto.createCipher()`. A warning is emitted when +they are used in order to avoid the risk of IV reuse that causes +vulnerabilities. For the case when IV is reused in GCM, see [Nonce-Disrespecting +Adversaries][] for details. ### crypto.createCipheriv(algorithm, key, iv) @@ -2024,6 +2028,7 @@ the `crypto`, `tls`, and `https` modules and are generally specific to OpenSSL. [NIST SP 800-131A]: http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar1.pdf [NIST SP 800-132]: http://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-132.pdf [OpenSSL cipher list format]: https://www.openssl.org/docs/man1.0.2/apps/ciphers.html#CIPHER-LIST-FORMAT +[Nonce-Disrespecting Adversaries]: https://github.com/nonce-disrespect/nonce-disrespect [OpenSSL's SPKAC implementation]: https://www.openssl.org/docs/man1.0.2/apps/spkac.html [publicly trusted list of CAs]: https://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt [RFC 2412]: https://www.rfc-editor.org/rfc/rfc2412.txt diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 09002972a94b5f..12ace3358373c1 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -3351,6 +3351,14 @@ void CipherBase::Init(const char* cipher_type, EVP_CIPHER_CTX_init(&ctx_); const bool encrypt = (kind_ == kCipher); EVP_CipherInit_ex(&ctx_, cipher_, nullptr, nullptr, nullptr, encrypt); + + int mode = EVP_CIPHER_CTX_mode(&ctx_); + if (encrypt && (mode == EVP_CIPH_CTR_MODE || mode == EVP_CIPH_GCM_MODE || + mode == EVP_CIPH_CCM_MODE)) { + ProcessEmitWarning(env(), "Use Cipheriv for counter mode of %s", + cipher_type); + } + if (!EVP_CIPHER_CTX_set_key_length(&ctx_, key_len)) { EVP_CIPHER_CTX_cleanup(&ctx_); return env()->ThrowError("Invalid key length"); diff --git a/test/parallel/test-crypto-cipher-decipher.js b/test/parallel/test-crypto-cipher-decipher.js index 8b1b0051d34962..6b2df3d81fd893 100644 --- a/test/parallel/test-crypto-cipher-decipher.js +++ b/test/parallel/test-crypto-cipher-decipher.js @@ -148,3 +148,7 @@ testCipher2(Buffer.from('0123456789abcdef')); assert.strictEqual(decipher.setAuthTag(tagbuf), decipher); assert.strictEqual(decipher.setAAD(aadbuf), decipher); } + +// https://github.com/nodejs/node/issues/13801 +common.expectWarning('Warning', 'Use Cipheriv for counter mode of aes-256-gcm'); +crypto.createCipher('aes-256-gcm', '0123456789'); From f2cafff9b09338cb5c5dbd4ff6bff714ac7229dd Mon Sep 17 00:00:00 2001 From: Shigeki Ohtsu Date: Fri, 25 Aug 2017 01:42:55 +0900 Subject: [PATCH 019/264] crypto: fix error of createCipher in wrap mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit EVP_CIPHER_CTX_FLAG_WRAP_ALLOW flag needs to be set in using wrap mode ciphers. In `crypto.createCipher()`, AES key wrap mode does not use a default IV defined in RFC3394 but a generated IV with `EVP_BytesToKey()` to be consistent API behaviors with other ciphers. The built-in AES wrap mode in OpenSSL is not supported in FIPS mode as http://openssl.6102.n7.nabble.com/AES-Key-Wrap-in-FIPS-Mode-td50238.html so its tests in FIPS mode are skipped. Backport-PR-URL: https://github.com/nodejs/node/pull/16584 Fixes: https://github.com/nodejs/node/issues/15009 PR-URL: https://github.com/nodejs/node/pull/15037 Reviewed-By: Fedor Indutny Reviewed-By: Ben Noordhuis Reviewed-By: Tobias Nießen Reviewed-By: James M Snell --- src/node_crypto.cc | 10 +++++++- test/parallel/test-crypto-binary-default.js | 21 ++++++++++++++++ .../test-crypto-cipheriv-decipheriv.js | 24 +++++++++++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 12ace3358373c1..4941d96655a9bf 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -3359,6 +3359,9 @@ void CipherBase::Init(const char* cipher_type, cipher_type); } + if (mode == EVP_CIPH_WRAP_MODE) + EVP_CIPHER_CTX_set_flags(&ctx_, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW); + if (!EVP_CIPHER_CTX_set_key_length(&ctx_, key_len)) { EVP_CIPHER_CTX_cleanup(&ctx_); return env()->ThrowError("Invalid key length"); @@ -3406,13 +3409,18 @@ void CipherBase::InitIv(const char* cipher_type, } const int expected_iv_len = EVP_CIPHER_iv_length(cipher_); - const bool is_gcm_mode = (EVP_CIPH_GCM_MODE == EVP_CIPHER_mode(cipher_)); + const int mode = EVP_CIPHER_mode(cipher_); + const bool is_gcm_mode = (EVP_CIPH_GCM_MODE == mode); if (is_gcm_mode == false && iv_len != expected_iv_len) { return env()->ThrowError("Invalid IV length"); } EVP_CIPHER_CTX_init(&ctx_); + + if (mode == EVP_CIPH_WRAP_MODE) + EVP_CIPHER_CTX_set_flags(&ctx_, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW); + const bool encrypt = (kind_ == kCipher); EVP_CipherInit_ex(&ctx_, cipher_, nullptr, nullptr, nullptr, encrypt); diff --git a/test/parallel/test-crypto-binary-default.js b/test/parallel/test-crypto-binary-default.js index 2343360df9fadf..c477301256d919 100644 --- a/test/parallel/test-crypto-binary-default.js +++ b/test/parallel/test-crypto-binary-default.js @@ -509,12 +509,33 @@ function testCipher4(key, iv) { 'encryption and decryption with key and iv'); } + +function testCipher5(key, iv) { + // Test encryption and decryption with explicit key with aes128-wrap + const plaintext = + '32|RmVZZkFUVmpRRkp0TmJaUm56ZU9qcnJkaXNNWVNpTTU*|iXmckfRWZBGWWELw' + + 'eCBsThSsfUHLeRe0KCsK8ooHgxie0zOINpXxfZi/oNG7uq9JWFVCk70gfzQH8ZUJ' + + 'jAfaFg**'; + const cipher = crypto.createCipher('id-aes128-wrap', key); + let ciph = cipher.update(plaintext, 'utf8', 'buffer'); + ciph = Buffer.concat([ciph, cipher.final('buffer')]); + + const decipher = crypto.createDecipher('id-aes128-wrap', key); + let txt = decipher.update(ciph, 'buffer', 'utf8'); + txt += decipher.final('utf8'); + + assert.strictEqual(txt, plaintext, + 'encryption and decryption with key'); +} + if (!common.hasFipsCrypto) { testCipher1('MySecretKey123'); testCipher1(Buffer.from('MySecretKey123')); testCipher2('0123456789abcdef'); testCipher2(Buffer.from('0123456789abcdef')); + + testCipher5(Buffer.from('0123456789abcd0123456789')); } testCipher3('0123456789abcd0123456789', '12345678'); diff --git a/test/parallel/test-crypto-cipheriv-decipheriv.js b/test/parallel/test-crypto-cipheriv-decipheriv.js index 2ee8e813233e77..285440643c42b8 100644 --- a/test/parallel/test-crypto-cipheriv-decipheriv.js +++ b/test/parallel/test-crypto-cipheriv-decipheriv.js @@ -55,12 +55,36 @@ function testCipher2(key, iv) { assert.strictEqual(txt, plaintext, 'encryption/decryption with key and iv'); } + +function testCipher3(key, iv) { + // Test encryption and decryption with explicit key and iv. + // AES Key Wrap test vector comes from RFC3394 + const plaintext = Buffer.from('00112233445566778899AABBCCDDEEFF', 'hex'); + + const cipher = crypto.createCipheriv('id-aes128-wrap', key, iv); + let ciph = cipher.update(plaintext, 'utf8', 'buffer'); + ciph = Buffer.concat([ciph, cipher.final('buffer')]); + const ciph2 = Buffer.from('1FA68B0A8112B447AEF34BD8FB5A7B829D3E862371D2CFE5', + 'hex'); + assert(ciph.equals(ciph2)); + const decipher = crypto.createDecipheriv('id-aes128-wrap', key, iv); + let deciph = decipher.update(ciph, 'buffer'); + deciph = Buffer.concat([deciph, decipher.final()]); + + assert(deciph.equals(plaintext), 'encryption/decryption with key and iv'); +} + testCipher1('0123456789abcd0123456789', '12345678'); testCipher1('0123456789abcd0123456789', Buffer.from('12345678')); testCipher1(Buffer.from('0123456789abcd0123456789'), '12345678'); testCipher1(Buffer.from('0123456789abcd0123456789'), Buffer.from('12345678')); testCipher2(Buffer.from('0123456789abcd0123456789'), Buffer.from('12345678')); +if (!common.hasFipsCrypto) { + testCipher3(Buffer.from('000102030405060708090A0B0C0D0E0F', 'hex'), + Buffer.from('A6A6A6A6A6A6A6A6', 'hex')); +} + // Zero-sized IV should be accepted in ECB mode. crypto.createCipheriv('aes-128-ecb', Buffer.alloc(16), Buffer.alloc(0)); From 79171e0c2f16fff17f5ab7a4899b2be0c2574c17 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Sun, 27 Aug 2017 06:31:59 +0200 Subject: [PATCH 020/264] src: turn key length exception into CHECK This exception can logically never happen because of the key stretching that takes place first. Failure must therefore be a bug in Node.js and not in the executing script. Backport-PR-URL: https://github.com/nodejs/node/pull/16585 PR-URL: https://github.com/nodejs/node/pull/15183 Reviewed-By: Colin Ihrig Reviewed-By: James M Snell --- src/node_crypto.cc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 4941d96655a9bf..b4c338aa59c34e 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -3362,10 +3362,7 @@ void CipherBase::Init(const char* cipher_type, if (mode == EVP_CIPH_WRAP_MODE) EVP_CIPHER_CTX_set_flags(&ctx_, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW); - if (!EVP_CIPHER_CTX_set_key_length(&ctx_, key_len)) { - EVP_CIPHER_CTX_cleanup(&ctx_); - return env()->ThrowError("Invalid key length"); - } + CHECK_EQ(1, EVP_CIPHER_CTX_set_key_length(&ctx_, key_len)); EVP_CipherInit_ex(&ctx_, nullptr, From f659e498621164af42a7d7d2d7e3d33e846015f7 Mon Sep 17 00:00:00 2001 From: Sam Roberts Date: Wed, 5 Jul 2017 14:25:55 -0700 Subject: [PATCH 021/264] src: whitelist v8 options with '_' or '-' V8 options allow either '_' or '-' to be used in options as a seperator, such as "--abort-on_uncaught-exception". Allow these case variations when used with NODE_OPTIONS. PR-URL: https://github.com/nodejs/node/pull/14093 Reviewed-By: Richard Lau Reviewed-By: Refael Ackermann Reviewed-By: James M Snell --- doc/api/cli.md | 2 +- src/node.cc | 33 ++++++++++++++++++++------ test/parallel/test-cli-node-options.js | 4 ++++ 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/doc/api/cli.md b/doc/api/cli.md index 41c747c1c3da75..f1b33e883ae883 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -372,7 +372,7 @@ Node options that are allowed are: V8 options that are allowed are: - `--abort-on-uncaught-exception` -- `--max_old_space_size` +- `--max-old-space-size` ### `NODE_REPL_HISTORY=file` diff --git a/src/node.cc b/src/node.cc index 98fde0dbbe3f65..2fd6da0c6f4c37 100644 --- a/src/node.cc +++ b/src/node.cc @@ -3786,15 +3786,34 @@ static void PrintHelp() { } +static bool ArgIsAllowed(const char* arg, const char* allowed) { + for (; *arg && *allowed; arg++, allowed++) { + // Like normal strcmp(), except that a '_' in `allowed` matches either a '-' + // or '_' in `arg`. + if (*allowed == '_') { + if (!(*arg == '_' || *arg == '-')) + return false; + } else { + if (*arg != *allowed) + return false; + } + } + + // "--some-arg=val" is allowed for "--some-arg" + if (*arg == '=') + return true; + + // Both must be null, or one string is just a prefix of the other, not a + // match. + return !*arg && !*allowed; +} + + static void CheckIfAllowedInEnv(const char* exe, bool is_env, const char* arg) { if (!is_env) return; - // Find the arg prefix when its --some_arg=val - const char* eq = strchr(arg, '='); - size_t arglen = eq ? eq - arg : strlen(arg); - static const char* whitelist[] = { // Node options, sorted in `node --help` order for ease of comparison. "--require", "-r", @@ -3820,14 +3839,14 @@ static void CheckIfAllowedInEnv(const char* exe, bool is_env, "--openssl-config", "--icu-data-dir", - // V8 options - "--abort-on-uncaught-exception", + // V8 options (define with '_', which allows '-' or '_') + "--abort_on_uncaught_exception", "--max_old_space_size", }; for (unsigned i = 0; i < arraysize(whitelist); i++) { const char* allowed = whitelist[i]; - if (strlen(allowed) == arglen && strncmp(allowed, arg, arglen) == 0) + if (ArgIsAllowed(arg, allowed)) return; } diff --git a/test/parallel/test-cli-node-options.js b/test/parallel/test-cli-node-options.js index 104473bfa69e34..a1148fd0516703 100644 --- a/test/parallel/test-cli-node-options.js +++ b/test/parallel/test-cli-node-options.js @@ -26,6 +26,7 @@ disallow('--interactive'); disallow('-i'); disallow('--v8-options'); disallow('--'); +disallow('--no_warnings'); // Node options don't allow '_' instead of '-'. function disallow(opt) { const options = {env: {NODE_OPTIONS: opt}}; @@ -43,6 +44,7 @@ const printA = require.resolve('../fixtures/printA.js'); expect(`-r ${printA}`, 'A\nB\n'); expect('--abort-on-uncaught-exception', 'B\n'); +expect('--abort_on_uncaught_exception', 'B\n'); expect('--no-deprecation', 'B\n'); expect('--no-warnings', 'B\n'); expect('--trace-warnings', 'B\n'); @@ -61,6 +63,8 @@ expect('--icu-data-dir=_d', 'B\n'); // V8 options expect('--max_old_space_size=0', 'B\n'); +expect('--max-old_space-size=0', 'B\n'); +expect('--max-old-space-size=0', 'B\n'); function expect(opt, want) { const printB = require.resolve('../fixtures/printB.js'); From ff66d636429149517050ed118b8b8392386875a2 Mon Sep 17 00:00:00 2001 From: Oblosys Date: Thu, 14 Sep 2017 01:31:37 +0200 Subject: [PATCH 022/264] doc: fix emitKeypressEvents stream type PR-URL: https://github.com/nodejs/node/pull/15399 Reviewed-By: Colin Ihrig Reviewed-By: Luigi Pinca Reviewed-By: James M Snell --- doc/api/readline.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/readline.md b/doc/api/readline.md index bccee609ed3e8e..06a8b86205e55c 100644 --- a/doc/api/readline.md +++ b/doc/api/readline.md @@ -446,7 +446,7 @@ added: v0.7.7 * `stream` {Readable} * `interface` {readline.Interface} -The `readline.emitKeypressEvents()` method causes the given [Writable][] +The `readline.emitKeypressEvents()` method causes the given [Readable][] `stream` to begin emitting `'keypress'` events corresponding to received input. Optionally, `interface` specifies a `readline.Interface` instance for which From 8813867577fce95ec57bf3890cdb60a701316acc Mon Sep 17 00:00:00 2001 From: Alex Gresnel <31708810+agresnel@users.noreply.github.com> Date: Sat, 9 Sep 2017 11:44:55 -0700 Subject: [PATCH 023/264] child_process: set shell to false in fork() This commit ensures that spawn()'s shell option is unconditionally set to false when fork() is called. Refs: https://github.com/nodejs/node/pull/15299 Fixes: https://github.com/nodejs/node/issues/13983 PR-URL: https://github.com/nodejs/node/pull/15352 Reviewed-By: James M Snell Reviewed-By: Luigi Pinca Reviewed-By: Richard Lau Reviewed-By: Colin Ihrig --- doc/api/child_process.md | 3 +++ lib/child_process.js | 1 + 2 files changed, 4 insertions(+) diff --git a/doc/api/child_process.md b/doc/api/child_process.md index b3484de5762890..c984004f94b6d2 100644 --- a/doc/api/child_process.md +++ b/doc/api/child_process.md @@ -304,6 +304,9 @@ output on this fd is expected to be line delimited JSON objects. *Note: Unlike the fork(2) POSIX system call, `child_process.fork()` does not clone the current process.* +*Note*: The `shell` option available in [`child_process.spawn()`][] is not +supported by `child_process.fork()` and will be ignored if set. + ### child_process.spawn(command[, args][, options]) \n` + - inc + `\n\n`; - input = input.split(include + '\n').join(includeData[fname] + '\n'); + `${inc}\n\n`; + input = input.split(`${include}\n`).join(`${includeData[fname]}\n`); if (incCount === 0) { return cb(null, input); } From a99755f3fd97e12d36dd548164e6ae0460082dab Mon Sep 17 00:00:00 2001 From: Jimi van der Woning Date: Mon, 6 Nov 2017 17:36:56 +0100 Subject: [PATCH 224/264] test: fix typos in read-buffer tests The offset-exceeding tests for readFloat contained a double test for readFloatLE instead of one for readFloatLE and one for readFloatBE. This is fixed in this commit. PR-URL: https://github.com/nodejs/node/pull/16834 Reviewed-By: Vse Mozhet Byt Reviewed-By: Rich Trott --- test/parallel/test-buffer-read.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/parallel/test-buffer-read.js b/test/parallel/test-buffer-read.js index d3a1c941422e51..5eac575ff5ab81 100644 --- a/test/parallel/test-buffer-read.js +++ b/test/parallel/test-buffer-read.js @@ -59,13 +59,13 @@ read(buf, 'readUIntBE', [2, 0], 0xfd); read(buf, 'readUIntLE', [2, 0], 0x48); // attempt to overflow buffers, similar to previous bug in array buffers -assert.throws(() => Buffer.allocUnsafe(8).readFloatLE(0xffffffff), +assert.throws(() => Buffer.allocUnsafe(8).readFloatBE(0xffffffff), RangeError); assert.throws(() => Buffer.allocUnsafe(8).readFloatLE(0xffffffff), RangeError); // ensure negative values can't get past offset -assert.throws(() => Buffer.allocUnsafe(8).readFloatLE(-1), RangeError); +assert.throws(() => Buffer.allocUnsafe(8).readFloatBE(-1), RangeError); assert.throws(() => Buffer.allocUnsafe(8).readFloatLE(-1), RangeError); // offset checks From f3749d7b2cabcc4a17c73b5dfa443304f4c07241 Mon Sep 17 00:00:00 2001 From: Vse Mozhet Byt Date: Mon, 6 Nov 2017 20:46:06 +0200 Subject: [PATCH 225/264] tools: remove unneeded parentheses in doc/html.js PR-URL: https://github.com/nodejs/node/pull/16845 Ref: https://github.com/nodejs/node/pull/16801#discussion_r149142120 Reviewed-By: Colin Ihrig Reviewed-By: Jeremiah Senkpiel Reviewed-By: Rich Trott --- tools/doc/html.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/doc/html.js b/tools/doc/html.js index 898118d42bf9da..730031471fcc04 100644 --- a/tools/doc/html.js +++ b/tools/doc/html.js @@ -466,7 +466,7 @@ function getId(text) { text = text.replace(/^_+|_+$/, ''); text = text.replace(/^([^a-z])/, '_$1'); if (idCounters.hasOwnProperty(text)) { - text += `_${(++idCounters[text])}`; + text += `_${++idCounters[text]}`; } else { idCounters[text] = 0; } From 9f9e824fc57637c1ee2a0d8ff98cb0a6bc134440 Mon Sep 17 00:00:00 2001 From: Dara Hayes Date: Mon, 6 Nov 2017 15:23:13 +0000 Subject: [PATCH 226/264] test: update test to use fixtures.readKey Use fixtures.readKey() rather than common.fixturesDir in test-regress-GH-1531. PR-URL: https://github.com/nodejs/node/pull/16811 Reviewed-By: Colin Ihrig Reviewed-By: Anatoli Papirovski Reviewed-By: Gireesh Punathil Reviewed-By: Rich Trott --- test/parallel/test-regress-GH-1531.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/test/parallel/test-regress-GH-1531.js b/test/parallel/test-regress-GH-1531.js index 7d1f4a0dbec4c1..a61cc64ab626af 100644 --- a/test/parallel/test-regress-GH-1531.js +++ b/test/parallel/test-regress-GH-1531.js @@ -1,16 +1,20 @@ 'use strict'; const common = require('../common'); +// This test ensures that a http request callback is called +// when the agent option is set +// See https://github.com/nodejs/node-v0.x-archive/issues/1531 + if (!common.hasCrypto) common.skip('missing crypto'); -const https = require('https'); +const fixtures = require('../common/fixtures'); -const fs = require('fs'); +const https = require('https'); const options = { - key: fs.readFileSync(`${common.fixturesDir}/keys/agent1-key.pem`), - cert: fs.readFileSync(`${common.fixturesDir}/keys/agent1-cert.pem`) + key: fixtures.readKey('agent1-key.pem'), + cert: fixtures.readKey('agent1-cert.pem') }; const server = https.createServer(options, function(req, res) { From 54d4557199159aa1338ae63411c15a7631fc631e Mon Sep 17 00:00:00 2001 From: "Maring, Damian Lion" Date: Mon, 6 Nov 2017 15:06:30 +0000 Subject: [PATCH 227/264] test: use fixtures module in test-repl PR-URL: https://github.com/nodejs/node/pull/16809 Reviewed-By: Rich Trott Reviewed-By: Gireesh Punathil --- test/parallel/test-repl.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/parallel/test-repl.js b/test/parallel/test-repl.js index 3b705f7b6be97f..44cd7f3383caeb 100644 --- a/test/parallel/test-repl.js +++ b/test/parallel/test-repl.js @@ -1,6 +1,7 @@ 'use strict'; const common = require('../common'); +const fixtures = require('../common/fixtures'); const assert = require('assert'); common.globalCheck = false; @@ -20,7 +21,7 @@ let server_tcp, server_unix, client_tcp, client_unix, replServer; // absolute path to test/fixtures/a.js -const moduleFilename = require('path').join(common.fixturesDir, 'a'); +const moduleFilename = fixtures.path('a'); console.error('repl test'); From 3d8b3f7b4aeacfd49ded5aed3f674e439c174426 Mon Sep 17 00:00:00 2001 From: Brian O'Connell Date: Mon, 6 Nov 2017 15:15:14 +0000 Subject: [PATCH 228/264] test: refactor tls test to use fixtres.readSync PR-URL: https://github.com/nodejs/node/pull/16816 Reviewed-By: Colin Ihrig Reviewed-By: Gireesh Punathil --- test/parallel/test-tls-hello-parser-failure.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/test/parallel/test-tls-hello-parser-failure.js b/test/parallel/test-tls-hello-parser-failure.js index a6659d4578bc9b..9d9f8c77716b64 100644 --- a/test/parallel/test-tls-hello-parser-failure.js +++ b/test/parallel/test-tls-hello-parser-failure.js @@ -1,6 +1,10 @@ 'use strict'; const common = require('../common'); +const fixtures = require('../common/fixtures'); + +// This test ensures that the tls parser causes a client error if the client +// sends invalid data. if (!common.hasCrypto) common.skip('missing crypto'); @@ -9,11 +13,10 @@ const assert = require('assert'); const tls = require('tls'); const net = require('net'); -const fs = require('fs'); const options = { - key: fs.readFileSync(`${common.fixturesDir}/test_key.pem`), - cert: fs.readFileSync(`${common.fixturesDir}/test_cert.pem`) + key: fixtures.readSync('test_key.pem'), + cert: fixtures.readSync('test_cert.pem') }; const bonkers = Buffer.alloc(1024 * 1024, 42); From dd558a56af26c4bfda0783f9ca24dcc3ed2eed6c Mon Sep 17 00:00:00 2001 From: Sascha Tandel Date: Mon, 6 Nov 2017 15:19:09 +0000 Subject: [PATCH 229/264] test: include file mode in assert message If the REPL history file is created with an invalid mode include the failed mode in the error message. PR-URL: https://github.com/nodejs/node/pull/16815 Reviewed-By: Gireesh Punathil Reviewed-By: Joyee Cheung --- test/parallel/test-repl-history-perm.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/parallel/test-repl-history-perm.js b/test/parallel/test-repl-history-perm.js index 81c4b50d6a1adf..773e91ac1bede2 100644 --- a/test/parallel/test-repl-history-perm.js +++ b/test/parallel/test-repl-history-perm.js @@ -1,4 +1,7 @@ 'use strict'; + +// Verifies that the REPL history file is created with mode 0600 + // Flags: --expose_internals const common = require('../common'); @@ -40,9 +43,10 @@ const checkResults = common.mustCall(function(err, r) { r.input.end(); const stat = fs.statSync(replHistoryPath); + const fileMode = stat.mode & 0o777; assert.strictEqual( - stat.mode & 0o777, 0o600, - 'REPL history file should be mode 0600'); + fileMode, 0o600, + `REPL history file should be mode 0600 but was 0${fileMode.toString(8)}`); }); repl.createInternalRepl( From ffbb4e68e85f02aff113fa25a82306c645263217 Mon Sep 17 00:00:00 2001 From: jonask Date: Mon, 6 Nov 2017 17:28:03 +0200 Subject: [PATCH 230/264] test: use default assertion message In test-child-process-spawnsync, the assert.strictEqual() custom message was hiding information about why the test has failed. It just showed what value is expected and in case of failure we want to know which value has caused test to fail. PR-URL: https://github.com/nodejs/node/pull/16819 Reviewed-By: Colin Ihrig Reviewed-By: Gireesh Punathil Reviewed-By: Anatoli Papirovski Reviewed-By: Rich Trott --- test/parallel/test-child-process-spawnsync.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/parallel/test-child-process-spawnsync.js b/test/parallel/test-child-process-spawnsync.js index 77d205f79a414e..91ac346f3ba5cf 100644 --- a/test/parallel/test-child-process-spawnsync.js +++ b/test/parallel/test-child-process-spawnsync.js @@ -7,7 +7,7 @@ const spawnSync = require('child_process').spawnSync; // Echo does different things on Windows and Unix, but in both cases, it does // more-or-less nothing if there are no parameters const ret = spawnSync('sleep', ['0']); -assert.strictEqual(ret.status, 0, 'exit status should be zero'); +assert.strictEqual(ret.status, 0); // Error test when command does not exist const ret_err = spawnSync('command_does_not_exist', ['bar']).error; From cedf8a1cb2aa7bb5bb0136db95b75e277fe9c817 Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Sun, 5 Nov 2017 14:44:43 +0000 Subject: [PATCH 231/264] test: move test-http-keepalive-maxsockets to sequential test-http-keepalive-maxsockets.js will fail if sufficient copies are run at once. Move to sequential. PR-URL: https://github.com/nodejs/node/pull/16777 Reviewed-By: Anatoli Papirovski Reviewed-By: Refael Ackermann Reviewed-By: Colin Ihrig Reviewed-By: Gireesh Punathil Reviewed-By: Yuta Hiroto Reviewed-By: James M Snell --- test/{parallel => sequential}/test-http-keepalive-maxsockets.js | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/{parallel => sequential}/test-http-keepalive-maxsockets.js (100%) diff --git a/test/parallel/test-http-keepalive-maxsockets.js b/test/sequential/test-http-keepalive-maxsockets.js similarity index 100% rename from test/parallel/test-http-keepalive-maxsockets.js rename to test/sequential/test-http-keepalive-maxsockets.js From 3acf156b68a062b712205fe66e77280ed84db068 Mon Sep 17 00:00:00 2001 From: mbornath Date: Mon, 6 Nov 2017 18:01:27 +0100 Subject: [PATCH 232/264] test: remove message argument in cluster setup test In test/parallel/test-cluster-setup-master-cumulative.js: Remove the message parameter to ensure that the compared objects are printed out. Add the original message as a comment above. PR-URL: https://github.com/nodejs/node/pull/16838 Reviewed-By: Colin Ihrig Reviewed-By: Luigi Pinca Reviewed-By: Gireesh Punathil Reviewed-By: Rich Trott --- test/parallel/test-cluster-setup-master-cumulative.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/test/parallel/test-cluster-setup-master-cumulative.js b/test/parallel/test-cluster-setup-master-cumulative.js index 977c89a56aa573..76f66e8fea13dd 100644 --- a/test/parallel/test-cluster-setup-master-cumulative.js +++ b/test/parallel/test-cluster-setup-master-cumulative.js @@ -5,11 +5,8 @@ const cluster = require('cluster'); assert(cluster.isMaster); -assert.deepStrictEqual( - cluster.settings, - {}, - 'cluster.settings should not be initialized until needed' -); +// cluster.settings should not be initialized until needed +assert.deepStrictEqual(cluster.settings, {}); cluster.setupMaster(); assert.deepStrictEqual(cluster.settings, { From c79dd9e3cec33ea38861116389789ed23e2f981a Mon Sep 17 00:00:00 2001 From: cjihrig Date: Sat, 4 Nov 2017 18:05:16 -0400 Subject: [PATCH 233/264] src: CHECK() for argument overflow in Spawn() This commit adds checks for overflow to args and env in Spawn(). It seems extremely unlikely that either of these values would overflow from a valid use case. Fixes: https://github.com/nodejs/node/issues/15622 PR-URL: https://github.com/nodejs/node/pull/16761 Reviewed-By: Gireesh Punathil --- src/process_wrap.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/process_wrap.cc b/src/process_wrap.cc index 0c41723ee77610..dcfda4678383f5 100644 --- a/src/process_wrap.cc +++ b/src/process_wrap.cc @@ -154,6 +154,8 @@ class ProcessWrap : public HandleWrap { if (!argv_v.IsEmpty() && argv_v->IsArray()) { Local js_argv = Local::Cast(argv_v); int argc = js_argv->Length(); + CHECK_GT(argc + 1, 0); // Check for overflow. + // Heap allocate to detect errors. +1 is for nullptr. options.args = new char*[argc + 1]; for (int i = 0; i < argc; i++) { @@ -177,6 +179,7 @@ class ProcessWrap : public HandleWrap { if (!env_v.IsEmpty() && env_v->IsArray()) { Local env_opt = Local::Cast(env_v); int envc = env_opt->Length(); + CHECK_GT(envc + 1, 0); // Check for overflow. options.env = new char*[envc + 1]; // Heap allocated to detect errors. for (int i = 0; i < envc; i++) { node::Utf8Value pair(env->isolate(), env_opt->Get(i)); From 727a0fe6419b7756a16defcca968a923d5ad45e3 Mon Sep 17 00:00:00 2001 From: cjihrig Date: Sat, 4 Nov 2017 10:36:41 -0400 Subject: [PATCH 234/264] doc: update subprocess.killed This commit changes the wording of subprocess.killed to reflect that a child process was successfully signaled, and not necessarily terminated. Fixes: https://github.com/nodejs/node/issues/16747 PR-URL: https://github.com/nodejs/node/pull/16748 Reviewed-By: Luigi Pinca Reviewed-By: Rich Trott Reviewed-By: James M Snell --- doc/api/child_process.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/api/child_process.md b/doc/api/child_process.md index 2859930c730626..a8baf56c69b2ba 100644 --- a/doc/api/child_process.md +++ b/doc/api/child_process.md @@ -904,10 +904,11 @@ added: v0.5.10 --> * {boolean} Set to `true` after `subprocess.kill()` is used to successfully - terminate the child process. + send a signal to the child process. -The `subprocess.killed` property indicates whether the child process was -successfully terminated using `subprocess.kill()`. +The `subprocess.killed` property indicates whether the child process +successfully received a signal from `subprocess.kill()`. The `killed` property +does not indicate that the child process has been terminated. ### subprocess.pid From b3b7858a9731066043f6bc901afd3e04fae6b00a Mon Sep 17 00:00:00 2001 From: woj Date: Mon, 6 Nov 2017 15:24:50 +0000 Subject: [PATCH 235/264] test: replace common.fixtiresDir with fixtures.readKey() Use fixtures module in test/parallel/test-tls-js-stream.js. PR-URL: https://github.com/nodejs/node/pull/16817 Reviewed-By: Rich Trott Reviewed-By: James M Snell --- test/parallel/test-tls-js-stream.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/test/parallel/test-tls-js-stream.js b/test/parallel/test-tls-js-stream.js index 56f62aecfa450f..bfebb06f8727fe 100644 --- a/test/parallel/test-tls-js-stream.js +++ b/test/parallel/test-tls-js-stream.js @@ -1,13 +1,15 @@ 'use strict'; const common = require('../common'); + if (!common.hasCrypto) common.skip('missing crypto'); +const fixtures = require('../common/fixtures'); + const assert = require('assert'); -const tls = require('tls'); -const stream = require('stream'); -const fs = require('fs'); const net = require('net'); +const stream = require('stream'); +const tls = require('tls'); const connected = { client: 0, @@ -15,8 +17,8 @@ const connected = { }; const server = tls.createServer({ - key: fs.readFileSync(`${common.fixturesDir}/keys/agent1-key.pem`), - cert: fs.readFileSync(`${common.fixturesDir}/keys/agent1-cert.pem`) + key: fixtures.readKey('agent1-key.pem'), + cert: fixtures.readKey('agent1-cert.pem') }, function(c) { console.log('new client'); connected.server++; From 8e5b4f543cee4b3e13f5127d86864967149b6c57 Mon Sep 17 00:00:00 2001 From: Adam Jeffery Date: Mon, 6 Nov 2017 15:44:56 +0000 Subject: [PATCH 236/264] test: add values to error message In test-require-extensions-main, include the values that caused the test to fail in the messages reporting the failure. PR-URL: https://github.com/nodejs/node/pull/16831 Reviewed-By: Rich Trott Reviewed-By: Gireesh Punathil --- test/parallel/test-require-extensions-main.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/parallel/test-require-extensions-main.js b/test/parallel/test-require-extensions-main.js index 40a857b8e63614..16fbad6cf7af6e 100644 --- a/test/parallel/test-require-extensions-main.js +++ b/test/parallel/test-require-extensions-main.js @@ -3,11 +3,11 @@ require('../common'); const assert = require('assert'); const fixtures = require('../common/fixtures'); -const fixturesRequire = - require(fixtures.path('require-bin', 'bin', 'req.js')); +const fixturesRequire = require(fixtures.path('require-bin', 'bin', 'req.js')); assert.strictEqual( fixturesRequire, '', - 'test-require-extensions-main failed to import fixture requirements' + 'test-require-extensions-main failed to import fixture requirements: ' + + fixturesRequire ); From 714eb0bc7cc4993900a47bac5cb02babae2e7826 Mon Sep 17 00:00:00 2001 From: Adam Wegrzynek Date: Mon, 6 Nov 2017 16:11:12 +0100 Subject: [PATCH 237/264] test: improve assertion in test-require-dot Include the value that differed from the expected value in an assertion message in test-require-dot. PR-URL: https://github.com/nodejs/node/pull/16805 Reviewed-By: Colin Ihrig Reviewed-By: Gireesh Punathil Reviewed-By: Michael Dawson Reviewed-By: James M Snell Reviewed-By: Rich Trott --- test/parallel/test-require-dot.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/parallel/test-require-dot.js b/test/parallel/test-require-dot.js index e2202efec1df1a..002a7ac988f2a1 100644 --- a/test/parallel/test-require-dot.js +++ b/test/parallel/test-require-dot.js @@ -14,5 +14,8 @@ process.env.NODE_PATH = fixtures.path('module-require', 'relative'); m._initPaths(); const c = require('.'); - -assert.strictEqual(c.value, 42, 'require(".") should honor NODE_PATH'); +assert.strictEqual( + c.value, + 42, + `require(".") should honor NODE_PATH; expected 42, found ${c.value}` +); From 668644008e279630c4285615b4a6a1233ce3eec7 Mon Sep 17 00:00:00 2001 From: Katie Stockton Roberts Date: Wed, 8 Nov 2017 12:28:47 +0000 Subject: [PATCH 238/264] test: improve assert messages in stream test In test-stream-pipe-await-train-manual-resume, include unexpected value in error messages. PR-URL: https://github.com/nodejs/node/pull/16884 Reviewed-By: Anna Henningsen Reviewed-By: Gireesh Punathil Reviewed-By: Rich Trott --- .../test-stream-pipe-await-drain-manual-resume.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/test/parallel/test-stream-pipe-await-drain-manual-resume.js b/test/parallel/test-stream-pipe-await-drain-manual-resume.js index 96360429e58856..68fe95e8a4a3f7 100644 --- a/test/parallel/test-stream-pipe-await-drain-manual-resume.js +++ b/test/parallel/test-stream-pipe-await-drain-manual-resume.js @@ -30,11 +30,13 @@ readable.once('pause', common.mustCall(() => { assert.strictEqual( readable._readableState.awaitDrain, 1, - 'awaitDrain doesn\'t increase' + 'Expected awaitDrain to equal 1 but instead got ' + + `${readable._readableState.awaitDrain}` ); // First pause, resume manually. The next write() to writable will still // return false, because chunks are still being buffered, so it will increase // the awaitDrain counter again. + process.nextTick(common.mustCall(() => { readable.resume(); })); @@ -43,7 +45,8 @@ readable.once('pause', common.mustCall(() => { assert.strictEqual( readable._readableState.awaitDrain, 1, - '.resume() does not reset counter' + '.resume() should not reset the counter but instead got ' + + `${readable._readableState.awaitDrain}` ); // Second pause, handle all chunks from now on. Once all callbacks that // are currently queued up are handled, the awaitDrain drain counter should @@ -64,7 +67,8 @@ writable.on('finish', common.mustCall(() => { assert.strictEqual( readable._readableState.awaitDrain, 0, - 'awaitDrain not 0 after all chunks are written' + 'awaitDrain should equal 0 after all chunks are written but instead got' + + `${readable._readableState.awaitDrain}` ); // Everything okay, all chunks were written. })); From fce790285ff3e1b777ca0984f4512e798d271010 Mon Sep 17 00:00:00 2001 From: Franziska Hinkelmann Date: Tue, 7 Nov 2017 18:22:23 +0100 Subject: [PATCH 239/264] doc: improve documentation for the vm module Add an intro section and example for the vm module. PR-URL: https://github.com/nodejs/node/pull/16867 Reviewed-By: Colin Ihrig Reviewed-By: Gireesh Punathil Reviewed-By: Luigi Pinca --- doc/api/vm.md | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/doc/api/vm.md b/doc/api/vm.md index 592c78148e7040..408a2f4fdfbebb 100644 --- a/doc/api/vm.md +++ b/doc/api/vm.md @@ -7,14 +7,38 @@ The `vm` module provides APIs for compiling and running code within V8 Virtual -Machine contexts. It can be accessed using: +Machine contexts. + +JavaScript code can be compiled and run immediately or +compiled, saved, and run later. + +A common use case is to run the code in a sandboxed environment. +The sandboxed code uses a different V8 Context, meaning that +it has a different global object than the rest of the code. + +One can provide the context by ["contextifying"][contextified] a sandbox +object. The sandboxed code treats any property on the sandbox like a +global variable. Any changes on global variables caused by the sandboxed +code are reflected in the sandbox object. ```js const vm = require('vm'); -``` -JavaScript code can be compiled and run immediately or compiled, saved, and run -later. +const x = 1; + +const sandbox = { x: 2 }; +vm.createContext(sandbox); // Contextify the sandbox. + +const code = 'x += 40; var y = 17;'; +// x and y are global variables in the sandboxed environment. +// Initially, x has the value 2 because that is the value of sandbox.x. +vm.runInContext(code, sandbox); + +console.log(sandbox.x); // 42 +console.log(sandbox.y); // 17 + +console.log(x); // 1; y is not defined. +``` *Note*: The vm module is not a security mechanism. **Do not use it to run untrusted code**. From 2043ce39d51b91543a72f1cd97991f3b36d2b5b3 Mon Sep 17 00:00:00 2001 From: Neil Vass Date: Wed, 8 Nov 2017 12:48:01 +0000 Subject: [PATCH 240/264] test: improve assertion messages Print content of domain stack if it doesn't match expected values PR-URL: https://github.com/nodejs/node/pull/16885 Reviewed-By: James M Snell Reviewed-By: Rich Trott Reviewed-By: Luigi Pinca Reviewed-By: Gireesh Punathil --- test/parallel/test-domain-safe-exit.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/test/parallel/test-domain-safe-exit.js b/test/parallel/test-domain-safe-exit.js index bbc3b2fe22cae8..bf8b9faaa424ce 100644 --- a/test/parallel/test-domain-safe-exit.js +++ b/test/parallel/test-domain-safe-exit.js @@ -1,16 +1,19 @@ 'use strict'; +require('../common'); // Make sure the domain stack doesn't get clobbered by un-matched .exit() -require('../common'); const assert = require('assert'); const domain = require('domain'); +const util = require('util'); const a = domain.create(); const b = domain.create(); a.enter(); // push b.enter(); // push -assert.deepStrictEqual(domain._stack, [a, b], 'b not pushed'); +assert.deepStrictEqual(domain._stack, [a, b], 'Unexpected stack shape ' + + `(domain._stack = ${util.inspect(domain._stack)})`); domain.create().exit(); // no-op -assert.deepStrictEqual(domain._stack, [a, b], 'stack mangled!'); +assert.deepStrictEqual(domain._stack, [a, b], 'Unexpected stack shape ' + + `(domain._stack = ${util.inspect(domain._stack)})`); From 2a1ebae56781280d42bee8c1c29d477103358a3f Mon Sep 17 00:00:00 2001 From: cjihrig Date: Thu, 9 Nov 2017 15:36:04 -0500 Subject: [PATCH 241/264] test: cover vm.runInNewContext() There is currently one if branch missing coverage in lib/vm.js. This commit adds a test to cover the case where the third argument to runInNewContext() is a string. PR-URL: https://github.com/nodejs/node/pull/16906 Reviewed-By: Ben Noordhuis Reviewed-By: Luigi Pinca Reviewed-By: Yuta Hiroto Reviewed-By: James M Snell Reviewed-By: Franziska Hinkelmann --- test/parallel/test-vm-run-in-new-context.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/test/parallel/test-vm-run-in-new-context.js b/test/parallel/test-vm-run-in-new-context.js index 73c1eccd937295..f3b70b3931050a 100644 --- a/test/parallel/test-vm-run-in-new-context.js +++ b/test/parallel/test-vm-run-in-new-context.js @@ -52,3 +52,23 @@ const fn = vm.runInNewContext('(function() { obj.p = {}; })', { obj: {} }); global.gc(); fn(); // Should not crash + +{ + // Verify that providing a custom filename as a string argument works. + const code = 'throw new Error("foo");'; + const file = 'test_file.vm'; + + assert.throws(() => { + vm.runInNewContext(code, {}, file); + }, (err) => { + const lines = err.stack.split('\n'); + + assert.strictEqual(lines[0].trim(), `${file}:1`); + assert.strictEqual(lines[1].trim(), code); + // Skip lines[2] and lines[3]. They're just a ^ and blank line. + assert.strictEqual(lines[4].trim(), 'Error: foo'); + assert.strictEqual(lines[5].trim(), `at ${file}:1:7`); + // The rest of the stack is uninteresting. + return true; + }); +} From a368e5fa63c8f6fe47a1d80ef15cb4ee2465f130 Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Tue, 7 Nov 2017 19:28:06 +0800 Subject: [PATCH 242/264] src: make StreamBase prototype accessors robust This PR makes the prototype accessors added by StreamBase::AddMethods nonenumerable and checks the signatures in the accessors so they throw instead of raising assertions when called with incompatible receivers. They could be enumerated when inspecting the prototype with util.inspect or the inspector protocol. PR-URL: https://github.com/nodejs/node/pull/16860 Reviewed-By: Anna Henningsen Reviewed-By: Ben Noordhuis Reviewed-By: James M Snell Reviewed-By: Colin Ihrig --- src/stream_base-inl.h | 15 ++++++++--- ...-base-prototype-accessors-enumerability.js | 19 +++++++++++++ .../test-stream-base-prototype-accessors.js | 27 +++++++++++++++++++ 3 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 test/parallel/test-stream-base-prototype-accessors-enumerability.js create mode 100644 test/parallel/test-stream-base-prototype-accessors.js diff --git a/src/stream_base-inl.h b/src/stream_base-inl.h index 23a3f6e8cd7c1c..6d857a74ddfdbd 100644 --- a/src/stream_base-inl.h +++ b/src/stream_base-inl.h @@ -11,6 +11,7 @@ namespace node { +using v8::AccessorSignature; using v8::External; using v8::FunctionCallbackInfo; using v8::FunctionTemplate; @@ -29,27 +30,33 @@ void StreamBase::AddMethods(Environment* env, HandleScope scope(env->isolate()); enum PropertyAttribute attributes = - static_cast(v8::ReadOnly | v8::DontDelete); + static_cast( + v8::ReadOnly | v8::DontDelete | v8::DontEnum); + Local signature = + AccessorSignature::New(env->isolate(), t); t->PrototypeTemplate()->SetAccessor(env->fd_string(), GetFD, nullptr, env->as_external(), v8::DEFAULT, - attributes); + attributes, + signature); t->PrototypeTemplate()->SetAccessor(env->external_stream_string(), GetExternal, nullptr, env->as_external(), v8::DEFAULT, - attributes); + attributes, + signature); t->PrototypeTemplate()->SetAccessor(env->bytes_read_string(), GetBytesRead, nullptr, env->as_external(), v8::DEFAULT, - attributes); + attributes, + signature); env->SetProtoMethod(t, "readStart", JSMethod); env->SetProtoMethod(t, "readStop", JSMethod); diff --git a/test/parallel/test-stream-base-prototype-accessors-enumerability.js b/test/parallel/test-stream-base-prototype-accessors-enumerability.js new file mode 100644 index 00000000000000..f59aced197c515 --- /dev/null +++ b/test/parallel/test-stream-base-prototype-accessors-enumerability.js @@ -0,0 +1,19 @@ +'use strict'; + +require('../common'); + +// This tests that the prototype accessors added by StreamBase::AddMethods +// are not enumerable. They could be enumerated when inspecting the prototype +// with util.inspect or the inspector protocol. + +const assert = require('assert'); + +// Or anything that calls StreamBase::AddMethods when setting up its prototype +const TTY = process.binding('tty_wrap').TTY; + +{ + assert.strictEqual(TTY.prototype.propertyIsEnumerable('bytesRead'), false); + assert.strictEqual(TTY.prototype.propertyIsEnumerable('fd'), false); + assert.strictEqual( + TTY.prototype.propertyIsEnumerable('_externalStream'), false); +} diff --git a/test/parallel/test-stream-base-prototype-accessors.js b/test/parallel/test-stream-base-prototype-accessors.js new file mode 100644 index 00000000000000..f9e12582a098d8 --- /dev/null +++ b/test/parallel/test-stream-base-prototype-accessors.js @@ -0,0 +1,27 @@ +'use strict'; + +require('../common'); + +// This tests that the prototype accessors added by StreamBase::AddMethods +// do not raise assersions when called with incompatible receivers. + +const assert = require('assert'); + +// Or anything that calls StreamBase::AddMethods when setting up its prototype +const TTY = process.binding('tty_wrap').TTY; + +// Should throw instead of raise assertions +{ + const msg = /TypeError: Method \w+ called on incompatible receiver/; + assert.throws(() => { + TTY.prototype.bytesRead; + }, msg); + + assert.throws(() => { + TTY.prototype.fd; + }, msg); + + assert.throws(() => { + TTY.prototype._externalStream; + }, msg); +} From 9d4abaa24342ba7dcb6c59421e877820c4608604 Mon Sep 17 00:00:00 2001 From: Tanvi Kini Date: Fri, 10 Nov 2017 05:22:12 +0000 Subject: [PATCH 243/264] test: replace string concatenation with template MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/16913 Reviewed-By: Luigi Pinca Reviewed-By: James M Snell Reviewed-By: Tobias Nießen Reviewed-By: Gireesh Punathil Reviewed-By: Colin Ihrig Reviewed-By: Franziska Hinkelmann --- test/fixtures/guess-hash-seed.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/fixtures/guess-hash-seed.js b/test/fixtures/guess-hash-seed.js index c0d072b23d2e48..18a6f5124dc1d8 100644 --- a/test/fixtures/guess-hash-seed.js +++ b/test/fixtures/guess-hash-seed.js @@ -134,7 +134,7 @@ const slow_str_gen = (function*() { let strgen_i = 0; outer: while (1) { - const str = '#' + (strgen_i++); + const str = `#${strgen_i++}`; for (let i = 0; i < 1000; i++) { if (time_set_lookup(tester_set, str) < tester_set_treshold) continue outer; From 969defaae9a5670e3760d58635d69d0c97ba7d16 Mon Sep 17 00:00:00 2001 From: Vipin Menon Date: Fri, 10 Nov 2017 12:00:09 +0530 Subject: [PATCH 244/264] test: enable mustCall() during child exit PR-URL: https://github.com/nodejs/node/pull/16915 Reviewed-By: Khaidi Chu Reviewed-By: Gireesh Punathil Reviewed-By: James M Snell Reviewed-By: Colin Ihrig Reviewed-By: Anatoli Papirovski Reviewed-By: Franziska Hinkelmann --- test/parallel/test-process-raw-debug.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/parallel/test-process-raw-debug.js b/test/parallel/test-process-raw-debug.js index 23163654d88c79..b9dbb8a2de9490 100644 --- a/test/parallel/test-process-raw-debug.js +++ b/test/parallel/test-process-raw-debug.js @@ -1,5 +1,5 @@ 'use strict'; -require('../common'); +const common = require('../common'); const assert = require('assert'); const os = require('os'); @@ -29,10 +29,10 @@ function parent() { console.log('ok - got expected message'); }); - child.on('exit', function(c) { + child.on('exit', common.mustCall(function(c) { assert(!c); console.log('ok - child exited nicely'); - }); + })); } function child() { From 674cbf840230eaec33dbb0e4aa61764eded90c77 Mon Sep 17 00:00:00 2001 From: Kabir Islam Date: Fri, 10 Nov 2017 12:20:28 +0530 Subject: [PATCH 245/264] test: replace string concatenation with template MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/16916 Reviewed-By: Vse Mozhet Byt Reviewed-By: James M Snell Reviewed-By: Daniel Bevenius Reviewed-By: Tobias Nießen Reviewed-By: Gireesh Punathil Reviewed-By: Colin Ihrig Reviewed-By: Franziska Hinkelmann --- test/fixtures/cluster-preload-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/fixtures/cluster-preload-test.js b/test/fixtures/cluster-preload-test.js index 43d3887b0daf01..1bc6c29fb7aa5e 100644 --- a/test/fixtures/cluster-preload-test.js +++ b/test/fixtures/cluster-preload-test.js @@ -2,6 +2,6 @@ var cluster = require('cluster'); if (cluster.isMaster) { cluster.fork(); // one child cluster.on('exit', function(worker, code, signal) { - console.log('worker terminated with code ' + code); + console.log(`worker terminated with code ${code}`); }); } From 2232231d4f69c3428167079eec37d024fd36c3f3 Mon Sep 17 00:00:00 2001 From: Suryanarayana Murthy N Date: Fri, 10 Nov 2017 13:36:00 +0530 Subject: [PATCH 246/264] test: change string concatenation to template MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/16919 Reviewed-By: James M Snell Reviewed-By: Tobias Nießen Reviewed-By: Colin Ihrig Reviewed-By: Gireesh Punathil Reviewed-By: Franziska Hinkelmann --- test/fixtures/print-10-lines.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/fixtures/print-10-lines.js b/test/fixtures/print-10-lines.js index 0aaf3ef293000e..8971e0c5bbcff8 100644 --- a/test/fixtures/print-10-lines.js +++ b/test/fixtures/print-10-lines.js @@ -1,3 +1,3 @@ for (var i = 0; i < 10; i++) { - console.log('count ' + i); + console.log(`count ${i}`); } From 79dfc3f47559df180a9f4656954ff5079680dfd9 Mon Sep 17 00:00:00 2001 From: Anawesha Khuntia Date: Fri, 10 Nov 2017 10:54:32 +0530 Subject: [PATCH 247/264] test: change concatenated string to template MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/16912 Reviewed-By: Gireesh Punathil Reviewed-By: Vse Mozhet Byt Reviewed-By: James M Snell Reviewed-By: Tobias Nießen Reviewed-By: Colin Ihrig Reviewed-By: Franziska Hinkelmann --- test/fixtures/loop.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/fixtures/loop.js b/test/fixtures/loop.js index e91b831d01b816..461fb393583e68 100644 --- a/test/fixtures/loop.js +++ b/test/fixtures/loop.js @@ -4,7 +4,7 @@ console.log('A message', 5); while (t > 0) { if (t++ === 1000) { t = 0; - console.log('Outputed message #' + k++); + console.log(`Outputed message #${k++}`); } } process.exit(55); From 1d3793eb77e53b38500dc6eeea3d84e3575da7f1 Mon Sep 17 00:00:00 2001 From: Deepthi Sebastian Date: Fri, 10 Nov 2017 17:57:00 +0530 Subject: [PATCH 248/264] test: change concatenated string to template MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/16929 Reviewed-By: Vse Mozhet Byt Reviewed-By: Tobias Nießen Reviewed-By: Colin Ihrig Reviewed-By: James M Snell Reviewed-By: Anatoli Papirovski Reviewed-By: Gireesh Punathil Reviewed-By: Franziska Hinkelmann --- test/fixtures/net-fd-passing-receiver.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/fixtures/net-fd-passing-receiver.js b/test/fixtures/net-fd-passing-receiver.js index 0dba242766a62b..fb4faee1264464 100644 --- a/test/fixtures/net-fd-passing-receiver.js +++ b/test/fixtures/net-fd-passing-receiver.js @@ -15,12 +15,12 @@ receiver = net.createServer(function(socket) { }); passedSocket.on('data', function(data) { - passedSocket.send('[echo] ' + data); + passedSocket.send(`[echo] ${data}`); }); passedSocket.on('close', function() { receiver.close(); }); - passedSocket.send('[greeting] ' + greeting); + passedSocket.send(`[greeting] ${greeting}`); }); }); From 090cc9713e1e0f7950d56ccd5c3eec5d71917d02 Mon Sep 17 00:00:00 2001 From: Stephan Smith Date: Mon, 6 Nov 2017 15:42:01 +0000 Subject: [PATCH 249/264] test: improve template value for test message Include value that cause failure in error message in test-cluster-master-kill.js. PR-URL: https://github.com/nodejs/node/pull/16826 Reviewed-By: Gireesh Punathil Reviewed-By: James M Snell Reviewed-By: Rich Trott --- test/parallel/test-cluster-master-kill.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/parallel/test-cluster-master-kill.js b/test/parallel/test-cluster-master-kill.js index 98ed0d22aa9cfd..6ad8eb9e43f727 100644 --- a/test/parallel/test-cluster-master-kill.js +++ b/test/parallel/test-cluster-master-kill.js @@ -60,7 +60,8 @@ if (cluster.isWorker) { process.once('exit', () => { assert.strictEqual(typeof pid, 'number', `got ${pid} instead of a worker pid`); - assert.strictEqual(alive, false, 'worker was alive after master died'); + assert.strictEqual(alive, false, + `worker was alive after master died (alive = ${alive})`); }); } From a8cff7ad4a77c0c72ba86a9c1e20df7fa5738f01 Mon Sep 17 00:00:00 2001 From: Javier Blanco Date: Mon, 6 Nov 2017 15:13:30 +0000 Subject: [PATCH 250/264] test: use common/fixtures module in hash-seed test Replace `common.fixturesDir` with `fixtures.path()` usage in test/pummel/test-hash-seed.js. PR-URL: https://github.com/nodejs/node/pull/16823 Reviewed-By: Joyee Cheung Reviewed-By: Gireesh Punathil Reviewed-By: James M Snell --- test/pummel/test-hash-seed.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/test/pummel/test-hash-seed.js b/test/pummel/test-hash-seed.js index 05d29fff0b8b90..fd59bbe5e0653c 100644 --- a/test/pummel/test-hash-seed.js +++ b/test/pummel/test-hash-seed.js @@ -1,20 +1,20 @@ 'use strict'; +// Check that spawn child doesn't create duplicated entries +require('../common'); const REPETITIONS = 2; - const assert = require('assert'); -const common = require('../common'); -const cp = require('child_process'); -const path = require('path'); -const targetScript = path.resolve(common.fixturesDir, 'guess-hash-seed.js'); +const fixtures = require('../common/fixtures'); +const { spawnSync } = require('child_process'); +const targetScript = fixtures.path('guess-hash-seed.js'); const seeds = []; for (let i = 0; i < REPETITIONS; ++i) { - const seed = cp.spawnSync(process.execPath, [targetScript], - { encoding: 'utf8' }).stdout.trim(); + const seed = spawnSync(process.execPath, [targetScript], { + encoding: 'utf8' + }).stdout.trim(); seeds.push(seed); } console.log(`Seeds: ${seeds}`); -const hasDuplicates = (new Set(seeds)).size !== seeds.length; -assert.strictEqual(hasDuplicates, false); +assert.strictEqual(new Set(seeds).size, seeds.length); From 4583f1be0c602336ddf02c703aabf0f247f14ec9 Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Sun, 1 Oct 2017 08:33:55 -0700 Subject: [PATCH 251/264] doc: reorganize COLLABORATOR_GUIDE.md Based on feedback during a recent collaborator onboarding, move the metadata description closer to where the instructions for editing a commit message are. Indicate which metadata are required and which are optional. Make the punctuation more consistent. Previously, sentences prior to instructions ended in a period, a colon, or no punctuation at all. Colon seems best, so changed the Technical How-To section to use colons. PR-URL: https://github.com/nodejs/node/pull/15710 Reviewed-By: Vse Mozhet Byt Reviewed-By: Benedikt Meurer Reviewed-By: Luigi Pinca Reviewed-By: James M Snell Reviewed-By: Refael Ackermann --- COLLABORATOR_GUIDE.md | 60 +++++++++++++++++++++++-------------------- doc/onboarding.md | 2 +- 2 files changed, 33 insertions(+), 29 deletions(-) diff --git a/COLLABORATOR_GUIDE.md b/COLLABORATOR_GUIDE.md index 3e1b058ac57c75..9788e9f05f72a4 100644 --- a/COLLABORATOR_GUIDE.md +++ b/COLLABORATOR_GUIDE.md @@ -365,25 +365,11 @@ The TSC should serve as the final arbiter where required. * If more than one author has contributed to the PR, keep the most recent author when squashing. -Always modify the original commit message to include additional meta -information regarding the change process: - -- A `PR-URL:` line that references the *full* GitHub URL of the original - pull request being merged so it's easy to trace a commit back to the - conversation that led up to that change. -- A `Fixes: X` line, where _X_ either includes the *full* GitHub URL - for an issue, and/or the hash and commit message if the commit fixes - a bug in a previous commit. Multiple `Fixes:` lines may be added if - appropriate. -- A `Refs:` line referencing a URL for any relevant background. -- A `Reviewed-By: Name ` line for yourself and any - other Collaborators who have reviewed the change. - - Useful for @mentions / contact list if something goes wrong in the PR. - - Protects against the assumption that GitHub will be around forever. - Review the commit message to ensure that it adheres to the guidelines outlined in the [contributing](./CONTRIBUTING.md#commit-message-guidelines) guide. +Add all necessary [metadata](#metadata) to commit messages before landing. + See the commit log for examples such as [this one](https://github.com/nodejs/node/commit/b636ba8186) if unsure exactly how to format your commit messages. @@ -391,34 +377,33 @@ exactly how to format your commit messages. Additionally: - Double check PRs to make sure the person's _full name_ and email address are correct before merging. -- Except when updating dependencies, all commits should be self - contained (meaning every commit should pass all tests). This makes - it much easier when bisecting to find a breaking change. +- All commits should be self-contained (meaning every commit should pass all + tests). This makes it much easier when bisecting to find a breaking change. ### Technical HOWTO -Clear any `am`/`rebase` that may already be underway. +Clear any `am`/`rebase` that may already be underway: ```text $ git am --abort $ git rebase --abort ``` -Checkout proper target branch +Checkout proper target branch: ```text $ git checkout master ``` Update the tree (assumes your repo is set up as detailed in -[CONTRIBUTING.md](CONTRIBUTING.md#step-1-fork)) +[CONTRIBUTING.md](CONTRIBUTING.md#step-1-fork)): ```text $ git fetch upstream $ git merge --ff-only upstream/master ``` -Apply external patches +Apply external patches: ```text $ curl -L https://github.com/nodejs/node/pull/xxx.patch | git am --whitespace=fix @@ -436,21 +421,19 @@ against the original PR carefully and build/test on at least one platform before landing. If the 3-way merge fails, then it is most likely that a conflicting PR has landed since the CI run and you will have to ask the author to rebase. -Check and re-review the changes +Check and re-review the changes: ```text $ git diff upstream/master ``` -Check number of commits and commit messages +Check number of commits and commit messages: ```text $ git log upstream/master...master ``` -If there are multiple commits that relate to the same feature or -one with a feature and separate with a test for that feature, -you'll need to use `squash` or `fixup`: +Squash commits and add metadata: ```text $ git rebase -i upstream/master @@ -506,9 +489,29 @@ Save the file and close the editor. You'll be asked to enter a new commit message for that commit. This is a good moment to fix incorrect commit logs, ensure that they are properly formatted, and add `Reviewed-By` lines. + * The commit message text must conform to the [commit message guidelines](./CONTRIBUTING.md#commit-message-guidelines). + +* Modify the original commit message to include additional metadata regarding + the change process. (If you use Chrome or Edge, [`node-review`][] fetches + the metadata for you.) + + * Required: A `PR-URL:` line that references the *full* GitHub URL of the + original pull request being merged so it's easy to trace a commit back to + the conversation that led up to that change. + * Optional: A `Fixes: X` line, where _X_ either includes the *full* GitHub URL + for an issue, and/or the hash and commit message if the commit fixes + a bug in a previous commit. Multiple `Fixes:` lines may be added if + appropriate. + * Optional: One or more `Refs:` lines referencing a URL for any relevant + background. + * Required: A `Reviewed-By: Name ` line for yourself and any + other Collaborators who have reviewed the change. + * Useful for @mentions / contact list if something goes wrong in the PR. + * Protects against the assumption that GitHub will be around forever. + Run tests (`make -j4 test` or `vcbuild test`). Even though there was a successful continuous integration run, other changes may have landed on master since then, so running the tests one last time locally is a good practice. @@ -672,3 +675,4 @@ LTS working group and the Release team. [Stability Index]: doc/api/documentation.md#stability-index [Enhancement Proposal]: https://github.com/nodejs/node-eps [git-username]: https://help.github.com/articles/setting-your-username-in-git/ +[`node-review`]: https://github.com/evanlucas/node-review diff --git a/doc/onboarding.md b/doc/onboarding.md index d028803aa0ef80..41df0d00bd93b3 100644 --- a/doc/onboarding.md +++ b/doc/onboarding.md @@ -158,7 +158,7 @@ onboarding session. * After one or two approvals, land the PR. * Be sure to add the `PR-URL: ` and appropriate `Reviewed-By:` metadata! * [`core-validate-commit`][] helps a lot with this – install and use it if you can! - * If you use Chrome, [`node-review`][] fetches the metadata for you + * If you use Chrome or Edge, [`node-review`][] fetches the metadata for you. ## Final notes From 5e2231e40717e0fef47f71016ca9ba43e8706a4e Mon Sep 17 00:00:00 2001 From: Grant Gasparyan Date: Mon, 6 Nov 2017 17:37:28 +0100 Subject: [PATCH 252/264] test: add a test description PR-URL: https://github.com/nodejs/node/pull/16833 Reviewed-By: James M Snell Reviewed-By: Rich Trott Reviewed-By: Vse Mozhet Byt Reviewed-By: Gireesh Punathil --- test/parallel/test-cluster-fork-env.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/parallel/test-cluster-fork-env.js b/test/parallel/test-cluster-fork-env.js index 112aeb087c49a1..faa8b954e4443c 100644 --- a/test/parallel/test-cluster-fork-env.js +++ b/test/parallel/test-cluster-fork-env.js @@ -1,5 +1,10 @@ 'use strict'; require('../common'); + +// This test checks that arguments provided to cluster.fork() will create +// new environment variables and override existing environment variables +// in the created worker process. + const assert = require('assert'); const cluster = require('cluster'); From f226ca6b1222a0e70da65ebb89b79b09f69a6eb2 Mon Sep 17 00:00:00 2001 From: Klemen Kogovsek Date: Mon, 6 Nov 2017 15:05:59 +0000 Subject: [PATCH 253/264] test: used fixturesDir from fixtures modules In test-fs-realpath-on-substed-drive, require common/fixtures module and swapped the location of fixturesDir from common to fixtures module. PR-URL: https://github.com/nodejs/node/pull/16813 Reviewed-By: James M Snell Reviewed-By: Rich Trott Reviewed-By: Gireesh Punathil --- test/parallel/test-fs-realpath-on-substed-drive.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/parallel/test-fs-realpath-on-substed-drive.js b/test/parallel/test-fs-realpath-on-substed-drive.js index 7a871b7e59807c..88fa04c2ced646 100644 --- a/test/parallel/test-fs-realpath-on-substed-drive.js +++ b/test/parallel/test-fs-realpath-on-substed-drive.js @@ -4,6 +4,8 @@ const common = require('../common'); if (!common.isWindows) common.skip('Test for Windows only'); +const fixtures = require('../common/fixtures'); + const assert = require('assert'); const fs = require('fs'); const spawnSync = require('child_process').spawnSync; @@ -16,7 +18,7 @@ let drive; let i; for (i = 0; i < driveLetters.length; ++i) { drive = `${driveLetters[i]}:`; - result = spawnSync('subst', [drive, common.fixturesDir]); + result = spawnSync('subst', [drive, fixtures.fixturesDir]); if (result.status === 0) break; } From 1bc5c3836c071390121d8d552d100d9c155b2c05 Mon Sep 17 00:00:00 2001 From: Rich Trott Date: Sun, 12 Nov 2017 16:29:27 -0800 Subject: [PATCH 254/264] doc: recommend node-core-utils for metadata MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/16978 Reviewed-By: Gireesh Punathil Reviewed-By: Luigi Pinca Reviewed-By: Khaidi Chu Reviewed-By: Colin Ihrig Reviewed-By: Tobias Nießen Reviewed-By: Anatoli Papirovski Reviewed-By: James M Snell --- COLLABORATOR_GUIDE.md | 5 ++--- doc/onboarding.md | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/COLLABORATOR_GUIDE.md b/COLLABORATOR_GUIDE.md index 9788e9f05f72a4..8f84f6f9f78baa 100644 --- a/COLLABORATOR_GUIDE.md +++ b/COLLABORATOR_GUIDE.md @@ -495,8 +495,7 @@ commit logs, ensure that they are properly formatted, and add * Modify the original commit message to include additional metadata regarding - the change process. (If you use Chrome or Edge, [`node-review`][] fetches - the metadata for you.) + the change process. ([`node-core-utils`][] fetches the metadata for you.) * Required: A `PR-URL:` line that references the *full* GitHub URL of the original pull request being merged so it's easy to trace a commit back to @@ -675,4 +674,4 @@ LTS working group and the Release team. [Stability Index]: doc/api/documentation.md#stability-index [Enhancement Proposal]: https://github.com/nodejs/node-eps [git-username]: https://help.github.com/articles/setting-your-username-in-git/ -[`node-review`]: https://github.com/evanlucas/node-review +[`node-core-utils`]: https://github.com/nodejs/node-core-utils diff --git a/doc/onboarding.md b/doc/onboarding.md index 41df0d00bd93b3..09cbb432a2bb85 100644 --- a/doc/onboarding.md +++ b/doc/onboarding.md @@ -158,7 +158,7 @@ onboarding session. * After one or two approvals, land the PR. * Be sure to add the `PR-URL: ` and appropriate `Reviewed-By:` metadata! * [`core-validate-commit`][] helps a lot with this – install and use it if you can! - * If you use Chrome or Edge, [`node-review`][] fetches the metadata for you. + * [`node-core-utils`][] fetches the metadata for you. ## Final notes @@ -180,4 +180,4 @@ onboarding session. [Code of Conduct]: https://github.com/nodejs/TSC/blob/master/CODE_OF_CONDUCT.md [`core-validate-commit`]: https://github.com/evanlucas/core-validate-commit -[`node-review`]: https://github.com/evanlucas/node-review +[`node-core-utils`]: https://github.com/nodejs/node-core-utils From 4752fc4336fcc1bc202d2ae65828aa3d467eafb9 Mon Sep 17 00:00:00 2001 From: ChrBergert Date: Mon, 6 Nov 2017 16:04:36 +0000 Subject: [PATCH 255/264] test: refactor comments in test-child-process-spawnsync-maxbuf * remove comment that isn't relevant/important * add comment that explains what the test does PR-URL: https://github.com/nodejs/node/pull/16829 Reviewed-By: Rich Trott Reviewed-By: Joyee Cheung Reviewed-By: Luigi Pinca Reviewed-By: James M Snell --- test/parallel/test-child-process-spawnsync-maxbuf.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/parallel/test-child-process-spawnsync-maxbuf.js b/test/parallel/test-child-process-spawnsync-maxbuf.js index 665cfd11bd2224..276308b7502cbd 100644 --- a/test/parallel/test-child-process-spawnsync-maxbuf.js +++ b/test/parallel/test-child-process-spawnsync-maxbuf.js @@ -1,12 +1,14 @@ 'use strict'; require('../common'); + +// This test checks that the maxBuffer option for child_process.spawnSync() +// works as expected. + const assert = require('assert'); const spawnSync = require('child_process').spawnSync; const msgOut = 'this is stdout'; - -// This is actually not os.EOL? const msgOutBuf = Buffer.from(`${msgOut}\n`); const args = [ From f0eeddb4b8c87f22fb3f330fbbd78021964c6682 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Nie=C3=9Fen?= Date: Fri, 10 Nov 2017 18:27:35 +0100 Subject: [PATCH 256/264] test: reuse existing PassThrough implementation PR-URL: https://github.com/nodejs/node/pull/16936 Reviewed-By: Colin Ihrig Reviewed-By: Refael Ackermann Reviewed-By: Anna Henningsen Reviewed-By: James M Snell Reviewed-By: Luigi Pinca --- test/parallel/test-stream-big-packet.js | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/test/parallel/test-stream-big-packet.js b/test/parallel/test-stream-big-packet.js index 09ed825036f2e4..9a5828f1fa7230 100644 --- a/test/parallel/test-stream-big-packet.js +++ b/test/parallel/test-stream-big-packet.js @@ -5,13 +5,6 @@ const stream = require('stream'); let passed = false; -class PassThrough extends stream.Transform { - _transform(chunk, encoding, done) { - this.push(chunk); - done(); - } -} - class TestStream extends stream.Transform { _transform(chunk, encoding, done) { if (!passed) { @@ -22,8 +15,8 @@ class TestStream extends stream.Transform { } } -const s1 = new PassThrough(); -const s2 = new PassThrough(); +const s1 = new stream.PassThrough(); +const s2 = new stream.PassThrough(); const s3 = new TestStream(); s1.pipe(s3); // Don't let s2 auto close which may close s3 From 925e58fecb87ed0f2f8361199dccc50165856fdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=C3=A1ng=20J=C3=B9nli=C3=A0ng?= Date: Fri, 3 Nov 2017 13:03:11 +0800 Subject: [PATCH 257/264] fs: fix stat dev unsigned cast overflow The `dev_t` is unsigned on Linux, use Integer::NewFromUnsigned to fix cast overflow PR-URL: https://github.com/nodejs/node/pull/16705 Fixes: https://github.com/nodejs/node/issues/16496 Reviewed-By: Ben Noordhuis Reviewed-By: Colin Ihrig Reviewed-By: James M Snell Reviewed-By: Khaidi Chu Reviewed-By: Benjamin Gruenbaum --- src/node_file.cc | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/node_file.cc b/src/node_file.cc index 40a9d65627dc42..914f2dbbd0b39d 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -451,14 +451,6 @@ Local BuildStatsObject(Environment* env, const uv_stat_t* s) { # else Local blksize = Undefined(env->isolate()); # endif -#undef X - - // Integers. -#define X(name) \ - Local name = Integer::New(env->isolate(), s->st_##name); \ - if (name.IsEmpty()) \ - return Local(); \ - X(dev) X(mode) X(nlink) From 644989cf6a8355d66e178a20cf163381fd69dbb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hu=C3=A1ng=20J=C3=B9nli=C3=A0ng?= Date: Fri, 3 Nov 2017 13:29:31 +0800 Subject: [PATCH 258/264] fs: use Number::New since all fields are uint64_t PR-URL: https://github.com/nodejs/node/pull/16705 Reviewed-By: Ben Noordhuis Reviewed-By: Colin Ihrig Reviewed-By: James M Snell Reviewed-By: Khaidi Chu Reviewed-By: Benjamin Gruenbaum --- src/node_file.cc | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/src/node_file.cc b/src/node_file.cc index 914f2dbbd0b39d..df58157d129b7e 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -436,39 +436,26 @@ Local BuildStatsObject(Environment* env, const uv_stat_t* s) { // We need to check the return value of Number::New() and Date::New() // and make sure that we bail out when V8 returns an empty handle. - // Unsigned integers. It does not actually seem to be specified whether - // uid and gid are unsigned or not, but in practice they are unsigned, - // and Node’s (F)Chown functions do check their arguments for unsignedness. + // Numbers. #define X(name) \ - Local name = Integer::NewFromUnsigned(env->isolate(), s->st_##name); \ + Local name = Number::New(env->isolate(), \ + static_cast(s->st_##name)); \ if (name.IsEmpty()) \ return Local(); \ X(uid) X(gid) -# if defined(__POSIX__) - X(blksize) -# else - Local blksize = Undefined(env->isolate()); -# endif + X(ino) + X(size) X(dev) X(mode) X(nlink) X(rdev) -#undef X - - // Numbers. -#define X(name) \ - Local name = Number::New(env->isolate(), \ - static_cast(s->st_##name)); \ - if (name.IsEmpty()) \ - return Local(); \ - - X(ino) - X(size) # if defined(__POSIX__) + X(blksize) X(blocks) # else + Local blksize = Undefined(env->isolate()); Local blocks = Undefined(env->isolate()); # endif #undef X From 6269ba334d4c1848efcf7fa436d6d3951838e87e Mon Sep 17 00:00:00 2001 From: Daniel Bevenius Date: Tue, 17 Oct 2017 07:27:07 +0200 Subject: [PATCH 259/264] test: allow tests to pass without internet Currently when running the test without an internet connection there are two JavaScript test failures This commit moves the two JavaScript tests to test/internet. Backport-PR-URL: https://github.com/nodejs/node/pull/17171 PR-URL: https://github.com/nodejs/node/pull/16255 Reviewed-By: Anna Henningsen Reviewed-By: James M Snell --- test/internet/test-dgram-membership.js | 37 ++++++++++++++++++++++++++ test/parallel/test-dgram-membership.js | 29 -------------------- 2 files changed, 37 insertions(+), 29 deletions(-) create mode 100644 test/internet/test-dgram-membership.js diff --git a/test/internet/test-dgram-membership.js b/test/internet/test-dgram-membership.js new file mode 100644 index 00000000000000..97bc1e648ad79e --- /dev/null +++ b/test/internet/test-dgram-membership.js @@ -0,0 +1,37 @@ +'use strict'; + +require('../common'); +const assert = require('assert'); +const dgram = require('dgram'); +const multicastAddress = '224.0.0.114'; + +const setup = dgram.createSocket.bind(dgram, { type: 'udp4', reuseAddr: true }); + +// addMembership() with valid socket and multicast address should not throw +{ + const socket = setup(); + assert.doesNotThrow(() => { socket.addMembership(multicastAddress); }); + socket.close(); +} + +// dropMembership() without previous addMembership should throw +{ + const socket = setup(); + assert.throws( + () => { socket.dropMembership(multicastAddress); }, + /^Error: dropMembership EADDRNOTAVAIL$/ + ); + socket.close(); +} + +// dropMembership() after addMembership() should not throw +{ + const socket = setup(); + assert.doesNotThrow( + () => { + socket.addMembership(multicastAddress); + socket.dropMembership(multicastAddress); + } + ); + socket.close(); +} diff --git a/test/parallel/test-dgram-membership.js b/test/parallel/test-dgram-membership.js index 1543b9043f7738..0ecc3d59b5e92a 100644 --- a/test/parallel/test-dgram-membership.js +++ b/test/parallel/test-dgram-membership.js @@ -56,32 +56,3 @@ const setup = dgram.createSocket.bind(dgram, {type: 'udp4', reuseAddr: true}); /^Error: dropMembership EINVAL$/); socket.close(); } - -// addMembership() with valid socket and multicast address should not throw -{ - const socket = setup(); - assert.doesNotThrow(() => { socket.addMembership(multicastAddress); }); - socket.close(); -} - -// dropMembership() without previous addMembership should throw -{ - const socket = setup(); - assert.throws( - () => { socket.dropMembership(multicastAddress); }, - /^Error: dropMembership EADDRNOTAVAIL$/ - ); - socket.close(); -} - -// dropMembership() after addMembership() should not throw -{ - const socket = setup(); - assert.doesNotThrow( - () => { - socket.addMembership(multicastAddress); - socket.dropMembership(multicastAddress); - } - ); - socket.close(); -} From c287f1235c9a52eda57ab22f872f0e8541162b31 Mon Sep 17 00:00:00 2001 From: Daniel Bevenius Date: Fri, 3 Nov 2017 08:05:11 -0700 Subject: [PATCH 260/264] build: include src\tracing when linting on win This commit excludes src\tracing\trace_event.h and src\tracing\trace_event_common.h from the linter but allows the rest of the files in src\tracing to be examined by the linter which is similar to what the Makefile does. Refs: https://github.com/nodejs/node/pull/16720 Backport-PR-URL: https://github.com/nodejs/node/pull/17172 PR-URL: https://github.com/nodejs/node/pull/16720 Reviewed-By: James M Snell --- vcbuild.bat | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/vcbuild.bat b/vcbuild.bat index 78f3c242455f3c..e6a6d0d20f7ac2 100644 --- a/vcbuild.bat +++ b/vcbuild.bat @@ -383,8 +383,10 @@ if %errorlevel% equ 0 goto exit echo %1 | findstr /c:"src\tree.h" if %errorlevel% equ 0 goto exit -@rem skip subfolders under /src -echo %1 | findstr /r /c:"src\\.*\\.*" +echo %1 | findstr /r /c:"src\\tracing\\trace_event.h" +if %errorlevel% equ 0 goto exit + +echo %1 | findstr /r /c:"src\\tracing\\trace_event_common.h" if %errorlevel% equ 0 goto exit echo %1 | findstr /r /c:"test\\addons\\[0-9].*_.*\.h" From ae3ad5502b2a696b51906c1a7dbbdded07ac3141 Mon Sep 17 00:00:00 2001 From: Daniel Bevenius Date: Fri, 13 Oct 2017 14:07:44 +0200 Subject: [PATCH 261/264] src: remove unused includes from node_wrap.h I cannot find any usages of these includes and think they can be removed. Backport-PR-URL: https://github.com/nodejs/node/pull/17092 PR-URL: https://github.com/nodejs/node/pull/16179 Reviewed-By: Gireesh Punathil Reviewed-By: Colin Ihrig Reviewed-By: James M Snell --- src/node_wrap.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/node_wrap.h b/src/node_wrap.h index 2df9b10f6f87af..8508ef7805c07b 100644 --- a/src/node_wrap.h +++ b/src/node_wrap.h @@ -3,13 +3,10 @@ #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS -#include "env-inl.h" -#include "js_stream.h" +#include "env.h" #include "pipe_wrap.h" #include "tcp_wrap.h" #include "tty_wrap.h" -#include "udp_wrap.h" -#include "util-inl.h" #include "uv.h" #include "v8.h" From 50c3dabc0f318786b6bd7c7beec05ee1bbff10ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Fri, 24 Nov 2017 22:34:08 +0100 Subject: [PATCH 262/264] deps: backport 4af8029 from upstream V8 Original commit message: [turbofan] Fix missing lazy deopt in object literals. This adds a missing lazy bailout point when defining data properties with computed property names in object literals. The runtime call to Runtime::kDefineDataPropertyInLiteral can trigger deopts. The necessary bailout ID already exists and is now properly used. R=jarin@chromium.org TEST=mjsunit/regress/regress-crbug-621816 BUG=chromium:621816 Review-Url: https://codereview.chromium.org/2099133003 Cr-Commit-Position: refs/heads/master@{#37294} Refs: https://github.com/v8/v8/commit/4af80298b66f6dc0abd7fbab93f377755388d065 PR-URL: https://github.com/nodejs/node/pull/17290 Fixes: https://github.com/nodejs/node/issues/14326 Reviewed-By: Franziska Hinkelmann Reviewed-By: Ben Noordhuis --- deps/v8/include/v8-version.h | 2 +- deps/v8/src/compiler/ast-graph-builder.cc | 6 ++++-- deps/v8/src/compiler/linkage.cc | 1 - .../src/full-codegen/arm/full-codegen-arm.cc | 2 ++ .../full-codegen/arm64/full-codegen-arm64.cc | 2 ++ .../src/full-codegen/ia32/full-codegen-ia32.cc | 2 ++ .../src/full-codegen/mips/full-codegen-mips.cc | 2 ++ .../full-codegen/mips64/full-codegen-mips64.cc | 2 ++ .../src/full-codegen/ppc/full-codegen-ppc.cc | 2 ++ .../src/full-codegen/s390/full-codegen-s390.cc | 2 ++ .../src/full-codegen/x64/full-codegen-x64.cc | 2 ++ .../src/full-codegen/x87/full-codegen-x87.cc | 2 ++ .../mjsunit/regress/regress-crbug-621816.js | 18 ++++++++++++++++++ 13 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 deps/v8/test/mjsunit/regress/regress-crbug-621816.js diff --git a/deps/v8/include/v8-version.h b/deps/v8/include/v8-version.h index e7931da11e423f..f5e1bcbd30bd20 100644 --- a/deps/v8/include/v8-version.h +++ b/deps/v8/include/v8-version.h @@ -11,7 +11,7 @@ #define V8_MAJOR_VERSION 5 #define V8_MINOR_VERSION 1 #define V8_BUILD_NUMBER 281 -#define V8_PATCH_LEVEL 108 +#define V8_PATCH_LEVEL 109 // Use 1 for candidates and 0 otherwise. // (Boolean macro values are not supported by all preprocessors.) diff --git a/deps/v8/src/compiler/ast-graph-builder.cc b/deps/v8/src/compiler/ast-graph-builder.cc index 89bb61949a0b04..e67a5236447dff 100644 --- a/deps/v8/src/compiler/ast-graph-builder.cc +++ b/deps/v8/src/compiler/ast-graph-builder.cc @@ -1620,7 +1620,8 @@ void AstGraphBuilder::VisitClassLiteralContents(ClassLiteral* expr) { jsgraph()->Constant(property->NeedsSetFunctionName()); const Operator* op = javascript()->CallRuntime(Runtime::kDefineDataPropertyInLiteral); - NewNode(op, receiver, key, value, attr, set_function_name); + Node* call = NewNode(op, receiver, key, value, attr, set_function_name); + PrepareFrameState(call, BailoutId::None()); break; } case ObjectLiteral::Property::GETTER: { @@ -1870,7 +1871,8 @@ void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) { jsgraph()->Constant(property->NeedsSetFunctionName()); const Operator* op = javascript()->CallRuntime(Runtime::kDefineDataPropertyInLiteral); - NewNode(op, receiver, key, value, attr, set_function_name); + Node* call = NewNode(op, receiver, key, value, attr, set_function_name); + PrepareFrameState(call, expr->GetIdForPropertySet(property_index)); break; } case ObjectLiteral::Property::PROTOTYPE: diff --git a/deps/v8/src/compiler/linkage.cc b/deps/v8/src/compiler/linkage.cc index 105bd353fca480..7627f09d150642 100644 --- a/deps/v8/src/compiler/linkage.cc +++ b/deps/v8/src/compiler/linkage.cc @@ -145,7 +145,6 @@ int Linkage::FrameStateInputCount(Runtime::FunctionId function) { switch (function) { case Runtime::kAllocateInTargetSpace: case Runtime::kCreateIterResultObject: - case Runtime::kDefineDataPropertyInLiteral: case Runtime::kDefineGetterPropertyUnchecked: // TODO(jarin): Is it safe? case Runtime::kDefineSetterPropertyUnchecked: // TODO(jarin): Is it safe? case Runtime::kFinalizeClassDefinition: // TODO(conradw): Is it safe? diff --git a/deps/v8/src/full-codegen/arm/full-codegen-arm.cc b/deps/v8/src/full-codegen/arm/full-codegen-arm.cc index 81c5ff2ae7704a..f687da72624cbc 100644 --- a/deps/v8/src/full-codegen/arm/full-codegen-arm.cc +++ b/deps/v8/src/full-codegen/arm/full-codegen-arm.cc @@ -1572,6 +1572,8 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { PushOperand(Smi::FromInt(NONE)); PushOperand(Smi::FromInt(property->NeedsSetFunctionName())); CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral); + PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), + NO_REGISTERS); } else { DropOperands(3); } diff --git a/deps/v8/src/full-codegen/arm64/full-codegen-arm64.cc b/deps/v8/src/full-codegen/arm64/full-codegen-arm64.cc index aa67117a7f4920..547863125d1420 100644 --- a/deps/v8/src/full-codegen/arm64/full-codegen-arm64.cc +++ b/deps/v8/src/full-codegen/arm64/full-codegen-arm64.cc @@ -1557,6 +1557,8 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { PushOperand(Smi::FromInt(NONE)); PushOperand(Smi::FromInt(property->NeedsSetFunctionName())); CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral); + PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), + NO_REGISTERS); } else { DropOperands(3); } diff --git a/deps/v8/src/full-codegen/ia32/full-codegen-ia32.cc b/deps/v8/src/full-codegen/ia32/full-codegen-ia32.cc index f1945c897cf2e2..3e56b615a43bf2 100644 --- a/deps/v8/src/full-codegen/ia32/full-codegen-ia32.cc +++ b/deps/v8/src/full-codegen/ia32/full-codegen-ia32.cc @@ -1493,6 +1493,8 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { PushOperand(Smi::FromInt(NONE)); PushOperand(Smi::FromInt(property->NeedsSetFunctionName())); CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral); + PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), + NO_REGISTERS); } else { DropOperands(3); } diff --git a/deps/v8/src/full-codegen/mips/full-codegen-mips.cc b/deps/v8/src/full-codegen/mips/full-codegen-mips.cc index f329a23d00c97a..91a856b8c51217 100644 --- a/deps/v8/src/full-codegen/mips/full-codegen-mips.cc +++ b/deps/v8/src/full-codegen/mips/full-codegen-mips.cc @@ -1569,6 +1569,8 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { PushOperand(Smi::FromInt(NONE)); PushOperand(Smi::FromInt(property->NeedsSetFunctionName())); CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral); + PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), + NO_REGISTERS); } else { DropOperands(3); } diff --git a/deps/v8/src/full-codegen/mips64/full-codegen-mips64.cc b/deps/v8/src/full-codegen/mips64/full-codegen-mips64.cc index 681abd12303222..278f589089eecc 100644 --- a/deps/v8/src/full-codegen/mips64/full-codegen-mips64.cc +++ b/deps/v8/src/full-codegen/mips64/full-codegen-mips64.cc @@ -1570,6 +1570,8 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { PushOperand(Smi::FromInt(NONE)); PushOperand(Smi::FromInt(property->NeedsSetFunctionName())); CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral); + PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), + NO_REGISTERS); } else { DropOperands(3); } diff --git a/deps/v8/src/full-codegen/ppc/full-codegen-ppc.cc b/deps/v8/src/full-codegen/ppc/full-codegen-ppc.cc index 301ccf53cc3000..9f403f4ac8198e 100644 --- a/deps/v8/src/full-codegen/ppc/full-codegen-ppc.cc +++ b/deps/v8/src/full-codegen/ppc/full-codegen-ppc.cc @@ -1532,6 +1532,8 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { PushOperand(Smi::FromInt(NONE)); PushOperand(Smi::FromInt(property->NeedsSetFunctionName())); CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral); + PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), + NO_REGISTERS); } else { DropOperands(3); } diff --git a/deps/v8/src/full-codegen/s390/full-codegen-s390.cc b/deps/v8/src/full-codegen/s390/full-codegen-s390.cc index 88bec4cab6e63f..8c8a84707771e1 100644 --- a/deps/v8/src/full-codegen/s390/full-codegen-s390.cc +++ b/deps/v8/src/full-codegen/s390/full-codegen-s390.cc @@ -1491,6 +1491,8 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { PushOperand(Smi::FromInt(NONE)); PushOperand(Smi::FromInt(property->NeedsSetFunctionName())); CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral); + PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), + NO_REGISTERS); } else { DropOperands(3); } diff --git a/deps/v8/src/full-codegen/x64/full-codegen-x64.cc b/deps/v8/src/full-codegen/x64/full-codegen-x64.cc index 992e7fe4f72dd8..775c721db374d7 100644 --- a/deps/v8/src/full-codegen/x64/full-codegen-x64.cc +++ b/deps/v8/src/full-codegen/x64/full-codegen-x64.cc @@ -1518,6 +1518,8 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { PushOperand(Smi::FromInt(NONE)); PushOperand(Smi::FromInt(property->NeedsSetFunctionName())); CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral); + PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), + NO_REGISTERS); } else { DropOperands(3); } diff --git a/deps/v8/src/full-codegen/x87/full-codegen-x87.cc b/deps/v8/src/full-codegen/x87/full-codegen-x87.cc index f14aaf69b02d97..54130e9f630c97 100644 --- a/deps/v8/src/full-codegen/x87/full-codegen-x87.cc +++ b/deps/v8/src/full-codegen/x87/full-codegen-x87.cc @@ -1485,6 +1485,8 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { PushOperand(Smi::FromInt(NONE)); PushOperand(Smi::FromInt(property->NeedsSetFunctionName())); CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral); + PrepareForBailoutForId(expr->GetIdForPropertySet(property_index), + NO_REGISTERS); } else { DropOperands(3); } diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-621816.js b/deps/v8/test/mjsunit/regress/regress-crbug-621816.js new file mode 100644 index 00000000000000..ca7f5ac6df314f --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-621816.js @@ -0,0 +1,18 @@ +// Copyright 2016 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax --turbo + +function f() { + var o = {}; + o.a = 1; +} +function g() { + var o = { ['a']: function(){} }; + f(); +} +f(); +f(); +%OptimizeFunctionOnNextCall(g); +g(); From a0c1d10e9111dc1278c67337e77a81ed04ff3a60 Mon Sep 17 00:00:00 2001 From: Yihong Wang Date: Wed, 1 Nov 2017 21:19:16 -0700 Subject: [PATCH 263/264] build: remove cctest extension cctest has `so.59` extension when building node shared library in linux. The appending is defined in node.gypi and the cctest target in node.gyp includes node.gypi. Moving the appending from node.gypi to node target in node.gyp fixes the issue. Signed-off-by: Yihong Wang Backport-PR-URL: https://github.com/nodejs/node/pull/17255 PR-URL: https://github.com/nodejs/node/pull/16680 Reviewed-By: Ben Noordhuis Reviewed-By: James M Snell Reviewed-By: Michael Dawson Reviewed-By: Colin Ihrig Reviewed-By: Gibson Fahnestock Reviewed-By: Gireesh Punathil Reviewed-By: Daniel Bevenius Reviewed-By: Refael Ackermann --- node.gyp | 5 +++++ node.gypi | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/node.gyp b/node.gyp index fa1b204ee6fb0b..345188257998e0 100644 --- a/node.gyp +++ b/node.gyp @@ -237,6 +237,11 @@ # Warn when using deprecated V8 APIs. 'V8_DEPRECATION_WARNINGS=1', ], + 'conditions': [ + [ 'node_shared=="true" and node_module_version!="" and OS!="win"', { + 'product_extension': '<(shlib_suffix)', + }] + ], }, { 'target_name': 'mkssldef', diff --git a/node.gypi b/node.gypi index 6aaabeed42aac1..3b3548fdab5308 100644 --- a/node.gypi +++ b/node.gypi @@ -11,11 +11,6 @@ 'defines': [ 'NODE_SHARED_MODE', ], - 'conditions': [ - [ 'node_module_version!="" and OS!="win"', { - 'product_extension': '<(shlib_suffix)', - }] - ], }], [ 'node_enable_d8=="true"', { 'dependencies': [ 'deps/v8/src/d8.gyp:d8' ], From 4a99c2bf858e91db6197541368d556e7d99ef507 Mon Sep 17 00:00:00 2001 From: Myles Borins Date: Tue, 21 Nov 2017 18:08:10 +0800 Subject: [PATCH 264/264] 2017-12-05, Version 6.12.1 'Boron' (LTS) Notable Changes: * build: - fix npm install with --shared (Ben Noordhuis) https://github.com/nodejs/node/pull/16438 * build: - building with python 3 is now supported (Emily Marigold Klassen) https://github.com/nodejs/node/pull/16058 * src: - v8 options can be specified with either '\_' or '-' in NODE_OPTIONS (Sam Roberts) https://github.com/nodejs/node/pull/14093 PR-URL: https://github.com/nodejs/node/pull/17180 --- CHANGELOG.md | 3 +- doc/changelogs/CHANGELOG_V6.md | 282 +++++++++++++++++++++++++++++++++ src/node_version.h | 2 +- 3 files changed, 285 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68ae334fd51fb0..fbe6611679bf73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,7 +26,8 @@ release. -6.12.0
+6.12.1
+6.12.0
6.11.5
6.11.4
6.11.3
diff --git a/doc/changelogs/CHANGELOG_V6.md b/doc/changelogs/CHANGELOG_V6.md index 19c1c8de35dc2a..2d544881688d1d 100644 --- a/doc/changelogs/CHANGELOG_V6.md +++ b/doc/changelogs/CHANGELOG_V6.md @@ -7,6 +7,7 @@ +6.12.1
6.12.0
6.11.5
6.11.4
@@ -55,6 +56,287 @@ [Node.js Long Term Support Plan](https://github.com/nodejs/LTS) and will be supported actively until April 2018 and maintained until April 2019. + +## 2017-12-05, Version 6.12.1 'Boron' (LTS), @MylesBorins + +This LTS release comes with 263 commits. This includes 173 which are test related, +41 which are doc related, 18 which are build / tool related and 1 commit which is an update to a dependency. + +### Notable Changes + +* **build**: + - fix npm install with --shared (Ben Noordhuis) [#16438](https://github.com/nodejs/node/pull/16438) +* **build**: + - building with python 3 is now supported (Emily Marigold Klassen) [#16058](https://github.com/nodejs/node/pull/16058) +* **src**: + - v8 options can be specified with either '\_' or '-' in NODE_OPTIONS (Sam Roberts) [#14093](https://github.com/nodejs/node/pull/14093) + +### Commits + +* [[`575a920a16`](https://github.com/nodejs/node/commit/575a920a16)] - **assert**: fix actual and expected order (Steve Jenkins) [#15866](https://github.com/nodejs/node/pull/15866) +* [[`a0c1d10e91`](https://github.com/nodejs/node/commit/a0c1d10e91)] - **build**: remove cctest extension (Yihong Wang) [#16680](https://github.com/nodejs/node/pull/16680) +* [[`c287f1235c`](https://github.com/nodejs/node/commit/c287f1235c)] - **build**: include src\tracing when linting on win (Daniel Bevenius) [#16720](https://github.com/nodejs/node/pull/16720) +* [[`706812bc2f`](https://github.com/nodejs/node/commit/706812bc2f)] - **build**: skip bin override on windows (Hitesh Kanwathirtha) [#16460](https://github.com/nodejs/node/pull/16460) +* [[`f4627603aa`](https://github.com/nodejs/node/commit/f4627603aa)] - **build**: fix npm install with --shared (Ben Noordhuis) [#16438](https://github.com/nodejs/node/pull/16438) +* [[`6d63612e93`](https://github.com/nodejs/node/commit/6d63612e93)] - **build**: correct minor typo in lttng help message (Daniel Bevenius) [#16101](https://github.com/nodejs/node/pull/16101) +* [[`de82db7f85`](https://github.com/nodejs/node/commit/de82db7f85)] - **build**: ignore empty folders in test-addons (Gregor) [#16031](https://github.com/nodejs/node/pull/16031) +* [[`ac1beb0fb0`](https://github.com/nodejs/node/commit/ac1beb0fb0)] - **build**: use bin override if no `python` in PATH (Bradley T. Hughes) [#16241](https://github.com/nodejs/node/pull/16241) +* [[`d4b3b633d8`](https://github.com/nodejs/node/commit/d4b3b633d8)] - **build**: allow build with system python 3 (Emily Marigold Klassen) [#16058](https://github.com/nodejs/node/pull/16058) +* [[`fc2ab06014`](https://github.com/nodejs/node/commit/fc2ab06014)] - **build, windows**: use /bigobj for debug builds (Nikolai Vavilov) [#16289](https://github.com/nodejs/node/pull/16289) +* [[`ccca11d026`](https://github.com/nodejs/node/commit/ccca11d026)] - **build,win**: set /MP separately in Debug and Release (Nikolai Vavilov) [#16415](https://github.com/nodejs/node/pull/16415) +* [[`a14f564686`](https://github.com/nodejs/node/commit/a14f564686)] - **build,win**: use /MP for debug builds (Nikolai Vavilov) [#16333](https://github.com/nodejs/node/pull/16333) +* [[`8813867577`](https://github.com/nodejs/node/commit/8813867577)] - **child_process**: set shell to false in fork() (Alex Gresnel) [#15352](https://github.com/nodejs/node/pull/15352) +* [[`f2cafff9b0`](https://github.com/nodejs/node/commit/f2cafff9b0)] - **crypto**: fix error of createCipher in wrap mode (Shigeki Ohtsu) [#15037](https://github.com/nodejs/node/pull/15037) +* [[`7115079c4f`](https://github.com/nodejs/node/commit/7115079c4f)] - **crypto**: warn if counter mode used in createCipher (Shigeki Ohtsu) [#13821](https://github.com/nodejs/node/pull/13821) +* [[`50c3dabc0f`](https://github.com/nodejs/node/commit/50c3dabc0f)] - **deps**: backport 4af8029 from upstream V8 (Michaël Zasso) [#17290](https://github.com/nodejs/node/pull/17290) +* [[`101eb981fe`](https://github.com/nodejs/node/commit/101eb981fe)] - **doc**: mention constant-time in crypto doc (Mithun Sasidharan) [#16604](https://github.com/nodejs/node/pull/16604) +* [[`1bc5c3836c`](https://github.com/nodejs/node/commit/1bc5c3836c)] - **doc**: recommend node-core-utils for metadata (Rich Trott) [#16978](https://github.com/nodejs/node/pull/16978) +* [[`4583f1be0c`](https://github.com/nodejs/node/commit/4583f1be0c)] - **doc**: reorganize COLLABORATOR_GUIDE.md (Rich Trott) [#15710](https://github.com/nodejs/node/pull/15710) +* [[`fce790285f`](https://github.com/nodejs/node/commit/fce790285f)] - **doc**: improve documentation for the vm module (Franziska Hinkelmann) [#16867](https://github.com/nodejs/node/pull/16867) +* [[`727a0fe641`](https://github.com/nodejs/node/commit/727a0fe641)] - **doc**: update subprocess.killed (cjihrig) [#16748](https://github.com/nodejs/node/pull/16748) +* [[`44c0385b04`](https://github.com/nodejs/node/commit/44c0385b04)] - **doc**: more accurate zlib windowBits information (Anna Henningsen) [#16511](https://github.com/nodejs/node/pull/16511) +* [[`732af9b8a4`](https://github.com/nodejs/node/commit/732af9b8a4)] - **doc**: add Gibson Fahnestock to Release team (Gibson Fahnestock) [#16620](https://github.com/nodejs/node/pull/16620) +* [[`935b15285f`](https://github.com/nodejs/node/commit/935b15285f)] - **doc**: slightly relax 50 character rule (James M Snell) [#16523](https://github.com/nodejs/node/pull/16523) +* [[`39c63da6d2`](https://github.com/nodejs/node/commit/39c63da6d2)] - **doc**: add note to releases.md (Jon Moss) [#16507](https://github.com/nodejs/node/pull/16507) +* [[`60ae428f30`](https://github.com/nodejs/node/commit/60ae428f30)] - **doc**: add dot in documentations (erwinwahyura) [#16542](https://github.com/nodejs/node/pull/16542) +* [[`7ae23b744b`](https://github.com/nodejs/node/commit/7ae23b744b)] - **doc**: fix missing newline character (Daijiro Wachi) [#16447](https://github.com/nodejs/node/pull/16447) +* [[`af869f03c1`](https://github.com/nodejs/node/commit/af869f03c1)] - **doc**: add recommendations for first timers (Refael Ackermann) [#16350](https://github.com/nodejs/node/pull/16350) +* [[`b7d609c2f8`](https://github.com/nodejs/node/commit/b7d609c2f8)] - **doc**: replace undocumented encoding aliases (Vse Mozhet Byt) [#16368](https://github.com/nodejs/node/pull/16368) +* [[`2cbf75da7e`](https://github.com/nodejs/node/commit/2cbf75da7e)] - **doc**: replace methods used in the example code (Damian) [#16416](https://github.com/nodejs/node/pull/16416) +* [[`0b5a0ada2a`](https://github.com/nodejs/node/commit/0b5a0ada2a)] - **doc**: fix comment in assert.md (umatoma) [#16335](https://github.com/nodejs/node/pull/16335) +* [[`4fbc490704`](https://github.com/nodejs/node/commit/4fbc490704)] - **doc**: add space after period (Diego Rodríguez Baquero) [#16334](https://github.com/nodejs/node/pull/16334) +* [[`c3cc0fd258`](https://github.com/nodejs/node/commit/c3cc0fd258)] - **doc**: minor correction to note on process section (Daniel Bevenius) [#16311](https://github.com/nodejs/node/pull/16311) +* [[`47bf494979`](https://github.com/nodejs/node/commit/47bf494979)] - **doc**: add apapirovski to collaborators (Anatoli Papirovski) [#16302](https://github.com/nodejs/node/pull/16302) +* [[`9c96d7f4fd`](https://github.com/nodejs/node/commit/9c96d7f4fd)] - **doc**: clarify os.cpus() returns logical CPU cores (Luke Childs) [#16282](https://github.com/nodejs/node/pull/16282) +* [[`ba62b0e48a`](https://github.com/nodejs/node/commit/ba62b0e48a)] - **doc**: support multidimensional arrays in type link (Vse Mozhet Byt) [#16207](https://github.com/nodejs/node/pull/16207) +* [[`aefaed40f0`](https://github.com/nodejs/node/commit/aefaed40f0)] - **doc**: move Shigeki to TSC Emeritus (Rich Trott) [#16195](https://github.com/nodejs/node/pull/16195) +* [[`1fdcf75f9c`](https://github.com/nodejs/node/commit/1fdcf75f9c)] - **doc**: Update a typo in module.js' comments (Orta) [#16205](https://github.com/nodejs/node/pull/16205) +* [[`799c6fdc1c`](https://github.com/nodejs/node/commit/799c6fdc1c)] - **doc**: add missing comma (Jon Moss) [#16204](https://github.com/nodejs/node/pull/16204) +* [[`8c070f9ed5`](https://github.com/nodejs/node/commit/8c070f9ed5)] - **doc**: added note to fs.watchFile on previousStat (NiveditN) [#16099](https://github.com/nodejs/node/pull/16099) +* [[`2515cad90e`](https://github.com/nodejs/node/commit/2515cad90e)] - **doc**: ensure collaborators validate commits (Bradley Farias) [#16162](https://github.com/nodejs/node/pull/16162) +* [[`7647d41da1`](https://github.com/nodejs/node/commit/7647d41da1)] - **doc**: move 8 collaborators to emeriti (Rich Trott) [#16173](https://github.com/nodejs/node/pull/16173) +* [[`de8155ebf2`](https://github.com/nodejs/node/commit/de8155ebf2)] - **doc**: include V8 commit URL in V8 backport guide (Gibson Fahnestock) [#16054](https://github.com/nodejs/node/pull/16054) +* [[`6f1ba792d7`](https://github.com/nodejs/node/commit/6f1ba792d7)] - **doc**: add pronoun for fhinkel (F. Hinkelmann) [#16069](https://github.com/nodejs/node/pull/16069) +* [[`8da3b51472`](https://github.com/nodejs/node/commit/8da3b51472)] - **doc**: document windows shell support (Tim Ermilov) [#16104](https://github.com/nodejs/node/pull/16104) +* [[`281023b20d`](https://github.com/nodejs/node/commit/281023b20d)] - **doc**: exempt test/doc only changes from 48-hr rule (Anna Henningsen) [#16135](https://github.com/nodejs/node/pull/16135) +* [[`04d5835722`](https://github.com/nodejs/node/commit/04d5835722)] - **doc**: rename good first contrib label (Jeremiah Senkpiel) [#16150](https://github.com/nodejs/node/pull/16150) +* [[`1064258f9d`](https://github.com/nodejs/node/commit/1064258f9d)] - **doc**: remove bold typography from STYLE_GUIDE.md (Rich Trott) [#16085](https://github.com/nodejs/node/pull/16085) +* [[`23e9bba9c8`](https://github.com/nodejs/node/commit/23e9bba9c8)] - **doc**: ctc -\> tsc in onboarding extras (Bryan English) [#15621](https://github.com/nodejs/node/pull/15621) +* [[`ff66d63642`](https://github.com/nodejs/node/commit/ff66d63642)] - **doc**: fix emitKeypressEvents stream type (Oblosys) [#15399](https://github.com/nodejs/node/pull/15399) +* [[`1bd6962842`](https://github.com/nodejs/node/commit/1bd6962842)] - **doc**: make stream.Readable consistent (Sakthipriyan Vairamani (thefourtheye)) [#16786](https://github.com/nodejs/node/pull/16786) +* [[`6b9bd51021`](https://github.com/nodejs/node/commit/6b9bd51021)] - **doc**: correct effects to affects (gowpen) [#16794](https://github.com/nodejs/node/pull/16794) +* [[`6af9311939`](https://github.com/nodejs/node/commit/6af9311939)] - **doc**: correct EventEmitter reference (gowpen) [#16791](https://github.com/nodejs/node/pull/16791) +* [[`1a633e3cd8`](https://github.com/nodejs/node/commit/1a633e3cd8)] - **doc**: add docs for Zlib#close() (Luigi Pinca) [#16592](https://github.com/nodejs/node/pull/16592) +* [[`290df5ac41`](https://github.com/nodejs/node/commit/290df5ac41)] - **doc**: add details about rss on process.memoryUsage (Anthony Nandaa) [#16566](https://github.com/nodejs/node/pull/16566) +* [[`3e6da45ce0`](https://github.com/nodejs/node/commit/3e6da45ce0)] - **doc**: howto decode buffers extending from Writable (dicearr) [#16403](https://github.com/nodejs/node/pull/16403) +* [[`c64ed977fc`](https://github.com/nodejs/node/commit/c64ed977fc)] - **doc, win**: remove note about resize (Bartosz Sosnowski) [#16320](https://github.com/nodejs/node/pull/16320) +* [[`644989cf6a`](https://github.com/nodejs/node/commit/644989cf6a)] - **fs**: use Number::New since all fields are uint64_t (Huáng Jùnliàng) [#16705](https://github.com/nodejs/node/pull/16705) +* [[`925e58fecb`](https://github.com/nodejs/node/commit/925e58fecb)] - **fs**: fix stat dev unsigned cast overflow (Huáng Jùnliàng) [#16705](https://github.com/nodejs/node/pull/16705) +* [[`92b13e455f`](https://github.com/nodejs/node/commit/92b13e455f)] - **https**: Use secureProtocol in Agent#getName (Andreas Lind) [#9452](https://github.com/nodejs/node/pull/9452) +* [[`b0ac76d145`](https://github.com/nodejs/node/commit/b0ac76d145)] - **meta**: add note about email sync to CONTRIBUTING.md (Vse Mozhet Byt) [#16340](https://github.com/nodejs/node/pull/16340) +* [[`bf7f63d51b`](https://github.com/nodejs/node/commit/bf7f63d51b)] - **net**: change assert to conform to other files (James Hodgskiss) [#15861](https://github.com/nodejs/node/pull/15861) +* [[`ae3ad5502b`](https://github.com/nodejs/node/commit/ae3ad5502b)] - **src**: remove unused includes from node_wrap.h (Daniel Bevenius) [#16179](https://github.com/nodejs/node/pull/16179) +* [[`a368e5fa63`](https://github.com/nodejs/node/commit/a368e5fa63)] - **src**: make StreamBase prototype accessors robust (Joyee Cheung) [#16860](https://github.com/nodejs/node/pull/16860) +* [[`c79dd9e3ce`](https://github.com/nodejs/node/commit/c79dd9e3ce)] - **src**: CHECK() for argument overflow in Spawn() (cjihrig) [#16761](https://github.com/nodejs/node/pull/16761) +* [[`7c69ca58e0`](https://github.com/nodejs/node/commit/7c69ca58e0)] - **src**: move handle properties to prototype (Ben Noordhuis) [#16482](https://github.com/nodejs/node/pull/16482) +* [[`c87a620ed8`](https://github.com/nodejs/node/commit/c87a620ed8)] - **src**: remove superfluous HandleScope (Ben Noordhuis) [#16482](https://github.com/nodejs/node/pull/16482) +* [[`2f5edc6fd5`](https://github.com/nodejs/node/commit/2f5edc6fd5)] - **src**: remove unused include in tty_wrap.h (Daniel Bevenius) [#16379](https://github.com/nodejs/node/pull/16379) +* [[`42cb64ee91`](https://github.com/nodejs/node/commit/42cb64ee91)] - **src**: fix etw provider include on Windows (Joyee Cheung) [#16639](https://github.com/nodejs/node/pull/16639) +* [[`b00ced5b52`](https://github.com/nodejs/node/commit/b00ced5b52)] - **src**: do not include x.h if x-inl.h is included (Joyee Cheung) [#16548](https://github.com/nodejs/node/pull/16548) +* [[`a4688b0c43`](https://github.com/nodejs/node/commit/a4688b0c43)] - **src**: make header file self-contained (Joyee Cheung) [#16518](https://github.com/nodejs/node/pull/16518) +* [[`cf80089477`](https://github.com/nodejs/node/commit/cf80089477)] - **src**: node_dtrace line continuations clean up (Daniel Bevenius) [#15777](https://github.com/nodejs/node/pull/15777) +* [[`4639cfff0a`](https://github.com/nodejs/node/commit/4639cfff0a)] - **src**: rename perfctr_macros.py-\>noperfctr_macros.py (Daniel Bevenius) [#16100](https://github.com/nodejs/node/pull/16100) +* [[`70f574e6ff`](https://github.com/nodejs/node/commit/70f574e6ff)] - **src**: add help for NODE_PENDING_DEPRECATION env (Thomas Corbière) [#15609](https://github.com/nodejs/node/pull/15609) +* [[`75b1e30e6b`](https://github.com/nodejs/node/commit/75b1e30e6b)] - **src**: add --pending-deprecation to NODE_OPTIONS (Thomas Corbière) [#15494](https://github.com/nodejs/node/pull/15494) +* [[`f659e49862`](https://github.com/nodejs/node/commit/f659e49862)] - **src**: whitelist v8 options with '_' or '-' (Sam Roberts) [#14093](https://github.com/nodejs/node/pull/14093) +* [[`79171e0c2f`](https://github.com/nodejs/node/commit/79171e0c2f)] - **src**: turn key length exception into CHECK (Ben Noordhuis) [#15183](https://github.com/nodejs/node/pull/15183) +* [[`e18df46092`](https://github.com/nodejs/node/commit/e18df46092)] - **src**: notify V8 for low memory when alloc fails (Anna Henningsen) [#8482](https://github.com/nodejs/node/pull/8482) +* [[`6a0eb9f6cf`](https://github.com/nodejs/node/commit/6a0eb9f6cf)] - **src**: provide allocation + nullptr check shortcuts (Anna Henningsen) [#8482](https://github.com/nodejs/node/pull/8482) +* [[`4aec8cfcd2`](https://github.com/nodejs/node/commit/4aec8cfcd2)] - **src**: pass desired return type to allocators (Anna Henningsen) [#8482](https://github.com/nodejs/node/pull/8482) +* [[`19f3ac9749`](https://github.com/nodejs/node/commit/19f3ac9749)] - **src**: add Malloc() size param + overflow detection (Anna Henningsen) [#8482](https://github.com/nodejs/node/pull/8482) +* [[`6269ba334d`](https://github.com/nodejs/node/commit/6269ba334d)] - **test**: allow tests to pass without internet (Daniel Bevenius) [#16255](https://github.com/nodejs/node/pull/16255) +* [[`f0eeddb4b8`](https://github.com/nodejs/node/commit/f0eeddb4b8)] - **test**: reuse existing PassThrough implementation (Tobias Nießen) [#16936](https://github.com/nodejs/node/pull/16936) +* [[`4752fc4336`](https://github.com/nodejs/node/commit/4752fc4336)] - **test**: refactor comments in test-child-process-spawnsync-maxbuf (ChrBergert) [#16829](https://github.com/nodejs/node/pull/16829) +* [[`f226ca6b12`](https://github.com/nodejs/node/commit/f226ca6b12)] - **test**: used fixturesDir from fixtures modules (Klemen Kogovsek) [#16813](https://github.com/nodejs/node/pull/16813) +* [[`5e2231e407`](https://github.com/nodejs/node/commit/5e2231e407)] - **test**: add a test description (Grant Gasparyan) [#16833](https://github.com/nodejs/node/pull/16833) +* [[`a8cff7ad4a`](https://github.com/nodejs/node/commit/a8cff7ad4a)] - **test**: use common/fixtures module in hash-seed test (Javier Blanco) [#16823](https://github.com/nodejs/node/pull/16823) +* [[`090cc9713e`](https://github.com/nodejs/node/commit/090cc9713e)] - **test**: improve template value for test message (Stephan Smith) [#16826](https://github.com/nodejs/node/pull/16826) +* [[`1d3793eb77`](https://github.com/nodejs/node/commit/1d3793eb77)] - **test**: change concatenated string to template (Deepthi Sebastian) [#16929](https://github.com/nodejs/node/pull/16929) +* [[`79dfc3f475`](https://github.com/nodejs/node/commit/79dfc3f475)] - **test**: change concatenated string to template (Anawesha Khuntia) [#16912](https://github.com/nodejs/node/pull/16912) +* [[`2232231d4f`](https://github.com/nodejs/node/commit/2232231d4f)] - **test**: change string concatenation to template (Suryanarayana Murthy N) [#16919](https://github.com/nodejs/node/pull/16919) +* [[`674cbf8402`](https://github.com/nodejs/node/commit/674cbf8402)] - **test**: replace string concatenation with template (Kabir Islam) [#16916](https://github.com/nodejs/node/pull/16916) +* [[`969defaae9`](https://github.com/nodejs/node/commit/969defaae9)] - **test**: enable mustCall() during child exit (Vipin Menon) [#16915](https://github.com/nodejs/node/pull/16915) +* [[`9d4abaa243`](https://github.com/nodejs/node/commit/9d4abaa243)] - **test**: replace string concatenation with template (Tanvi Kini) [#16913](https://github.com/nodejs/node/pull/16913) +* [[`2a1ebae567`](https://github.com/nodejs/node/commit/2a1ebae567)] - **test**: cover vm.runInNewContext() (cjihrig) [#16906](https://github.com/nodejs/node/pull/16906) +* [[`2043ce39d5`](https://github.com/nodejs/node/commit/2043ce39d5)] - **test**: improve assertion messages (Neil Vass) [#16885](https://github.com/nodejs/node/pull/16885) +* [[`668644008e`](https://github.com/nodejs/node/commit/668644008e)] - **test**: improve assert messages in stream test (Katie Stockton Roberts) [#16884](https://github.com/nodejs/node/pull/16884) +* [[`714eb0bc7c`](https://github.com/nodejs/node/commit/714eb0bc7c)] - **test**: improve assertion in test-require-dot (Adam Wegrzynek) [#16805](https://github.com/nodejs/node/pull/16805) +* [[`8e5b4f543c`](https://github.com/nodejs/node/commit/8e5b4f543c)] - **test**: add values to error message (Adam Jeffery) [#16831](https://github.com/nodejs/node/pull/16831) +* [[`b3b7858a97`](https://github.com/nodejs/node/commit/b3b7858a97)] - **test**: replace common.fixtiresDir with fixtures.readKey() (woj) [#16817](https://github.com/nodejs/node/pull/16817) +* [[`3acf156b68`](https://github.com/nodejs/node/commit/3acf156b68)] - **test**: remove message argument in cluster setup test (mbornath) [#16838](https://github.com/nodejs/node/pull/16838) +* [[`cedf8a1cb2`](https://github.com/nodejs/node/commit/cedf8a1cb2)] - **test**: move test-http-keepalive-maxsockets to sequential (Rich Trott) [#16777](https://github.com/nodejs/node/pull/16777) +* [[`ffbb4e68e8`](https://github.com/nodejs/node/commit/ffbb4e68e8)] - **test**: use default assertion message (jonask) [#16819](https://github.com/nodejs/node/pull/16819) +* [[`dd558a56af`](https://github.com/nodejs/node/commit/dd558a56af)] - **test**: include file mode in assert message (Sascha Tandel) [#16815](https://github.com/nodejs/node/pull/16815) +* [[`3d8b3f7b4a`](https://github.com/nodejs/node/commit/3d8b3f7b4a)] - **test**: refactor tls test to use fixtres.readSync (Brian O'Connell) [#16816](https://github.com/nodejs/node/pull/16816) +* [[`54d4557199`](https://github.com/nodejs/node/commit/54d4557199)] - **test**: use fixtures module in test-repl (Maring, Damian Lion) [#16809](https://github.com/nodejs/node/pull/16809) +* [[`9f9e824fc5`](https://github.com/nodejs/node/commit/9f9e824fc5)] - **test**: update test to use fixtures.readKey (Dara Hayes) [#16811](https://github.com/nodejs/node/pull/16811) +* [[`a99755f3fd`](https://github.com/nodejs/node/commit/a99755f3fd)] - **test**: fix typos in read-buffer tests (Jimi van der Woning) [#16834](https://github.com/nodejs/node/pull/16834) +* [[`e7a456a5ee`](https://github.com/nodejs/node/commit/e7a456a5ee)] - **test**: replace common.fixturesDir with fixtures module (Dumitru Glavan) [#16803](https://github.com/nodejs/node/pull/16803) +* [[`04af0fdab7`](https://github.com/nodejs/node/commit/04af0fdab7)] - **test**: replace common.fixturesDir with fixtures.readSync() (Adri Van Houdt) [#16802](https://github.com/nodejs/node/pull/16802) +* [[`755f5e3fd1`](https://github.com/nodejs/node/commit/755f5e3fd1)] - **test**: update test to use fixtures (Adam Wegrzynek) [#16799](https://github.com/nodejs/node/pull/16799) +* [[`143d8a1b3d`](https://github.com/nodejs/node/commit/143d8a1b3d)] - **test**: fix typo (Oscar Funes) [#15938](https://github.com/nodejs/node/pull/15938) +* [[`84741fdc81`](https://github.com/nodejs/node/commit/84741fdc81)] - **test**: update test-timers-block-eventloop.js (zhangzifa) [#16314](https://github.com/nodejs/node/pull/16314) +* [[`8e62fcb2cf`](https://github.com/nodejs/node/commit/8e62fcb2cf)] - **test**: replace fixturesDir in test-tls-connect (Casie Lynch) [#15849](https://github.com/nodejs/node/pull/15849) +* [[`d6dc579f3c`](https://github.com/nodejs/node/commit/d6dc579f3c)] - **test**: use fixtures module (Iryna Yaremtso) [#15901](https://github.com/nodejs/node/pull/15901) +* [[`10c24a157c`](https://github.com/nodejs/node/commit/10c24a157c)] - **test**: add details in assertions in test-vm-context (Vladimir Ilic) [#16116](https://github.com/nodejs/node/pull/16116) +* [[`cb1d16d26b`](https://github.com/nodejs/node/commit/cb1d16d26b)] - **test**: increase fs.exists coverage (Nigel Kibodeaux) [#15963](https://github.com/nodejs/node/pull/15963) +* [[`d3981ae552`](https://github.com/nodejs/node/commit/d3981ae552)] - **test**: use fixtures module in test-fs-realpath.js (Raphael Rheault) [#15904](https://github.com/nodejs/node/pull/15904) +* [[`532c9606b3`](https://github.com/nodejs/node/commit/532c9606b3)] - **test**: use fixtures module (Scott J Beck) [#15843](https://github.com/nodejs/node/pull/15843) +* [[`58fe9b4ec3`](https://github.com/nodejs/node/commit/58fe9b4ec3)] - **test**: imporove assert messages (Hadis-Fard) [#16021](https://github.com/nodejs/node/pull/16021) +* [[`91f9779794`](https://github.com/nodejs/node/commit/91f9779794)] - **test**: show values instead of assertion message (Cheyenne Arrowsmith) [#15979](https://github.com/nodejs/node/pull/15979) +* [[`0ace5a158d`](https://github.com/nodejs/node/commit/0ace5a158d)] - **test**: include values in assertion messages (nhoel) [#15996](https://github.com/nodejs/node/pull/15996) +* [[`8663b05711`](https://github.com/nodejs/node/commit/8663b05711)] - **test**: use process.features.debug in common module (Rich Trott) [#16537](https://github.com/nodejs/node/pull/16537) +* [[`1fffa165a1`](https://github.com/nodejs/node/commit/1fffa165a1)] - **test**: use common.buildType in repl-domain-abort (Rich Trott) [#16538](https://github.com/nodejs/node/pull/16538) +* [[`7d93da54bb`](https://github.com/nodejs/node/commit/7d93da54bb)] - **test**: skip test-process-config if no config.gypi (Gibson Fahnestock) [#16436](https://github.com/nodejs/node/pull/16436) +* [[`5c20164354`](https://github.com/nodejs/node/commit/5c20164354)] - **test**: use fixtures module in tls-handshake-error (Mark Walker) [#15939](https://github.com/nodejs/node/pull/15939) +* [[`4f04d15aa3`](https://github.com/nodejs/node/commit/4f04d15aa3)] - **test**: add failing vm tests to known_issues (Michaël Zasso) [#16410](https://github.com/nodejs/node/pull/16410) +* [[`2b1042bb29`](https://github.com/nodejs/node/commit/2b1042bb29)] - **test**: allow for different nsswitch.conf settings (Daniel Bevenius) [#16378](https://github.com/nodejs/node/pull/16378) +* [[`5095b991c0`](https://github.com/nodejs/node/commit/5095b991c0)] - **test**: handle blank shells in test-os.js (Gibson Fahnestock) [#16287](https://github.com/nodejs/node/pull/16287) +* [[`62dd6a2c40`](https://github.com/nodejs/node/commit/62dd6a2c40)] - **test**: increase enoughTestMem to 1.75 Gb (Rich Trott) [#16374](https://github.com/nodejs/node/pull/16374) +* [[`9c229b4bd3`](https://github.com/nodejs/node/commit/9c229b4bd3)] - **test**: use fixtures.readKey in https-timeout-server (Nicolas 'Pixel' Noble) [#15871](https://github.com/nodejs/node/pull/15871) +* [[`773652903d`](https://github.com/nodejs/node/commit/773652903d)] - **test**: use fixtures.readKey instead of fixturesDir (Paul Marion Camantigue) [#15976](https://github.com/nodejs/node/pull/15976) +* [[`34dfce7710`](https://github.com/nodejs/node/commit/34dfce7710)] - **test**: replace fixturesDir with fixtures module (tpurcell) [#16262](https://github.com/nodejs/node/pull/16262) +* [[`0a88e1bd60`](https://github.com/nodejs/node/commit/0a88e1bd60)] - **test**: replace fixturesDir with fixtures module (André Føyn Berge) [#15947](https://github.com/nodejs/node/pull/15947) +* [[`9e74e542a2`](https://github.com/nodejs/node/commit/9e74e542a2)] - **test**: skip test due to file size limit (jBarz) [#16273](https://github.com/nodejs/node/pull/16273) +* [[`e070e592dd`](https://github.com/nodejs/node/commit/e070e592dd)] - **test**: remove error msg in test-vm-symbols.js (Daniel Abrão) [#15873](https://github.com/nodejs/node/pull/15873) +* [[`257ece287c`](https://github.com/nodejs/node/commit/257ece287c)] - **test**: remove error messages in test-buffer-alloc (Braden Whitten) [#15867](https://github.com/nodejs/node/pull/15867) +* [[`32fa91519a`](https://github.com/nodejs/node/commit/32fa91519a)] - **test**: update assert error messages (Omar Gonzalez) [#16035](https://github.com/nodejs/node/pull/16035) +* [[`da85e6c552`](https://github.com/nodejs/node/commit/da85e6c552)] - **test**: expand error message (Stefania Sharp) [#15991](https://github.com/nodejs/node/pull/15991) +* [[`cbbe125f71`](https://github.com/nodejs/node/commit/cbbe125f71)] - **test**: use fixtures module (Kanika Shah) [#15959](https://github.com/nodejs/node/pull/15959) +* [[`6f15b011c0`](https://github.com/nodejs/node/commit/6f15b011c0)] - **test**: remove literal messages (Oscar Funes) [#15938](https://github.com/nodejs/node/pull/15938) +* [[`aa269ad59b`](https://github.com/nodejs/node/commit/aa269ad59b)] - **test**: fix stderr reference (Oscar Funes) [#15938](https://github.com/nodejs/node/pull/15938) +* [[`3f35fc063e`](https://github.com/nodejs/node/commit/3f35fc063e)] - **test**: use fixtures module in test-https-truncate (Gene Wu) [#15875](https://github.com/nodejs/node/pull/15875) +* [[`c58eaaf1a8`](https://github.com/nodejs/node/commit/c58eaaf1a8)] - **test**: use fixtures module (Alvaro Cruz) [#15874](https://github.com/nodejs/node/pull/15874) +* [[`48e1320c44`](https://github.com/nodejs/node/commit/48e1320c44)] - **test**: use fixtures module (Lance Barlaan) [#15872](https://github.com/nodejs/node/pull/15872) +* [[`339bdca558`](https://github.com/nodejs/node/commit/339bdca558)] - **test**: use default message for assert.strictEqual (hwaisiu) [#15970](https://github.com/nodejs/node/pull/15970) +* [[`ab580c3ae2`](https://github.com/nodejs/node/commit/ab580c3ae2)] - **test**: improve assert message in internet test (Nikki St Onge) [#15998](https://github.com/nodejs/node/pull/15998) +* [[`6285e7221e`](https://github.com/nodejs/node/commit/6285e7221e)] - **test**: replace common.fixturesDir (Shawn McGinty) [#15834](https://github.com/nodejs/node/pull/15834) +* [[`fa8315cb68`](https://github.com/nodejs/node/commit/fa8315cb68)] - **test**: refactor test-process-kill-null (Luigi Pinca) [#16236](https://github.com/nodejs/node/pull/16236) +* [[`c26abc8e94`](https://github.com/nodejs/node/commit/c26abc8e94)] - **test**: add missing spaces in concatenations (Vse Mozhet Byt) [#16244](https://github.com/nodejs/node/pull/16244) +* [[`a94a75f69a`](https://github.com/nodejs/node/commit/a94a75f69a)] - **test**: update output to include exit code & signal (Jenna Zeigen) [#15945](https://github.com/nodejs/node/pull/15945) +* [[`8eb84d6780`](https://github.com/nodejs/node/commit/8eb84d6780)] - **test**: change common.fixturesDir to fixtures.path (tejbirsingh) [#15860](https://github.com/nodejs/node/pull/15860) +* [[`806f03e54c`](https://github.com/nodejs/node/commit/806f03e54c)] - **test**: split up and refactor test-domain (Anna Henningsen) [#13614](https://github.com/nodejs/node/pull/13614) +* [[`e5fbc03563`](https://github.com/nodejs/node/commit/e5fbc03563)] - **test**: replace fixturesDir with common.fixtures (Kasim Doctor) [#15810](https://github.com/nodejs/node/pull/15810) +* [[`2ab826c497`](https://github.com/nodejs/node/commit/2ab826c497)] - **test**: replaced fs.readSync with fixtures.readSync (Lam Chan) [#15882](https://github.com/nodejs/node/pull/15882) +* [[`1fe3e866cf`](https://github.com/nodejs/node/commit/1fe3e866cf)] - **test**: improve coverage for process.umask (Evan Lucas) [#16188](https://github.com/nodejs/node/pull/16188) +* [[`0689ea66ed`](https://github.com/nodejs/node/commit/0689ea66ed)] - **test**: remove message from notStrictEqual (twk-b) [#16048](https://github.com/nodejs/node/pull/16048) +* [[`fafbbb6347`](https://github.com/nodejs/node/commit/fafbbb6347)] - **test**: use fixtures module (Ben Hallion) [#15808](https://github.com/nodejs/node/pull/15808) +* [[`f2108fa51d`](https://github.com/nodejs/node/commit/f2108fa51d)] - **test**: use ES6 classes instead of util.inherits (Tobias Nießen) [#16938](https://github.com/nodejs/node/pull/16938) +* [[`eb11a70424`](https://github.com/nodejs/node/commit/eb11a70424)] - **test**: refactor test-cluster-setup-master (Jean-Baptiste Brossard) [#16065](https://github.com/nodejs/node/pull/16065) +* [[`e00a4c820f`](https://github.com/nodejs/node/commit/e00a4c820f)] - **test**: replace fixtureDir with fixtures methods (Vladimir Ilic) [#16114](https://github.com/nodejs/node/pull/16114) +* [[`f46e1187b3`](https://github.com/nodejs/node/commit/f46e1187b3)] - **test**: remove error messages in crypto-binary test (Kim Gentes) [#15981](https://github.com/nodejs/node/pull/15981) +* [[`086d8519a1`](https://github.com/nodejs/node/commit/086d8519a1)] - **test**: use fixtures module over fixturesDir (JamesNimlos) [#15847](https://github.com/nodejs/node/pull/15847) +* [[`38179fd1ed`](https://github.com/nodejs/node/commit/38179fd1ed)] - **test**: use common.fixtures module (Shaun Sweet) [#15992](https://github.com/nodejs/node/pull/15992) +* [[`229a1fa299`](https://github.com/nodejs/node/commit/229a1fa299)] - **test**: replace fixturesDir with fixtures.path (Bear Trickey) [#15994](https://github.com/nodejs/node/pull/15994) +* [[`c10594f70f`](https://github.com/nodejs/node/commit/c10594f70f)] - **test**: update fixturesDir import (Tyler Seabrook) [#15887](https://github.com/nodejs/node/pull/15887) +* [[`53449f303f`](https://github.com/nodejs/node/commit/53449f303f)] - **test**: replace fixturesDir with fixtures methods (Komivi Agbakpem) [#15967](https://github.com/nodejs/node/pull/15967) +* [[`a28d666f0e`](https://github.com/nodejs/node/commit/a28d666f0e)] - **test**: replace fixturesDir with the fixtures module (WeiPlanet) [#16027](https://github.com/nodejs/node/pull/16027) +* [[`d59175090d`](https://github.com/nodejs/node/commit/d59175090d)] - **test**: change crypto decipheriv assertion messages (Daniel Kostro) [#16007](https://github.com/nodejs/node/pull/16007) +* [[`541866ea86`](https://github.com/nodejs/node/commit/541866ea86)] - **test**: replaces fixturesDir with fixtures (Mike Fleming) [#15835](https://github.com/nodejs/node/pull/15835) +* [[`57ae105c72`](https://github.com/nodejs/node/commit/57ae105c72)] - **test**: remove test messages for assert.strictEqual (Ali Groening) [#15995](https://github.com/nodejs/node/pull/15995) +* [[`87b9b7c8c4`](https://github.com/nodejs/node/commit/87b9b7c8c4)] - **test**: move to common.fixtures (Justin Beckwith) [#15987](https://github.com/nodejs/node/pull/15987) +* [[`72f69f3c2c`](https://github.com/nodejs/node/commit/72f69f3c2c)] - **test**: added fixtures module (Michael Pal) [#15980](https://github.com/nodejs/node/pull/15980) +* [[`65c5ff8e92`](https://github.com/nodejs/node/commit/65c5ff8e92)] - **test**: use fixtures in test-tls-multi-key.js (Cheyenne Arrowsmith) [#15844](https://github.com/nodejs/node/pull/15844) +* [[`9eac5aab8c`](https://github.com/nodejs/node/commit/9eac5aab8c)] - **test**: switch to use common.fixtures.fixturesDir (Roger Jiang) [#15814](https://github.com/nodejs/node/pull/15814) +* [[`449538851c`](https://github.com/nodejs/node/commit/449538851c)] - **test**: use common.fixtures module (Chi-chi Wang) [#16012](https://github.com/nodejs/node/pull/16012) +* [[`04f3f6dd6a`](https://github.com/nodejs/node/commit/04f3f6dd6a)] - **test**: escape script filename on Windows (Bartosz Sosnowski) [#16124](https://github.com/nodejs/node/pull/16124) +* [[`501acdf38c`](https://github.com/nodejs/node/commit/501acdf38c)] - **test**: improve assert message in test-dh-regr (Mabry Cervin) [#15912](https://github.com/nodejs/node/pull/15912) +* [[`4c98e07702`](https://github.com/nodejs/node/commit/4c98e07702)] - **test**: fixtures in test-net-pipe-connect-errors (Eric Freiberg) [#15922](https://github.com/nodejs/node/pull/15922) +* [[`244bfb398d`](https://github.com/nodejs/node/commit/244bfb398d)] - **test**: fixtures in test-process-redirect-warnings-env (Kat Rosario) [#15930](https://github.com/nodejs/node/pull/15930) +* [[`18479d3cff`](https://github.com/nodejs/node/commit/18479d3cff)] - **test**: fix ordering of strictEqual actual/expected (Chad Zezula) [#16008](https://github.com/nodejs/node/pull/16008) +* [[`66fd6a1409`](https://github.com/nodejs/node/commit/66fd6a1409)] - **test**: use fixtures.readSync (szhang351) +* [[`6d33564b1a`](https://github.com/nodejs/node/commit/6d33564b1a)] - **test**: replaced fixturesDir with common.fixtures (Dolapo Toki) [#15836](https://github.com/nodejs/node/pull/15836) +* [[`a6f04bec9e`](https://github.com/nodejs/node/commit/a6f04bec9e)] - **test**: use fixtures.fixturesDir (Gene Wu) [#15822](https://github.com/nodejs/node/pull/15822) +* [[`2103453977`](https://github.com/nodejs/node/commit/2103453977)] - **test**: replaces fixturesDir with fixtures methods (Christian Murphy) [#15817](https://github.com/nodejs/node/pull/15817) +* [[`e705ad2076`](https://github.com/nodejs/node/commit/e705ad2076)] - **test**: fixtures in test-process-redirect-warnings (Nicolas Chaulet) [#15917](https://github.com/nodejs/node/pull/15917) +* [[`9ddbcc877b`](https://github.com/nodejs/node/commit/9ddbcc877b)] - **test**: update test-crypto-from-binary (Raj Parekh) [#16011](https://github.com/nodejs/node/pull/16011) +* [[`6b8830c1df`](https://github.com/nodejs/node/commit/6b8830c1df)] - **test**: use fixtures in test-https-set-timeout-server (Bob Clewell) [#15886](https://github.com/nodejs/node/pull/15886) +* [[`57590cd097`](https://github.com/nodejs/node/commit/57590cd097)] - **test**: make use of common/fixtures.fixturesDir (Jem Bezooyen) [#15815](https://github.com/nodejs/node/pull/15815) +* [[`c9d07faa04`](https://github.com/nodejs/node/commit/c9d07faa04)] - **test**: use common/fixtures in test-https-close (Alberto Lopez de Lara) [#15870](https://github.com/nodejs/node/pull/15870) +* [[`68a2d394dd`](https://github.com/nodejs/node/commit/68a2d394dd)] - **test**: use fixtures in test-process-warnings (Suresh Srinivas) [#15869](https://github.com/nodejs/node/pull/15869) +* [[`28756b318a`](https://github.com/nodejs/node/commit/28756b318a)] - **test**: use fixtures in tls-friendly-error-message (tobyfarley) [#15905](https://github.com/nodejs/node/pull/15905) +* [[`a05fe5f716`](https://github.com/nodejs/node/commit/a05fe5f716)] - **test**: use common/fixtures in tls-connect-no-host (Donovan Buck) [#15986](https://github.com/nodejs/node/pull/15986) +* [[`cf31eb7532`](https://github.com/nodejs/node/commit/cf31eb7532)] - **test**: use common/fixtures in test-https-agent (jpaulptr) [#15941](https://github.com/nodejs/node/pull/15941) +* [[`c9c37d076c`](https://github.com/nodejs/node/commit/c9c37d076c)] - **test**: use common fixtures module (Kat Rosario) [#15856](https://github.com/nodejs/node/pull/15856) +* [[`76ab029bea`](https://github.com/nodejs/node/commit/76ab029bea)] - **test**: fs.readFileSync -\> fixtures.readKey (Ethan Brown) [#16030](https://github.com/nodejs/node/pull/16030) +* [[`dabdb2d186`](https://github.com/nodejs/node/commit/dabdb2d186)] - **test**: reduce run time for misc benchmark tests (Rich Trott) [#16120](https://github.com/nodejs/node/pull/16120) +* [[`3f56ac4450`](https://github.com/nodejs/node/commit/3f56ac4450)] - **test**: improve assertion message in dgram test (Shakeel Mohamed) [#16121](https://github.com/nodejs/node/pull/16121) +* [[`44a60c3807`](https://github.com/nodejs/node/commit/44a60c3807)] - **test**: use of fixtures in test-pipe-head (Nicolas Chaulet) [#15868](https://github.com/nodejs/node/pull/15868) +* [[`c4db4e44b8`](https://github.com/nodejs/node/commit/c4db4e44b8)] - **test**: use fixtures in test-https-localaddress.js (Charles T Wall III) [#15811](https://github.com/nodejs/node/pull/15811) +* [[`c252d874d7`](https://github.com/nodejs/node/commit/c252d874d7)] - **test**: use common/fixtures in fs-symlink test (AlexeyM) [#15830](https://github.com/nodejs/node/pull/15830) +* [[`07c14f3054`](https://github.com/nodejs/node/commit/07c14f3054)] - **test**: replace common.fixtures with fixtures module (Jonathan Eskew) [#15877](https://github.com/nodejs/node/pull/15877) +* [[`0f23836e7b`](https://github.com/nodejs/node/commit/0f23836e7b)] - **test**: improve assert message (Tri Nguyen) [#15909](https://github.com/nodejs/node/pull/15909) +* [[`bbdbf8b9b0`](https://github.com/nodejs/node/commit/bbdbf8b9b0)] - **test**: replace fixturesDir with fixtures method (suraiyah) [#15894](https://github.com/nodejs/node/pull/15894) +* [[`c35420d21d`](https://github.com/nodejs/node/commit/c35420d21d)] - **test**: normalize fixtures use (Ruxandra Fediuc) [#15855](https://github.com/nodejs/node/pull/15855) +* [[`3c176fd6f6`](https://github.com/nodejs/node/commit/3c176fd6f6)] - **test**: replace common.fixturesDir w/common.fixtures (Jason Walton) [#15853](https://github.com/nodejs/node/pull/15853) +* [[`77f9ef32bd`](https://github.com/nodejs/node/commit/77f9ef32bd)] - **test**: switch to use common.fixtures module for fixturesDir (r1cebank) [#15821](https://github.com/nodejs/node/pull/15821) +* [[`71e68799ef`](https://github.com/nodejs/node/commit/71e68799ef)] - **test**: fixturesDir replaced to fixtures module (Pawel Golda) [#15809](https://github.com/nodejs/node/pull/15809) +* [[`d70f9f6a35`](https://github.com/nodejs/node/commit/d70f9f6a35)] - **test**: replace common.fixturesDir with fixtures (Stefania Sharp) [#16015](https://github.com/nodejs/node/pull/16015) +* [[`4cf84ea76e`](https://github.com/nodejs/node/commit/4cf84ea76e)] - **test**: replaces common.fixturesDir usage (Ruy Adorno) [#15818](https://github.com/nodejs/node/pull/15818) +* [[`788d7db4e9`](https://github.com/nodejs/node/commit/788d7db4e9)] - **test**: use common.fixtures.path() (Tobias Kieslich) [#16112](https://github.com/nodejs/node/pull/16112) +* [[`b7865ea70d`](https://github.com/nodejs/node/commit/b7865ea70d)] - **test**: replace common.fixturesDir with fixtures (Shakeel Mohamed) [#15857](https://github.com/nodejs/node/pull/15857) +* [[`9b39ca6cbb`](https://github.com/nodejs/node/commit/9b39ca6cbb)] - **test**: use fixtures module in test (Nigel Kibodeaux) [#16117](https://github.com/nodejs/node/pull/16117) +* [[`5e65069289`](https://github.com/nodejs/node/commit/5e65069289)] - **test**: use template literals in test-string-decoder (Edward Andrew Robinson) [#15884](https://github.com/nodejs/node/pull/15884) +* [[`d2b74fe1e3`](https://github.com/nodejs/node/commit/d2b74fe1e3)] - **test**: switch to fixtures module (Christopher Sidebottom) [#15880](https://github.com/nodejs/node/pull/15880) +* [[`1144be09b7`](https://github.com/nodejs/node/commit/1144be09b7)] - **test**: rewrite assert message (Martin Michaelis) [#15879](https://github.com/nodejs/node/pull/15879) +* [[`095df35a5e`](https://github.com/nodejs/node/commit/095df35a5e)] - **test**: change fixturesDir to fixtures.path (Guilherme Akio Sakae) [#15863](https://github.com/nodejs/node/pull/15863) +* [[`4fd5bf5ff7`](https://github.com/nodejs/node/commit/4fd5bf5ff7)] - **test**: replace fixturesDir with common.fixtures (Oliver Luebeck) [#15907](https://github.com/nodejs/node/pull/15907) +* [[`e3e234ea1c`](https://github.com/nodejs/node/commit/e3e234ea1c)] - **test**: update http test client function signatures (Jakub Mrowiec - Alkagar) [#15807](https://github.com/nodejs/node/pull/15807) +* [[`08ca73f52a`](https://github.com/nodejs/node/commit/08ca73f52a)] - **test**: replace common.fixturesDir w/ fixtures.path (Druotic) [#15819](https://github.com/nodejs/node/pull/15819) +* [[`39ae3f1802`](https://github.com/nodejs/node/commit/39ae3f1802)] - **test**: replace fixtureDir with fixtures.path (matthewreed26) [#15943](https://github.com/nodejs/node/pull/15943) +* [[`1365a6f597`](https://github.com/nodejs/node/commit/1365a6f597)] - **test**: use common.fixtures module for file path (Adil L) [#16017](https://github.com/nodejs/node/pull/16017) +* [[`bd8d4401ee`](https://github.com/nodejs/node/commit/bd8d4401ee)] - **test**: use fixtures module (Maurice Hayward) [#16034](https://github.com/nodejs/node/pull/16034) +* [[`bba5263d00`](https://github.com/nodejs/node/commit/bba5263d00)] - **test**: replace fixturesDir with fixtures module (tabulatedreams) [#16036](https://github.com/nodejs/node/pull/16036) +* [[`a8e7fa4e75`](https://github.com/nodejs/node/commit/a8e7fa4e75)] - **test**: replace fixturesDir with fixtures module (Ivan Etchart) [#15893](https://github.com/nodejs/node/pull/15893) +* [[`1fc3851642`](https://github.com/nodejs/node/commit/1fc3851642)] - **test**: change fixturesDir to fixtures.path (Savio Lucena) [#15902](https://github.com/nodejs/node/pull/15902) +* [[`683e48cb55`](https://github.com/nodejs/node/commit/683e48cb55)] - **test**: changed fixtures require (creisle) [#15899](https://github.com/nodejs/node/pull/15899) +* [[`f82f691d5e`](https://github.com/nodejs/node/commit/f82f691d5e)] - **test**: replaced fixturesDir with fixtures module (Alex McKenzie) [#15908](https://github.com/nodejs/node/pull/15908) +* [[`e68ef291e7`](https://github.com/nodejs/node/commit/e68ef291e7)] - **test**: use common.fixtures in tls test (Ben Michel) [#15965](https://github.com/nodejs/node/pull/15965) +* [[`71daa68c3d`](https://github.com/nodejs/node/commit/71daa68c3d)] - **test**: use fixtures module instead of common (Joe Grace) [#15925](https://github.com/nodejs/node/pull/15925) +* [[`e81fc8aca7`](https://github.com/nodejs/node/commit/e81fc8aca7)] - **test**: replaced fixturesDir with fixtures module (Alex McKenzie) [#15927](https://github.com/nodejs/node/pull/15927) +* [[`33ea6deeab`](https://github.com/nodejs/node/commit/33ea6deeab)] - **test**: replace fixturesDir with fixtures module (Greg Matthews) [#15932](https://github.com/nodejs/node/pull/15932) +* [[`be2b70bb56`](https://github.com/nodejs/node/commit/be2b70bb56)] - **test**: replace fixturesDir with fixtures (Mujtaba Al-Tameemi) [#15949](https://github.com/nodejs/node/pull/15949) +* [[`25a5bf02c7`](https://github.com/nodejs/node/commit/25a5bf02c7)] - **test**: remove common.fixturesDir (Luis Del Águila) [#15950](https://github.com/nodejs/node/pull/15950) +* [[`51d87e338e`](https://github.com/nodejs/node/commit/51d87e338e)] - **test**: replace fixturesDir with fixtures module (BinarySo1o) [#15961](https://github.com/nodejs/node/pull/15961) +* [[`05286b6c80`](https://github.com/nodejs/node/commit/05286b6c80)] - **test**: replaced fixturesDir with common.fixtures (jopann) [#15971](https://github.com/nodejs/node/pull/15971) +* [[`683c5fa58f`](https://github.com/nodejs/node/commit/683c5fa58f)] - **test**: use common.fixtures module in test-preload (Laura Cabrera) [#15975](https://github.com/nodejs/node/pull/15975) +* [[`000965d427`](https://github.com/nodejs/node/commit/000965d427)] - **test**: replaced common.fixturesDir with readKey (Sean Cox) [#15933](https://github.com/nodejs/node/pull/15933) +* [[`0f8b315a9e`](https://github.com/nodejs/node/commit/0f8b315a9e)] - **test**: replace fixturesDir in tls-env-bad-extra-ca (Annie Weng) [#15813](https://github.com/nodejs/node/pull/15813) +* [[`48a55d1364`](https://github.com/nodejs/node/commit/48a55d1364)] - **test**: use common.fixtures in checkServerIdentity (Emily Marigold Klassen) [#15951](https://github.com/nodejs/node/pull/15951) +* [[`909e587a93`](https://github.com/nodejs/node/commit/909e587a93)] - **test**: replaced common.fixturesDir with readKey (rhalldearn) [#15952](https://github.com/nodejs/node/pull/15952) +* [[`544cbd7884`](https://github.com/nodejs/node/commit/544cbd7884)] - **test**: replace fixturesDir with fixtures.readKey (Thomas Schorn) [#15948](https://github.com/nodejs/node/pull/15948) +* [[`4005ed619f`](https://github.com/nodejs/node/commit/4005ed619f)] - **test**: replace common.fixturesDir with fixtures. (Sam Skjonsberg) [#15802](https://github.com/nodejs/node/pull/15802) +* [[`8c5b51d9c3`](https://github.com/nodejs/node/commit/8c5b51d9c3)] - **test**: replace fixturesDir with common.fixtures (rachelnicole) [#16051](https://github.com/nodejs/node/pull/16051) +* [[`107acb1c56`](https://github.com/nodejs/node/commit/107acb1c56)] - **test**: update fixturesDir to fixtures.readKey (bitandbang) [#16016](https://github.com/nodejs/node/pull/16016) +* [[`643a2c6b19`](https://github.com/nodejs/node/commit/643a2c6b19)] - **test**: replace fixturesDir with common.fixtures (Pooya Paridel) [#15837](https://github.com/nodejs/node/pull/15837) +* [[`14aee78554`](https://github.com/nodejs/node/commit/14aee78554)] - **test**: update 'fixturesDir' refs in a test file (James M. Greene) [#15824](https://github.com/nodejs/node/pull/15824) +* [[`e1c45efdbb`](https://github.com/nodejs/node/commit/e1c45efdbb)] - **test**: use fixtures.readKey in https-agent test (Greg Byram) [#15913](https://github.com/nodejs/node/pull/15913) +* [[`2c6aa17fa9`](https://github.com/nodejs/node/commit/2c6aa17fa9)] - **test**: add test for fork() + shell (cjihrig) [#15352](https://github.com/nodejs/node/pull/15352) +* [[`148a030345`](https://github.com/nodejs/node/commit/148a030345)] - **test**: remove node-tap lookalike (cjihrig) [#13707](https://github.com/nodejs/node/pull/13707) +* [[`fa5c706bec`](https://github.com/nodejs/node/commit/fa5c706bec)] - **test**: refactor exitedAfterDisconnect test (Rich Trott) [#16729](https://github.com/nodejs/node/pull/16729) +* [[`9416dab7ac`](https://github.com/nodejs/node/commit/9416dab7ac)] - **test**: use fixtures module in test-https-pfx (Ken Takagi) [#15895](https://github.com/nodejs/node/pull/15895) +* [[`7e9779aade`](https://github.com/nodejs/node/commit/7e9779aade)] - **test**: refactor test-readline-keys (Rich Trott) [#11281](https://github.com/nodejs/node/pull/11281) +* [[`8264328087`](https://github.com/nodejs/node/commit/8264328087)] - **test,net**: remove scatological terminology (Rich Trott) [#16599](https://github.com/nodejs/node/pull/16599) +* [[`bb81390db2`](https://github.com/nodejs/node/commit/bb81390db2)] - **timers**: fix eventloop block (zhangzifa) [#15072](https://github.com/nodejs/node/pull/15072) +* [[`f3749d7b2c`](https://github.com/nodejs/node/commit/f3749d7b2c)] - **tools**: remove unneeded parentheses in doc/html.js (Vse Mozhet Byt) [#16845](https://github.com/nodejs/node/pull/16845) +* [[`1c192f50f6`](https://github.com/nodejs/node/commit/1c192f50f6)] - **tools**: replace string concatenation with template literals (Kevin Yu) [#16804](https://github.com/nodejs/node/pull/16804) +* [[`ce007be05b`](https://github.com/nodejs/node/commit/ce007be05b)] - **tools**: replace string concatenation with template literals (Giovanni Lela) [#16806](https://github.com/nodejs/node/pull/16806) +* [[`d165d3fd1c`](https://github.com/nodejs/node/commit/d165d3fd1c)] - **tools**: replace string concetation with templates (Patrick Heneise) [#16801](https://github.com/nodejs/node/pull/16801) +* [[`a8d7f5f52e`](https://github.com/nodejs/node/commit/a8d7f5f52e)] - **tools**: fix cpplint.py when path contains non-ascii (sharkfisher) [#16047](https://github.com/nodejs/node/pull/16047) +* [[`b48471ac10`](https://github.com/nodejs/node/commit/b48471ac10)] - **tools**: rename unused variale in more pythonic way (Nikhil Komawar) [#16171](https://github.com/nodejs/node/pull/16171) +* [[`5b5b5c0f15`](https://github.com/nodejs/node/commit/5b5b5c0f15)] - **tools**: use template literal in error message (Tim Chon) [#15846](https://github.com/nodejs/node/pull/15846) +* [[`ae5930bbe4`](https://github.com/nodejs/node/commit/ae5930bbe4)] - **tty,doc**: add type-check to isatty (Bryan English) [#15567](https://github.com/nodejs/node/pull/15567) + ## 2017-11-07, Version 6.12.0 'Boron' (LTS), @MylesBorins diff --git a/src/node_version.h b/src/node_version.h index 6402225de45051..1d51dd26601860 100644 --- a/src/node_version.h +++ b/src/node_version.h @@ -8,7 +8,7 @@ #define NODE_VERSION_IS_LTS 1 #define NODE_VERSION_LTS_CODENAME "Boron" -#define NODE_VERSION_IS_RELEASE 0 +#define NODE_VERSION_IS_RELEASE 1 #ifndef NODE_STRINGIFY #define NODE_STRINGIFY(n) NODE_STRINGIFY_HELPER(n)