diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 00000000000000..18ce90bb9da344 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,88 @@ +# Remember: order matters. Subsequent rules will override prior rules. + +*addons* @nodejs/addon-api +*assert* @nodejs/testing +*async_hook* @nodejs/async_hooks @nodejs/diagnostics +*async_wrap* @nodejs/async_hooks +*buffer* @nodejs/buffer +*child_process* @nodejs/child_process +*cluster* @nodejs/cluster +*crypto* @nodejs/crypto +*eslint* @nodejs/linting +*fs* @nodejs/fs +*tls* @nodejs/tls @nodejs/crypto +*dgram* @nodejs/dgram +*domain* @nodejs/domains +*http* @nodejs/http +*http2* @nodejs/http2 +*https* @nodejs/http @nodejs/crypto @nodejs/tls @nodejs/http2 +*inspector* @nodejs/v8-inspector +*net* @nodejs/streams +*node_api* @nodejs/n-api +*repl* @nodejs/repl +*stream* @nodejs/streams +*timer* @nodejs/timers +*trace_events* @nodejs/trace-events +*url* @nodejs/url +*util* @nodejs/util +*vm* @nodejs/vm +*zlib* @nodejs/zlib + +*esm* @nodejs/modules +/lib/internal/modules/esm/ @nodejs/modules +/lib/internal/bootstrap/loaders.js @nodejs/modules + +/src/node.cc @nodejs/process +/src/node_file.* @nodejs/fs +/src/node_stat_watcher.* @nodejs/fs +/lib/internal/bootstrap/ @nodejs/process +/lib/internal/process/ @nodejs/process +/test/ @nodejs/testing + +/deps/node-inspect @nodejs/V8-inspector +/deps/gtest/ @nodejs/testing @nodejs/v8 @nodejs/v8-update +/deps/icu/ @nodejs/intl +/deps/http_parser/ @nodejs/http-parser @nodejs/http +/deps/zlib/ @nodejs/zlib +/deps/uv/ @nodejs/libuv +/deps/npm/ @nodejs/npm +/deps/v8/ @nodejs/v8 @nodejs/v8-update +/deps/zlib @nodejs/zlib +/deps/openssl @nodejs/crypto + +/benchmark/ @nodejs/performance @nodejs/benchmarking + +/doc/ @nodejs/documentation +*.md @nodejs/documentation +*.py @nodejs/python +*.gyp @nodejs/gyp +*.gypi @nodejs/gyp + +Makefile @nodejs/build +vcbuild.bat @nodejs/build +BUILDING.md @nodejs/build +configure @nodejs/build +BSDMakefile @nodejs/build +android-configure @nodejs/build + +*aix* @nodejs/platform-aix +*arm* @nodejs/platform-arm +*freebsd* @nodejs/platform-freebsd +*macos* @nodejs/platform-macos +*ppc* @nodejs/platform-ppc +*smartos* @nodejs/platform-smartos +*s390* @nodejs/platform-s390 +*windows* @nodejs/platform-windows + +/src/node_postmortem_metadata.cc @nodejs/diagnostics @nodejs/post-mortem +/src/*.d @nodejs/diagnostics @nodejs/platform-smartos @nodejs/platform-freebsd @nodejs/platform-macos @nodejs/dtrace-mdb +/src/node.stp @nodejs/diagnostics + +/.github/ @nodejs/tsc +CODE_OF_CONDUCT.md @nodejs/tsc +COLLABORATOR_GUIDE.md @nodejs/tsc +CONTRIBUTING.md @nodejs/tsc +CPP_STYLE_GUIDE.md @nodejs/tsc +GOVERNANCE.md @nodejs/tsc +LICENSE @nodejs/tsc +/README.md @nodejs/tsc diff --git a/.gitignore b/.gitignore index ebeedeac6b8fe0..e6b25de69040fb 100644 --- a/.gitignore +++ b/.gitignore @@ -123,6 +123,8 @@ deps/uv/docs/src/guide/ # do not override V8's .gitignore !deps/v8/** # ignore VS compiler output unhandled by V8's .gitignore +deps/v8/gypfiles/Debug/ +deps/v8/gypfiles/Release/ deps/v8/src/Debug/ deps/v8/src/Release/ deps/v8/src/inspector/Debug/ diff --git a/.mailmap b/.mailmap index 48da4f54b23828..16c9bf1ea21ef6 100644 --- a/.mailmap +++ b/.mailmap @@ -110,6 +110,7 @@ Evan Lucas FangDun Cai Fangdun Cai (Fundon) Fangshi He hefangshi Farid Neshat +Fatah N fatahn Fedor Indutny Felix Böhm Felix Geisendörfer @@ -145,6 +146,7 @@ Imran Iqbal Ionică Bizău Isaac Z. Schlueter Isaac Z. Schlueter +Isuru Siriwardana isurusiri Italo A. Casas Jackson Tian Jake Verbaten @@ -169,6 +171,7 @@ John Barboza jBarz John Barboza jBarz John Gardner Alhadis John McGuirk jmcgui05 +John Musgrave musgravejw Johnny Ray Austin Johnny Ray Jon Tippens legalcodes Jonas Pfenniger @@ -365,6 +368,7 @@ Tom Hughes-Croucher Tom Purcell tpurcell Tom White Tomoki Okahana umatoma +Tracy Hinds Tracy Travis Meisenheimer Trevor Burnham Trivikram Kamat <16024985+trivikr@users.noreply.github.com> diff --git a/.nycrc b/.nycrc index 9e34a976e21ef6..c826fbc02d5dd0 100644 --- a/.nycrc +++ b/.nycrc @@ -2,5 +2,6 @@ "exclude": [ "**/internal/process/write-coverage.js" ], + "compact": false, "reporter": ["html", "text"] } diff --git a/AUTHORS b/AUTHORS index dfacc53994b2d8..3a156cbd2cb373 100644 --- a/AUTHORS +++ b/AUTHORS @@ -2139,5 +2139,63 @@ wangzengdi Garwah Lam jaspal-yupana Arian Santrach +Forrest Wolf +Fatah N +Divyanshu Singh +FallenRiteMonk +Rajkumar Purushothaman +Chris Miller +Dave O'Mahony +nodeav <30617226+nodeav@users.noreply.github.com> +Zhenzhen Zhan +Ryusei Yamaguchi +Kohei Hiraga +Nick Filatov +Jesse Gorzinski +Pieter Mees +Malcolm White +Gerhard Stoebich +Matei Copot +ikasumiwt +Gurin, Sebastian +Indranil Dasgupta +Harry Sarson +Snehil Verma +Joseph Gordon +Antoine du HAMEL +Rémi Berson +Alec Larson +Daven Casia +Isuru Siriwardana +Spencer Greene +Palash Nigam +SheetJS +Bryan Azofeifa +Christine E. Taylor +John Musgrave +Dhansuhu Uzumaki +Beni von Cheni +Ilya Sotov +William Cohen +Ajido +Mithun Sasidharan +kailash k yogeshwar +Daniel Hritzkiv +Mark Tiedemann +xsbchen +Kyle Martin +Denis Fäcke +Daylor Yanes +Carrie Coxwell +BeniCheni +Masashi Hirano +Brandon Ruggles +Allen Yonghuang Wang +Yichao 'Peak' Ji +Jesse W. Collins +TSUYUSATO Kitsune +daGo +Lambdac0re +Yulong Wang # Generated by tools/update-authors.sh diff --git a/BUILDING.md b/BUILDING.md index 9690e826c396f8..3e053050743c10 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -133,7 +133,7 @@ More Developer Tools...`. This step will install `clang`, `clang++`, and If the path to your build directory contains a space, the build will likely fail. -After building, setting up [firewall rules](tools/macosx-firewall.sh) can avoid +After building, setting up [firewall rules](tools/macos-firewall.sh) can avoid popups asking to accept incoming network connections when running tests. Running the following script on macOS will add the firewall rules for the @@ -141,7 +141,7 @@ executable `node` in the `out` directory and the symbolic `node` link in the project's root directory. ```console -$ sudo ./tools/macosx-firewall.sh +$ sudo ./tools/macos-firewall.sh ``` On FreeBSD and OpenBSD, you may also need: @@ -423,8 +423,9 @@ $ ./configure --link-module '/root/myModule.js' --link-module './myModule2.js' ### Windows -To make `./myCustomModule.js` available via `require('myCustomModule')`. +To make `./myModule.js` available via `require('myModule')` and +`./myModule2.js` available via `require('myModule2')`: ```console -> .\vcbuild link-module './myCustomModule.js' +> .\vcbuild link-module './myModule.js' link-module './myModule2.js' ``` diff --git a/CHANGELOG.md b/CHANGELOG.md index 053e4381c1563c..8ddad5af9fb4c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,7 +33,8 @@ release. -10.1.0
+10.2.0
+10.1.0
10.0.0
diff --git a/COLLABORATOR_GUIDE.md b/COLLABORATOR_GUIDE.md index 0cb03822c98947..f5ffd35f04aa02 100644 --- a/COLLABORATOR_GUIDE.md +++ b/COLLABORATOR_GUIDE.md @@ -411,8 +411,11 @@ recommended but not required. ### Deprecations -**Deprecation** refers to the identification of Public APIs that should no -longer be used. +[_Deprecation_][] is "the discouragement of use of some … feature … or practice, +typically because it has been superseded or is no longer considered efficient or +safe, without completely removing it or prohibiting its use. It can also imply +that a feature, design, or practice will be removed or discontinued entirely in +the future." Node.js uses three Deprecation levels: @@ -843,7 +846,7 @@ LTS working group and the Release team. | `lib/domains` | @nodejs/domains | | `lib/fs`, `src/{fs,file}` | @nodejs/fs | | `lib/{_}http{*}` | @nodejs/http | -| `lib/inspector.js`, `src/inspector_*` | @nodejs/V8-inspector | +| `lib/inspector.js`, `src/inspector_*` | @nodejs/v8-inspector | | `lib/internal/bootstrap/*` | @nodejs/process | | `lib/internal/url`, `src/node_url` | @nodejs/url | | `lib/net` | @bnoordhuis, @indutny, @nodejs/streams | @@ -875,17 +878,18 @@ When things need extra attention, are controversial, or `semver-major`: If you cannot find who to cc for a file, `git shortlog -n -s ` may help. -[backporting guide]: doc/guides/backporting-to-release-lines.md -[contributing]: ./doc/guides/contributing/pull-requests.md#commit-message-guidelines -[Stability Index]: doc/api/documentation.md#stability-index +["Merge Pull Request"]: https://help.github.com/articles/merging-a-pull-request/#merging-a-pull-request-on-github [Enhancement Proposal]: https://github.com/nodejs/node-eps +[Stability Index]: doc/api/documentation.md#stability-index +[TSC]: https://github.com/nodejs/TSC +[_Deprecation_]: https://en.wikipedia.org/wiki/Deprecation [`--pending-deprecation`]: doc/api/cli.md#--pending-deprecation +[`node-core-utils`]: https://github.com/nodejs/node-core-utils +[backporting guide]: doc/guides/backporting-to-release-lines.md +[contributing]: ./doc/guides/contributing/pull-requests.md#commit-message-guidelines +[flaky tests]: https://github.com/nodejs/node/issues?q=is%3Aopen+is%3Aissue+label%3A%22CI+%2F+flaky+test%22y [git-node]: https://github.com/nodejs/node-core-utils/blob/master/docs/git-node.md [git-node-metadata]: https://github.com/nodejs/node-core-utils/blob/master/docs/git-node.md#git-node-metadata [git-username]: https://help.github.com/articles/setting-your-username-in-git/ -[`node-core-utils`]: https://github.com/nodejs/node-core-utils -[TSC]: https://github.com/nodejs/TSC -[node-core-utils-issues]: https://github.com/nodejs/node-core-utils/issues [node-core-utils-credentials]: https://github.com/nodejs/node-core-utils#setting-up-credentials -["Merge Pull Request"]: https://help.github.com/articles/merging-a-pull-request/#merging-a-pull-request-on-github -[flaky tests]: https://github.com/nodejs/node/issues?q=is%3Aopen+is%3Aissue+label%3A%22CI+%2F+flaky+test%22 +[node-core-utils-issues]: https://github.com/nodejs/node-core-utils/issues diff --git a/Makefile b/Makefile index 02d97b633d87d6..a7099947c72a78 100644 --- a/Makefile +++ b/Makefile @@ -165,8 +165,6 @@ coverage: coverage-test ## Run the tests and generate a coverage report. .PHONY: coverage-build coverage-build: all mkdir -p node_modules - if [ ! -d node_modules/istanbul-merge ]; then \ - $(NODE) ./deps/npm install istanbul-merge --no-save --no-package-lock; fi if [ ! -d node_modules/nyc ]; then \ $(NODE) ./deps/npm install nyc --no-save --no-package-lock; fi if [ ! -d gcovr ]; then git clone -b 3.4 --depth=1 \ @@ -195,11 +193,11 @@ coverage-test: coverage-build mv lib lib__ mv lib_ lib mkdir -p coverage .cov_tmp - $(NODE) ./node_modules/.bin/istanbul-merge --out \ - .cov_tmp/libcov.json 'out/Release/.coverage/coverage-*.json' + $(NODE) ./node_modules/.bin/nyc merge 'out/Release/.coverage' \ + .cov_tmp/libcov.json (cd lib && .$(NODE) ../node_modules/.bin/nyc report \ --temp-directory "$(CURDIR)/.cov_tmp" \ - --report-dir "../coverage") + --report-dir "$(CURDIR)/coverage") -(cd out && "../gcovr/scripts/gcovr" --gcov-exclude='.*deps' \ --gcov-exclude='.*usr' -v -r Release/obj.target \ --html --html-detail -o ../coverage/cxxcoverage.html \ @@ -234,7 +232,8 @@ v8: .PHONY: jstest jstest: build-addons build-addons-napi ## Runs addon tests and JS tests - $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=release \ + $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=$(BUILDTYPE_LOWER) \ + --skip-tests=$(CI_SKIP_TESTS) \ $(CI_JS_SUITES) \ $(CI_NATIVE_SUITES) @@ -265,17 +264,16 @@ test-cov: all $(MAKE) build-addons $(MAKE) build-addons-napi # $(MAKE) cctest - $(MAKE) jstest - $(MAKE) lint + CI_SKIP_TESTS=core_line_numbers.js $(MAKE) jstest test-parallel: all - $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=release parallel + $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=$(BUILDTYPE_LOWER) parallel test-valgrind: all - $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=release --valgrind sequential parallel message + $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=$(BUILDTYPE_LOWER) --valgrind sequential parallel message test-check-deopts: all - $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=release --check-deopts parallel sequential + $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=$(BUILDTYPE_LOWER) --check-deopts parallel sequential benchmark/misc/function_call/build/Release/binding.node: all \ benchmark/misc/function_call/binding.cc \ @@ -398,7 +396,7 @@ clear-stalled: .PHONY: test-gc test-gc: all test/gc/build/Release/binding.node - $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=release gc + $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=$(BUILDTYPE_LOWER) gc .PHONY: test-gc-clean test-gc-clean: @@ -425,7 +423,7 @@ CI_DOC := doctool test-ci-native: LOGLEVEL := info test-ci-native: | test/addons/.buildstamp test/addons-napi/.buildstamp $(PYTHON) tools/test.py $(PARALLEL_ARGS) -p tap --logfile test.tap \ - --mode=release --flaky-tests=$(FLAKY_TESTS) \ + --mode=$(BUILDTYPE_LOWER) --flaky-tests=$(FLAKY_TESTS) \ $(TEST_CI_ARGS) $(CI_NATIVE_SUITES) .PHONY: test-ci-js @@ -433,7 +431,7 @@ test-ci-native: | test/addons/.buildstamp test/addons-napi/.buildstamp # Related CI job: node-test-commit-arm-fanned test-ci-js: | clear-stalled $(PYTHON) tools/test.py $(PARALLEL_ARGS) -p tap --logfile test.tap \ - --mode=release --flaky-tests=$(FLAKY_TESTS) \ + --mode=$(BUILDTYPE_LOWER) --flaky-tests=$(FLAKY_TESTS) \ $(TEST_CI_ARGS) $(CI_JS_SUITES) # Clean up any leftover processes, error if found. ps awwx | grep Release/node | grep -v grep | cat @@ -448,7 +446,7 @@ test-ci: LOGLEVEL := info test-ci: | clear-stalled build-addons build-addons-napi doc-only out/Release/cctest --gtest_output=tap:cctest.tap $(PYTHON) tools/test.py $(PARALLEL_ARGS) -p tap --logfile test.tap \ - --mode=release --flaky-tests=$(FLAKY_TESTS) \ + --mode=$(BUILDTYPE_LOWER) --flaky-tests=$(FLAKY_TESTS) \ $(TEST_CI_ARGS) $(CI_JS_SUITES) $(CI_NATIVE_SUITES) $(CI_DOC) # Clean up any leftover processes, error if found. ps awwx | grep Release/node | grep -v grep | cat @@ -475,7 +473,7 @@ run-ci: build-ci $(MAKE) test-ci test-release: test-build - $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=release + $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=$(BUILDTYPE_LOWER) test-debug: test-build $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=debug @@ -521,7 +519,7 @@ test-npm-publish: $(NODE_EXE) .PHONY: test-addons-napi test-addons-napi: test-build-addons-napi - $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=release addons-napi + $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=$(BUILDTYPE_LOWER) addons-napi .PHONY: test-addons-napi-clean test-addons-napi-clean: @@ -530,7 +528,7 @@ test-addons-napi-clean: .PHONY: test-addons test-addons: test-build test-addons-napi - $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=release addons + $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=$(BUILDTYPE_LOWER) addons .PHONY: test-addons-clean test-addons-clean: @@ -541,19 +539,19 @@ test-addons-clean: test-timers: $(MAKE) --directory=tools faketime - $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=release timers + $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=$(BUILDTYPE_LOWER) timers test-timers-clean: $(MAKE) --directory=tools clean test-async-hooks: - $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=release async-hooks + $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=$(BUILDTYPE_LOWER) async-hooks test-with-async-hooks: $(MAKE) build-addons $(MAKE) build-addons-napi $(MAKE) cctest - NODE_TEST_WITH_ASYNC_HOOKS=1 $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=release \ + NODE_TEST_WITH_ASYNC_HOOKS=1 $(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=$(BUILDTYPE_LOWER) \ $(CI_JS_SUITES) \ $(CI_NATIVE_SUITES) diff --git a/benchmark/tls/secure-pair.js b/benchmark/tls/secure-pair.js new file mode 100644 index 00000000000000..ed678b9060983e --- /dev/null +++ b/benchmark/tls/secure-pair.js @@ -0,0 +1,105 @@ +'use strict'; +const common = require('../common.js'); +const bench = common.createBenchmark(main, { + dur: [5], + securing: ['SecurePair', 'TLSSocket'], + size: [2, 1024, 1024 * 1024] +}); + +const fs = require('fs'); +const tls = require('tls'); +const net = require('net'); +const path = require('path'); + +const cert_dir = path.resolve(__dirname, '../../test/fixtures'); +const REDIRECT_PORT = 28347; + +function main({ dur, size, securing }) { + const chunk = Buffer.alloc(size, 'b'); + + const options = { + key: fs.readFileSync(`${cert_dir}/test_key.pem`), + cert: fs.readFileSync(`${cert_dir}/test_cert.pem`), + ca: [ fs.readFileSync(`${cert_dir}/test_ca.pem`) ], + ciphers: 'AES256-GCM-SHA384', + isServer: true, + requestCert: true, + rejectUnauthorized: true, + }; + + const server = net.createServer(onRedirectConnection); + server.listen(REDIRECT_PORT, () => { + const proxy = net.createServer(onProxyConnection); + proxy.listen(common.PORT, () => { + const clientOptions = { + port: common.PORT, + ca: options.ca, + key: options.key, + cert: options.cert, + isServer: false, + rejectUnauthorized: false, + }; + const conn = tls.connect(clientOptions, () => { + setTimeout(() => { + const mbits = (received * 8) / (1024 * 1024); + bench.end(mbits); + if (conn) + conn.destroy(); + server.close(); + proxy.close(); + }, dur * 1000); + bench.start(); + conn.on('drain', write); + write(); + }); + conn.on('error', (e) => { + throw new Error(`Client error: ${e}`); + }); + + function write() { + while (false !== conn.write(chunk)); + } + }); + }); + + function onProxyConnection(conn) { + const client = net.connect(REDIRECT_PORT, () => { + switch (securing) { + case 'SecurePair': + securePair(conn, client); + break; + case 'TLSSocket': + secureTLSSocket(conn, client); + break; + default: + throw new Error('Invalid securing method'); + } + }); + } + + function securePair(conn, client) { + const serverCtx = tls.createSecureContext(options); + const serverPair = tls.createSecurePair(serverCtx, true, true, false); + conn.pipe(serverPair.encrypted); + serverPair.encrypted.pipe(conn); + serverPair.on('error', (error) => { + throw new Error(`Pair error: ${error}`); + }); + serverPair.cleartext.pipe(client); + } + + function secureTLSSocket(conn, client) { + const serverSocket = new tls.TLSSocket(conn, options); + serverSocket.on('error', (e) => { + throw new Error(`Socket error: ${e}`); + }); + serverSocket.pipe(client); + } + + let received = 0; + function onRedirectConnection(conn) { + conn.on('data', (chunk) => { + received += chunk.length; + }); + } +} diff --git a/common.gypi b/common.gypi index 3bb10d611fb1d5..d7a730906b537b 100644 --- a/common.gypi +++ b/common.gypi @@ -27,7 +27,7 @@ # Reset this number to 0 on major V8 upgrades. # Increment by one for each non-official patch applied to deps/v8. - 'v8_embedder_string': '-node.6', + 'v8_embedder_string': '-node.8', # Enable disassembler for `--print-code` v8 options 'v8_enable_disassembler': 1, diff --git a/deps/uv/AUTHORS b/deps/uv/AUTHORS index ba360e3f74e277..b605a0f3bc1544 100644 --- a/deps/uv/AUTHORS +++ b/deps/uv/AUTHORS @@ -337,3 +337,4 @@ Thomas Versteeg zzzjim Alex Arslan Kyle Farnung +ssrlive <30760636+ssrlive@users.noreply.github.com> diff --git a/deps/uv/ChangeLog b/deps/uv/ChangeLog index a7cd0ad2dc5003..0ec1488412d630 100644 --- a/deps/uv/ChangeLog +++ b/deps/uv/ChangeLog @@ -1,3 +1,22 @@ +2018.05.08, Version 1.20.3 (Stable), 8cfd67e59195251dff793ee47c185c9d6a8f3818 + +Changes since version 1.20.2: + +* win: add Windows XP support to uv_if_indextoname() (ssrlive) + +* win: fix `'floor' undefined` compiler warning (ssrlive) + +* win, pipe: stop read for overlapped pipe (Bartosz Sosnowski) + +* build: fix utf-8 name of copyright holder (Jérémy Lal) + +* zos: initialize pollfd revents (jBarz) + +* zos,doc: add system V message queue note (jBarz) + +* linux: don't use uv__nonblock_ioctl() on sparc (Ben Noordhuis) + + 2018.04.23, Version 1.20.2 (Stable), c51fd3f66bbb386a1efdeba6812789f35a372d1e Changes since version 1.20.1: diff --git a/deps/uv/README.md b/deps/uv/README.md index 1aaed1a88e7f10..d42ada56a8267e 100644 --- a/deps/uv/README.md +++ b/deps/uv/README.md @@ -322,6 +322,13 @@ describes the package in more detail. AIX support for filesystem events is not compiled when building with `gyp`. +### z/OS Notes + +z/OS creates System V semaphores and message queues. These persist on the system +after the process terminates unless the event loop is closed. + +Use the `ipcrm` command to manually clear up System V resources. + ## Patches See the [guidelines for contributing][]. diff --git a/deps/uv/configure.ac b/deps/uv/configure.ac index f4d97daaba0cb9..5178c60ba1938e 100644 --- a/deps/uv/configure.ac +++ b/deps/uv/configure.ac @@ -13,7 +13,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_PREREQ(2.57) -AC_INIT([libuv], [1.20.2], [https://github.com/libuv/libuv/issues]) +AC_INIT([libuv], [1.20.3], [https://github.com/libuv/libuv/issues]) AC_CONFIG_MACRO_DIR([m4]) m4_include([m4/libuv-extra-automake-flags.m4]) m4_include([m4/as_case.m4]) diff --git a/deps/uv/include/uv-version.h b/deps/uv/include/uv-version.h index 18f40da890bcb9..75f2940cd46b3e 100644 --- a/deps/uv/include/uv-version.h +++ b/deps/uv/include/uv-version.h @@ -32,7 +32,7 @@ #define UV_VERSION_MAJOR 1 #define UV_VERSION_MINOR 20 -#define UV_VERSION_PATCH 2 +#define UV_VERSION_PATCH 3 #define UV_VERSION_IS_RELEASE 1 #define UV_VERSION_SUFFIX "" diff --git a/deps/uv/m4/libuv-check-flags.m4 b/deps/uv/m4/libuv-check-flags.m4 index 59c30635577d1a..e347056ae2ef2c 100644 --- a/deps/uv/m4/libuv-check-flags.m4 +++ b/deps/uv/m4/libuv-check-flags.m4 @@ -1,5 +1,5 @@ dnl Macros to check the presence of generic (non-typed) symbols. -dnl Copyright (c) 2006-2008 Diego Pettenà +dnl Copyright (c) 2006-2008 Diego Pettenò dnl Copyright (c) 2006-2008 xine project dnl dnl This program is free software; you can redistribute it and/or modify @@ -316,4 +316,4 @@ AC_DEFUN([CC_ATTRIBUTE_ALIGNED], [ AC_DEFINE_UNQUOTED([ATTRIBUTE_ALIGNED_MAX], [$cc_cv_attribute_aligned], [Define the highest alignment supported]) fi -]) \ No newline at end of file +]) diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h index b6df1ab9d3e52d..63e478fd98124b 100644 --- a/deps/uv/src/unix/internal.h +++ b/deps/uv/src/unix/internal.h @@ -185,6 +185,18 @@ struct uv__stream_queued_fds_s { #define uv__nonblock uv__nonblock_fcntl #endif +/* On Linux, uv__nonblock_fcntl() and uv__nonblock_ioctl() do not commute + * when O_NDELAY is not equal to O_NONBLOCK. Case in point: linux/sparc32 + * and linux/sparc64, where O_NDELAY is O_NONBLOCK + another bit. + * + * Libuv uses uv__nonblock_fcntl() directly sometimes so ensure that it + * commutes with uv__nonblock(). + */ +#if defined(__linux__) && O_NDELAY != O_NONBLOCK +#undef uv__nonblock +#define uv__nonblock uv__nonblock_fcntl +#endif + /* core */ int uv__cloexec_ioctl(int fd, int set); int uv__cloexec_fcntl(int fd, int set); diff --git a/deps/uv/src/unix/os390-syscalls.c b/deps/uv/src/unix/os390-syscalls.c index 21558ea8689a00..a5dd34426de969 100644 --- a/deps/uv/src/unix/os390-syscalls.c +++ b/deps/uv/src/unix/os390-syscalls.c @@ -215,6 +215,7 @@ uv__os390_epoll* epoll_create1(int flags) { maybe_resize(lst, 1); lst->items[lst->size - 1].fd = lst->msg_queue; lst->items[lst->size - 1].events = POLLIN; + lst->items[lst->size - 1].revents = 0; uv_once(&once, epoll_init); uv_mutex_lock(&global_epoll_lock); QUEUE_INSERT_TAIL(&global_epoll_queue, &lst->member); @@ -252,6 +253,7 @@ int epoll_ctl(uv__os390_epoll* lst, } lst->items[fd].fd = fd; lst->items[fd].events = event->events; + lst->items[fd].revents = 0; } else if (op == EPOLL_CTL_MOD) { if (fd >= lst->size || lst->items[fd].fd == -1) { uv_mutex_unlock(&global_epoll_lock); diff --git a/deps/uv/src/win/getaddrinfo.c b/deps/uv/src/win/getaddrinfo.c index 282d919cf75513..5adc7663bd6b68 100644 --- a/deps/uv/src/win/getaddrinfo.c +++ b/deps/uv/src/win/getaddrinfo.c @@ -392,15 +392,21 @@ int uv_if_indextoname(unsigned int ifindex, char* buffer, size_t* size) { DWORD bufsize; int r; + uv__once_init(); + if (buffer == NULL || size == NULL || *size == 0) return UV_EINVAL; - r = ConvertInterfaceIndexToLuid(ifindex, &luid); + if (pConvertInterfaceIndexToLuid == NULL) + return UV_ENOSYS; + r = pConvertInterfaceIndexToLuid(ifindex, &luid); if (r != 0) return uv_translate_sys_error(r); - r = ConvertInterfaceLuidToNameW(&luid, wname, ARRAY_SIZE(wname)); + if (pConvertInterfaceLuidToNameW == NULL) + return UV_ENOSYS; + r = pConvertInterfaceLuidToNameW(&luid, wname, ARRAY_SIZE(wname)); if (r != 0) return uv_translate_sys_error(r); diff --git a/deps/uv/src/win/pipe.c b/deps/uv/src/win/pipe.c index 0ecfbf1f0e5145..83ee4f99ca363d 100644 --- a/deps/uv/src/win/pipe.c +++ b/deps/uv/src/win/pipe.c @@ -735,6 +735,13 @@ void uv__pipe_unpause_read(uv_pipe_t* handle) { void uv__pipe_stop_read(uv_pipe_t* handle) { + if (pCancelIoEx && + !(handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) && + !(handle->flags & UV_HANDLE_EMULATE_IOCP) && + handle->flags & UV_HANDLE_READING && + handle->read_req.type == UV_READ) { + pCancelIoEx(handle->handle, &handle->read_req.u.io.overlapped); + } handle->flags &= ~UV_HANDLE_READING; uv__pipe_pause_read((uv_pipe_t*)handle); uv__pipe_unpause_read((uv_pipe_t*)handle); diff --git a/deps/uv/src/win/util.c b/deps/uv/src/win/util.c index 5d1c812dd75b2c..49b5bc72061c30 100644 --- a/deps/uv/src/win/util.c +++ b/deps/uv/src/win/util.c @@ -37,7 +37,7 @@ #include #include #include - +#include /* * Max title length; the only thing MSDN tells us about the maximum length diff --git a/deps/uv/src/win/winapi.c b/deps/uv/src/win/winapi.c index 4ccdf0a5f97ca2..c3307861427884 100644 --- a/deps/uv/src/win/winapi.c +++ b/deps/uv/src/win/winapi.c @@ -55,12 +55,16 @@ sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification; /* User32.dll function pointer */ sSetWinEventHook pSetWinEventHook; +/* iphlpapi.dll function pointer */ +sConvertInterfaceIndexToLuid pConvertInterfaceIndexToLuid = NULL; +sConvertInterfaceLuidToNameW pConvertInterfaceLuidToNameW = NULL; void uv_winapi_init(void) { HMODULE ntdll_module; HMODULE kernel32_module; HMODULE powrprof_module; HMODULE user32_module; + HMODULE iphlpapi_module; ntdll_module = GetModuleHandleA("ntdll.dll"); if (ntdll_module == NULL) { @@ -166,4 +170,11 @@ void uv_winapi_init(void) { GetProcAddress(user32_module, "SetWinEventHook"); } + iphlpapi_module = LoadLibraryA("iphlpapi.dll"); + if (iphlpapi_module != NULL) { + pConvertInterfaceIndexToLuid = (sConvertInterfaceIndexToLuid) + GetProcAddress(iphlpapi_module, "ConvertInterfaceIndexToLuid"); + pConvertInterfaceLuidToNameW = (sConvertInterfaceLuidToNameW) + GetProcAddress(iphlpapi_module, "ConvertInterfaceLuidToNameW"); + } } diff --git a/deps/uv/src/win/winapi.h b/deps/uv/src/win/winapi.h index cc54b79b08dd19..38570c2ffa7598 100644 --- a/deps/uv/src/win/winapi.h +++ b/deps/uv/src/win/winapi.h @@ -4775,4 +4775,19 @@ extern sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotifi /* User32.dll function pointer */ extern sSetWinEventHook pSetWinEventHook; +/* iphlpapi.dll function pointer */ +union _NET_LUID_LH; +typedef DWORD (WINAPI *sConvertInterfaceIndexToLuid)( + ULONG InterfaceIndex, + union _NET_LUID_LH *InterfaceLuid); + +typedef DWORD (WINAPI *sConvertInterfaceLuidToNameW)( + const union _NET_LUID_LH *InterfaceLuid, + PWSTR InterfaceName, + size_t Length); + +extern sConvertInterfaceIndexToLuid pConvertInterfaceIndexToLuid; +extern sConvertInterfaceLuidToNameW pConvertInterfaceLuidToNameW; + + #endif /* UV_WIN_WINAPI_H_ */ diff --git a/deps/v8/include/libplatform/v8-tracing.h b/deps/v8/include/libplatform/v8-tracing.h index 9dcf3d7bca760a..e430e7c3502741 100644 --- a/deps/v8/include/libplatform/v8-tracing.h +++ b/deps/v8/include/libplatform/v8-tracing.h @@ -112,6 +112,8 @@ class V8_PLATFORM_EXPORT TraceWriter { virtual void Flush() = 0; static TraceWriter* CreateJSONTraceWriter(std::ostream& stream); + static TraceWriter* CreateJSONTraceWriter(std::ostream& stream, + const std::string& tag); private: // Disallow copy and assign diff --git a/deps/v8/include/v8-version.h b/deps/v8/include/v8-version.h index 81f014cbd4b68d..cdb2c5381e3c85 100644 --- a/deps/v8/include/v8-version.h +++ b/deps/v8/include/v8-version.h @@ -11,7 +11,7 @@ #define V8_MAJOR_VERSION 6 #define V8_MINOR_VERSION 6 #define V8_BUILD_NUMBER 346 -#define V8_PATCH_LEVEL 27 +#define V8_PATCH_LEVEL 32 // Use 1 for candidates and 0 otherwise. // (Boolean macro values are not supported by all preprocessors.) diff --git a/deps/v8/include/v8.h b/deps/v8/include/v8.h index 201c2cc05ca6bd..31407fa0839bb9 100644 --- a/deps/v8/include/v8.h +++ b/deps/v8/include/v8.h @@ -3503,6 +3503,17 @@ class V8_EXPORT Object : public Value { */ Isolate* GetIsolate(); + /** + * If this object is a Set, Map, WeakSet or WeakMap, this returns a + * representation of the elements of this object as an array. + * If this object is a SetIterator or MapIterator, this returns all + * elements of the underlying collection, starting at the iterator's current + * position. + * For other types, this will return an empty MaybeLocal (without + * scheduling an exception). + */ + MaybeLocal PreviewEntries(bool* is_key_value); + static Local New(Isolate* isolate); V8_INLINE static Object* Cast(Value* obj); diff --git a/deps/v8/src/api.cc b/deps/v8/src/api.cc index 2c3f1b797664fd..f5be62058a0f94 100644 --- a/deps/v8/src/api.cc +++ b/deps/v8/src/api.cc @@ -9526,21 +9526,20 @@ int debug::EstimatedValueSize(Isolate* v8_isolate, v8::Local value) { return i::Handle::cast(object)->Size(); } -v8::MaybeLocal debug::EntriesPreview(Isolate* v8_isolate, - v8::Local value, - bool* is_key_value) { - i::Isolate* isolate = reinterpret_cast(v8_isolate); - ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); - if (value->IsMap()) { +v8::MaybeLocal v8::Object::PreviewEntries(bool* is_key_value) { + if (IsMap()) { *is_key_value = true; - return value.As()->AsArray(); + return Map::Cast(this)->AsArray(); } - if (value->IsSet()) { + if (IsSet()) { *is_key_value = false; - return value.As()->AsArray(); + return Set::Cast(this)->AsArray(); } - i::Handle object = Utils::OpenHandle(*value); + i::Handle object = Utils::OpenHandle(this); + i::Isolate* isolate = object->GetIsolate(); + Isolate* v8_isolate = reinterpret_cast(isolate); + ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate); if (object->IsJSWeakCollection()) { *is_key_value = object->IsJSWeakMap(); return Utils::ToLocal(i::JSWeakCollection::GetEntries( diff --git a/deps/v8/src/builtins/arm/builtins-arm.cc b/deps/v8/src/builtins/arm/builtins-arm.cc index 1ea0bb733b324a..329fee575fd44e 100644 --- a/deps/v8/src/builtins/arm/builtins-arm.cc +++ b/deps/v8/src/builtins/arm/builtins-arm.cc @@ -859,9 +859,13 @@ static void AdvanceBytecodeOffsetOrReturn(MacroAssembler* masm, Label process_bytecode, extra_wide; STATIC_ASSERT(0 == static_cast(interpreter::Bytecode::kWide)); STATIC_ASSERT(1 == static_cast(interpreter::Bytecode::kExtraWide)); - __ cmp(bytecode, Operand(0x1)); + STATIC_ASSERT(2 == static_cast(interpreter::Bytecode::kDebugBreakWide)); + STATIC_ASSERT(3 == + static_cast(interpreter::Bytecode::kDebugBreakExtraWide)); + __ cmp(bytecode, Operand(0x3)); __ b(hi, &process_bytecode); - __ b(eq, &extra_wide); + __ tst(bytecode, Operand(0x1)); + __ b(ne, &extra_wide); // Load the next bytecode and update table to the wide scaled table. __ add(bytecode_offset, bytecode_offset, Operand(1)); diff --git a/deps/v8/src/builtins/arm64/builtins-arm64.cc b/deps/v8/src/builtins/arm64/builtins-arm64.cc index 54d2524d6e7d15..f06969ec6bf22d 100644 --- a/deps/v8/src/builtins/arm64/builtins-arm64.cc +++ b/deps/v8/src/builtins/arm64/builtins-arm64.cc @@ -952,9 +952,13 @@ static void AdvanceBytecodeOffsetOrReturn(MacroAssembler* masm, Label process_bytecode, extra_wide; STATIC_ASSERT(0 == static_cast(interpreter::Bytecode::kWide)); STATIC_ASSERT(1 == static_cast(interpreter::Bytecode::kExtraWide)); - __ Cmp(bytecode, Operand(0x1)); + STATIC_ASSERT(2 == static_cast(interpreter::Bytecode::kDebugBreakWide)); + STATIC_ASSERT(3 == + static_cast(interpreter::Bytecode::kDebugBreakExtraWide)); + __ Cmp(bytecode, Operand(0x3)); __ B(hi, &process_bytecode); - __ B(eq, &extra_wide); + __ Tst(bytecode, Operand(0x1)); + __ B(ne, &extra_wide); // Load the next bytecode and update table to the wide scaled table. __ Add(bytecode_offset, bytecode_offset, Operand(1)); diff --git a/deps/v8/src/builtins/builtins-api.cc b/deps/v8/src/builtins/builtins-api.cc index 971fb7c678499f..bb66b082f3edf3 100644 --- a/deps/v8/src/builtins/builtins-api.cc +++ b/deps/v8/src/builtins/builtins-api.cc @@ -21,17 +21,21 @@ namespace { // Returns the holder JSObject if the function can legally be called with this // receiver. Returns nullptr if the call is illegal. // TODO(dcarney): CallOptimization duplicates this logic, merge. -JSObject* GetCompatibleReceiver(Isolate* isolate, FunctionTemplateInfo* info, - JSObject* receiver) { +JSReceiver* GetCompatibleReceiver(Isolate* isolate, FunctionTemplateInfo* info, + JSReceiver* receiver) { Object* recv_type = info->signature(); // No signature, return holder. if (!recv_type->IsFunctionTemplateInfo()) return receiver; + // A Proxy cannot have been created from the signature template. + if (!receiver->IsJSObject()) return nullptr; + + JSObject* js_obj_receiver = JSObject::cast(receiver); FunctionTemplateInfo* signature = FunctionTemplateInfo::cast(recv_type); // Check the receiver. Fast path for receivers with no hidden prototypes. - if (signature->IsTemplateFor(receiver)) return receiver; - if (!receiver->map()->has_hidden_prototype()) return nullptr; - for (PrototypeIterator iter(isolate, receiver, kStartAtPrototype, + if (signature->IsTemplateFor(js_obj_receiver)) return receiver; + if (!js_obj_receiver->map()->has_hidden_prototype()) return nullptr; + for (PrototypeIterator iter(isolate, js_obj_receiver, kStartAtPrototype, PrototypeIterator::END_AT_NON_HIDDEN); !iter.IsAtEnd(); iter.Advance()) { JSObject* current = iter.GetCurrent(); @@ -45,8 +49,8 @@ MUST_USE_RESULT MaybeHandle HandleApiCallHelper( Isolate* isolate, Handle function, Handle new_target, Handle fun_data, Handle receiver, BuiltinArguments args) { - Handle js_receiver; - JSObject* raw_holder; + Handle js_receiver; + JSReceiver* raw_holder; if (is_construct) { DCHECK(args.receiver()->IsTheHole(isolate)); if (fun_data->instance_template()->IsUndefined(isolate)) { @@ -68,21 +72,18 @@ MUST_USE_RESULT MaybeHandle HandleApiCallHelper( raw_holder = *js_receiver; } else { DCHECK(receiver->IsJSReceiver()); - - if (!receiver->IsJSObject()) { - // This function cannot be called with the given receiver. Abort! - THROW_NEW_ERROR( - isolate, NewTypeError(MessageTemplate::kIllegalInvocation), Object); - } - - js_receiver = Handle::cast(receiver); + js_receiver = Handle::cast(receiver); if (!fun_data->accept_any_receiver() && - js_receiver->IsAccessCheckNeeded() && - !isolate->MayAccess(handle(isolate->context()), js_receiver)) { - isolate->ReportFailedAccessCheck(js_receiver); - RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); - return isolate->factory()->undefined_value(); + js_receiver->IsAccessCheckNeeded()) { + // Proxies never need access checks. + DCHECK(js_receiver->IsJSObject()); + Handle js_obj_receiver = Handle::cast(js_receiver); + if (!isolate->MayAccess(handle(isolate->context()), js_obj_receiver)) { + isolate->ReportFailedAccessCheck(js_obj_receiver); + RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); + return isolate->factory()->undefined_value(); + } } raw_holder = GetCompatibleReceiver(isolate, *fun_data, *js_receiver); diff --git a/deps/v8/src/builtins/builtins-promise-gen.cc b/deps/v8/src/builtins/builtins-promise-gen.cc index d3ea3f82e2eb0c..032d0ef1001a27 100644 --- a/deps/v8/src/builtins/builtins-promise-gen.cc +++ b/deps/v8/src/builtins/builtins-promise-gen.cc @@ -999,7 +999,7 @@ TF_BUILTIN(PromiseResolveThenableJob, PromiseBuiltinsAssembler) { // We need to reject the {thenable}. Node* const result = CallJS( CodeFactory::Call(isolate(), ConvertReceiverMode::kNullOrUndefined), - native_context, UndefinedConstant(), var_exception.value()); + native_context, reject, UndefinedConstant(), var_exception.value()); Return(result); } } diff --git a/deps/v8/src/builtins/ia32/builtins-ia32.cc b/deps/v8/src/builtins/ia32/builtins-ia32.cc index 3319dd0c514cce..5bc083f531207d 100644 --- a/deps/v8/src/builtins/ia32/builtins-ia32.cc +++ b/deps/v8/src/builtins/ia32/builtins-ia32.cc @@ -783,9 +783,13 @@ static void AdvanceBytecodeOffsetOrReturn(MacroAssembler* masm, Label process_bytecode, extra_wide; STATIC_ASSERT(0 == static_cast(interpreter::Bytecode::kWide)); STATIC_ASSERT(1 == static_cast(interpreter::Bytecode::kExtraWide)); - __ cmpb(bytecode, Immediate(0x1)); + STATIC_ASSERT(2 == static_cast(interpreter::Bytecode::kDebugBreakWide)); + STATIC_ASSERT(3 == + static_cast(interpreter::Bytecode::kDebugBreakExtraWide)); + __ cmpb(bytecode, Immediate(0x3)); __ j(above, &process_bytecode, Label::kNear); - __ j(equal, &extra_wide, Label::kNear); + __ test(bytecode, Immediate(0x1)); + __ j(not_equal, &extra_wide, Label::kNear); // Load the next bytecode and update table to the wide scaled table. __ inc(bytecode_offset); diff --git a/deps/v8/src/builtins/mips/builtins-mips.cc b/deps/v8/src/builtins/mips/builtins-mips.cc index e2d4421f860a25..0d42834612757c 100644 --- a/deps/v8/src/builtins/mips/builtins-mips.cc +++ b/deps/v8/src/builtins/mips/builtins-mips.cc @@ -840,8 +840,12 @@ static void AdvanceBytecodeOffsetOrReturn(MacroAssembler* masm, Label process_bytecode, extra_wide; STATIC_ASSERT(0 == static_cast(interpreter::Bytecode::kWide)); STATIC_ASSERT(1 == static_cast(interpreter::Bytecode::kExtraWide)); - __ Branch(&process_bytecode, hi, bytecode, Operand(1)); - __ Branch(&extra_wide, eq, bytecode, Operand(1)); + STATIC_ASSERT(2 == static_cast(interpreter::Bytecode::kDebugBreakWide)); + STATIC_ASSERT(3 == + static_cast(interpreter::Bytecode::kDebugBreakExtraWide)); + __ Branch(&process_bytecode, hi, bytecode, Operand(3)); + __ And(scratch2, bytecode, Operand(1)); + __ Branch(&extra_wide, ne, scratch2, Operand(zero_reg)); // Load the next bytecode and update table to the wide scaled table. __ Addu(bytecode_offset, bytecode_offset, Operand(1)); diff --git a/deps/v8/src/builtins/mips64/builtins-mips64.cc b/deps/v8/src/builtins/mips64/builtins-mips64.cc index 80ac1fadb10039..15fdfc3d7d0e0c 100644 --- a/deps/v8/src/builtins/mips64/builtins-mips64.cc +++ b/deps/v8/src/builtins/mips64/builtins-mips64.cc @@ -837,8 +837,12 @@ static void AdvanceBytecodeOffsetOrReturn(MacroAssembler* masm, Label process_bytecode, extra_wide; STATIC_ASSERT(0 == static_cast(interpreter::Bytecode::kWide)); STATIC_ASSERT(1 == static_cast(interpreter::Bytecode::kExtraWide)); - __ Branch(&process_bytecode, hi, bytecode, Operand(1)); - __ Branch(&extra_wide, eq, bytecode, Operand(1)); + STATIC_ASSERT(2 == static_cast(interpreter::Bytecode::kDebugBreakWide)); + STATIC_ASSERT(3 == + static_cast(interpreter::Bytecode::kDebugBreakExtraWide)); + __ Branch(&process_bytecode, hi, bytecode, Operand(3)); + __ And(scratch2, bytecode, Operand(1)); + __ Branch(&extra_wide, ne, scratch2, Operand(zero_reg)); // Load the next bytecode and update table to the wide scaled table. __ Daddu(bytecode_offset, bytecode_offset, Operand(1)); diff --git a/deps/v8/src/builtins/ppc/builtins-ppc.cc b/deps/v8/src/builtins/ppc/builtins-ppc.cc index 7ae635b0c15eba..9206920d457f08 100644 --- a/deps/v8/src/builtins/ppc/builtins-ppc.cc +++ b/deps/v8/src/builtins/ppc/builtins-ppc.cc @@ -859,9 +859,13 @@ static void AdvanceBytecodeOffsetOrReturn(MacroAssembler* masm, Label process_bytecode, extra_wide; STATIC_ASSERT(0 == static_cast(interpreter::Bytecode::kWide)); STATIC_ASSERT(1 == static_cast(interpreter::Bytecode::kExtraWide)); - __ cmpi(bytecode, Operand(0x1)); + STATIC_ASSERT(2 == static_cast(interpreter::Bytecode::kDebugBreakWide)); + STATIC_ASSERT(3 == + static_cast(interpreter::Bytecode::kDebugBreakExtraWide)); + __ cmpi(bytecode, Operand(0x3)); __ bgt(&process_bytecode); - __ beq(&extra_wide); + __ andi(r0, bytecode, Operand(0x1)); + __ bne(&extra_wide, cr0); // Load the next bytecode and update table to the wide scaled table. __ addi(bytecode_offset, bytecode_offset, Operand(1)); diff --git a/deps/v8/src/builtins/s390/builtins-s390.cc b/deps/v8/src/builtins/s390/builtins-s390.cc index 9d7bc3fb80e7e5..86239e0052b6bc 100644 --- a/deps/v8/src/builtins/s390/builtins-s390.cc +++ b/deps/v8/src/builtins/s390/builtins-s390.cc @@ -861,9 +861,13 @@ static void AdvanceBytecodeOffsetOrReturn(MacroAssembler* masm, Label process_bytecode, extra_wide; STATIC_ASSERT(0 == static_cast(interpreter::Bytecode::kWide)); STATIC_ASSERT(1 == static_cast(interpreter::Bytecode::kExtraWide)); - __ CmpP(bytecode, Operand(0x1)); + STATIC_ASSERT(2 == static_cast(interpreter::Bytecode::kDebugBreakWide)); + STATIC_ASSERT(3 == + static_cast(interpreter::Bytecode::kDebugBreakExtraWide)); + __ CmpP(bytecode, Operand(0x3)); __ bgt(&process_bytecode); - __ beq(&extra_wide); + __ tmll(bytecode, Operand(0x1)); + __ bne(&extra_wide); // Load the next bytecode and update table to the wide scaled table. __ AddP(bytecode_offset, bytecode_offset, Operand(1)); diff --git a/deps/v8/src/builtins/x64/builtins-x64.cc b/deps/v8/src/builtins/x64/builtins-x64.cc index 898fe9c14c7988..ae7e0c151ea964 100644 --- a/deps/v8/src/builtins/x64/builtins-x64.cc +++ b/deps/v8/src/builtins/x64/builtins-x64.cc @@ -848,9 +848,13 @@ static void AdvanceBytecodeOffsetOrReturn(MacroAssembler* masm, Label process_bytecode, extra_wide; STATIC_ASSERT(0 == static_cast(interpreter::Bytecode::kWide)); STATIC_ASSERT(1 == static_cast(interpreter::Bytecode::kExtraWide)); - __ cmpb(bytecode, Immediate(0x1)); + STATIC_ASSERT(2 == static_cast(interpreter::Bytecode::kDebugBreakWide)); + STATIC_ASSERT(3 == + static_cast(interpreter::Bytecode::kDebugBreakExtraWide)); + __ cmpb(bytecode, Immediate(0x3)); __ j(above, &process_bytecode, Label::kNear); - __ j(equal, &extra_wide, Label::kNear); + __ testb(bytecode, Immediate(0x1)); + __ j(not_equal, &extra_wide, Label::kNear); // Load the next bytecode and update table to the wide scaled table. __ incl(bytecode_offset); diff --git a/deps/v8/src/compiler/js-call-reducer.cc b/deps/v8/src/compiler/js-call-reducer.cc index f229cdefedf30e..417191c6802114 100644 --- a/deps/v8/src/compiler/js-call-reducer.cc +++ b/deps/v8/src/compiler/js-call-reducer.cc @@ -5135,6 +5135,7 @@ Reduction JSCallReducer::ReducePromisePrototypeThen(Node* node) { Node* context = NodeProperties::GetContextInput(node); Node* effect = NodeProperties::GetEffectInput(node); Node* control = NodeProperties::GetControlInput(node); + Node* frame_state = NodeProperties::GetFrameStateInput(node); // Check that promises aren't being observed through (debug) hooks. if (!isolate()->IsPromiseHookProtectorIntact()) return NoChange(); @@ -5193,9 +5194,9 @@ Reduction JSCallReducer::ReducePromisePrototypeThen(Node* node) { graph()->NewNode(javascript()->CreatePromise(), context, effect); // Chain {result} onto {receiver}. - result = effect = graph()->NewNode(javascript()->PerformPromiseThen(), - receiver, on_fulfilled, on_rejected, - result, context, effect, control); + result = effect = graph()->NewNode( + javascript()->PerformPromiseThen(), receiver, on_fulfilled, on_rejected, + result, context, frame_state, effect, control); ReplaceWithValue(node, result, effect, control); return Replace(result); } diff --git a/deps/v8/src/compiler/operator-properties.cc b/deps/v8/src/compiler/operator-properties.cc index bd715df25eb0be..673d643da0067b 100644 --- a/deps/v8/src/compiler/operator-properties.cc +++ b/deps/v8/src/compiler/operator-properties.cc @@ -118,6 +118,7 @@ bool OperatorProperties::HasFrameStateInput(const Operator* op) { case IrOpcode::kJSPromiseResolve: case IrOpcode::kJSRejectPromise: case IrOpcode::kJSResolvePromise: + case IrOpcode::kJSPerformPromiseThen: return true; default: diff --git a/deps/v8/src/debug/debug-interface.h b/deps/v8/src/debug/debug-interface.h index eef65f5100ec29..6d50be6e0ea0c2 100644 --- a/deps/v8/src/debug/debug-interface.h +++ b/deps/v8/src/debug/debug-interface.h @@ -204,10 +204,6 @@ void ResetBlackboxedStateCache(Isolate* isolate, int EstimatedValueSize(Isolate* isolate, v8::Local value); -v8::MaybeLocal EntriesPreview(Isolate* isolate, - v8::Local value, - bool* is_key_value); - enum Builtin { kObjectKeys, kObjectGetPrototypeOf, diff --git a/deps/v8/src/inspector/v8-debugger.cc b/deps/v8/src/inspector/v8-debugger.cc index 9b0ca38018a43e..0f3fd0377e9e94 100644 --- a/deps/v8/src/inspector/v8-debugger.cc +++ b/deps/v8/src/inspector/v8-debugger.cc @@ -29,8 +29,10 @@ v8::MaybeLocal collectionsEntries(v8::Local context, v8::Isolate* isolate = context->GetIsolate(); v8::Local entries; bool isKeyValue = false; - if (!v8::debug::EntriesPreview(isolate, value, &isKeyValue).ToLocal(&entries)) + if (!value->IsObject() || + !value.As()->PreviewEntries(&isKeyValue).ToLocal(&entries)) { return v8::MaybeLocal(); + } v8::Local wrappedEntries = v8::Array::New(isolate); CHECK(!isKeyValue || wrappedEntries->Length() % 2 == 0); diff --git a/deps/v8/src/interpreter/bytecodes.h b/deps/v8/src/interpreter/bytecodes.h index 293c0562e9b0e7..be31f27c76e949 100644 --- a/deps/v8/src/interpreter/bytecodes.h +++ b/deps/v8/src/interpreter/bytecodes.h @@ -28,6 +28,23 @@ namespace interpreter { V(Wide, AccumulatorUse::kNone) \ V(ExtraWide, AccumulatorUse::kNone) \ \ + /* Debug Breakpoints - one for each possible size of unscaled bytecodes */ \ + /* and one for each operand widening prefix bytecode */ \ + V(DebugBreakWide, AccumulatorUse::kReadWrite) \ + V(DebugBreakExtraWide, AccumulatorUse::kReadWrite) \ + V(DebugBreak0, AccumulatorUse::kReadWrite) \ + V(DebugBreak1, AccumulatorUse::kReadWrite, OperandType::kReg) \ + V(DebugBreak2, AccumulatorUse::kReadWrite, OperandType::kReg, \ + OperandType::kReg) \ + V(DebugBreak3, AccumulatorUse::kReadWrite, OperandType::kReg, \ + OperandType::kReg, OperandType::kReg) \ + V(DebugBreak4, AccumulatorUse::kReadWrite, OperandType::kReg, \ + OperandType::kReg, OperandType::kReg, OperandType::kReg) \ + V(DebugBreak5, AccumulatorUse::kReadWrite, OperandType::kRuntimeId, \ + OperandType::kReg, OperandType::kReg) \ + V(DebugBreak6, AccumulatorUse::kReadWrite, OperandType::kRuntimeId, \ + OperandType::kReg, OperandType::kReg, OperandType::kReg) \ + \ /* Loading the accumulator */ \ V(LdaZero, AccumulatorUse::kWrite) \ V(LdaSmi, AccumulatorUse::kWrite, OperandType::kImm) \ @@ -325,23 +342,6 @@ namespace interpreter { /* Debugger */ \ V(Debugger, AccumulatorUse::kNone) \ \ - /* Debug Breakpoints - one for each possible size of unscaled bytecodes */ \ - /* and one for each operand widening prefix bytecode */ \ - V(DebugBreak0, AccumulatorUse::kReadWrite) \ - V(DebugBreak1, AccumulatorUse::kReadWrite, OperandType::kReg) \ - V(DebugBreak2, AccumulatorUse::kReadWrite, OperandType::kReg, \ - OperandType::kReg) \ - V(DebugBreak3, AccumulatorUse::kReadWrite, OperandType::kReg, \ - OperandType::kReg, OperandType::kReg) \ - V(DebugBreak4, AccumulatorUse::kReadWrite, OperandType::kReg, \ - OperandType::kReg, OperandType::kReg, OperandType::kReg) \ - V(DebugBreak5, AccumulatorUse::kReadWrite, OperandType::kRuntimeId, \ - OperandType::kReg, OperandType::kReg) \ - V(DebugBreak6, AccumulatorUse::kReadWrite, OperandType::kRuntimeId, \ - OperandType::kReg, OperandType::kReg, OperandType::kReg) \ - V(DebugBreakWide, AccumulatorUse::kReadWrite) \ - V(DebugBreakExtraWide, AccumulatorUse::kReadWrite) \ - \ /* Block Coverage */ \ V(IncBlockCounter, AccumulatorUse::kNone, OperandType::kIdx) \ \ diff --git a/deps/v8/src/isolate.cc b/deps/v8/src/isolate.cc index 38506bfc254047..37a5578763d8d1 100644 --- a/deps/v8/src/isolate.cc +++ b/deps/v8/src/isolate.cc @@ -8,6 +8,7 @@ #include // NOLINT(readability/streams) #include +#include #include "src/api.h" #include "src/assembler-inl.h" @@ -136,8 +137,6 @@ void ThreadLocalTop::Free() { base::Thread::LocalStorageKey Isolate::isolate_key_; base::Thread::LocalStorageKey Isolate::thread_id_key_; base::Thread::LocalStorageKey Isolate::per_isolate_thread_data_key_; -base::LazyMutex Isolate::thread_data_table_mutex_ = LAZY_MUTEX_INITIALIZER; -Isolate::ThreadDataTable* Isolate::thread_data_table_ = nullptr; base::Atomic32 Isolate::isolate_counter_ = 0; #if DEBUG base::Atomic32 Isolate::isolate_key_created_ = 0; @@ -148,13 +147,13 @@ Isolate::PerIsolateThreadData* ThreadId thread_id = ThreadId::Current(); PerIsolateThreadData* per_thread = nullptr; { - base::LockGuard lock_guard(thread_data_table_mutex_.Pointer()); - per_thread = thread_data_table_->Lookup(this, thread_id); + base::LockGuard lock_guard(&thread_data_table_mutex_); + per_thread = thread_data_table_.Lookup(thread_id); if (per_thread == nullptr) { per_thread = new PerIsolateThreadData(this, thread_id); - thread_data_table_->Insert(per_thread); + thread_data_table_.Insert(per_thread); } - DCHECK(thread_data_table_->Lookup(this, thread_id) == per_thread); + DCHECK(thread_data_table_.Lookup(thread_id) == per_thread); } return per_thread; } @@ -165,12 +164,11 @@ void Isolate::DiscardPerThreadDataForThisThread() { if (thread_id_int) { ThreadId thread_id = ThreadId(thread_id_int); DCHECK(!thread_manager_->mutex_owner_.Equals(thread_id)); - base::LockGuard lock_guard(thread_data_table_mutex_.Pointer()); - PerIsolateThreadData* per_thread = - thread_data_table_->Lookup(this, thread_id); + base::LockGuard lock_guard(&thread_data_table_mutex_); + PerIsolateThreadData* per_thread = thread_data_table_.Lookup(thread_id); if (per_thread) { DCHECK(!per_thread->thread_state_); - thread_data_table_->Remove(per_thread); + thread_data_table_.Remove(per_thread); } } } @@ -186,23 +184,20 @@ Isolate::PerIsolateThreadData* Isolate::FindPerThreadDataForThread( ThreadId thread_id) { PerIsolateThreadData* per_thread = nullptr; { - base::LockGuard lock_guard(thread_data_table_mutex_.Pointer()); - per_thread = thread_data_table_->Lookup(this, thread_id); + base::LockGuard lock_guard(&thread_data_table_mutex_); + per_thread = thread_data_table_.Lookup(thread_id); } return per_thread; } void Isolate::InitializeOncePerProcess() { - base::LockGuard lock_guard(thread_data_table_mutex_.Pointer()); - CHECK_NULL(thread_data_table_); isolate_key_ = base::Thread::CreateThreadLocalKey(); #if DEBUG base::Relaxed_Store(&isolate_key_created_, 1); #endif thread_id_key_ = base::Thread::CreateThreadLocalKey(); per_isolate_thread_data_key_ = base::Thread::CreateThreadLocalKey(); - thread_data_table_ = new Isolate::ThreadDataTable(); } Address Isolate::get_address_from_id(IsolateAddressId id) { @@ -2240,14 +2235,9 @@ char* Isolate::RestoreThread(char* from) { return from + sizeof(ThreadLocalTop); } -Isolate::ThreadDataTable::ThreadDataTable() : list_(nullptr) {} +Isolate::ThreadDataTable::ThreadDataTable() : table_() {} -Isolate::ThreadDataTable::~ThreadDataTable() { - // TODO(svenpanne) The assertion below would fire if an embedder does not - // cleanly dispose all Isolates before disposing v8, so we are conservative - // and leave it out for now. - // DCHECK_NULL(list_); -} +Isolate::ThreadDataTable::~ThreadDataTable() {} void Isolate::ReleaseManagedObjects() { Isolate::ManagedObjectFinalizer* current = @@ -2294,40 +2284,30 @@ Isolate::PerIsolateThreadData::~PerIsolateThreadData() { #endif } - -Isolate::PerIsolateThreadData* - Isolate::ThreadDataTable::Lookup(Isolate* isolate, - ThreadId thread_id) { - for (PerIsolateThreadData* data = list_; data != nullptr; - data = data->next_) { - if (data->Matches(isolate, thread_id)) return data; - } - return nullptr; +Isolate::PerIsolateThreadData* Isolate::ThreadDataTable::Lookup( + ThreadId thread_id) { + auto t = table_.find(thread_id); + if (t == table_.end()) return nullptr; + return t->second; } void Isolate::ThreadDataTable::Insert(Isolate::PerIsolateThreadData* data) { - if (list_ != nullptr) list_->prev_ = data; - data->next_ = list_; - list_ = data; + bool inserted = table_.insert(std::make_pair(data->thread_id_, data)).second; + CHECK(inserted); } void Isolate::ThreadDataTable::Remove(PerIsolateThreadData* data) { - if (list_ == data) list_ = data->next_; - if (data->next_ != nullptr) data->next_->prev_ = data->prev_; - if (data->prev_ != nullptr) data->prev_->next_ = data->next_; + table_.erase(data->thread_id_); delete data; } - -void Isolate::ThreadDataTable::RemoveAllThreads(Isolate* isolate) { - PerIsolateThreadData* data = list_; - while (data != nullptr) { - PerIsolateThreadData* next = data->next_; - if (data->isolate() == isolate) Remove(data); - data = next; +void Isolate::ThreadDataTable::RemoveAllThreads() { + for (auto& x : table_) { + delete x.second; } + table_.clear(); } @@ -2502,10 +2482,6 @@ Isolate::Isolate(bool enable_serializer) cancelable_task_manager_(new CancelableTaskManager()), abort_on_uncaught_exception_callback_(nullptr), total_regexp_code_generated_(0) { - { - base::LockGuard lock_guard(thread_data_table_mutex_.Pointer()); - CHECK(thread_data_table_); - } id_ = base::Relaxed_AtomicIncrement(&isolate_counter_, 1); TRACE_ISOLATE(constructor); @@ -2563,8 +2539,8 @@ void Isolate::TearDown() { Deinit(); { - base::LockGuard lock_guard(thread_data_table_mutex_.Pointer()); - thread_data_table_->RemoveAllThreads(this); + base::LockGuard lock_guard(&thread_data_table_mutex_); + thread_data_table_.RemoveAllThreads(); } #ifdef DEBUG @@ -2578,12 +2554,6 @@ void Isolate::TearDown() { } -void Isolate::GlobalTearDown() { - delete thread_data_table_; - thread_data_table_ = nullptr; -} - - void Isolate::ClearSerializerData() { delete external_reference_table_; external_reference_table_ = nullptr; diff --git a/deps/v8/src/isolate.h b/deps/v8/src/isolate.h index 5538992af17f4d..40135ef3248906 100644 --- a/deps/v8/src/isolate.h +++ b/deps/v8/src/isolate.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include "include/v8.h" @@ -247,6 +248,8 @@ class ThreadId { return *this; } + bool operator==(const ThreadId& other) const { return Equals(other); } + // Returns ThreadId for current thread. static ThreadId Current() { return ThreadId(GetCurrentThreadId()); } @@ -287,7 +290,6 @@ class ThreadId { friend class Isolate; }; - #define FIELD_ACCESSOR(type, name) \ inline void set_##name(type v) { name##_ = v; } \ inline type name() const { return name##_; } @@ -550,8 +552,6 @@ class Isolate { void ReleaseManagedObjects(); - static void GlobalTearDown(); - void ClearSerializerData(); // Find the PerThread for this particular (isolate, thread) combination @@ -1371,20 +1371,24 @@ class Isolate { void* embedder_data_[Internals::kNumIsolateDataSlots]; Heap heap_; - // The per-process lock should be acquired before the ThreadDataTable is - // modified. class ThreadDataTable { public: ThreadDataTable(); ~ThreadDataTable(); - PerIsolateThreadData* Lookup(Isolate* isolate, ThreadId thread_id); + PerIsolateThreadData* Lookup(ThreadId thread_id); void Insert(PerIsolateThreadData* data); void Remove(PerIsolateThreadData* data); - void RemoveAllThreads(Isolate* isolate); + void RemoveAllThreads(); private: - PerIsolateThreadData* list_; + struct Hasher { + std::size_t operator()(const ThreadId& t) const { + return std::hash()(t.ToInteger()); + } + }; + + std::unordered_map table_; }; // These items form a stack synchronously with threads Enter'ing and Exit'ing @@ -1412,12 +1416,15 @@ class Isolate { DISALLOW_COPY_AND_ASSIGN(EntryStackItem); }; - static base::LazyMutex thread_data_table_mutex_; + // TODO(kenton@cloudflare.com): This mutex can be removed if + // thread_data_table_ is always accessed under the isolate lock. I do not + // know if this is the case, so I'm preserving it for now. + base::Mutex thread_data_table_mutex_; static base::Thread::LocalStorageKey per_isolate_thread_data_key_; static base::Thread::LocalStorageKey isolate_key_; static base::Thread::LocalStorageKey thread_id_key_; - static ThreadDataTable* thread_data_table_; + ThreadDataTable thread_data_table_; // A global counter for all generated Isolates, might overflow. static base::Atomic32 isolate_counter_; diff --git a/deps/v8/src/libplatform/tracing/trace-writer.cc b/deps/v8/src/libplatform/tracing/trace-writer.cc index 36a8783499d140..7bfc7664694f8d 100644 --- a/deps/v8/src/libplatform/tracing/trace-writer.cc +++ b/deps/v8/src/libplatform/tracing/trace-writer.cc @@ -119,8 +119,12 @@ void JSONTraceWriter::AppendArgValue(ConvertableToTraceFormat* value) { stream_ << arg_stringified; } -JSONTraceWriter::JSONTraceWriter(std::ostream& stream) : stream_(stream) { - stream_ << "{\"traceEvents\":["; +JSONTraceWriter::JSONTraceWriter(std::ostream& stream) + : JSONTraceWriter(stream, "traceEvents") {} + +JSONTraceWriter::JSONTraceWriter(std::ostream& stream, const std::string& tag) + : stream_(stream) { + stream_ << "{\"" << tag << "\":["; } JSONTraceWriter::~JSONTraceWriter() { stream_ << "]}"; } @@ -171,6 +175,11 @@ TraceWriter* TraceWriter::CreateJSONTraceWriter(std::ostream& stream) { return new JSONTraceWriter(stream); } +TraceWriter* TraceWriter::CreateJSONTraceWriter(std::ostream& stream, + const std::string& tag) { + return new JSONTraceWriter(stream, tag); +} + } // namespace tracing } // namespace platform } // namespace v8 diff --git a/deps/v8/src/libplatform/tracing/trace-writer.h b/deps/v8/src/libplatform/tracing/trace-writer.h index 7e1bdc24d687ae..d81135138992f7 100644 --- a/deps/v8/src/libplatform/tracing/trace-writer.h +++ b/deps/v8/src/libplatform/tracing/trace-writer.h @@ -14,6 +14,7 @@ namespace tracing { class JSONTraceWriter : public TraceWriter { public: explicit JSONTraceWriter(std::ostream& stream); + JSONTraceWriter(std::ostream& stream, const std::string& tag); ~JSONTraceWriter(); void AppendTraceEvent(TraceObject* trace_event) override; void Flush() override; diff --git a/deps/v8/src/managed.h b/deps/v8/src/managed.h index 63fefdd480ae10..d0ccb4e739db4f 100644 --- a/deps/v8/src/managed.h +++ b/deps/v8/src/managed.h @@ -59,22 +59,30 @@ class Managed : public Foreign { isolate->factory()->NewForeign(reinterpret_cast
(finalizer))); Handle global_handle = isolate->global_handles()->Create(*handle); finalizer->global_handle_location = global_handle.location(); - GlobalHandles::MakeWeak(finalizer->global_handle_location, - handle->GetFinalizer(), &Managed::GCDelete, - v8::WeakCallbackType::kParameter); + GlobalHandles::MakeWeak( + finalizer->global_handle_location, handle->GetFinalizer(), + &ResetWeakAndScheduleGCDelete, v8::WeakCallbackType::kParameter); return handle; } private: - static void GCDelete(const v8::WeakCallbackInfo& data) { + static void ResetWeakAndScheduleGCDelete( + const v8::WeakCallbackInfo& data) { FinalizerWithHandle* finalizer = reinterpret_cast(data.GetParameter()); - + GlobalHandles::Destroy(finalizer->global_handle_location); Isolate* isolate = reinterpret_cast(data.GetIsolate()); isolate->UnregisterFromReleaseAtTeardown(finalizer); + // We need to call GCDelete as a second pass callback because + // it can trigger garbage collection. The first pass callbacks + // are not allowed to invoke V8 API. + data.SetSecondPassCallback(&GCDelete); + } - GlobalHandles::Destroy(finalizer->global_handle_location); + static void GCDelete(const v8::WeakCallbackInfo& data) { + FinalizerWithHandle* finalizer = + reinterpret_cast(data.GetParameter()); NativeDelete(finalizer); } diff --git a/deps/v8/src/v8.cc b/deps/v8/src/v8.cc index ab4918efec2fb7..d3b4c471a4f8a4 100644 --- a/deps/v8/src/v8.cc +++ b/deps/v8/src/v8.cc @@ -49,7 +49,6 @@ void V8::TearDown() { Bootstrapper::TearDownExtensions(); ElementsAccessor::TearDown(); RegisteredExtension::UnregisterAll(); - Isolate::GlobalTearDown(); sampler::Sampler::TearDown(); FlagList::ResetAllFlags(); // Frees memory held by string arguments. } diff --git a/deps/v8/test/cctest/libplatform/test-tracing.cc b/deps/v8/test/cctest/libplatform/test-tracing.cc index da202057de312c..b949785bcfacbe 100644 --- a/deps/v8/test/cctest/libplatform/test-tracing.cc +++ b/deps/v8/test/cctest/libplatform/test-tracing.cc @@ -128,44 +128,42 @@ TEST(TestTraceBufferRingBuffer) { delete ring_buffer; } -TEST(TestJSONTraceWriter) { - std::ostringstream stream; - // Create a scope for the tracing controller to terminate the trace writer. - { - v8::Platform* old_platform = i::V8::GetCurrentPlatform(); - std::unique_ptr default_platform( - v8::platform::NewDefaultPlatform()); - i::V8::SetPlatformForTesting(default_platform.get()); - auto tracing = - base::make_unique(); - v8::platform::tracing::TracingController* tracing_controller = - tracing.get(); - static_cast(default_platform.get()) - ->SetTracingController(std::move(tracing)); - TraceWriter* writer = TraceWriter::CreateJSONTraceWriter(stream); +void PopulateJSONWriter(TraceWriter* writer) { + v8::Platform* old_platform = i::V8::GetCurrentPlatform(); + std::unique_ptr default_platform( + v8::platform::NewDefaultPlatform()); + i::V8::SetPlatformForTesting(default_platform.get()); + auto tracing = base::make_unique(); + v8::platform::tracing::TracingController* tracing_controller = tracing.get(); + static_cast(default_platform.get()) + ->SetTracingController(std::move(tracing)); - TraceBuffer* ring_buffer = - TraceBuffer::CreateTraceBufferRingBuffer(1, writer); - tracing_controller->Initialize(ring_buffer); - TraceConfig* trace_config = new TraceConfig(); - trace_config->AddIncludedCategory("v8-cat"); - tracing_controller->StartTracing(trace_config); + TraceBuffer* ring_buffer = + TraceBuffer::CreateTraceBufferRingBuffer(1, writer); + tracing_controller->Initialize(ring_buffer); + TraceConfig* trace_config = new TraceConfig(); + trace_config->AddIncludedCategory("v8-cat"); + tracing_controller->StartTracing(trace_config); - TraceObject trace_object; - trace_object.InitializeForTesting( - 'X', tracing_controller->GetCategoryGroupEnabled("v8-cat"), "Test0", - v8::internal::tracing::kGlobalScope, 42, 123, 0, nullptr, nullptr, - nullptr, nullptr, TRACE_EVENT_FLAG_HAS_ID, 11, 22, 100, 50, 33, 44); - writer->AppendTraceEvent(&trace_object); - trace_object.InitializeForTesting( - 'Y', tracing_controller->GetCategoryGroupEnabled("v8-cat"), "Test1", - v8::internal::tracing::kGlobalScope, 43, 456, 0, nullptr, nullptr, - nullptr, nullptr, 0, 55, 66, 110, 55, 77, 88); - writer->AppendTraceEvent(&trace_object); - tracing_controller->StopTracing(); - i::V8::SetPlatformForTesting(old_platform); - } + TraceObject trace_object; + trace_object.InitializeForTesting( + 'X', tracing_controller->GetCategoryGroupEnabled("v8-cat"), "Test0", + v8::internal::tracing::kGlobalScope, 42, 123, 0, nullptr, nullptr, + nullptr, nullptr, TRACE_EVENT_FLAG_HAS_ID, 11, 22, 100, 50, 33, 44); + writer->AppendTraceEvent(&trace_object); + trace_object.InitializeForTesting( + 'Y', tracing_controller->GetCategoryGroupEnabled("v8-cat"), "Test1", + v8::internal::tracing::kGlobalScope, 43, 456, 0, nullptr, nullptr, + nullptr, nullptr, 0, 55, 66, 110, 55, 77, 88); + writer->AppendTraceEvent(&trace_object); + tracing_controller->StopTracing(); + i::V8::SetPlatformForTesting(old_platform); +} +TEST(TestJSONTraceWriter) { + std::ostringstream stream; + TraceWriter* writer = TraceWriter::CreateJSONTraceWriter(stream); + PopulateJSONWriter(writer); std::string trace_str = stream.str(); std::string expected_trace_str = "{\"traceEvents\":[{\"pid\":11,\"tid\":22,\"ts\":100,\"tts\":50," @@ -177,6 +175,21 @@ TEST(TestJSONTraceWriter) { CHECK_EQ(expected_trace_str, trace_str); } +TEST(TestJSONTraceWriterWithCustomtag) { + std::ostringstream stream; + TraceWriter* writer = TraceWriter::CreateJSONTraceWriter(stream, "customTag"); + PopulateJSONWriter(writer); + std::string trace_str = stream.str(); + std::string expected_trace_str = + "{\"customTag\":[{\"pid\":11,\"tid\":22,\"ts\":100,\"tts\":50," + "\"ph\":\"X\",\"cat\":\"v8-cat\",\"name\":\"Test0\",\"dur\":33," + "\"tdur\":44,\"id\":\"0x2a\",\"args\":{}},{\"pid\":55,\"tid\":66," + "\"ts\":110,\"tts\":55,\"ph\":\"Y\",\"cat\":\"v8-cat\",\"name\":" + "\"Test1\",\"dur\":77,\"tdur\":88,\"args\":{}}]}"; + + CHECK_EQ(expected_trace_str, trace_str); +} + TEST(TestTracingController) { v8::Platform* old_platform = i::V8::GetCurrentPlatform(); std::unique_ptr default_platform( diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc index fe1aca5a0fb440..5d4c260752a02f 100644 --- a/deps/v8/test/cctest/test-api.cc +++ b/deps/v8/test/cctest/test-api.cc @@ -1088,6 +1088,34 @@ THREADED_PROFILED_TEST(FunctionTemplate) { TestFunctionTemplateAccessor(construct_callback, Return239Callback); } +static void FunctionCallbackForProxyTest( + const v8::FunctionCallbackInfo& info) { + info.GetReturnValue().Set(info.This()); +} + +THREADED_TEST(FunctionTemplateWithProxy) { + LocalContext env; + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); + + v8::Local function_template = + v8::FunctionTemplate::New(isolate, FunctionCallbackForProxyTest); + v8::Local function = + function_template->GetFunction(env.local()).ToLocalChecked(); + CHECK((*env)->Global()->Set(env.local(), v8_str("f"), function).FromJust()); + v8::Local proxy = + CompileRun("var proxy = new Proxy({}, {}); proxy"); + CHECK(proxy->IsProxy()); + + v8::Local result = CompileRun("f(proxy)"); + CHECK(result->Equals(env.local(), (*env)->Global()).FromJust()); + + result = CompileRun("f.call(proxy)"); + CHECK(result->Equals(env.local(), proxy).FromJust()); + + result = CompileRun("Reflect.apply(f, proxy, [1])"); + CHECK(result->Equals(env.local(), proxy).FromJust()); +} static void SimpleCallback(const v8::FunctionCallbackInfo& info) { ApiTestFuzzer::Fuzz(); @@ -17613,6 +17641,35 @@ TEST(PromiseRejectCallback) { CHECK_EQ(7, promise_reject_msg_column_number); } +void PromiseRejectCallbackConstructError( + v8::PromiseRejectMessage reject_message) { + v8::Local context = CcTest::isolate()->GetCurrentContext(); + CHECK_EQ(v8::Promise::PromiseState::kRejected, + reject_message.GetPromise()->State()); + USE(v8::Script::Compile(context, v8_str("new Error('test')")) + .ToLocalChecked() + ->Run(context)); +} + +TEST(PromiseRejectCallbackConstructError) { + i::FLAG_allow_natives_syntax = true; + LocalContext env; + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); + + isolate->SetPromiseRejectCallback(PromiseRejectCallbackConstructError); + + ResetPromiseStates(); + CompileRun( + "function f(p) {" + " p.catch(() => {});" + "}" + "f(Promise.reject());" + "f(Promise.reject());" + "%OptimizeFunctionOnNextCall(f);" + "let p = Promise.reject();" + "f(p);"); +} void AnalyzeStackOfEvalWithSourceURL( const v8::FunctionCallbackInfo& args) { diff --git a/deps/v8/test/debugger/regress/regress-crbug-835973.js b/deps/v8/test/debugger/regress/regress-crbug-835973.js new file mode 100644 index 00000000000000..c2df20c94a411a --- /dev/null +++ b/deps/v8/test/debugger/regress/regress-crbug-835973.js @@ -0,0 +1,289 @@ +// Copyright 2018 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. + +// Test that stepping works correctly with bytecode scaling prefix. +class MyClass { f(p) { this.x += p; } }; + +let obj = new MyClass(); + +function foo() { + obj.f(0); + obj.f(1); + obj.f(2); + obj.f(3); + obj.f(4); + obj.f(5); + obj.f(6); + obj.f(7); + obj.f(8); + obj.f(9); + obj.f(10); + obj.f(11); + obj.f(12); + obj.f(13); + obj.f(14); + obj.f(15); + obj.f(16); + obj.f(17); + obj.f(18); + obj.f(19); + obj.f(20); + obj.f(21); + obj.f(22); + obj.f(23); + obj.f(24); + obj.f(25); + obj.f(26); + obj.f(27); + obj.f(28); + obj.f(29); + obj.f(30); + obj.f(31); + obj.f(32); + obj.f(33); + obj.f(34); + obj.f(35); + obj.f(36); + obj.f(37); + obj.f(38); + obj.f(39); + obj.f(40); + obj.f(41); + obj.f(42); + obj.f(43); + obj.f(44); + obj.f(45); + obj.f(46); + obj.f(47); + obj.f(48); + obj.f(49); + obj.f(50); + obj.f(51); + obj.f(52); + obj.f(53); + obj.f(54); + obj.f(55); + obj.f(56); + obj.f(57); + obj.f(58); + obj.f(59); + obj.f(60); + obj.f(61); + obj.f(62); + obj.f(63); + obj.f(64); + obj.f(65); + obj.f(66); + obj.f(67); + obj.f(68); + obj.f(69); + obj.f(70); + obj.f(71); + obj.f(72); + obj.f(73); + obj.f(74); + obj.f(75); + obj.f(76); + obj.f(77); + obj.f(78); + obj.f(79); + obj.f(80); + obj.f(81); + obj.f(82); + obj.f(83); + obj.f(84); + obj.f(85); + obj.f(86); + obj.f(87); + obj.f(88); + obj.f(89); + obj.f(90); + obj.f(91); + obj.f(92); + obj.f(93); + obj.f(94); + obj.f(95); + obj.f(96); + obj.f(97); + obj.f(98); + obj.f(99); + obj.f(100); + obj.f(101); + obj.f(102); + obj.f(103); + obj.f(104); + obj.f(105); + obj.f(106); + obj.f(107); + obj.f(108); + obj.f(109); + obj.f(110); + obj.f(111); + obj.f(112); + obj.f(113); + obj.f(114); + obj.f(115); + obj.f(116); + obj.f(117); + obj.f(118); + obj.f(119); + obj.f(120); + obj.f(121); + obj.f(122); + obj.f(123); + obj.f(124); + obj.f(125); + obj.f(126); + obj.f(127); + obj.f(128); + obj.f(129); + obj.f(130); + obj.f(131); + obj.f(132); + obj.f(133); + obj.f(134); + obj.f(135); + obj.f(136); + obj.f(137); + obj.f(138); + obj.f(139); + obj.f(140); + obj.f(141); + obj.f(142); + obj.f(143); + obj.f(144); + obj.f(145); + obj.f(146); + obj.f(147); + obj.f(148); + obj.f(149); + obj.f(150); + obj.f(151); + obj.f(152); + obj.f(153); + obj.f(154); + obj.f(155); + obj.f(156); + obj.f(157); + obj.f(158); + obj.f(159); + obj.f(160); + obj.f(161); + obj.f(162); + obj.f(163); + obj.f(164); + obj.f(165); + obj.f(166); + obj.f(167); + obj.f(168); + obj.f(169); + obj.f(170); + obj.f(171); + obj.f(172); + obj.f(173); + obj.f(174); + obj.f(175); + obj.f(176); + obj.f(177); + obj.f(178); + obj.f(179); + obj.f(180); + obj.f(181); + obj.f(182); + obj.f(183); + obj.f(184); + obj.f(185); + obj.f(186); + obj.f(187); + obj.f(188); + obj.f(189); + obj.f(190); + obj.f(191); + obj.f(192); + obj.f(193); + obj.f(194); + obj.f(195); + obj.f(196); + obj.f(197); + obj.f(198); + obj.f(199); + obj.f(200); + obj.f(201); + obj.f(202); + obj.f(203); + obj.f(204); + obj.f(205); + obj.f(206); + obj.f(207); + obj.f(208); + obj.f(209); + obj.f(210); + obj.f(211); + obj.f(212); + obj.f(213); + obj.f(214); + obj.f(215); + obj.f(216); + obj.f(217); + obj.f(218); + obj.f(219); + obj.f(220); + obj.f(221); + obj.f(222); + obj.f(223); + obj.f(224); + obj.f(225); + obj.f(226); + obj.f(227); + obj.f(228); + obj.f(229); + obj.f(230); + obj.f(231); + obj.f(232); + obj.f(233); + obj.f(234); + obj.f(235); + obj.f(236); + obj.f(237); + obj.f(238); + obj.f(239); + obj.f(240); + obj.f(241); + obj.f(242); + obj.f(243); + obj.f(244); + obj.f(245); + obj.f(246); + obj.f(247); + obj.f(248); + obj.f(249); + obj.f(250); + obj.f(251); + obj.f(252); + obj.f(253); + obj.f(254); + obj.f(255); + debugger; + obj.f(256); + obj.f(257); + obj.f(258); + obj.f(259); +} + +let break_count = 0; + +function listener(event, exec_state, event_data, data) { + if (event != debug.Debug.DebugEvent.Break) return; + try { + exec_state.prepareStep(debug.Debug.StepAction.StepNext); + break_count++; + } catch { + %AbortJS("unexpected exception"); + } +} + +debug.Debug.setListener(listener); +foo(); +debug.Debug.setListener(null); +assertEquals(7, break_count); diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-830565.js b/deps/v8/test/mjsunit/regress/regress-crbug-830565.js new file mode 100644 index 00000000000000..ee2c3bdacad1d1 --- /dev/null +++ b/deps/v8/test/mjsunit/regress/regress-crbug-830565.js @@ -0,0 +1,17 @@ +// Copyright 2018 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 + +testAsync(assert => { + assert.plan(1); + const error = new TypeError('Throwing'); + Promise.resolve({ then(resolve, reject) { + throw error; + }}).then(v => { + assert.unreachable(); + }, e => { + assert.equals(error, e); + }); +}); diff --git a/deps/v8/test/webkit/fast/js/Promise-resolve-with-then-exception-expected.txt b/deps/v8/test/webkit/fast/js/Promise-resolve-with-then-exception-expected.txt index 8b44ae59b5c602..7c2a301dc34c93 100644 --- a/deps/v8/test/webkit/fast/js/Promise-resolve-with-then-exception-expected.txt +++ b/deps/v8/test/webkit/fast/js/Promise-resolve-with-then-exception-expected.txt @@ -3,6 +3,8 @@ Test whether Promise treats thenable correctly. On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". The promise is already rejected now. +PASS rejected +PASS result is "hello" PASS successfullyParsed is true TEST COMPLETE diff --git a/doc/api/addons.md b/doc/api/addons.md index a207a71b717604..afbbdd843cb223 100644 --- a/doc/api/addons.md +++ b/doc/api/addons.md @@ -219,7 +219,7 @@ illustration of how it can be used. ## N-API -> Stability: 1 - Experimental +> Stability: 2 - Stable N-API is an API for building native Addons. It is independent from the underlying JavaScript runtime (e.g. V8) and is maintained as part of diff --git a/doc/api/assert.md b/doc/api/assert.md index 43e5800ff031b8..45132eec85cfb5 100644 --- a/doc/api/assert.md +++ b/doc/api/assert.md @@ -154,8 +154,8 @@ assert.deepEqual(/a/gi, new Date()); -* `value` {any} -* `message` {any} +* `value` {any} The input that is checked for being truthy. +* `message` {string|Error} An alias of [`assert.ok()`][]. @@ -181,7 +181,7 @@ changes: --> * `actual` {any} * `expected` {any} -* `message` {any} +* `message` {string|Error} **Strict mode** @@ -235,18 +235,18 @@ const obj3 = { const obj4 = Object.create(obj1); assert.deepEqual(obj1, obj1); -// OK, object is equal to itself +// OK +// Values of b are different: assert.deepEqual(obj1, obj2); // AssertionError: { a: { b: 1 } } deepEqual { a: { b: 2 } } -// values of b are different assert.deepEqual(obj1, obj3); -// OK, objects are equal +// OK +// Prototypes are ignored: assert.deepEqual(obj1, obj4); // AssertionError: { a: { b: 1 } } deepEqual {} -// Prototypes are ignored ``` If the values are not equal, an `AssertionError` is thrown with a `message` @@ -285,7 +285,7 @@ changes: --> * `actual` {any} * `expected` {any} -* `message` {any} +* `message` {string|Error} Tests for deep equality between the `actual` and `expected` parameters. "Deep" equality means that the enumerable "own" properties of child objects @@ -406,7 +406,7 @@ added: v10.0.0 --> * `block` {Function|Promise} * `error` {RegExp|Function} -* `message` {any} +* `message` {string|Error} Awaits the `block` promise or, if `block` is a function, immediately calls the function and awaits the returned promise to complete. It will then check that @@ -460,7 +460,7 @@ changes: --> * `block` {Function} * `error` {RegExp|Function} -* `message` {any} +* `message` {string|Error} Asserts that the function `block` does not throw an error. @@ -528,7 +528,7 @@ added: v0.1.21 --> * `actual` {any} * `expected` {any} -* `message` {any} +* `message` {string|Error} **Strict mode** @@ -565,7 +565,7 @@ parameter is an instance of an [`Error`][] then it will be thrown instead of the -* `message` {any} **Default:** `'Failed'` +* `message` {string|Error} **Default:** `'Failed'` Throws an `AssertionError` with the provided error message or a default error message. If the `message` parameter is an instance of an [`Error`][] then it @@ -598,7 +598,7 @@ changes: --> * `actual` {any} * `expected` {any} -* `message` {any} +* `message` {string|Error} * `operator` {string} **Default:** `'!='` * `stackStartFunction` {Function} **Default:** `assert.fail` @@ -659,8 +659,8 @@ changes: an `AssertionError` that contains the full stack trace. - version: v10.0.0 pr-url: https://github.com/nodejs/node/pull/18247 - description: Value may now only be `undefined` or `null`. Before any truthy - input was accepted. + description: Value may now only be `undefined` or `null`. Before all falsy + values were handled the same as `null` and did not throw. --> * `value` {any} @@ -717,7 +717,7 @@ changes: --> * `actual` {any} * `expected` {any} -* `message` {any} +* `message` {string|Error} **Strict mode** @@ -753,13 +753,13 @@ assert.notDeepEqual(obj1, obj1); // AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } } assert.notDeepEqual(obj1, obj2); -// OK: obj1 and obj2 are not deeply equal +// OK assert.notDeepEqual(obj1, obj3); // AssertionError: { a: { b: 1 } } notDeepEqual { a: { b: 1 } } assert.notDeepEqual(obj1, obj4); -// OK: obj1 and obj4 are not deeply equal +// OK ``` If the values are deeply equal, an `AssertionError` is thrown with a `message` @@ -798,7 +798,7 @@ changes: --> * `actual` {any} * `expected` {any} -* `message` {any} +* `message` {string|Error} Tests for deep strict inequality. Opposite of [`assert.deepStrictEqual()`][]. @@ -821,7 +821,7 @@ added: v0.1.21 --> * `actual` {any} * `expected` {any} -* `message` {any} +* `message` {string|Error} **Strict mode** @@ -863,7 +863,7 @@ changes: --> * `actual` {any} * `expected` {any} -* `message` {any} +* `message` {string|Error} Tests strict inequality between the `actual` and `expected` parameters as determined by the [SameValue Comparison][]. @@ -897,7 +897,7 @@ changes: error message. --> * `value` {any} -* `message` {any} +* `message` {string|Error} Tests if `value` is truthy. It is equivalent to `assert.equal(!!value, true, message)`. @@ -960,7 +960,7 @@ added: v10.0.0 --> * `block` {Function|Promise} * `error` {RegExp|Function|Object|Error} -* `message` {any} +* `message` {string|Error} Awaits the `block` promise or, if `block` is a function, immediately calls the function and awaits the returned promise to complete. It will then check that @@ -1022,7 +1022,7 @@ changes: --> * `actual` {any} * `expected` {any} -* `message` {any} +* `message` {string|Error} Tests strict equality between the `actual` and `expected` parameters as determined by the [SameValue Comparison][]. @@ -1056,6 +1056,10 @@ instead of the `AssertionError`. * `block` {Function} * `error` {RegExp|Function|Object|Error} -* `message` {any} +* `message` {string|Error} Expects the function `block` to throw an error. If specified, `error` can be a [`Class`][], [`RegExp`][], a validation function, -an object where each property will be tested for, or an instance of error where -each property will be tested for including the non-enumerable `message` and -`name` properties. +a validation object where each property will be tested for strict deep equality, +or an instance of error where each property will be tested for strict deep +equality including the non-enumerable `message` and `name` properties. When +using an object, it is also possible to use a regular expression, when +validating against a string property. See below for examples. If specified, `message` will be the message provided by the `AssertionError` if the block fails to throw. -Custom error object / error instance: +Custom validation object / error instance: ```js const err = new TypeError('Wrong value'); err.code = 404; +err.foo = 'bar'; +err.info = { + nested: true, + baz: 'text' +}; +err.reg = /abc/i; assert.throws( () => { @@ -1089,8 +1101,38 @@ assert.throws( }, { name: 'TypeError', - message: 'Wrong value' - // Note that only properties on the error object will be tested! + message: 'Wrong value', + info: { + nested: true, + baz: 'text' + } + // Note that only properties on the validation object will be tested for. + // Using nested objects requires all properties to be present. Otherwise + // the validation is going to fail. + } +); + +// Using regular expressions to validate error properties: +assert.throws( + () => { + throw err; + }, + { + // The `name` and `message` properties are strings and using regular + // expressions on those will match against the string. If they fail, an + // error is thrown. + name: /^TypeError$/, + message: /Wrong/, + foo: 'bar', + info: { + nested: true, + // It is not possible to use regular expressions for nested properties! + baz: 'text' + }, + // The `reg` property contains a regular expression and only if the + // validation object contains an identical regular expression, it is going + // to pass. + reg: /abc/i } ); diff --git a/doc/api/cli.md b/doc/api/cli.md index 6d055d9d03a6dd..aecc636489c32d 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -217,6 +217,29 @@ are linked from more than one location in the dependency tree (Node.js would see those as two separate modules and would attempt to load the module multiple times, causing an exception to be thrown). +The `--preserve-symlinks` flag does not apply to the main module, which allows +`node --preserve-symlinks node_module/.bin/` to work. To apply the same +behavior for the main module, also use `--preserve-symlinks-main`. + +### `--preserve-symlinks-main` + + +Instructs the module loader to preserve symbolic links when resolving and +caching the main module (`require.main`). + +This flag exists so that the main module can be opted-in to the same behavior +that `--preserve-symlinks` gives to all other imports; they are separate flags, +however, for backward compatibility with older Node.js versions. + +Note that `--preserve-symlinks-main` does not imply `--preserve-symlinks`; it +is expected that `--preserve-symlinks-main` will be used in addition to +`--preserve-symlinks` when it is not desirable to follow symlinks before +resolving relative paths. + +See `--preserve-symlinks` for more information. + ### `--prof-process` > Stability: 0 - Deprecated: Use [`crypto.createCipheriv()`][] instead. @@ -1331,7 +1336,9 @@ Creates and returns a `Cipher` object that uses the given `algorithm` and The `options` argument controls stream behavior and is optional except when a cipher in CCM mode is used (e.g. `'aes-128-ccm'`). In that case, the `authTagLength` option is required and specifies the length of the -authentication tag in bytes, see [CCM mode][]. +authentication tag in bytes, see [CCM mode][]. In GCM mode, the `authTagLength` +option is not required but can be used to set the length of the authentication +tag that will be returned by `getAuthTag()` and defaults to 16 bytes. The `algorithm` is dependent on OpenSSL, examples are `'aes192'`, etc. On recent OpenSSL releases, `openssl list -cipher-algorithms` @@ -1362,6 +1369,10 @@ Adversaries][] for details. + +> Stability: 1 - Experimental. This feature is still under active development +> and subject to non-backwards compatible changes, or even removal, in any +> future version. Use of the feature is not recommended in production +> environments. Experimental features are not subject to the Node.js Semantic +> Versioning model. + + + +> Stability: 2 - Stable. The API has proven satisfactory. Compatibility with the +> npm ecosystem is a high priority, and will not be broken unless absolutely +> necessary. Caution must be used when making use of `Experimental` features, particularly within modules that may be used as dependencies (or dependencies of diff --git a/doc/api/errors.md b/doc/api/errors.md index a2489c6ac2e7e7..0c3c5fba7d0e49 100644 --- a/doc/api/errors.md +++ b/doc/api/errors.md @@ -1704,6 +1704,7 @@ Creation of a [`zlib`][] object failed due to incorrect configuration. [`--force-fips`]: cli.html#cli_force_fips [`child_process`]: child_process.html [`cipher.getAuthTag()`]: crypto.html#crypto_cipher_getauthtag +[`Class: assert.AssertionError`]: assert.html#assert_class_assert_assertionerror [`crypto.timingSafeEqual()`]: crypto.html#crypto_crypto_timingsafeequal_a_b [`dgram.createSocket()`]: dgram.html#dgram_dgram_createsocket_options_callback [`ERR_INVALID_ARG_TYPE`]: #ERR_INVALID_ARG_TYPE @@ -1736,7 +1737,7 @@ Creation of a [`zlib`][] object failed due to incorrect configuration. [`process.setUncaughtExceptionCaptureCallback()`]: process.html#process_process_setuncaughtexceptioncapturecallback_fn [`require('crypto').setEngine()`]: crypto.html#crypto_crypto_setengine_engine_flags [`server.listen()`]: net.html#net_server_listen -[`Class: assert.AssertionError`]: assert.html#assert_class_assert_assertionerror +[`zlib`]: zlib.html [ES6 module]: esm.html [Node.js Error Codes]: #nodejs-error-codes [V8's stack trace API]: https://github.com/v8/v8/wiki/Stack-Trace-API @@ -1748,8 +1749,7 @@ Creation of a [`zlib`][] object failed due to incorrect configuration. [ICU]: intl.html#intl_internationalization_support [online]: http://man7.org/linux/man-pages/man3/errno.3.html [stream-based]: stream.html -[syscall]: http://man7.org/linux/man-pages/man2/syscall.2.html +[syscall]: http://man7.org/linux/man-pages/man2/syscalls.2.html [try-catch]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch [vm]: vm.html [WHATWG Supported Encodings]: util.html#util_whatwg_supported_encodings -[`zlib`]: zlib.html diff --git a/doc/api/esm.md b/doc/api/esm.md index a1e3cb149ab7d8..459f87771815cc 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -95,16 +95,43 @@ When loaded via `import` these modules will provide a single `default` export representing the value of `module.exports` at the time they finished evaluating. ```js -import fs from 'fs'; -fs.readFile('./foo.txt', (err, body) => { +// foo.js +module.exports = { one: 1 }; + +// bar.js +import foo from './foo.js'; +foo.one === 1; // true +``` + +Builtin modules will provide named exports of their public API, as well as a +default export which can be used for, among other things, modifying the named +exports. Named exports of builtin modules are updated when the corresponding +exports property is accessed, redefined, or deleted. + +```js +import EventEmitter from 'events'; +const e = new EventEmitter(); +``` + +```js +import { readFile } from 'fs'; +readFile('./foo.txt', (err, source) => { if (err) { console.error(err); } else { - console.log(body); + console.log(source); } }); ``` +```js +import fs, { readFileSync } from 'fs'; + +fs.readFileSync = () => Buffer.from('Hello, ESM'); + +fs.readFileSync === readFileSync; +``` + ## Loader hooks diff --git a/doc/api/fs.md b/doc/api/fs.md index 30d6729d48c13d..26eda38f739892 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -746,17 +746,9 @@ changes: Tests a user's permissions for the file or directory specified by `path`. The `mode` argument is an optional integer that specifies the accessibility -checks to be performed. The following constants define the possible values of -`mode`. It is possible to create a mask consisting of the bitwise OR of two or -more values (e.g. `fs.constants.W_OK | fs.constants.R_OK`). - -* `fs.constants.F_OK` - `path` is visible to the calling process. This is useful -for determining if a file exists, but says nothing about `rwx` permissions. -Default if no `mode` is specified. -* `fs.constants.R_OK` - `path` can be read by the calling process. -* `fs.constants.W_OK` - `path` can be written by the calling process. -* `fs.constants.X_OK` - `path` can be executed by the calling process. This has -no effect on Windows (will behave like `fs.constants.F_OK`). +checks to be performed. Check [File Access Constants][] for possible values +of `mode`. It is possible to create a mask consisting of the bitwise OR of +two or more values (e.g. `fs.constants.W_OK | fs.constants.R_OK`). The final argument, `callback`, is a callback function that is invoked with a possible error argument. If any of the accessibility checks fail, the error @@ -889,19 +881,12 @@ changes: * `path` {string|Buffer|URL} * `mode` {integer} **Default:** `fs.constants.F_OK` -Synchronously tests a user's permissions for the file or directory specified by -`path`. The `mode` argument is an optional integer that specifies the -accessibility checks to be performed. The following constants define the -possible values of `mode`. It is possible to create a mask consisting of the -bitwise OR of two or more values (e.g. `fs.constants.W_OK | fs.constants.R_OK`). - -* `fs.constants.F_OK` - `path` is visible to the calling process. This is useful -for determining if a file exists, but says nothing about `rwx` permissions. -Default if no `mode` is specified. -* `fs.constants.R_OK` - `path` can be read by the calling process. -* `fs.constants.W_OK` - `path` can be written by the calling process. -* `fs.constants.X_OK` - `path` can be executed by the calling process. This has -no effect on Windows (will behave like `fs.constants.F_OK`). +Synchronously tests a user's permissions for the file or directory specified +by `path`. The `mode` argument is an optional integer that specifies the +accessibility checks to be performed. Check [File Access Constants][] for +possible values of `mode`. It is possible to create a mask consisting of +the bitwise OR of two or more values +(e.g. `fs.constants.W_OK | fs.constants.R_OK`). If any of the accessibility checks fail, an `Error` will be thrown. Otherwise, the method will return `undefined`. @@ -3051,9 +3036,9 @@ The recursive option is only supported on macOS and Windows. This feature depends on the underlying operating system providing a way to be notified of filesystem changes. -* On Linux systems, this uses [`inotify`] -* On BSD systems, this uses [`kqueue`] -* On macOS, this uses [`kqueue`] for files and [`FSEvents`] for directories. +* On Linux systems, this uses [`inotify(7)`]. +* On BSD systems, this uses [`kqueue(2)`]. +* On macOS, this uses [`kqueue(2)`] for files and [`FSEvents`] for directories. * On SunOS systems (including Solaris and SmartOS), this uses [`event ports`]. * On Windows systems, this feature depends on [`ReadDirectoryChangesW`]. * On Aix systems, this feature depends on [`AHAFS`], which must be enabled. @@ -3458,6 +3443,7 @@ added: v10.0.0 Closes the file descriptor. ```js +const fsPromises = require('fs').promises; async function openAndClose() { let filehandle; try { @@ -3569,6 +3555,9 @@ For example, the following program retains only the first four bytes of the file: ```js +const fs = require('fs'); +const fsPromises = fs.promises; + console.log(fs.readFileSync('temp.txt', 'utf8')); // Prints: Node.js @@ -3585,6 +3574,9 @@ If the file previously was shorter than `len` bytes, it is extended, and the extended part is filled with null bytes (`'\0'`). For example, ```js +const fs = require('fs'); +const fsPromises = fs.promises; + console.log(fs.readFileSync('temp.txt', 'utf8')); // Prints: Node.js @@ -3679,17 +3671,9 @@ added: v10.0.0 Tests a user's permissions for the file or directory specified by `path`. The `mode` argument is an optional integer that specifies the accessibility -checks to be performed. The following constants define the possible values of -`mode`. It is possible to create a mask consisting of the bitwise OR of two or -more values (e.g. `fs.constants.W_OK | fs.constants.R_OK`). - -* `fs.constants.F_OK` - `path` is visible to the calling process. This is useful -for determining if a file exists, but says nothing about `rwx` permissions. -Default if no `mode` is specified. -* `fs.constants.R_OK` - `path` can be read by the calling process. -* `fs.constants.W_OK` - `path` can be written by the calling process. -* `fs.constants.X_OK` - `path` can be executed by the calling process. This has -no effect on Windows (will behave like `fs.constants.F_OK`). +checks to be performed. Check [File Access Constants][] for possible values +of `mode`. It is possible to create a mask consisting of the bitwise OR of +two or more values (e.g. `fs.constants.W_OK | fs.constants.R_OK`). If the accessibility check is successful, the `Promise` is resolved with no value. If any of the accessibility checks fail, the `Promise` is rejected @@ -3697,6 +3681,9 @@ with an `Error` object. The following example checks if the file `/etc/passwd` can be read and written by the current process. ```js +const fs = require('fs'); +const fsPromises = fs.promises; + fsPromises.access('/etc/passwd', fs.constants.R_OK | fs.constants.W_OK) .then(() => console.log('can access')) .catch(() => console.error('cannot access')); @@ -3789,7 +3776,7 @@ then the operation will fail. Example: ```js -const fs = require('fs'); +const fsPromises = require('fs').promises; // destination.txt will be created or overwritten by default. fsPromises.copyFile('source.txt', 'destination.txt') @@ -3802,6 +3789,7 @@ following example. ```js const fs = require('fs'); +const fsPromises = fs.promises; const { COPYFILE_EXCL } = fs.constants; // By using COPYFILE_EXCL, the operation will fail if destination.txt exists. @@ -4329,7 +4317,9 @@ The following constants are meant for use with [`fs.access()`][]. F_OK - Flag indicating that the file is visible to the calling process. + Flag indicating that the file is visible to the calling process. + This is useful for determining if a file exists, but says nothing + about rwx permissions. Default if no mode is specified. R_OK @@ -4343,7 +4333,8 @@ The following constants are meant for use with [`fs.access()`][]. X_OK Flag indicating that the file can be executed by the calling - process. + process. This has no effect on Windows + (will behave like fs.constants.F_OK). @@ -4689,8 +4680,8 @@ the file contents. [`fs.watch()`]: #fs_fs_watch_filename_options_listener [`fs.write()`]: #fs_fs_write_fd_buffer_offset_length_position_callback [`fs.writeFile()`]: #fs_fs_writefile_file_data_options_callback -[`inotify`]: http://man7.org/linux/man-pages/man7/inotify.7.html -[`kqueue`]: https://www.freebsd.org/cgi/man.cgi?kqueue +[`inotify(7)`]: http://man7.org/linux/man-pages/man7/inotify.7.html +[`kqueue(2)`]: https://www.freebsd.org/cgi/man.cgi?query=kqueue&sektion=2 [`net.Socket`]: net.html#net_class_net_socket [`stat()`]: fs.html#fs_fs_stat_path_callback [`util.promisify()`]: util.html#util_util_promisify_original @@ -4706,3 +4697,4 @@ the file contents. [Naming Files, Paths, and Namespaces]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx [MSDN-Using-Streams]: https://msdn.microsoft.com/en-us/library/windows/desktop/bb540537.aspx [support of file system `flags`]: #fs_file_system_flags +[File Access Constants]: #fs_file_access_constants diff --git a/doc/api/http2.md b/doc/api/http2.md index d737471e8670ee..72233407d6c9e2 100644 --- a/doc/api/http2.md +++ b/doc/api/http2.md @@ -664,9 +664,9 @@ added: v8.4.0 added: v9.4.0 --> -* `alt`: {string} -* `origin`: {string} -* `streamId`: {number} +* `alt` {string} +* `origin` {string} +* `streamId` {number} The `'altsvc'` event is emitted whenever an `ALTSVC` frame is received by the client. The event is emitted with the `ALTSVC` value, origin, and stream @@ -846,6 +846,8 @@ the `http2stream.rstCode` property. If the code is any value other than added: v8.4.0 --> +* `error` {Error} + The `'error'` event is emitted when an error occurs during the processing of an `Http2Stream`. @@ -878,6 +880,10 @@ The `'trailers'` event is emitted when a block of headers associated with trailing header fields is received. The listener callback is passed the [HTTP/2 Headers Object][] and flags associated with the headers. +Note that this event might not be emitted if `http2stream.end()` is called +before trailers are received and the incoming data is not being read or +listened for. + ```js stream.on('trailers', (headers, flags) => { console.log(headers); @@ -3119,7 +3125,7 @@ added: v8.4.0 --> Call [`http2stream.pushStream()`][] with the given headers, and wraps the -given newly created [`Http2Stream`] on `Http2ServerRespose`. +given newly created [`Http2Stream`] on `Http2ServerResponse`. The callback will be called with an error with code `ERR_HTTP2_STREAM_CLOSED` if the stream is closed. diff --git a/doc/api/modules.md b/doc/api/modules.md index c9b83859d99079..c46b30560da81f 100644 --- a/doc/api/modules.md +++ b/doc/api/modules.md @@ -175,7 +175,7 @@ LOAD_AS_DIRECTORY(X) 2. LOAD_INDEX(X) LOAD_NODE_MODULES(X, START) -1. let DIRS=NODE_MODULES_PATHS(START) +1. let DIRS = NODE_MODULES_PATHS(START) 2. for each DIR in DIRS: a. LOAD_AS_FILE(DIR/X) b. LOAD_AS_DIRECTORY(DIR/X) @@ -183,7 +183,7 @@ LOAD_NODE_MODULES(X, START) NODE_MODULES_PATHS(START) 1. let PARTS = path split(START) 2. let I = count of PARTS - 1 -3. let DIRS = [] +3. let DIRS = [GLOBAL_FOLDERS] 4. while I >= 0, a. if PARTS[I] = "node_modules" CONTINUE b. DIR = path join(PARTS[0 .. I] + "node_modules") @@ -419,7 +419,7 @@ when people are unaware that `NODE_PATH` must be set. Sometimes a module's dependencies change, causing a different version (or even a different module) to be loaded as the `NODE_PATH` is searched. -Additionally, Node.js will search in the following locations: +Additionally, Node.js will search in the following list of GLOBAL_FOLDERS: * 1: `$HOME/.node_modules` * 2: `$HOME/.node_libraries` @@ -649,9 +649,11 @@ changes: * `request` {string} The module path to resolve. * `options` {Object} * `paths` {string[]} Paths to resolve module location from. If present, these - paths are used instead of the default resolution paths. Note that each of - these paths is used as a starting point for the module resolution algorithm, - meaning that the `node_modules` hierarchy is checked from this location. + paths are used instead of the default resolution paths, with the exception + of [GLOBAL_FOLDERS][] like `$HOME/.node_modules`, which are always + included. Note that each of these paths is used as a starting point for + the module resolution algorithm, meaning that the `node_modules` hierarchy + is checked from this location. * Returns: {string} Use the internal `require()` machinery to look up the location of a module, @@ -891,6 +893,7 @@ const builtin = require('module').builtinModules; [`Error`]: errors.html#errors_class_error [`module` object]: #modules_the_module_object [`path.dirname()`]: path.html#path_path_dirname_path +[GLOBAL_FOLDERS]: #modules_loading_from_the_global_folders [exports shortcut]: #modules_exports_shortcut [module resolution]: #modules_all_together [module wrapper]: #modules_the_module_wrapper diff --git a/doc/api/n-api.md b/doc/api/n-api.md index 17958c8daf255e..a8d1ae46d09cdc 100644 --- a/doc/api/n-api.md +++ b/doc/api/n-api.md @@ -343,7 +343,7 @@ TypeError [ERR_ERROR_1] added: v8.0.0 --> ```C -NODE_EXTERN napi_status napi_throw(napi_env env, napi_value error); +NAPI_EXTERN napi_status napi_throw(napi_env env, napi_value error); ``` - `[in] env`: The environment that the API is invoked under. - `[in] error`: The JavaScript value to be thrown. @@ -357,7 +357,7 @@ This API throws the JavaScript value provided. added: v8.0.0 --> ```C -NODE_EXTERN napi_status napi_throw_error(napi_env env, +NAPI_EXTERN napi_status napi_throw_error(napi_env env, const char* code, const char* msg); ``` @@ -375,7 +375,7 @@ This API throws a JavaScript `Error` with the text provided. added: v8.0.0 --> ```C -NODE_EXTERN napi_status napi_throw_type_error(napi_env env, +NAPI_EXTERN napi_status napi_throw_type_error(napi_env env, const char* code, const char* msg); ``` @@ -393,7 +393,7 @@ This API throws a JavaScript `TypeError` with the text provided. added: v8.0.0 --> ```C -NODE_EXTERN napi_status napi_throw_range_error(napi_env env, +NAPI_EXTERN napi_status napi_throw_range_error(napi_env env, const char* code, const char* msg); ``` @@ -411,7 +411,7 @@ This API throws a JavaScript `RangeError` with the text provided. added: v8.0.0 --> ```C -NODE_EXTERN napi_status napi_is_error(napi_env env, +NAPI_EXTERN napi_status napi_is_error(napi_env env, napi_value value, bool* result); ``` @@ -429,7 +429,7 @@ This API queries a `napi_value` to check if it represents an error object. added: v8.0.0 --> ```C -NODE_EXTERN napi_status napi_create_error(napi_env env, +NAPI_EXTERN napi_status napi_create_error(napi_env env, napi_value code, napi_value msg, napi_value* result); @@ -450,7 +450,7 @@ This API returns a JavaScript `Error` with the text provided. added: v8.0.0 --> ```C -NODE_EXTERN napi_status napi_create_type_error(napi_env env, +NAPI_EXTERN napi_status napi_create_type_error(napi_env env, napi_value code, napi_value msg, napi_value* result); @@ -471,9 +471,9 @@ This API returns a JavaScript `TypeError` with the text provided. added: v8.0.0 --> ```C -NODE_EXTERN napi_status napi_create_range_error(napi_env env, +NAPI_EXTERN napi_status napi_create_range_error(napi_env env, napi_value code, - const char* msg, + napi_value msg, napi_value* result); ``` - `[in] env`: The environment that the API is invoked under. @@ -659,7 +659,7 @@ can only be called once. added: v8.0.0 --> ```C -NODE_EXTERN napi_status napi_open_handle_scope(napi_env env, +NAPI_EXTERN napi_status napi_open_handle_scope(napi_env env, napi_handle_scope* result); ``` - `[in] env`: The environment that the API is invoked under. @@ -674,7 +674,7 @@ This API open a new scope. added: v8.0.0 --> ```C -NODE_EXTERN napi_status napi_close_handle_scope(napi_env env, +NAPI_EXTERN napi_status napi_close_handle_scope(napi_env env, napi_handle_scope scope); ``` - `[in] env`: The environment that the API is invoked under. @@ -692,7 +692,7 @@ This API can be called even if there is a pending JavaScript exception. added: v8.0.0 --> ```C -NODE_EXTERN napi_status +NAPI_EXTERN napi_status napi_open_escapable_handle_scope(napi_env env, napi_handle_scope* result); ``` @@ -709,7 +709,7 @@ to the outer scope. added: v8.0.0 --> ```C -NODE_EXTERN napi_status +NAPI_EXTERN napi_status napi_close_escapable_handle_scope(napi_env env, napi_handle_scope scope); ``` @@ -793,7 +793,7 @@ individual count. added: v8.0.0 --> ```C -NODE_EXTERN napi_status napi_create_reference(napi_env env, +NAPI_EXTERN napi_status napi_create_reference(napi_env env, napi_value value, int initial_refcount, napi_ref* result); @@ -815,7 +815,7 @@ to the `Object` passed in. added: v8.0.0 --> ```C -NODE_EXTERN napi_status napi_delete_reference(napi_env env, napi_ref ref); +NAPI_EXTERN napi_status napi_delete_reference(napi_env env, napi_ref ref); ``` - `[in] env`: The environment that the API is invoked under. @@ -832,7 +832,7 @@ This API can be called even if there is a pending JavaScript exception. added: v8.0.0 --> ```C -NODE_EXTERN napi_status napi_reference_ref(napi_env env, +NAPI_EXTERN napi_status napi_reference_ref(napi_env env, napi_ref ref, int* result); ``` @@ -850,7 +850,7 @@ passed in and returns the resulting reference count. added: v8.0.0 --> ```C -NODE_EXTERN napi_status napi_reference_unref(napi_env env, +NAPI_EXTERN napi_status napi_reference_unref(napi_env env, napi_ref ref, int* result); ``` @@ -868,7 +868,7 @@ passed in and returns the resulting reference count. added: v8.0.0 --> ```C -NODE_EXTERN napi_status napi_get_reference_value(napi_env env, +NAPI_EXTERN napi_status napi_get_reference_value(napi_env env, napi_ref ref, napi_value* result); ``` @@ -886,6 +886,58 @@ If still valid, this API returns the `napi_value` representing the JavaScript `Object` associated with the `napi_ref`. Otherwise, result will be NULL. +### Cleanup on exit of the current Node.js instance + +While a Node.js process typically releases all its resources when exiting, +embedders of Node.js, or future Worker support, may require addons to register +clean-up hooks that will be run once the current Node.js instance exits. + +N-API provides functions for registering and un-registering such callbacks. +When those callbacks are run, all resources that are being held by the addon +should be freed up. + +#### napi_add_env_cleanup_hook + +```C +NODE_EXTERN napi_status napi_add_env_cleanup_hook(napi_env env, + void (*fun)(void* arg), + void* arg); +``` + +Registers `fun` as a function to be run with the `arg` parameter once the +current Node.js environment exits. + +A function can safely be specified multiple times with different +`arg` values. In that case, it will be called multiple times as well. +Providing the same `fun` and `arg` values multiple times is not allowed +and will lead the process to abort. + +The hooks will be called in reverse order, i.e. the most recently added one +will be called first. + +Removing this hook can be done by using `napi_remove_env_cleanup_hook`. +Typically, that happens when the resource for which this hook was added +is being torn down anyway. + +#### napi_remove_env_cleanup_hook + +```C +NAPI_EXTERN napi_status napi_remove_env_cleanup_hook(napi_env env, + void (*fun)(void* arg), + void* arg); +``` + +Unregisters `fun` as a function to be run with the `arg` parameter once the +current Node.js environment exits. Both the argument and the function value +need to be exact matches. + +The function must have originally been registered +with `napi_add_env_cleanup_hook`, otherwise the process will abort. + ## Module registration N-API modules are registered in a manner similar to other modules except that instead of using the `NODE_MODULE` macro the following @@ -1697,8 +1749,9 @@ napi_status napi_get_typedarray_info(napi_env env, - `[in] typedarray`: `napi_value` representing the `TypedArray` whose properties to query. - `[out] type`: Scalar datatype of the elements within the `TypedArray`. -- `[out] length`: `Number` of elements in the `TypedArray`. -- `[out] data`: The data buffer underlying the typed array. +- `[out] length`: The number of elements in the `TypedArray`. +- `[out] data`: The data buffer underlying the `TypedArray`. +- `[out] arraybuffer`: The `ArrayBuffer` underlying the `TypedArray`. - `[out] byte_offset`: The byte offset within the data buffer from which to start projecting the `TypedArray`. diff --git a/doc/api/net.md b/doc/api/net.md index 21d14fc7068bc5..5ac60403e5ee02 100644 --- a/doc/api/net.md +++ b/doc/api/net.md @@ -204,7 +204,8 @@ length of the queue of pending connections. The actual length will be determined by the OS through sysctl settings such as `tcp_max_syn_backlog` and `somaxconn` on Linux. The default value of this parameter is 511 (not 512). -All [`net.Socket`][] are set to `SO_REUSEADDR` (See [socket(7)][] for details). +All [`net.Socket`][] are set to `SO_REUSEADDR` (see [`socket(7)`][] for +details). The `server.listen()` method can be called again if and only if there was an error during the first `server.listen()` call or `server.close()` has been @@ -1135,6 +1136,7 @@ Returns `true` if input is a version 6 IP address, otherwise returns `false`. [`server.listen(handle)`]: #net_server_listen_handle_backlog_callback [`server.listen(options)`]: #net_server_listen_options_callback [`server.listen(path)`]: #net_server_listen_path_backlog_callback +[`socket(7)`]: http://man7.org/linux/man-pages/man7/socket.7.html [`socket.connect()`]: #net_socket_connect [`socket.connect(options)`]: #net_socket_connect_options_connectlistener [`socket.connect(path)`]: #net_socket_connect_path_connectlistener @@ -1152,7 +1154,6 @@ Returns `true` if input is a version 6 IP address, otherwise returns `false`. [Readable Stream]: stream.html#stream_class_stream_readable [duplex stream]: stream.html#stream_class_stream_duplex [half-closed]: https://tools.ietf.org/html/rfc1122 -[socket(7)]: http://man7.org/linux/man-pages/man7/socket.7.html [stream_writable_write]: stream.html#stream_writable_write_chunk_encoding_callback [unspecified IPv4 address]: https://en.wikipedia.org/wiki/0.0.0.0 [unspecified IPv6 address]: https://en.wikipedia.org/wiki/IPv6_address#Unspecified_address diff --git a/doc/api/timers.md b/doc/api/timers.md index 376b5312e5a41a..1eb511c3b92b48 100644 --- a/doc/api/timers.md +++ b/doc/api/timers.md @@ -74,6 +74,21 @@ When called, requests that the Node.js event loop *not* exit so long as the By default, all `Timeout` objects are "ref'ed", making it normally unnecessary to call `timeout.ref()` unless `timeout.unref()` had been called previously. +### timeout.refresh() + + +* Returns: {Timeout} a reference to `timeout` + +Sets the timer's start time to the current time, and reschedules the timer to +call its callback at the previously specified duration adjusted to the current +time. This is useful for refreshing a timer without allocating a new +JavaScript object. + +Using this on a timer that has already called its callback will reactivate the +timer. + ### timeout.unref() + +* Returns: {boolean} + +Returns `true` if the value is a `BigInt64Array` instance. The +`--harmony-bigint` command line flag is required in order to use the +`BigInt64Array` type, but it is not required in order to use +`isBigInt64Array()`. + +For example: + +```js +util.types.isBigInt64Array(new BigInt64Array()); // Returns true +util.types.isBigInt64Array(new BigUint64Array()); // Returns false +``` + +### util.types.isBigUint64Array(value) + + +* Returns: {boolean} + +Returns `true` if the value is a `BigUint64Array` instance. The +`--harmony-bigint` command line flag is required in order to use the +`BigUint64Array` type, but it is not required in order to use +`isBigUint64Array()`. + +For example: + +```js +util.types.isBigUint64Array(new BigInt64Array()); // Returns false +util.types.isBigUint64Array(new BigUint64Array()); // Returns true +``` + ### util.types.isBooleanObject(value) + +* Returns: {boolean} + +Returns `true` if the value is an instance of a [Module Namespace Object][]. + +For example: + + +```js +import * as ns from './a.js'; + +util.types.isModuleNamespaceObject(ns); // Returns true +``` + ### util.types.isNativeError(value) ' + - '

Describe Something in more detail here. ' + - '

' + '

Describe Something in more detail here.

' }, { file: fixtures.path('doc_with_includes.md'), html: '' + '

Look here!

' + - '' + - '' + + '' + '

foobar#

' + - '

I exist and am being linked to.

' + - '' + '

I exist and am being linked to.

' }, { file: fixtures.path('sample_document.md'), @@ -92,34 +83,34 @@ const testData = [ const spaces = /\s/g; -testData.forEach((item) => { - // Normalize expected data by stripping whitespace - const expected = item.html.replace(spaces, ''); - const includeAnalytics = typeof item.analyticsId !== 'undefined'; +testData.forEach(({ file, html, analyticsId }) => { + // Normalize expected data by stripping whitespace. + const expected = html.replace(spaces, ''); + const includeAnalytics = typeof analyticsId !== 'undefined'; - fs.readFile(item.file, 'utf8', common.mustCall((err, input) => { + readFile(file, 'utf8', common.mustCall((err, input) => { assert.ifError(err); - processIncludes(item.file, input, common.mustCall((err, preprocessed) => { + processIncludes(file, input, common.mustCall((err, preprocessed) => { assert.ifError(err); - html( + toHTML( { input: preprocessed, filename: 'foo', nodeVersion: process.version, - analytics: item.analyticsId, + analytics: analyticsId, }, common.mustCall((err, output) => { assert.ifError(err); const actual = output.replace(spaces, ''); - const scriptDomain = 'google-analytics.com'; // Assert that the input stripped of all whitespace contains the - // expected list + // expected markup. assert(actual.includes(expected)); // Testing the insertion of Google Analytics script when - // an analytics id is provided. Should not be present by default + // an analytics id is provided. Should not be present by default. + const scriptDomain = 'google-analytics.com'; if (includeAnalytics) { assert(actual.includes(scriptDomain), `Google Analytics script was not present in "${actual}"`); diff --git a/test/es-module/test-esm-dynamic-import.js b/test/es-module/test-esm-dynamic-import.js index c6daa95f9a6b98..91757172880f67 100644 --- a/test/es-module/test-esm-dynamic-import.js +++ b/test/es-module/test-esm-dynamic-import.js @@ -52,6 +52,7 @@ function expectFsNamespace(result) { Promise.resolve(result) .then(common.mustCall(ns => { assert.strictEqual(typeof ns.default.writeFile, 'function'); + assert.strictEqual(typeof ns.writeFile, 'function'); })); } diff --git a/test/es-module/test-esm-live-binding.mjs b/test/es-module/test-esm-live-binding.mjs new file mode 100644 index 00000000000000..d151e004dff4b2 --- /dev/null +++ b/test/es-module/test-esm-live-binding.mjs @@ -0,0 +1,143 @@ +// Flags: --experimental-modules + +import '../common'; +import assert from 'assert'; + +import fs, { readFile, readFileSync } from 'fs'; +import events, { defaultMaxListeners } from 'events'; +import util from 'util'; + +const readFileDescriptor = Reflect.getOwnPropertyDescriptor(fs, 'readFile'); +const readFileSyncDescriptor = + Reflect.getOwnPropertyDescriptor(fs, 'readFileSync'); + +const s = Symbol(); +const fn = () => s; + +Reflect.deleteProperty(fs, 'readFile'); + +assert.deepStrictEqual([fs.readFile, readFile], [undefined, undefined]); + +fs.readFile = fn; + +assert.deepStrictEqual([fs.readFile(), readFile()], [s, s]); + +Reflect.defineProperty(fs, 'readFile', { + value: fn, + configurable: true, + writable: true, +}); + +assert.deepStrictEqual([fs.readFile(), readFile()], [s, s]); + +Reflect.deleteProperty(fs, 'readFile'); + +assert.deepStrictEqual([fs.readFile, readFile], [undefined, undefined]); + +let count = 0; + +Reflect.defineProperty(fs, 'readFile', { + get() { return count; }, + configurable: true, +}); + +count++; + +assert.deepStrictEqual([readFile, fs.readFile, readFile], [0, 1, 1]); + +let otherValue; + +Reflect.defineProperty(fs, 'readFile', { // eslint-disable-line accessor-pairs + set(value) { + Reflect.deleteProperty(fs, 'readFile'); + otherValue = value; + }, + configurable: true, +}); + +Reflect.defineProperty(fs, 'readFileSync', { + get() { + return otherValue; + }, + configurable: true, +}); + +fs.readFile = 2; + +assert.deepStrictEqual([readFile, readFileSync], [undefined, 2]); + +Reflect.defineProperty(fs, 'readFile', readFileDescriptor); +Reflect.defineProperty(fs, 'readFileSync', readFileSyncDescriptor); + +const originDefaultMaxListeners = events.defaultMaxListeners; +const utilProto = util.__proto__; // eslint-disable-line no-proto + +count = 0; + +Reflect.defineProperty(Function.prototype, 'defaultMaxListeners', { + configurable: true, + enumerable: true, + get: function() { return ++count; }, + set: function(v) { + Reflect.defineProperty(this, 'defaultMaxListeners', { + configurable: true, + enumerable: true, + writable: true, + value: v, + }); + }, +}); + +assert.strictEqual(defaultMaxListeners, originDefaultMaxListeners); +assert.strictEqual(events.defaultMaxListeners, originDefaultMaxListeners); + +assert.strictEqual(++events.defaultMaxListeners, + originDefaultMaxListeners + 1); + +assert.strictEqual(defaultMaxListeners, originDefaultMaxListeners + 1); +assert.strictEqual(Function.prototype.defaultMaxListeners, 1); + +Function.prototype.defaultMaxListeners = 'foo'; + +assert.strictEqual(Function.prototype.defaultMaxListeners, 'foo'); +assert.strictEqual(events.defaultMaxListeners, originDefaultMaxListeners + 1); +assert.strictEqual(defaultMaxListeners, originDefaultMaxListeners + 1); + +count = 0; + +const p = { + get foo() { return ++count; }, + set foo(v) { + Reflect.defineProperty(this, 'foo', { + configurable: true, + enumerable: true, + writable: true, + value: v, + }); + }, +}; + +util.__proto__ = p; // eslint-disable-line no-proto + +assert.strictEqual(util.foo, 1); + +util.foo = 'bar'; + +assert.strictEqual(count, 1); +assert.strictEqual(util.foo, 'bar'); +assert.strictEqual(p.foo, 2); + +p.foo = 'foo'; + +assert.strictEqual(p.foo, 'foo'); + +events.defaultMaxListeners = originDefaultMaxListeners; +util.__proto__ = utilProto; // eslint-disable-line no-proto + +Reflect.deleteProperty(util, 'foo'); +Reflect.deleteProperty(Function.prototype, 'defaultMaxListeners'); + +assert.throws( + () => Object.defineProperty(events, 'defaultMaxListeners', { value: 3 }), + /TypeError: Cannot redefine/ +); diff --git a/test/es-module/test-esm-namespace.mjs b/test/es-module/test-esm-namespace.mjs index 04845e2b3e4da0..dcd159f6c8729a 100644 --- a/test/es-module/test-esm-namespace.mjs +++ b/test/es-module/test-esm-namespace.mjs @@ -2,5 +2,13 @@ import '../common'; import * as fs from 'fs'; import assert from 'assert'; +import Module from 'module'; -assert.deepStrictEqual(Object.keys(fs), ['default']); +const keys = Object.entries( + Object.getOwnPropertyDescriptors(new Module().require('fs'))) + .filter(([name, d]) => d.enumerable) + .map(([name]) => name) + .concat('default') + .sort(); + +assert.deepStrictEqual(Object.keys(fs).sort(), keys); diff --git a/test/es-module/test-esm-preserve-symlinks-main.js b/test/es-module/test-esm-preserve-symlinks-main.js new file mode 100644 index 00000000000000..fbca5dce743674 --- /dev/null +++ b/test/es-module/test-esm-preserve-symlinks-main.js @@ -0,0 +1,57 @@ +'use strict'; + +const common = require('../common'); +const { spawn } = require('child_process'); +const assert = require('assert'); +const path = require('path'); +const fs = require('fs'); + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); +const tmpDir = tmpdir.path; + +fs.mkdirSync(path.join(tmpDir, 'nested')); +fs.mkdirSync(path.join(tmpDir, 'nested2')); + +const entry = path.join(tmpDir, 'nested', 'entry.js'); +const entry_link_absolute_path = path.join(tmpDir, 'link.js'); +const submodule = path.join(tmpDir, 'nested2', 'submodule.js'); +const submodule_link_absolute_path = path.join(tmpDir, 'submodule_link.js'); + +fs.writeFileSync(entry, ` +const assert = require('assert'); + +// this import only resolves with --preserve-symlinks-main set +require('./submodule_link.js'); +`); +fs.writeFileSync(submodule, ''); + +try { + fs.symlinkSync(entry, entry_link_absolute_path); + fs.symlinkSync(submodule, submodule_link_absolute_path); +} catch (err) { + if (err.code !== 'EPERM') throw err; + common.skip('insufficient privileges for symlinks'); +} + +function doTest(flags, done) { + // invoke the main file via a symlink. In this case --preserve-symlinks-main + // dictates that it'll resolve relative imports in the main file relative to + // the symlink, and not relative to the symlink target; the file structure set + // up above requires this to not crash when loading ./submodule_link.js + spawn(process.execPath, + flags.concat([ + '--preserve-symlinks', + '--preserve-symlinks-main', entry_link_absolute_path + ]), + { stdio: 'inherit' }).on('exit', (code) => { + assert.strictEqual(code, 0); + done(); + }); +} + +// first test the commonjs module loader +doTest([], () => { + // now test the new loader + doTest(['--experimental-modules'], () => {}); +}); diff --git a/test/fixtures/es-module-loaders/js-loader.mjs b/test/fixtures/es-module-loaders/js-loader.mjs index 2173b0b503ef45..9fa6b9eed4d029 100644 --- a/test/fixtures/es-module-loaders/js-loader.mjs +++ b/test/fixtures/es-module-loaders/js-loader.mjs @@ -1,10 +1,11 @@ -import _url from 'url'; +import { URL } from 'url'; + const builtins = new Set( Object.keys(process.binding('natives')).filter(str => /^(?!(?:internal|node|v8)\/)/.test(str)) ) -const baseURL = new _url.URL('file://'); +const baseURL = new URL('file://'); baseURL.pathname = process.cwd() + '/'; export function resolve (specifier, base = baseURL) { @@ -15,7 +16,7 @@ export function resolve (specifier, base = baseURL) { }; } // load all dependencies as esm, regardless of file extension - const url = new _url.URL(specifier, base).href; + const url = new URL(specifier, base).href; return { url, format: 'esm' diff --git a/test/fixtures/url-setter-tests.js b/test/fixtures/url-setter-tests.js index 289812cb7e33ff..1e460ff2d8dd7c 100644 --- a/test/fixtures/url-setter-tests.js +++ b/test/fixtures/url-setter-tests.js @@ -2,7 +2,7 @@ /* The following tests are copied from WPT. Modifications to them should be upstreamed first. Refs: - https://github.com/w3c/web-platform-tests/blob/ed4bb727ed/url/setters_tests.json + https://github.com/w3c/web-platform-tests/blob/f0fe479/url/setters_tests.json License: http://www.w3.org/Consortium/Legal/2008/04-testsuite-copyright.html */ module.exports = @@ -727,6 +727,17 @@ module.exports = "port": "80" } }, + { + "comment": "Port number is removed if new port is scheme default and existing URL has a non-default port", + "href": "http://example.net:8080", + "new_value": "example.com:80", + "expected": { + "href": "http://example.com/", + "host": "example.com", + "hostname": "example.com", + "port": "" + } + }, { "comment": "Stuff after a / delimiter is ignored", "href": "http://example.net/path", diff --git a/test/fixtures/url-tests.js b/test/fixtures/url-tests.js index 745adb8d8aab43..48533ed09073db 100644 --- a/test/fixtures/url-tests.js +++ b/test/fixtures/url-tests.js @@ -2,7 +2,7 @@ /* The following tests are copied from WPT. Modifications to them should be upstreamed first. Refs: - https://github.com/w3c/web-platform-tests/blob/ed4bb727ed/url/urltestdata.json + https://github.com/w3c/web-platform-tests/blob/88b75886e/url/urltestdata.json License: http://www.w3.org/Consortium/Legal/2008/04-testsuite-copyright.html */ module.exports = @@ -6529,27 +6529,34 @@ module.exports = "search": "?a", "hash": "#%GH" }, - "Bad bases", + "URLs that require a non-about:blank base. (Also serve as invalid base tests.)", { - "input": "test-a.html", - "base": "a", + "input": "a", + "base": "about:blank", "failure": true }, { - "input": "test-a-slash.html", - "base": "a/", + "input": "a/", + "base": "about:blank", "failure": true }, { - "input": "test-a-slash-slash.html", - "base": "a//", + "input": "a//", + "base": "about:blank", "failure": true }, + "Bases that don't fail to parse but fail to be bases", { "input": "test-a-colon.html", "base": "a:", "failure": true }, + { + "input": "test-a-colon-b.html", + "base": "a:b", + "failure": true + }, + "Other base URL tests, that must succeed", { "input": "test-a-colon-slash.html", "base": "a:/", @@ -6578,11 +6585,6 @@ module.exports = "search": "", "hash": "" }, - { - "input": "test-a-colon-b.html", - "base": "a:b", - "failure": true - }, { "input": "test-a-colon-slash-b.html", "base": "a:/b", diff --git a/test/message/assert_throws_stack.out b/test/message/assert_throws_stack.out index 62a25a63673dcf..3d5f4de4cf26a6 100644 --- a/test/message/assert_throws_stack.out +++ b/test/message/assert_throws_stack.out @@ -1,6 +1,6 @@ assert.js:* - throw new AssertionError(obj); - ^ + throw err; + ^ AssertionError [ERR_ASSERTION]: Input A expected to strictly deep-equal input B: + expected - actual diff --git a/test/message/console_low_stack_space.js b/test/message/console_low_stack_space.js index 9128eb49d120e0..4834ffd9cd0b36 100644 --- a/test/message/console_low_stack_space.js +++ b/test/message/console_low_stack_space.js @@ -1,8 +1,11 @@ 'use strict'; -// copy console accessor because requiring ../common touches it +// Copy console accessor because requiring ../common touches it const consoleDescriptor = Object.getOwnPropertyDescriptor(global, 'console'); -delete global.console; -global.console = {}; +Object.defineProperty(global, 'console', { + configurable: true, + writable: true, + value: {} +}); require('../common'); diff --git a/test/message/util_inspect_error.js b/test/message/util_inspect_error.js new file mode 100644 index 00000000000000..20affd6c711fd8 --- /dev/null +++ b/test/message/util_inspect_error.js @@ -0,0 +1,12 @@ +'use strict'; + +require('../common'); +const util = require('util'); + +const err = new Error('foo\nbar'); + +console.log(util.inspect({ err, nested: { err } }, { compact: true })); +console.log(util.inspect({ err, nested: { err } }, { compact: false })); + +err.foo = 'bar'; +console.log(util.inspect(err, { compact: true, breakLength: 5 })); diff --git a/test/message/util_inspect_error.out b/test/message/util_inspect_error.out new file mode 100644 index 00000000000000..406d8112ce2599 --- /dev/null +++ b/test/message/util_inspect_error.out @@ -0,0 +1,63 @@ +{ err: + Error: foo + bar + at *util_inspect_error* + at * + at * + at * + at * + at * + at * + at * + at * + nested: + { err: + Error: foo + bar + at *util_inspect_error* + at * + at * + at * + at * + at * + at * + at * + at * } } +{ + err: Error: foo + bar + at *util_inspect_error* + at * + at * + at * + at * + at * + at * + at * + at *, + nested: { + err: Error: foo + bar + at *util_inspect_error* + at * + at * + at * + at * + at * + at * + at * + at * + } +} +{ Error: foo +bar + at *util_inspect_error* + at * + at * + at * + at * + at * + at * + at * + at * + foo: 'bar' } diff --git a/test/parallel/test-assert-checktag.js b/test/parallel/test-assert-checktag.js index 38ebaa1a1436e7..70a67e15d3f5f8 100644 --- a/test/parallel/test-assert-checktag.js +++ b/test/parallel/test-assert-checktag.js @@ -2,6 +2,12 @@ require('../common'); const assert = require('assert'); +// Disable colored output to prevent color codes from breaking assertion +// message comparisons. This should only be an issue when process.stdout +// is a TTY. +if (process.stdout.isTTY) + process.env.NODE_DISABLE_COLORS = '1'; + // Turn off no-restricted-properties because we are testing deepEqual! /* eslint-disable no-restricted-properties */ diff --git a/test/parallel/test-assert-deep.js b/test/parallel/test-assert-deep.js index 4fa091ef2af96c..538f4bef49d8c6 100644 --- a/test/parallel/test-assert-deep.js +++ b/test/parallel/test-assert-deep.js @@ -7,6 +7,12 @@ const { AssertionError } = assert; const defaultMsgStart = 'Input A expected to strictly deep-equal input B:\n' + '+ expected - actual'; +// Disable colored output to prevent color codes from breaking assertion +// message comparisons. This should only be an issue when process.stdout +// is a TTY. +if (process.stdout.isTTY) + process.env.NODE_DISABLE_COLORS = '1'; + // Template tag function turning an error message into a RegExp // for assert.throws() function re(literals, ...values) { diff --git a/test/parallel/test-assert.js b/test/parallel/test-assert.js index d892122ed62ff2..eb084e9b01cb2b 100644 --- a/test/parallel/test-assert.js +++ b/test/parallel/test-assert.js @@ -27,13 +27,18 @@ const common = require('../common'); const assert = require('assert'); -const { EOL } = require('os'); const EventEmitter = require('events'); -const { errorCache } = require('internal/errors'); +const { errorCache } = require('internal/assert'); const { writeFileSync, unlinkSync } = require('fs'); const { inspect } = require('util'); const a = assert; +// Disable colored output to prevent color codes from breaking assertion +// message comparisons. This should only be an issue when process.stdout +// is a TTY. +if (process.stdout.isTTY) + process.env.NODE_DISABLE_COLORS = '1'; + const start = 'Input A expected to strictly deep-equal input B:'; const actExp = '+ expected - actual'; @@ -456,8 +461,8 @@ assert.throws( { code: 'ERR_ASSERTION', type: assert.AssertionError, - message: `The expression evaluated to a falsy value:${EOL}${EOL} ` + - `assert.ok(typeof 123 === 'string')${EOL}` + message: 'The expression evaluated to a falsy value:\n\n ' + + "assert.ok(typeof 123 === 'string')\n" } ); Error.stackTraceLimit = tmpLimit; @@ -619,8 +624,8 @@ common.expectsError( code: 'ERR_ASSERTION', type: assert.AssertionError, generatedMessage: true, - message: `The expression evaluated to a falsy value:${EOL}${EOL} ` + - `assert.ok(null)${EOL}` + message: 'The expression evaluated to a falsy value:\n\n ' + + 'assert.ok(null)\n' } ); common.expectsError( @@ -629,8 +634,18 @@ common.expectsError( code: 'ERR_ASSERTION', type: assert.AssertionError, generatedMessage: true, - message: `The expression evaluated to a falsy value:${EOL}${EOL} ` + - `assert(typeof 123 === 'string')${EOL}` + message: 'The expression evaluated to a falsy value:\n\n ' + + "assert(typeof 123 === 'string')\n" + } +); + +common.expectsError( + () => assert(false, Symbol('foo')), + { + code: 'ERR_ASSERTION', + type: assert.AssertionError, + generatedMessage: false, + message: 'Symbol(foo)' } ); @@ -650,8 +665,8 @@ common.expectsError( { code: 'ERR_ASSERTION', type: assert.AssertionError, - message: `The expression evaluated to a falsy value:${EOL}${EOL} ` + - `assert(Buffer.from('test') instanceof Error)${EOL}` + message: 'The expression evaluated to a falsy value:\n\n ' + + "assert(Buffer.from('test') instanceof Error)\n" } ); common.expectsError( @@ -659,8 +674,8 @@ common.expectsError( { code: 'ERR_ASSERTION', type: assert.AssertionError, - message: `The expression evaluated to a falsy value:${EOL}${EOL} ` + - `assert(Buffer.from('test') instanceof Error)${EOL}` + message: 'The expression evaluated to a falsy value:\n\n ' + + "assert(Buffer.from('test') instanceof Error)\n" } ); fs.close = tmp; @@ -679,22 +694,63 @@ common.expectsError( { code: 'ERR_ASSERTION', type: assert.AssertionError, - message: `The expression evaluated to a falsy value:${EOL}${EOL} ` + - `assert((() => 'string')()${EOL}` + - ` // eslint-disable-next-line${EOL}` + - ` ===${EOL}` + - ` 123 instanceof${EOL}` + - ` Buffer)${EOL}` + message: 'The expression evaluated to a falsy value:\n\n' + + ' assert((() => \'string\')()\n' + + ' // eslint-disable-next-line\n' + + ' ===\n' + + ' 123 instanceof\n' + + ' Buffer)\n' + } +); + +common.expectsError( + () => { + a( + (() => 'string')() + // eslint-disable-next-line + === + 123 instanceof + Buffer + ); + }, + { + code: 'ERR_ASSERTION', + type: assert.AssertionError, + message: 'The expression evaluated to a falsy value:\n\n' + + ' assert((() => \'string\')()\n' + + ' // eslint-disable-next-line\n' + + ' ===\n' + + ' 123 instanceof\n' + + ' Buffer)\n' } ); +/* eslint-disable indent */ +common.expectsError(() => { +a(( + () => 'string')() === +123 instanceof +Buffer +); +}, { + code: 'ERR_ASSERTION', + type: assert.AssertionError, + message: 'The expression evaluated to a falsy value:\n\n' + + ' assert((\n' + + ' () => \'string\')() ===\n' + + ' 123 instanceof\n' + + ' Buffer)\n' + } +); +/* eslint-enable indent */ + common.expectsError( () => assert(null, undefined), { code: 'ERR_ASSERTION', type: assert.AssertionError, - message: `The expression evaluated to a falsy value:${EOL}${EOL} ` + - `assert(null, undefined)${EOL}` + message: 'The expression evaluated to a falsy value:\n\n ' + + 'assert(null, undefined)\n' } ); @@ -740,7 +796,9 @@ common.expectsError( const frames = err.stack.split('\n'); const [, filename, line, column] = frames[1].match(/\((.+):(\d+):(\d+)\)/); // Reset the cache to check again + const size = errorCache.size; errorCache.delete(`${filename}${line - 1}${column - 1}`); + assert.strictEqual(errorCache.size, size - 1); const data = `${'\n'.repeat(line - 1)}${' '.repeat(column - 1)}` + 'ok(failed(badly));'; try { @@ -849,6 +907,7 @@ common.expectsError( { name: 'AssertionError [ERR_ASSERTION]', code: 'ERR_ASSERTION', + generatedMessage: true, message: `${start}\n${actExp}\n\n` + " Comparison {\n name: 'Error',\n- message: 'foo'" + "\n+ message: ''\n }" @@ -914,3 +973,71 @@ assert.throws( } ); } + +assert.throws( + () => { throw new TypeError('foobar'); }, + { + message: /foo/, + name: /^TypeError$/ + } +); + +assert.throws( + () => assert.throws( + () => { throw new TypeError('foobar'); }, + { + message: /fooa/, + name: /^TypeError$/ + } + ), + { + message: `${start}\n${actExp}\n\n` + + ' Comparison {\n' + + "- message: 'foobar',\n" + + '+ message: /fooa/,\n' + + " name: 'TypeError'\n" + + ' }' + } +); + +{ + let actual = null; + const expected = { message: 'foo' }; + assert.throws( + () => assert.throws( + () => { throw actual; }, + expected + ), + { + operator: 'throws', + actual, + expected, + generatedMessage: true, + message: `${start}\n${actExp}\n\n` + + '- null\n' + + '+ {\n' + + "+ message: 'foo'\n" + + '+ }' + } + ); + + actual = 'foobar'; + const message = 'message'; + assert.throws( + () => assert.throws( + () => { throw actual; }, + { message: 'foobar' }, + message + ), + { + actual, + message, + operator: 'throws', + generatedMessage: false + } + ); +} + +// TODO: This case is only there to make sure there is no breaking change. +// eslint-disable-next-line no-restricted-syntax, no-throw-literal +assert.throws(() => { throw 4; }, 4); diff --git a/test/parallel/test-bootstrap-modules.js b/test/parallel/test-bootstrap-modules.js new file mode 100644 index 00000000000000..4a46ac905b8161 --- /dev/null +++ b/test/parallel/test-bootstrap-modules.js @@ -0,0 +1,14 @@ +/* eslint-disable node-core/required-modules */ + +'use strict'; + +// Ordinarily test files must require('common') but that action causes +// the global console to be compiled, defeating the purpose of this test. +// This makes sure no additional files are added without carefully considering +// lazy loading. Please adjust the value if necessary. + +const list = process.moduleLoadList.slice(); + +const assert = require('assert'); + +assert(list.length <= 73, list); diff --git a/test/parallel/test-buffer-sharedarraybuffer.js b/test/parallel/test-buffer-sharedarraybuffer.js index ce3241ec0e7a0f..52cec6e9c5cd1a 100644 --- a/test/parallel/test-buffer-sharedarraybuffer.js +++ b/test/parallel/test-buffer-sharedarraybuffer.js @@ -1,4 +1,3 @@ -/* global SharedArrayBuffer */ 'use strict'; require('../common'); diff --git a/test/parallel/test-child-process-exec-env.js b/test/parallel/test-child-process-exec-env.js index c34fdb7b49a161..41aaf992cfc8c9 100644 --- a/test/parallel/test-child-process-exec-env.js +++ b/test/parallel/test-child-process-exec-env.js @@ -34,10 +34,10 @@ function after(err, stdout, stderr) { console.log(`error!: ${err.code}`); console.log(`stdout: ${JSON.stringify(stdout)}`); console.log(`stderr: ${JSON.stringify(stderr)}`); - assert.strictEqual(false, err.killed); + assert.strictEqual(err.killed, false); } else { success_count++; - assert.notStrictEqual('', stdout); + assert.notStrictEqual(stdout, ''); } } @@ -56,7 +56,7 @@ child.stdout.on('data', function(chunk) { process.on('exit', function() { console.log('response: ', response); - assert.strictEqual(1, success_count); - assert.strictEqual(0, error_count); + assert.strictEqual(success_count, 1); + assert.strictEqual(error_count, 0); assert.ok(response.includes('HELLO=WORLD')); }); diff --git a/test/parallel/test-child-process-exec-maxBuffer.js b/test/parallel/test-child-process-exec-maxBuffer.js index 4a65ccf5be7510..94545e719ba2d7 100644 --- a/test/parallel/test-child-process-exec-maxBuffer.js +++ b/test/parallel/test-child-process-exec-maxBuffer.js @@ -41,3 +41,25 @@ const unicode = '中文测试'; // length = 4, byte length = 12 cp.exec(cmd, { maxBuffer: 10 }, checkFactory('stderr')); } + +{ + const cmd = `"${process.execPath}" -e "console.log('${unicode}');"`; + + const child = cp.exec( + cmd, + { encoding: null, maxBuffer: 10 }, + checkFactory('stdout')); + + child.stdout.setEncoding('utf-8'); +} + +{ + const cmd = `"${process.execPath}" -e "console.error('${unicode}');"`; + + const child = cp.exec( + cmd, + { encoding: null, maxBuffer: 10 }, + checkFactory('stderr')); + + child.stderr.setEncoding('utf-8'); +} diff --git a/test/parallel/test-child-process-exec-std-encoding.js b/test/parallel/test-child-process-exec-std-encoding.js new file mode 100644 index 00000000000000..11cb66cf42cc5b --- /dev/null +++ b/test/parallel/test-child-process-exec-std-encoding.js @@ -0,0 +1,23 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const cp = require('child_process'); +const stdoutData = 'foo'; +const stderrData = 'bar'; +const expectedStdout = `${stdoutData}\n`; +const expectedStderr = `${stderrData}\n`; + +if (process.argv[2] === 'child') { + // The following console calls are part of the test. + console.log(stdoutData); + console.error(stderrData); +} else { + const cmd = `"${process.execPath}" "${__filename}" child`; + const child = cp.exec(cmd, common.mustCall((err, stdout, stderr) => { + assert.ifError(err); + assert.strictEqual(stdout, expectedStdout); + assert.strictEqual(stderr, expectedStderr); + })); + child.stdout.setEncoding('utf-8'); + child.stderr.setEncoding('utf-8'); +} diff --git a/test/parallel/test-child-process-fork-closed-channel-segfault.js b/test/parallel/test-child-process-fork-closed-channel-segfault.js index 87b599c7bb29f2..14cb4b8fd97ae9 100644 --- a/test/parallel/test-child-process-fork-closed-channel-segfault.js +++ b/test/parallel/test-child-process-fork-closed-channel-segfault.js @@ -66,7 +66,7 @@ const server = net send(function(err) { // Ignore errors when sending the second handle because the worker // may already have exited. - if (err && err.message !== 'Channel closed') { + if (err && err.code !== 'ERR_IPC_CHANNEL_CLOSED') { throw err; } }); diff --git a/test/parallel/test-console-table.js b/test/parallel/test-console-table.js index 64e2533f175e1d..2b63556acaa478 100644 --- a/test/parallel/test-console-table.js +++ b/test/parallel/test-console-table.js @@ -29,6 +29,7 @@ test(undefined, 'undefined\n'); test(false, 'false\n'); test('hi', 'hi\n'); test(Symbol(), 'Symbol()\n'); +test(function() {}, '[Function]\n'); test([1, 2, 3], ` ┌─────────┬────────┐ diff --git a/test/parallel/test-crypto-aes-wrap.js b/test/parallel/test-crypto-aes-wrap.js new file mode 100644 index 00000000000000..6fe35258f7d6b2 --- /dev/null +++ b/test/parallel/test-crypto-aes-wrap.js @@ -0,0 +1,62 @@ +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const crypto = require('crypto'); + +const test = [ + { + algorithm: 'aes128-wrap', + key: 'b26f309fbe57e9b3bb6ae5ef31d54450', + iv: '3fd838af4093d749', + text: '12345678123456781234567812345678' + }, + { + algorithm: 'id-aes128-wrap-pad', + key: 'b26f309fbe57e9b3bb6ae5ef31d54450', + iv: '3fd838af', + text: '12345678123456781234567812345678123' + }, + { + algorithm: 'aes192-wrap', + key: '40978085d68091f7dfca0d7dfc7a5ee76d2cc7f2f345a304', + iv: '3fd838af4093d749', + text: '12345678123456781234567812345678' + }, + { + algorithm: 'id-aes192-wrap-pad', + key: '40978085d68091f7dfca0d7dfc7a5ee76d2cc7f2f345a304', + iv: '3fd838af', + text: '12345678123456781234567812345678123' + }, + { + algorithm: 'aes256-wrap', + key: '29c9eab5ed5ad44134a1437fe2e673b4d88a5b7c72e68454fea08721392b7323', + iv: '3fd838af4093d749', + text: '12345678123456781234567812345678' + }, + { + algorithm: 'id-aes256-wrap-pad', + key: '29c9eab5ed5ad44134a1437fe2e673b4d88a5b7c72e68454fea08721392b7323', + iv: '3fd838af', + text: '12345678123456781234567812345678123' + }, +]; + +test.forEach((data) => { + const cipher = crypto.createCipheriv( + data.algorithm, + Buffer.from(data.key, 'hex'), + Buffer.from(data.iv, 'hex')); + const ciphertext = cipher.update(data.text, 'utf8'); + + const decipher = crypto.createDecipheriv( + data.algorithm, + Buffer.from(data.key, 'hex'), + Buffer.from(data.iv, 'hex')); + const msg = decipher.update(ciphertext, 'buffer', 'utf8'); + + assert.strictEqual(msg, data.text, `${data.algorithm} test case failed`); +}); diff --git a/test/parallel/test-crypto-authenticated.js b/test/parallel/test-crypto-authenticated.js index 73e3a23f72ac81..99dee6f5391227 100644 --- a/test/parallel/test-crypto-authenticated.js +++ b/test/parallel/test-crypto-authenticated.js @@ -727,6 +727,75 @@ for (const test of TEST_CASES) { 'qkuZpJWCewa6Szih'); decrypt.setAuthTag(Buffer.from('1'.repeat(length))); } + + // Explicitely passing invalid lengths should throw. + for (const length of [0, 1, 2, 6, 9, 10, 11, 17]) { + common.expectsError(() => { + crypto.createCipheriv('aes-256-gcm', + 'FxLKsqdmv0E9xrQhp0b1ZgI0K7JFZJM8', + 'qkuZpJWCewa6Szih', + { + authTagLength: length + }); + }, { + type: Error, + message: `Invalid GCM authentication tag length: ${length}` + }); + + common.expectsError(() => { + crypto.createDecipheriv('aes-256-gcm', + 'FxLKsqdmv0E9xrQhp0b1ZgI0K7JFZJM8', + 'qkuZpJWCewa6Szih', + { + authTagLength: length + }); + }, { + type: Error, + message: `Invalid GCM authentication tag length: ${length}` + }); + } +} + +// Test that GCM can produce shorter authentication tags than 16 bytes. +{ + const fullTag = '1debb47b2c91ba2cea16fad021703070'; + for (const [authTagLength, e] of [[undefined, 16], [12, 12], [4, 4]]) { + const cipher = crypto.createCipheriv('aes-256-gcm', + 'FxLKsqdmv0E9xrQhp0b1ZgI0K7JFZJM8', + 'qkuZpJWCewa6Szih', { + authTagLength + }); + cipher.setAAD(Buffer.from('abcd')); + cipher.update('01234567', 'hex'); + cipher.final(); + const tag = cipher.getAuthTag(); + assert.strictEqual(tag.toString('hex'), fullTag.substr(0, 2 * e)); + } +} + +// Test that users can manually restrict the GCM tag length to a single value. +{ + const decipher = crypto.createDecipheriv('aes-256-gcm', + 'FxLKsqdmv0E9xrQhp0b1ZgI0K7JFZJM8', + 'qkuZpJWCewa6Szih', { + authTagLength: 8 + }); + + common.expectsError(() => { + // This tag would normally be allowed. + decipher.setAuthTag(Buffer.from('1'.repeat(12))); + }, { + type: Error, + message: 'Invalid GCM authentication tag length: 12' + }); + + // The Decipher object should be left intact. + decipher.setAuthTag(Buffer.from('445352d3ff85cf94', 'hex')); + const text = Buffer.concat([ + decipher.update('3a2a3647', 'hex'), + decipher.final() + ]); + assert.strictEqual(text.toString('utf8'), 'node'); } // Test that create(De|C)ipher(iv)? throws if the mode is CCM and an invalid diff --git a/test/parallel/test-crypto-binary-default.js b/test/parallel/test-crypto-binary-default.js index 6cdc894753c3ac..228e2cc8abdc81 100644 --- a/test/parallel/test-crypto-binary-default.js +++ b/test/parallel/test-crypto-binary-default.js @@ -20,6 +20,8 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; +// Flags: --expose-internals + // This is the same as test/simple/test-crypto, but from before the shift // to use buffers by default. @@ -36,7 +38,7 @@ const tls = require('tls'); const fixtures = require('../common/fixtures'); const DH_NOT_SUITABLE_GENERATOR = crypto.constants.DH_NOT_SUITABLE_GENERATOR; -crypto.DEFAULT_ENCODING = 'latin1'; +require('internal/crypto/util').setDefaultEncoding('latin1'); // Test Certificates const certPem = fixtures.readSync('test_cert.pem', 'ascii'); diff --git a/test/parallel/test-crypto-certificate.js b/test/parallel/test-crypto-certificate.js index 3252e53aa4fd09..a426e0be003da0 100644 --- a/test/parallel/test-crypto-certificate.js +++ b/test/parallel/test-crypto-certificate.js @@ -29,8 +29,6 @@ const crypto = require('crypto'); const { Certificate } = crypto; const fixtures = require('../common/fixtures'); -crypto.DEFAULT_ENCODING = 'buffer'; - // Test Certificates const spkacValid = fixtures.readSync('spkac.valid'); const spkacFail = fixtures.readSync('spkac.fail'); diff --git a/test/parallel/test-crypto-des3-wrap.js b/test/parallel/test-crypto-des3-wrap.js new file mode 100644 index 00000000000000..75c8cd574fd662 --- /dev/null +++ b/test/parallel/test-crypto-des3-wrap.js @@ -0,0 +1,25 @@ +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const assert = require('assert'); +const crypto = require('crypto'); + +// Test case for des-ede3 wrap/unwrap. des3-wrap needs extra 2x blocksize +// then plaintext to store ciphertext. +const test = { + key: Buffer.from('3c08e25be22352910671cfe4ba3652b1220a8a7769b490ba', 'hex'), + iv: Buffer.alloc(0), + plaintext: '32|RmVZZkFUVmpRRkp0TmJaUm56ZU9qcnJkaXNNWVNpTTU*|iXmckfRWZBG' + + 'WWELweCBsThSsfUHLeRe0KCsK8ooHgxie0zOINpXxfZi/oNG7uq9JWFVCk70gfzQH8ZU' + + 'JjAfaFg**' +}; + +const cipher = crypto.createCipheriv('des3-wrap', test.key, test.iv); +const ciphertext = cipher.update(test.plaintext, 'utf8'); + +const decipher = crypto.createDecipheriv('des3-wrap', test.key, test.iv); +const msg = decipher.update(ciphertext, 'buffer', 'utf8'); + +assert.strictEqual(msg, test.plaintext); diff --git a/test/parallel/test-crypto-ecb.js b/test/parallel/test-crypto-ecb.js index 4faf4af2c576fd..c88ebaabb05e7f 100644 --- a/test/parallel/test-crypto-ecb.js +++ b/test/parallel/test-crypto-ecb.js @@ -30,8 +30,6 @@ if (common.hasFipsCrypto) const assert = require('assert'); const crypto = require('crypto'); -crypto.DEFAULT_ENCODING = 'buffer'; - // Testing whether EVP_CipherInit_ex is functioning correctly. // Reference: bug#1997 diff --git a/test/parallel/test-crypto-padding-aes256.js b/test/parallel/test-crypto-padding-aes256.js index 9fb80f3eed7856..2919c60294be07 100644 --- a/test/parallel/test-crypto-padding-aes256.js +++ b/test/parallel/test-crypto-padding-aes256.js @@ -27,8 +27,6 @@ if (!common.hasCrypto) const assert = require('assert'); const crypto = require('crypto'); -crypto.DEFAULT_ENCODING = 'buffer'; - function aes256(decipherFinal) { const iv = Buffer.from('00000000000000000000000000000000', 'hex'); const key = Buffer.from('0123456789abcdef0123456789abcdef' + diff --git a/test/parallel/test-crypto-padding.js b/test/parallel/test-crypto-padding.js index 00b600efb735e8..d4a5b95cec9242 100644 --- a/test/parallel/test-crypto-padding.js +++ b/test/parallel/test-crypto-padding.js @@ -27,8 +27,6 @@ if (!common.hasCrypto) const assert = require('assert'); const crypto = require('crypto'); -crypto.DEFAULT_ENCODING = 'buffer'; - // Input data. const ODD_LENGTH_PLAIN = 'Hello node world!'; const EVEN_LENGTH_PLAIN = 'Hello node world!AbC09876dDeFgHi'; diff --git a/test/parallel/test-crypto-random.js b/test/parallel/test-crypto-random.js index 77801f6d53eef2..f00e474b6f2798 100644 --- a/test/parallel/test-crypto-random.js +++ b/test/parallel/test-crypto-random.js @@ -32,8 +32,6 @@ const { kMaxLength } = require('buffer'); const kMaxUint32 = Math.pow(2, 32) - 1; const kMaxPossibleLength = Math.min(kMaxLength, kMaxUint32); -crypto.DEFAULT_ENCODING = 'buffer'; - // bump, we register a lot of exit listeners process.setMaxListeners(256); diff --git a/test/parallel/test-crypto-verify-failure.js b/test/parallel/test-crypto-verify-failure.js index 72dfb926413d8b..7e9fda9f6791f6 100644 --- a/test/parallel/test-crypto-verify-failure.js +++ b/test/parallel/test-crypto-verify-failure.js @@ -29,8 +29,6 @@ const crypto = require('crypto'); const tls = require('tls'); const fixtures = require('../common/fixtures'); -crypto.DEFAULT_ENCODING = 'buffer'; - const certPem = fixtures.readSync('test_cert.pem', 'ascii'); const options = { diff --git a/test/parallel/test-crypto.js b/test/parallel/test-crypto.js index 3047d37c962cff..88d49167100fbe 100644 --- a/test/parallel/test-crypto.js +++ b/test/parallel/test-crypto.js @@ -30,8 +30,6 @@ const crypto = require('crypto'); const tls = require('tls'); const fixtures = require('../common/fixtures'); -crypto.DEFAULT_ENCODING = 'buffer'; - // Test Certificates const caPem = fixtures.readSync('test_ca.pem', 'ascii'); const certPem = fixtures.readSync('test_cert.pem', 'ascii'); @@ -131,7 +129,7 @@ assert(tlsCiphers.every((value) => noCapitals.test(value))); validateList(tlsCiphers); // Assert that we have sha1 and sha256 but not SHA1 and SHA256. -assert.notStrictEqual(0, crypto.getHashes().length); +assert.notStrictEqual(crypto.getHashes().length, 0); assert(crypto.getHashes().includes('sha1')); assert(crypto.getHashes().includes('sha256')); assert(!crypto.getHashes().includes('SHA1')); @@ -141,7 +139,7 @@ assert(!crypto.getHashes().includes('rsa-sha1')); validateList(crypto.getHashes()); // Assume that we have at least secp384r1. -assert.notStrictEqual(0, crypto.getCurves().length); +assert.notStrictEqual(crypto.getCurves().length, 0); assert(crypto.getCurves().includes('secp384r1')); assert(!crypto.getCurves().includes('SECP384R1')); validateList(crypto.getCurves()); diff --git a/test/parallel/test-domain-crypto.js b/test/parallel/test-domain-crypto.js index 3890a7b4641ade..26ee6b888efb2d 100644 --- a/test/parallel/test-domain-crypto.js +++ b/test/parallel/test-domain-crypto.js @@ -29,7 +29,7 @@ if (!common.hasCrypto) const crypto = require('crypto'); // Pollution of global is intentional as part of test. -common.globalCheck = false; +common.allowGlobals(require('domain')); // See https://github.com/nodejs/node/commit/d1eff9ab global.domain = require('domain'); diff --git a/test/parallel/test-eslint-require-buffer.js b/test/parallel/test-eslint-require-buffer.js index da17d44c7f600d..d928c435480e5e 100644 --- a/test/parallel/test-eslint-require-buffer.js +++ b/test/parallel/test-eslint-require-buffer.js @@ -5,7 +5,7 @@ const common = require('../common'); common.skipIfEslintMissing(); const RuleTester = require('../../tools/node_modules/eslint').RuleTester; -const rule = require('../../tools/eslint-rules/require-buffer'); +const rule = require('../../tools/eslint-rules/require-globals'); const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 }, env: { node: true } @@ -18,7 +18,7 @@ const useStrict = '\'use strict\';\n\n'; const bufferModule = 'const { Buffer } = require(\'buffer\');\n'; const mockComment = '// Some Comment\n//\n// Another Comment\n\n'; const useBuffer = 'Buffer;'; -ruleTester.run('require-buffer', rule, { +ruleTester.run('require-globals', rule, { valid: [ 'foo', 'const Buffer = require("Buffer"); Buffer;', diff --git a/test/parallel/test-fs-access.js b/test/parallel/test-fs-access.js index 20448ffde6c6ea..d053b9323bc275 100644 --- a/test/parallel/test-fs-access.js +++ b/test/parallel/test-fs-access.js @@ -62,37 +62,70 @@ assert.strictEqual(typeof fs.R_OK, 'number'); assert.strictEqual(typeof fs.W_OK, 'number'); assert.strictEqual(typeof fs.X_OK, 'number'); -fs.access(__filename, common.mustCall(assert.ifError)); -fs.access(__filename, fs.R_OK, common.mustCall(assert.ifError)); -fs.access(readOnlyFile, fs.F_OK | fs.R_OK, common.mustCall(assert.ifError)); - -fs.access(doesNotExist, common.mustCall((err) => { - assert.notStrictEqual(err, null, 'error should exist'); - assert.strictEqual(err.code, 'ENOENT'); - assert.strictEqual(err.path, doesNotExist); -})); +const throwNextTick = (e) => { process.nextTick(() => { throw e; }); }; -fs.access(readOnlyFile, fs.W_OK, common.mustCall(function(err) { - assert.strictEqual(this, undefined); - if (hasWriteAccessForReadonlyFile) { - assert.ifError(err); - } else { - assert.notStrictEqual(err, null, 'error should exist'); - assert.strictEqual(err.path, readOnlyFile); - } +fs.access(__filename, common.mustCall(function(...args) { + assert.deepStrictEqual(args, [null]); +})); +fs.promises.access(__filename) + .then(common.mustCall()) + .catch(throwNextTick); +fs.access(__filename, fs.R_OK, common.mustCall(function(...args) { + assert.deepStrictEqual(args, [null]); })); +fs.promises.access(__filename, fs.R_OK) + .then(common.mustCall()) + .catch(throwNextTick); +fs.access(readOnlyFile, fs.F_OK | fs.R_OK, common.mustCall(function(...args) { + assert.deepStrictEqual(args, [null]); +})); +fs.promises.access(readOnlyFile, fs.F_OK | fs.R_OK) + .then(common.mustCall()) + .catch(throwNextTick); -common.expectsError( - () => { - fs.access(100, fs.F_OK, common.mustNotCall()); - }, - { - code: 'ERR_INVALID_ARG_TYPE', - type: TypeError, - message: 'The "path" argument must be one of type string, Buffer, or URL.' + - ' Received type number' +{ + const expectedError = (err) => { + assert.notStrictEqual(err, null); + assert.strictEqual(err.code, 'ENOENT'); + assert.strictEqual(err.path, doesNotExist); + }; + fs.access(doesNotExist, common.mustCall(expectedError)); + fs.promises.access(doesNotExist) + .then(common.mustNotCall(), common.mustCall(expectedError)) + .catch(throwNextTick); +} + +{ + function expectedError(err) { + assert.strictEqual(this, undefined); + if (hasWriteAccessForReadonlyFile) { + assert.ifError(err); + } else { + assert.notStrictEqual(err, null); + assert.strictEqual(err.path, readOnlyFile); + } } -); + fs.access(readOnlyFile, fs.W_OK, common.mustCall(expectedError)); + fs.promises.access(readOnlyFile, fs.W_OK) + .then(common.mustNotCall(), common.mustCall(expectedError)) + .catch(throwNextTick); +} + +{ + const expectedError = (err) => { + assert.strictEqual(err.code, 'ERR_INVALID_ARG_TYPE'); + assert.ok(err instanceof TypeError); + return true; + }; + assert.throws( + () => { fs.access(100, fs.F_OK, common.mustNotCall()); }, + expectedError + ); + + fs.promises.access(100, fs.F_OK) + .then(common.mustNotCall(), common.mustCall(expectedError)) + .catch(throwNextTick); +} common.expectsError( () => { diff --git a/test/parallel/test-fs-append-file.js b/test/parallel/test-fs-append-file.js index 29ae1b2f3b9e9a..9ab36a67767946 100644 --- a/test/parallel/test-fs-append-file.js +++ b/test/parallel/test-fs-append-file.js @@ -27,8 +27,6 @@ const join = require('path').join; const tmpdir = require('../common/tmpdir'); -const filename = join(tmpdir.path, 'append.txt'); - const currentFileData = 'ABCD'; const n = 220; @@ -44,35 +42,63 @@ let ncallbacks = 0; tmpdir.refresh(); -// test that empty file will be created and have content added -fs.appendFile(filename, s, function(e) { - assert.ifError(e); +const throwNextTick = (e) => { process.nextTick(() => { throw e; }); }; - ncallbacks++; +// test that empty file will be created and have content added (callback API) +{ + const filename = join(tmpdir.path, 'append.txt'); - fs.readFile(filename, function(e, buffer) { + fs.appendFile(filename, s, common.mustCall(function(e) { assert.ifError(e); - ncallbacks++; - assert.strictEqual(Buffer.byteLength(s), buffer.length); - }); -}); - -// test that appends data to a non empty file -const filename2 = join(tmpdir.path, 'append2.txt'); -fs.writeFileSync(filename2, currentFileData); - -fs.appendFile(filename2, s, function(e) { - assert.ifError(e); - ncallbacks++; - - fs.readFile(filename2, function(e, buffer) { + fs.readFile(filename, common.mustCall(function(e, buffer) { + assert.ifError(e); + assert.strictEqual(Buffer.byteLength(s), buffer.length); + })); + })); +} + +// test that empty file will be created and have content added (promise API) +{ + const filename = join(tmpdir.path, 'append-promise.txt'); + + fs.promises.appendFile(filename, s) + .then(common.mustCall(() => fs.promises.readFile(filename))) + .then((buffer) => { + assert.strictEqual(Buffer.byteLength(s), buffer.length); + }) + .catch(throwNextTick); +} + +// test that appends data to a non-empty file (callback API) +{ + const filename = join(tmpdir.path, 'append-non-empty.txt'); + fs.writeFileSync(filename, currentFileData); + + fs.appendFile(filename, s, common.mustCall(function(e) { assert.ifError(e); - ncallbacks++; - assert.strictEqual(Buffer.byteLength(s) + currentFileData.length, - buffer.length); - }); -}); + + fs.readFile(filename, common.mustCall(function(e, buffer) { + assert.ifError(e); + assert.strictEqual(Buffer.byteLength(s) + currentFileData.length, + buffer.length); + })); + })); +} + +// test that appends data to a non-empty file (promise API) +{ + const filename = join(tmpdir.path, 'append-non-empty-promise.txt'); + fs.writeFileSync(filename, currentFileData); + + fs.promises.appendFile(filename, s) + .then(common.mustCall(() => fs.promises.readFile(filename))) + .then((buffer) => { + assert.strictEqual(Buffer.byteLength(s) + currentFileData.length, + buffer.length); + }) + .catch(throwNextTick); +} // test that appendFile accepts buffers const filename3 = join(tmpdir.path, 'append3.txt'); @@ -151,10 +177,8 @@ assert.throws( { code: 'ERR_INVALID_CALLBACK' }); process.on('exit', function() { - assert.strictEqual(12, ncallbacks); + assert.strictEqual(ncallbacks, 8); - fs.unlinkSync(filename); - fs.unlinkSync(filename2); fs.unlinkSync(filename3); fs.unlinkSync(filename4); fs.unlinkSync(filename5); diff --git a/test/parallel/test-fs-close.js b/test/parallel/test-fs-close.js new file mode 100644 index 00000000000000..da0d0dfdc832d8 --- /dev/null +++ b/test/parallel/test-fs-close.js @@ -0,0 +1,12 @@ +'use strict'; + +const common = require('../common'); + +const assert = require('assert'); +const fs = require('fs'); + +const fd = fs.openSync(__filename, 'r'); + +fs.close(fd, common.mustCall(function(...args) { + assert.deepStrictEqual(args, [null]); +})); diff --git a/test/parallel/test-fs-promises.js b/test/parallel/test-fs-promises.js index 43b5da700484ff..992f30afec233e 100644 --- a/test/parallel/test-fs-promises.js +++ b/test/parallel/test-fs-promises.js @@ -5,7 +5,8 @@ const assert = require('assert'); const tmpdir = require('../common/tmpdir'); const fixtures = require('../common/fixtures'); const path = require('path'); -const fsPromises = require('fs').promises; +const fs = require('fs'); +const fsPromises = fs.promises; const { access, chmod, @@ -38,6 +39,10 @@ const tmpDir = tmpdir.path; common.crashOnUnhandledRejection(); +// fs.promises should not be enumerable as long as it causes a warning to be +// emitted. +assert.strictEqual(Object.keys(fs).includes('promises'), false); + { access(__filename, 'r') .then(common.mustCall()) @@ -82,24 +87,60 @@ function verifyStatObject(stat) { stats = await stat(dest); verifyStatObject(stats); + stats = await handle.stat(); + verifyStatObject(stats); + await fdatasync(handle); + await handle.datasync(); await fsync(handle); + await handle.sync(); - const buf = Buffer.from('hello world'); - + const buf = Buffer.from('hello fsPromises'); + const bufLen = buf.length; await write(handle, buf); - - const ret = await read(handle, Buffer.alloc(11), 0, 11, 0); - assert.strictEqual(ret.bytesRead, 11); + const ret = await read(handle, Buffer.alloc(bufLen), 0, bufLen, 0); + assert.strictEqual(ret.bytesRead, bufLen); assert.deepStrictEqual(ret.buffer, buf); + const buf2 = Buffer.from('hello FileHandle'); + const buf2Len = buf2.length; + await handle.write(buf2, 0, buf2Len, 0); + const ret2 = await handle.read(Buffer.alloc(buf2Len), 0, buf2Len, 0); + assert.strictEqual(ret2.bytesRead, buf2Len); + assert.deepStrictEqual(ret2.buffer, buf2); + await chmod(dest, 0o666); await fchmod(handle, 0o666); + await handle.chmod(0o666); + + // `mode` can't be > 0o777 + assert.rejects( + async () => chmod(handle, (0o777 + 1)), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError [ERR_INVALID_ARG_TYPE]' + } + ); + assert.rejects( + async () => fchmod(handle, (0o777 + 1)), + { + code: 'ERR_OUT_OF_RANGE', + name: 'RangeError [ERR_OUT_OF_RANGE]' + } + ); + assert.rejects( + async () => handle.chmod(handle, (0o777 + 1)), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError [ERR_INVALID_ARG_TYPE]' + } + ); await utimes(dest, new Date(), new Date()); try { await futimes(handle, new Date(), new Date()); + await handle.utimes(new Date(), new Date()); } catch (err) { // Some systems do not have futimes. If there is an error, // expect it to be ENOSYS @@ -147,6 +188,15 @@ function verifyStatObject(stat) { await rmdir(newdir); await mkdtemp(path.resolve(tmpDir, 'FOO')); + assert.rejects( + // mkdtemp() expects to get a string prefix. + async () => mkdtemp(1), + { + code: 'ERR_INVALID_ARG_TYPE', + name: 'TypeError [ERR_INVALID_ARG_TYPE]' + } + ); + } doTest().then(common.mustCall()); diff --git a/test/parallel/test-global.js b/test/parallel/test-global.js index 46db72eeceb586..b139a6287488d2 100644 --- a/test/parallel/test-global.js +++ b/test/parallel/test-global.js @@ -28,7 +28,7 @@ const fixtures = require('../common/fixtures'); const assert = require('assert'); -common.globalCheck = false; +common.allowGlobals('bar', 'foo'); baseFoo = 'foo'; // eslint-disable-line no-undef global.baseBar = 'bar'; diff --git a/test/parallel/test-http-agent-remove.js b/test/parallel/test-http-agent-remove.js new file mode 100644 index 00000000000000..24fc7fcb8282fe --- /dev/null +++ b/test/parallel/test-http-agent-remove.js @@ -0,0 +1,21 @@ +'use strict'; +const { mustCall } = require('../common'); + +const http = require('http'); +const { strictEqual } = require('assert'); + +const server = http.createServer(mustCall((req, res) => { + res.flushHeaders(); +})); + +server.listen(0, mustCall(() => { + const req = http.get({ + port: server.address().port + }, mustCall(() => { + const { socket } = req; + socket.emit('agentRemove'); + strictEqual(socket._httpMessage, req); + socket.destroy(); + server.close(); + })); +})); diff --git a/test/parallel/test-http-req-res-close.js b/test/parallel/test-http-req-res-close.js new file mode 100644 index 00000000000000..240134cb5d0902 --- /dev/null +++ b/test/parallel/test-http-req-res-close.js @@ -0,0 +1,16 @@ +'use strict'; + +const common = require('../common'); +const http = require('http'); + +const server = http.Server(common.mustCall((req, res) => { + res.end(); + res.on('finish', common.mustCall()); + res.on('close', common.mustCall()); + req.on('close', common.mustCall()); + res.socket.on('close', () => server.close()); +})); + +server.listen(0, common.mustCall(() => { + http.get({ port: server.address().port }, common.mustCall()); +})); diff --git a/test/parallel/test-http-response-close.js b/test/parallel/test-http-response-close.js index c58a5884d59d1a..4c36003357980b 100644 --- a/test/parallel/test-http-response-close.js +++ b/test/parallel/test-http-response-close.js @@ -23,29 +23,50 @@ const common = require('../common'); const http = require('http'); -const server = http.createServer(common.mustCall(function(req, res) { - res.writeHead(200); - res.write('a'); +{ + const server = http.createServer( + common.mustCall((req, res) => { + res.writeHead(200); + res.write('a'); + }) + ); + server.listen( + 0, + common.mustCall(() => { + http.get( + { port: server.address().port }, + common.mustCall((res) => { + res.on('data', common.mustCall(() => { + res.destroy(); + })); + res.on('close', common.mustCall(() => { + server.close(); + })); + }) + ); + }) + ); +} - req.on('close', common.mustCall(function() { - console.error('request aborted'); - })); - res.on('close', common.mustCall(function() { - console.error('response aborted'); - })); -})); -server.listen(0); - -server.on('listening', function() { - console.error('make req'); - http.get({ - port: this.address().port - }, function(res) { - console.error('got res'); - res.on('data', function(data) { - console.error('destroy res'); - res.destroy(); - server.close(); - }); - }); -}); +{ + const server = http.createServer( + common.mustCall((req, res) => { + res.writeHead(200); + res.end('a'); + }) + ); + server.listen( + 0, + common.mustCall(() => { + http.get( + { port: server.address().port }, + common.mustCall((res) => { + res.on('close', common.mustCall(() => { + server.close(); + })); + res.resume(); + }) + ); + }) + ); +} diff --git a/test/parallel/test-http2-client-destroy.js b/test/parallel/test-http2-client-destroy.js index 6238363511a791..43fc6819e21f7a 100644 --- a/test/parallel/test-http2-client-destroy.js +++ b/test/parallel/test-http2-client-destroy.js @@ -109,9 +109,6 @@ const Countdown = require('../common/countdown'); server.listen(0, common.mustCall(() => { const client = h2.connect(`http://localhost:${server.address().port}`); - // On some platforms (e.g. windows), an ECONNRESET may occur at this - // point -- or it may not. Do not make this a mustCall - client.on('error', () => {}); client.on('close', () => { server.close(); @@ -119,10 +116,7 @@ const Countdown = require('../common/countdown'); client.destroy(); }); - const req = client.request(); - // On some platforms (e.g. windows), an ECONNRESET may occur at this - // point -- or it may not. Do not make this a mustCall - req.on('error', () => {}); + client.request(); })); } diff --git a/test/parallel/test-http2-client-upload-reject.js b/test/parallel/test-http2-client-upload-reject.js index ece7cbdf233f1f..678114130e3dba 100644 --- a/test/parallel/test-http2-client-upload-reject.js +++ b/test/parallel/test-http2-client-upload-reject.js @@ -20,12 +20,15 @@ fs.readFile(loc, common.mustCall((err, data) => { const server = http2.createServer(); server.on('stream', common.mustCall((stream) => { - stream.on('close', common.mustCall(() => { - assert.strictEqual(stream.rstCode, 0); - })); - - stream.respond({ ':status': 400 }); - stream.end(); + // Wait for some data to come through. + setImmediate(() => { + stream.on('close', common.mustCall(() => { + assert.strictEqual(stream.rstCode, 0); + })); + + stream.respond({ ':status': 400 }); + stream.end(); + }); })); server.listen(0, common.mustCall(() => { diff --git a/test/parallel/test-http2-compat-client-upload-reject.js b/test/parallel/test-http2-compat-client-upload-reject.js new file mode 100644 index 00000000000000..e6a187cb12b264 --- /dev/null +++ b/test/parallel/test-http2-compat-client-upload-reject.js @@ -0,0 +1,44 @@ +'use strict'; + +// Verifies that uploading data from a client works + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); +const assert = require('assert'); +const http2 = require('http2'); +const fs = require('fs'); +const fixtures = require('../common/fixtures'); + +const loc = fixtures.path('person-large.jpg'); + +assert(fs.existsSync(loc)); + +fs.readFile(loc, common.mustCall((err, data) => { + assert.ifError(err); + + const server = http2.createServer(common.mustCall((req, res) => { + setImmediate(() => { + res.writeHead(400); + res.end(); + }); + })); + + server.listen(0, common.mustCall(() => { + const client = http2.connect(`http://localhost:${server.address().port}`); + + const req = client.request({ ':method': 'POST' }); + req.on('response', common.mustCall((headers) => { + assert.strictEqual(headers[':status'], 400); + })); + + req.resume(); + req.on('end', common.mustCall(() => { + server.close(); + client.close(); + })); + + const str = fs.createReadStream(loc); + str.pipe(req); + })); +})); diff --git a/test/parallel/test-http2-many-writes-and-destroy.js b/test/parallel/test-http2-many-writes-and-destroy.js new file mode 100644 index 00000000000000..78db76e001cd3a --- /dev/null +++ b/test/parallel/test-http2-many-writes-and-destroy.js @@ -0,0 +1,30 @@ +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); +const http2 = require('http2'); + +{ + const server = http2.createServer((req, res) => { + req.pipe(res); + }); + + server.listen(0, () => { + const url = `http://localhost:${server.address().port}`; + const client = http2.connect(url); + const req = client.request({ ':method': 'POST' }); + + for (let i = 0; i < 4000; i++) { + req.write(Buffer.alloc(6)); + } + + req.on('close', common.mustCall(() => { + console.log('(req onclose)'); + server.close(); + client.close(); + })); + + req.once('data', common.mustCall(() => req.destroy())); + }); +} diff --git a/test/parallel/test-http2-no-wanttrailers-listener.js b/test/parallel/test-http2-no-wanttrailers-listener.js index 7ba25d0e491e15..87bc21df48aa2c 100644 --- a/test/parallel/test-http2-no-wanttrailers-listener.js +++ b/test/parallel/test-http2-no-wanttrailers-listener.js @@ -3,7 +3,6 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); -const assert = require('assert'); const h2 = require('http2'); const server = h2.createServer(); @@ -25,9 +24,7 @@ server.on('listening', common.mustCall(function() { const client = h2.connect(`http://localhost:${this.address().port}`); const req = client.request(); req.resume(); - req.on('trailers', common.mustCall((headers) => { - assert.strictEqual(Object.keys(headers).length, 0); - })); + req.on('trailers', common.mustNotCall()); req.on('close', common.mustCall(() => { server.close(); client.close(); diff --git a/test/parallel/test-http2-pipe.js b/test/parallel/test-http2-pipe.js index 2a759f9848721b..d7dd99df91edb5 100644 --- a/test/parallel/test-http2-pipe.js +++ b/test/parallel/test-http2-pipe.js @@ -33,6 +33,7 @@ server.listen(0, common.mustCall(() => { const client = http2.connect(`http://localhost:${server.address().port}`); const req = client.request({ ':method': 'POST' }); + req.on('response', common.mustCall()); req.resume(); diff --git a/test/parallel/test-http2-server-close-callback.js b/test/parallel/test-http2-server-close-callback.js new file mode 100644 index 00000000000000..f822d8a4a92d78 --- /dev/null +++ b/test/parallel/test-http2-server-close-callback.js @@ -0,0 +1,27 @@ +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); + +const Countdown = require('../common/countdown'); +const http2 = require('http2'); + +const server = http2.createServer(); + +let session; + +const countdown = new Countdown(2, () => { + server.close(common.mustCall()); + session.destroy(); +}); + +server.listen(0, common.mustCall(() => { + const client = http2.connect(`http://localhost:${server.address().port}`); + client.on('connect', common.mustCall(() => countdown.dec())); +})); + +server.on('session', common.mustCall((s) => { + session = s; + countdown.dec(); +})); diff --git a/test/parallel/test-http2-server-sessionerror.js b/test/parallel/test-http2-server-sessionerror.js index 525eb2e6efd11a..c50352fcc35c28 100644 --- a/test/parallel/test-http2-server-sessionerror.js +++ b/test/parallel/test-http2-server-sessionerror.js @@ -35,14 +35,17 @@ server.on('session', common.mustCall((session) => { server.listen(0, common.mustCall(() => { const url = `http://localhost:${server.address().port}`; http2.connect(url) - // An ECONNRESET error may occur depending on the platform (due largely - // to differences in the timing of socket closing). Do not wrap this in - // a common must call. - .on('error', () => {}) + .on('error', common.expectsError({ + code: 'ERR_HTTP2_SESSION_ERROR', + message: 'Session closed with error code 2', + })) .on('close', () => { server.removeAllListeners('error'); http2.connect(url) - .on('error', () => {}) + .on('error', common.expectsError({ + code: 'ERR_HTTP2_SESSION_ERROR', + message: 'Session closed with error code 2', + })) .on('close', () => server.close()); }); })); diff --git a/test/parallel/test-http2-server-shutdown-options-errors.js b/test/parallel/test-http2-server-shutdown-options-errors.js index 95849411a29182..9dde6660ea25ce 100644 --- a/test/parallel/test-http2-server-shutdown-options-errors.js +++ b/test/parallel/test-http2-server-shutdown-options-errors.js @@ -55,13 +55,7 @@ server.listen( 0, common.mustCall(() => { const client = http2.connect(`http://localhost:${server.address().port}`); - // On certain operating systems, an ECONNRESET may occur. We do not need - // to test for it here. Do not make this a mustCall - client.on('error', () => {}); const req = client.request(); - // On certain operating systems, an ECONNRESET may occur. We do not need - // to test for it here. Do not make this a mustCall - req.on('error', () => {}); req.resume(); req.on('close', common.mustCall(() => { client.close(); diff --git a/test/parallel/test-http2-server-socket-destroy.js b/test/parallel/test-http2-server-socket-destroy.js index 03afc1957b8af4..99595aeb63004d 100644 --- a/test/parallel/test-http2-server-socket-destroy.js +++ b/test/parallel/test-http2-server-socket-destroy.js @@ -41,14 +41,20 @@ server.on('listening', common.mustCall(() => { // The client may have an ECONNRESET error here depending on the operating // system, due mainly to differences in the timing of socket closing. Do // not wrap this in a common mustCall. - client.on('error', () => {}); + client.on('error', (err) => { + if (err.code !== 'ECONNRESET') + throw err; + }); client.on('close', common.mustCall()); const req = client.request({ ':method': 'POST' }); // The client may have an ECONNRESET error here depending on the operating // system, due mainly to differences in the timing of socket closing. Do // not wrap this in a common mustCall. - req.on('error', () => {}); + req.on('error', (err) => { + if (err.code !== 'ECONNRESET') + throw err; + }); req.on('aborted', common.mustCall()); req.resume(); diff --git a/test/parallel/test-http2-server-stream-session-destroy.js b/test/parallel/test-http2-server-stream-session-destroy.js index 989c72ec959679..6a262e2736e4bc 100644 --- a/test/parallel/test-http2-server-stream-session-destroy.js +++ b/test/parallel/test-http2-server-stream-session-destroy.js @@ -44,10 +44,8 @@ server.on('stream', common.mustCall((stream) => { server.listen(0, common.mustCall(() => { const client = h2.connect(`http://localhost:${server.address().port}`); - client.on('error', () => {}); const req = client.request(); req.resume(); req.on('end', common.mustCall()); - req.on('close', common.mustCall(() => server.close())); - req.on('error', () => {}); + req.on('close', common.mustCall(() => server.close(common.mustCall()))); })); diff --git a/test/parallel/test-http2-server-timeout.js b/test/parallel/test-http2-server-timeout.js index 4410cb51c169c5..88fc4eab2e08c0 100755 --- a/test/parallel/test-http2-server-timeout.js +++ b/test/parallel/test-http2-server-timeout.js @@ -6,10 +6,10 @@ if (!common.hasCrypto) const http2 = require('http2'); const server = http2.createServer(); -server.setTimeout(common.platformTimeout(1)); +server.setTimeout(common.platformTimeout(50)); const onServerTimeout = common.mustCall((session) => { - session.close(() => session.destroy()); + session.close(); }); server.on('stream', common.mustNotCall()); @@ -18,14 +18,8 @@ server.once('timeout', onServerTimeout); server.listen(0, common.mustCall(() => { const url = `http://localhost:${server.address().port}`; const client = http2.connect(url); - // Because of the timeout, an ECONNRESET error may or may not happen here. - // Keep this as a non-op and do not use common.mustCall() - client.on('error', () => {}); client.on('close', common.mustCall(() => { const client2 = http2.connect(url); - // Because of the timeout, an ECONNRESET error may or may not happen here. - // Keep this as a non-op and do not use common.mustCall() - client2.on('error', () => {}); client2.on('close', common.mustCall(() => server.close())); })); })); diff --git a/test/parallel/test-http2-session-unref.js b/test/parallel/test-http2-session-unref.js index e63cd0d208e32b..0381971c0eace5 100644 --- a/test/parallel/test-http2-session-unref.js +++ b/test/parallel/test-http2-session-unref.js @@ -9,16 +9,20 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); const http2 = require('http2'); +const Countdown = require('../common/countdown'); const makeDuplexPair = require('../common/duplexpair'); const server = http2.createServer(); const { clientSide, serverSide } = makeDuplexPair(); +const counter = new Countdown(3, () => server.unref()); + // 'session' event should be emitted 3 times: // - the vanilla client // - the destroyed client // - manual 'connection' event emission with generic Duplex stream server.on('session', common.mustCallAtLeast((session) => { + counter.dec(); session.unref(); }, 3)); @@ -34,8 +38,11 @@ server.listen(0, common.mustCall(() => { // unref destroyed client { const client = http2.connect(`http://localhost:${port}`); - client.destroy(); - client.unref(); + + client.on('connect', common.mustCall(() => { + client.destroy(); + client.unref(); + })); } // unref destroyed client @@ -43,9 +50,11 @@ server.listen(0, common.mustCall(() => { const client = http2.connect(`http://localhost:${port}`, { createConnection: common.mustCall(() => clientSide) }); - client.destroy(); - client.unref(); + + client.on('connect', common.mustCall(() => { + client.destroy(); + client.unref(); + })); } })); server.emit('connection', serverSide); -server.unref(); diff --git a/test/parallel/test-http2-too-many-settings.js b/test/parallel/test-http2-too-many-settings.js index 0302fe623da07c..acfd73ada68416 100644 --- a/test/parallel/test-http2-too-many-settings.js +++ b/test/parallel/test-http2-too-many-settings.js @@ -29,9 +29,10 @@ function doTest(session) { server.listen(0, common.mustCall(() => { const client = h2.connect(`http://localhost:${server.address().port}`); - // On some operating systems, an ECONNRESET error may be emitted. - // On others it won't be. Do not make this a mustCall - client.on('error', () => {}); + client.on('error', common.expectsError({ + code: 'ERR_HTTP2_SESSION_ERROR', + message: 'Session closed with error code 2', + })); client.on('close', common.mustCall(() => server.close())); })); } diff --git a/test/parallel/test-http2-trailers.js b/test/parallel/test-http2-trailers.js index 2b7f6158ca3951..bdc0931157ad58 100644 --- a/test/parallel/test-http2-trailers.js +++ b/test/parallel/test-http2-trailers.js @@ -18,6 +18,7 @@ server.on('stream', common.mustCall(onStream)); function onStream(stream, headers, flags) { stream.on('trailers', common.mustCall((headers) => { assert.strictEqual(headers[trailerKey], trailerValue); + stream.end(body); })); stream.respond({ 'content-type': 'text/html', @@ -41,8 +42,6 @@ function onStream(stream, headers, flags) { type: Error } ); - - stream.end(body); } server.listen(0); diff --git a/test/parallel/test-inspector-multisession-js.js b/test/parallel/test-inspector-multisession-js.js index 58533f4cd6241e..c899eeae713908 100644 --- a/test/parallel/test-inspector-multisession-js.js +++ b/test/parallel/test-inspector-multisession-js.js @@ -56,4 +56,8 @@ async function test() { common.crashOnUnhandledRejection(); -test(); +const interval = setInterval(() => {}, 1000); +test().then(() => { + clearInterval(interval); + console.log('Done!'); +}); diff --git a/test/parallel/test-inspector-tracing-domain.js b/test/parallel/test-inspector-tracing-domain.js new file mode 100644 index 00000000000000..61a853a265780c --- /dev/null +++ b/test/parallel/test-inspector-tracing-domain.js @@ -0,0 +1,70 @@ +'use strict'; + +const common = require('../common'); + +common.skipIfInspectorDisabled(); + +const assert = require('assert'); +const { Session } = require('inspector'); + +const session = new Session(); + +function compareIgnoringOrder(array1, array2) { + const set = new Set(array1); + const test = set.size === array2.length && array2.every((el) => set.has(el)); + assert.ok(test, `[${array1}] differs from [${array2}]`); +} + +function post(message, data) { + return new Promise((resolve, reject) => { + session.post(message, data, (err, result) => { + if (err) + reject(new Error(JSON.stringify(err))); + else + resolve(result); + }); + }); +} + +function generateTrace() { + return new Promise((resolve) => setTimeout(() => { + for (let i = 0; i << 1000000; i++) { + 'test' + i; + } + resolve(); + }, 1)); +} + +async function test() { + // This interval ensures Node does not terminate till the test is finished. + // Inspector session does not keep the node process running (e.g. it does not + // have async handles on the main event loop). It is debatable whether this + // should be considered a bug, and there are no plans to fix it atm. + const interval = setInterval(() => {}, 5000); + session.connect(); + let traceNotification = null; + let tracingComplete = false; + session.on('NodeTracing.dataCollected', (n) => traceNotification = n); + session.on('NodeTracing.tracingComplete', () => tracingComplete = true); + const { categories } = await post('NodeTracing.getCategories'); + compareIgnoringOrder(['node', 'node.async', 'node.bootstrap', 'node.fs.sync', + 'node.perf', 'node.perf.usertiming', + 'node.perf.timerify', 'v8'], + categories); + + const traceConfig = { includedCategories: ['node'] }; + await post('NodeTracing.start', { traceConfig }); + + for (let i = 0; i < 5; i++) + await generateTrace(); + JSON.stringify(await post('NodeTracing.stop', { traceConfig })); + session.disconnect(); + assert(traceNotification.data.value.length > 0); + assert(tracingComplete); + clearInterval(interval); + console.log('Success'); +} + +common.crashOnUnhandledRejection(); + +test(); diff --git a/test/parallel/test-module-relative-lookup.js b/test/parallel/test-module-relative-lookup.js index 6ebb8ee1881962..3e1904dc14fa61 100644 --- a/test/parallel/test-module-relative-lookup.js +++ b/test/parallel/test-module-relative-lookup.js @@ -6,10 +6,10 @@ const _module = require('module'); // avoid collision with global.module const lookupResults = _module._resolveLookupPaths('./lodash'); let paths = lookupResults[1]; -assert.strictEqual(paths[0], '.', - 'Current directory gets highest priority for local modules'); +// Current directory gets highest priority for local modules +assert.strictEqual(paths[0], '.'); paths = _module._resolveLookupPaths('./lodash', null, true); -assert.strictEqual(paths && paths[0], '.', - 'Current directory gets highest priority for local modules'); +// Current directory gets highest priority for local modules +assert.strictEqual(paths && paths[0], '.'); diff --git a/test/parallel/test-net-socket-local-address.js b/test/parallel/test-net-socket-local-address.js index c4f11db76bc4f2..1aa51e0c5c1d87 100644 --- a/test/parallel/test-net-socket-local-address.js +++ b/test/parallel/test-net-socket-local-address.js @@ -17,8 +17,8 @@ const server = net.createServer((socket) => { }); server.on('close', common.mustCall(() => { - assert.deepStrictEqual(clientLocalPorts, serverRemotePorts, - 'client and server should agree on the ports used'); + // client and server should agree on the ports used + assert.deepStrictEqual(clientLocalPorts, serverRemotePorts); assert.strictEqual(2, conns); })); diff --git a/test/parallel/test-readline-keys.js b/test/parallel/test-readline-keys.js index 62d5ab24b85cef..f739999110b12f 100644 --- a/test/parallel/test-readline-keys.js +++ b/test/parallel/test-readline-keys.js @@ -279,6 +279,23 @@ addTest('\x1b[31ma\x1b[39ma', [ { name: 'a', sequence: 'a' }, ]); +// rxvt keys with modifiers +addTest('\x1b[a\x1b[b\x1b[c\x1b[d\x1b[e', [ + { name: 'up', sequence: '\x1b[a', code: '[a', shift: true }, + { name: 'down', sequence: '\x1b[b', code: '[b', shift: true }, + { name: 'right', sequence: '\x1b[c', code: '[c', shift: true }, + { name: 'left', sequence: '\x1b[d', code: '[d', shift: true }, + { name: 'clear', sequence: '\x1b[e', code: '[e', shift: true }, +]); + +addTest('\x1bOa\x1bOb\x1bOc\x1bOd\x1bOe', [ + { name: 'up', sequence: '\x1bOa', code: 'Oa', ctrl: true }, + { name: 'down', sequence: '\x1bOb', code: 'Ob', ctrl: true }, + { name: 'right', sequence: '\x1bOc', code: 'Oc', ctrl: true }, + { name: 'left', sequence: '\x1bOd', code: 'Od', ctrl: true }, + { name: 'clear', sequence: '\x1bOe', code: 'Oe', ctrl: true }, +]); + // Reduce array of addKeyIntervalTest(..) right to left // with () => {} as initial function const runKeyIntervalTests = [ diff --git a/test/parallel/test-repl-autolibs.js b/test/parallel/test-repl-autolibs.js index 52234deb5e732e..024dd971bf44e1 100644 --- a/test/parallel/test-repl-autolibs.js +++ b/test/parallel/test-repl-autolibs.js @@ -25,9 +25,6 @@ const assert = require('assert'); const util = require('util'); const repl = require('repl'); -// This test adds global variables -common.globalCheck = false; - const putIn = new common.ArrayStream(); repl.start('', putIn, null, true); @@ -65,6 +62,7 @@ function test2() { }; const val = {}; global.url = val; + common.allowGlobals(val); assert(!gotWrite); putIn.run(['url']); assert(gotWrite); diff --git a/test/parallel/test-repl-console.js b/test/parallel/test-repl-console.js deleted file mode 100644 index 94547e4768bb76..00000000000000 --- a/test/parallel/test-repl-console.js +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -'use strict'; -const common = require('../common'); -const assert = require('assert'); -const repl = require('repl'); - -// Create a dummy stream that does nothing -const stream = new common.ArrayStream(); - -const r = repl.start({ - input: stream, - output: stream, - useGlobal: false -}); - - -// ensure that the repl context gets its own "console" instance -assert(r.context.console); - -// ensure that the repl console instance is not the global one -assert.notStrictEqual(r.context.console, console); - -// ensure that the repl console instance does not have a setter -assert.throws(() => r.context.console = 'foo', TypeError); diff --git a/test/parallel/test-repl-context.js b/test/parallel/test-repl-context.js index 9d18067bc2aca4..914aa563bd50fb 100644 --- a/test/parallel/test-repl-context.js +++ b/test/parallel/test-repl-context.js @@ -4,32 +4,39 @@ const assert = require('assert'); const repl = require('repl'); const vm = require('vm'); -// Create a dummy stream that does nothing +// Create a dummy stream that does nothing. const stream = new common.ArrayStream(); -// Test when useGlobal is false -testContext(repl.start({ - input: stream, - output: stream, - useGlobal: false -})); +// Test context when useGlobal is false. +{ + const r = repl.start({ + input: stream, + output: stream, + useGlobal: false + }); -function testContext(repl) { - const context = repl.createContext(); - // ensure that the repl context gets its own "console" instance + // Ensure that the repl context gets its own "console" instance. + assert(r.context.console); + + // Ensure that the repl console instance is not the global one. + assert.notStrictEqual(r.context.console, console); + + const context = r.createContext(); + // Ensure that the repl context gets its own "console" instance. assert(context.console instanceof require('console').Console); - // ensure that the repl's global property is the context + // Ensure that the repl's global property is the context. assert.strictEqual(context.global, context); - // ensure that the repl console instance does not have a setter - assert.throws(() => context.console = 'foo', TypeError); - repl.close(); + // Ensure that the repl console instance is writable. + context.console = 'foo'; + r.close(); } -testContextSideEffects(repl.start({ input: stream, output: stream })); +// Test for context side effects. +{ + const server = repl.start({ input: stream, output: stream }); -function testContextSideEffects(server) { assert.ok(!server.underscoreAssigned); assert.strictEqual(server.lines.length, 0); diff --git a/test/parallel/test-repl-envvars.js b/test/parallel/test-repl-envvars.js index d29e7b3574c1f2..d6a45a664fa3b7 100644 --- a/test/parallel/test-repl-envvars.js +++ b/test/parallel/test-repl-envvars.js @@ -2,7 +2,7 @@ // Flags: --expose-internals -const common = require('../common'); +require('../common'); const stream = require('stream'); const REPL = require('internal/repl'); const assert = require('assert'); @@ -47,9 +47,6 @@ function run(test) { REPL.createInternalRepl(env, opts, function(err, repl) { assert.ifError(err); - // The REPL registers 'module' and 'require' globals - common.allowGlobals(repl.context.module, repl.context.require); - assert.strictEqual(expected.terminal, repl.terminal, `Expected ${inspect(expected)} with ${inspect(env)}`); assert.strictEqual(expected.useColors, repl.useColors, diff --git a/test/parallel/test-repl-function-definition-edge-case.js b/test/parallel/test-repl-function-definition-edge-case.js index 1e3063e3db53ff..952fba4103cc26 100644 --- a/test/parallel/test-repl-function-definition-edge-case.js +++ b/test/parallel/test-repl-function-definition-edge-case.js @@ -1,12 +1,10 @@ // Reference: https://github.com/nodejs/node/pull/7624 'use strict'; -const common = require('../common'); +require('../common'); const assert = require('assert'); const repl = require('repl'); const stream = require('stream'); -common.globalCheck = false; - const r = initRepl(); r.input.emit('data', 'function a() { return 42; } (1)\n'); diff --git a/test/parallel/test-repl-history-perm.js b/test/parallel/test-repl-history-perm.js index b125fa551dc858..03ce1435d9ba4e 100644 --- a/test/parallel/test-repl-history-perm.js +++ b/test/parallel/test-repl-history-perm.js @@ -38,9 +38,6 @@ const replHistoryPath = path.join(tmpdir.path, '.node_repl_history'); const checkResults = common.mustCall(function(err, r) { assert.ifError(err); - // The REPL registers 'module' and 'require' globals - common.allowGlobals(r.context.module, r.context.require); - r.input.end(); const stat = fs.statSync(replHistoryPath); const fileMode = stat.mode & 0o777; diff --git a/test/parallel/test-repl-let-process.js b/test/parallel/test-repl-let-process.js index 3e6c3e85665be1..dd8fa60f463d8b 100644 --- a/test/parallel/test-repl-let-process.js +++ b/test/parallel/test-repl-let-process.js @@ -2,8 +2,6 @@ const common = require('../common'); const repl = require('repl'); -common.globalCheck = false; - // Regression test for https://github.com/nodejs/node/issues/6802 const input = new common.ArrayStream(); repl.start({ input, output: process.stdout, useGlobal: true }); diff --git a/test/parallel/test-repl-mode.js b/test/parallel/test-repl-mode.js index 60b430d8c7ee31..df84d86a3c8dc3 100644 --- a/test/parallel/test-repl-mode.js +++ b/test/parallel/test-repl-mode.js @@ -1,11 +1,9 @@ 'use strict'; -const common = require('../common'); +require('../common'); const assert = require('assert'); const Stream = require('stream'); const repl = require('repl'); -common.globalCheck = false; - const tests = [ testSloppyMode, testStrictMode, diff --git a/test/parallel/test-repl-options.js b/test/parallel/test-repl-options.js index 6bd908aadf935d..1de49c8e861391 100644 --- a/test/parallel/test-repl-options.js +++ b/test/parallel/test-repl-options.js @@ -24,8 +24,6 @@ const common = require('../common'); const assert = require('assert'); const repl = require('repl'); -common.globalCheck = false; - // Create a dummy stream that does nothing const stream = new common.ArrayStream(); diff --git a/test/parallel/test-repl-persistent-history.js b/test/parallel/test-repl-persistent-history.js index 4d0330272ab3c6..bb10085eccfcf6 100644 --- a/test/parallel/test-repl-persistent-history.js +++ b/test/parallel/test-repl-persistent-history.js @@ -216,9 +216,6 @@ function runTest(assertCleaned) { throw err; } - // The REPL registers 'module' and 'require' globals - common.allowGlobals(repl.context.module, repl.context.require); - repl.once('close', () => { if (repl._flushing) { repl.once('flushHistory', onClose); diff --git a/test/parallel/test-repl-reset-event.js b/test/parallel/test-repl-reset-event.js index 83ab7fd6a3ec52..96d1d199af34c9 100644 --- a/test/parallel/test-repl-reset-event.js +++ b/test/parallel/test-repl-reset-event.js @@ -21,12 +21,13 @@ 'use strict'; const common = require('../common'); -common.globalCheck = false; const assert = require('assert'); const repl = require('repl'); const util = require('util'); +common.allowGlobals(42); + // Create a dummy stream that does nothing const dummy = new common.ArrayStream(); diff --git a/test/parallel/test-repl-underscore.js b/test/parallel/test-repl-underscore.js index 57929244ae4374..628a7739fecf4e 100644 --- a/test/parallel/test-repl-underscore.js +++ b/test/parallel/test-repl-underscore.js @@ -174,7 +174,7 @@ function testError() { // The error, both from the original throw and the `_error` echo. 'Error: foo', - 'Error: foo', + '[Error: foo]', // The sync error, with individual property echoes /Error: ENOENT: no such file or directory, scandir '.*nonexistent.*'/, diff --git a/test/parallel/test-repl-use-global.js b/test/parallel/test-repl-use-global.js index c76505272b2682..947adc7f255035 100644 --- a/test/parallel/test-repl-use-global.js +++ b/test/parallel/test-repl-use-global.js @@ -18,9 +18,6 @@ const globalTest = (useGlobal, cb, output) => (err, repl) => { if (err) return cb(err); - // The REPL registers 'module' and 'require' globals - common.allowGlobals(repl.context.module, repl.context.require); - let str = ''; output.on('data', (data) => (str += data)); global.lunch = 'tacos'; diff --git a/test/parallel/test-repl.js b/test/parallel/test-repl.js index e14398541dd8de..9aaf366c6807f0 100644 --- a/test/parallel/test-repl.js +++ b/test/parallel/test-repl.js @@ -26,7 +26,6 @@ const assert = require('assert'); const net = require('net'); const repl = require('repl'); -common.globalCheck = false; common.crashOnUnhandledRejection(); const message = 'Read, Eval, Print Loop'; @@ -41,7 +40,6 @@ global.invoke_me = function(arg) { return `invoked ${arg}`; }; - // Helpers for describing the expected output: const kArrow = /^ *\^+ *$/; // Arrow of ^ pointing to syntax error location const kSource = Symbol('kSource'); // Placeholder standing for input readback @@ -132,6 +130,29 @@ const strictModeTests = [ } ]; +const friendlyExitTests = [ + { + send: 'exit', + expect: '(To exit, press ^D or type .exit)' + }, + { + send: 'quit', + expect: '(To exit, press ^D or type .exit)' + }, + { + send: 'quit = 1', + expect: '1' + }, + { + send: 'quit', + expect: '1' + }, + { + send: 'exit', + expect: '(To exit, press ^D or type .exit)' + }, +]; + const errorTests = [ // Uncaught error throws and prints out { @@ -742,6 +763,7 @@ const tcpTests = [ const [ socket, replServer ] = await startUnixRepl(); await runReplTests(socket, prompt_unix, unixTests); + await runReplTests(socket, prompt_unix, friendlyExitTests); await runReplTests(socket, prompt_unix, errorTests); replServer.replMode = repl.REPL_MODE_STRICT; await runReplTests(socket, prompt_unix, strictModeTests); @@ -755,6 +777,7 @@ const tcpTests = [ socket.end(); } + common.allowGlobals(...Object.values(global)); })(); function startTCPRepl() { diff --git a/test/parallel/test-require-deps-deprecation.js b/test/parallel/test-require-deps-deprecation.js index 24a2e86e6a42ee..80bf66d7f6b74f 100644 --- a/test/parallel/test-require-deps-deprecation.js +++ b/test/parallel/test-require-deps-deprecation.js @@ -2,8 +2,6 @@ const common = require('../common'); const assert = require('assert'); -// The v8 modules when imported leak globals. Disable global check. -common.globalCheck = false; const deprecatedModules = [ 'node-inspect/lib/_inspect', @@ -53,3 +51,6 @@ for (const m of deps) { } assert.notStrictEqual(path, m); } + +// The V8 modules add the WebInspector to the globals. +common.allowGlobals(global.WebInspector); diff --git a/test/parallel/test-stdio-pipe-stderr.js b/test/parallel/test-stdio-pipe-stderr.js new file mode 100644 index 00000000000000..06e93429d03f6d --- /dev/null +++ b/test/parallel/test-stdio-pipe-stderr.js @@ -0,0 +1,37 @@ +'use strict'; +require('../common'); +const tmpdir = require('../common/tmpdir'); +const assert = require('assert'); +const fs = require('fs'); +const join = require('path').join; +const spawn = require('child_process').spawnSync; + +// Test that invoking node with require, and piping stderr to file, +// does not result in exception, +// see: https://github.com/nodejs/node/issues/11257 + +tmpdir.refresh(); +const fakeModulePath = join(tmpdir.path, 'batman.js'); +const stderrOutputPath = join(tmpdir.path, 'stderr-output.txt'); +// we need to redirect stderr to a file to produce #11257 +const stream = fs.createWriteStream(stderrOutputPath); + +// the error described in #11257 only happens when we require a +// non-built-in module. +fs.writeFileSync(fakeModulePath, '', 'utf8'); + +stream.on('open', () => { + spawn(process.execPath, { + input: `require("${fakeModulePath.replace(/\\/g, '/')}")`, + stdio: ['pipe', 'pipe', stream] + }); + const stderr = fs.readFileSync(stderrOutputPath, 'utf8').trim(); + assert.strictEqual( + stderr, + '', + `piping stderr to file should not result in exception: ${stderr}` + ); + stream.end(); + fs.unlinkSync(stderrOutputPath); + fs.unlinkSync(fakeModulePath); +}); diff --git a/test/parallel/test-stream-readable-setEncoding-null.js b/test/parallel/test-stream-readable-setEncoding-null.js new file mode 100644 index 00000000000000..b95b26bb795728 --- /dev/null +++ b/test/parallel/test-stream-readable-setEncoding-null.js @@ -0,0 +1,15 @@ +'use strict'; + +require('../common'); +const assert = require('assert'); +const { Readable } = require('stream'); + + +{ + const readable = new Readable({ encoding: 'hex' }); + assert.strictEqual(readable._readableState.encoding, 'hex'); + + readable.setEncoding(null); + + assert.strictEqual(readable._readableState.encoding, 'utf8'); +} diff --git a/test/parallel/test-timer-immediate.js b/test/parallel/test-timer-immediate.js index 385fa4baca4ee5..b0f52db1b713d3 100644 --- a/test/parallel/test-timer-immediate.js +++ b/test/parallel/test-timer-immediate.js @@ -1,5 +1,5 @@ 'use strict'; const common = require('../common'); -common.globalCheck = false; global.process = {}; // Boom! +common.allowGlobals(global.process); setImmediate(common.mustCall()); diff --git a/test/parallel/test-timers-refresh.js b/test/parallel/test-timers-refresh.js index 25a22329c01ee9..2c47be8d8d15ae 100644 --- a/test/parallel/test-timers-refresh.js +++ b/test/parallel/test-timers-refresh.js @@ -5,7 +5,7 @@ const common = require('../common'); const { strictEqual } = require('assert'); -const { setUnrefTimeout, refreshFnSymbol } = require('internal/timers'); +const { setUnrefTimeout } = require('internal/timers'); // Schedule the unrefed cases first so that the later case keeps the event loop // active. @@ -27,7 +27,7 @@ const { setUnrefTimeout, refreshFnSymbol } = require('internal/timers'); strictEqual(called, false, 'unref()\'d timer returned before check'); }), 1); - timer[refreshFnSymbol](); + strictEqual(timer.refresh(), timer); } // unref pooled timer @@ -41,7 +41,7 @@ const { setUnrefTimeout, refreshFnSymbol } = require('internal/timers'); strictEqual(called, false, 'unref pooled timer returned before check'); }), 1); - timer[refreshFnSymbol](); + strictEqual(timer.refresh(), timer); } // regular timer @@ -55,5 +55,22 @@ const { setUnrefTimeout, refreshFnSymbol } = require('internal/timers'); strictEqual(called, false, 'pooled timer returned before check'); }), 1); - timer[refreshFnSymbol](); + strictEqual(timer.refresh(), timer); +} + +// interval +{ + let called = 0; + const timer = setInterval(common.mustCall(() => { + called += 1; + if (called === 2) { + clearInterval(timer); + } + }, 2), 1); + + setTimeout(common.mustCall(() => { + strictEqual(called, 0, 'pooled timer returned before check'); + }), 1); + + strictEqual(timer.refresh(), timer); } diff --git a/test/parallel/test-tls-handshake-exception.js b/test/parallel/test-tls-handshake-exception.js new file mode 100644 index 00000000000000..1ba4bc6438e2f9 --- /dev/null +++ b/test/parallel/test-tls-handshake-exception.js @@ -0,0 +1,57 @@ +'use strict'; + +// Verify that exceptions from a callback don't result in +// failed CHECKs when trying to print the exception message. + +// This test is convoluted because it needs to trigger a callback +// into JS land at just the right time when an exception is pending, +// and does so by exploiting a weakness in the streams infrastructure. +// I won't shed any tears if this test ever becomes invalidated. + +const common = require('../common'); + +if (!common.hasCrypto) + common.skip('missing crypto'); + +if (process.argv[2] === 'child') { + const fixtures = require('../common/fixtures'); + const https = require('https'); + const net = require('net'); + const tls = require('tls'); + const { Duplex } = require('stream'); + const { mustCall } = common; + + const cert = fixtures.readSync('test_cert.pem'); + const key = fixtures.readSync('test_key.pem'); + + net.createServer(mustCall(onplaintext)).listen(0, mustCall(onlisten)); + + function onlisten() { + const { port } = this.address(); + https.get({ port, rejectUnauthorized: false }); + } + + function onplaintext(c) { + const d = new class extends Duplex { + _read(n) { + const data = c.read(n); + if (data) d.push(data); + } + _write(...xs) { + c.write(...xs); + } + }(); + c.on('data', d.push.bind(d)); + + const options = { key, cert }; + const fail = () => { throw new Error('eyecatcher'); }; + tls.createServer(options, mustCall(fail)).emit('connection', d); + } +} else { + const assert = require('assert'); + const { spawnSync } = require('child_process'); + const result = spawnSync(process.execPath, [__filename, 'child']); + const stderr = result.stderr.toString(); + const ok = stderr.includes('Error: eyecatcher'); + assert(ok, stderr); +} diff --git a/test/parallel/test-tls-two-cas-one-string.js b/test/parallel/test-tls-multiple-cas-as-string.js similarity index 77% rename from test/parallel/test-tls-two-cas-one-string.js rename to test/parallel/test-tls-multiple-cas-as-string.js index bbde78a24ed706..2612de55fe988f 100644 --- a/test/parallel/test-tls-two-cas-one-string.js +++ b/test/parallel/test-tls-multiple-cas-as-string.js @@ -4,6 +4,9 @@ const common = require('../common'); if (!common.hasCrypto) common.skip('missing crypto'); +// Verify that multiple CA certificates can be provided, and that for +// convenience that can also be in newline-separated strings. + const tls = require('tls'); const fixtures = require('../common/fixtures'); @@ -30,6 +33,8 @@ function test(ca, next) { } } +// `ca1` is not actually necessary for the certificate validation -- maybe +// the fixtures should be written in a way that requires it? const array = [ca1, ca2]; const string = `${ca1}\n${ca2}`; test(array, common.mustCall(() => test(string))); diff --git a/test/parallel/test-trace-events-api.js b/test/parallel/test-trace-events-api.js index b4f7112d07ac77..a68a2850a37c45 100644 --- a/test/parallel/test-trace-events-api.js +++ b/test/parallel/test-trace-events-api.js @@ -130,7 +130,8 @@ if (isChild) { assert(common.fileExists(file)); fs.readFile(file, common.mustCall((err, data) => { - const traces = JSON.parse(data.toString()).traceEvents; + const traces = JSON.parse(data.toString()).traceEvents + .filter((trace) => trace.cat !== '__metadata'); assert.strictEqual(traces.length, expectedMarks.length + expectedBegins.length + diff --git a/test/parallel/test-trace-events-async-hooks.js b/test/parallel/test-trace-events-async-hooks.js index d3c5a0af5b8e50..e0b5e0625bea6f 100644 --- a/test/parallel/test-trace-events-async-hooks.js +++ b/test/parallel/test-trace-events-async-hooks.js @@ -3,6 +3,7 @@ const common = require('../common'); const assert = require('assert'); const cp = require('child_process'); const fs = require('fs'); +const util = require('util'); const CODE = 'setTimeout(() => { for (var i = 0; i < 100000; i++) { "test" + i } }, 1)'; @@ -58,9 +59,9 @@ proc.once('exit', common.mustCall(() => { const initEvents = traces.filter((trace) => { return (trace.ph === 'b' && !trace.name.includes('_CALLBACK')); }); - assert(initEvents.every((trace) => { + assert.ok(initEvents.every((trace) => { return (trace.args.executionAsyncId > 0 && trace.args.triggerAsyncId > 0); - })); + }), `Unexpected initEvents format: ${util.inspect(initEvents)}`); })); })); diff --git a/test/parallel/test-trace-events-binding.js b/test/parallel/test-trace-events-binding.js index 35fbfc3692a5d3..e52f1c769f5283 100644 --- a/test/parallel/test-trace-events-binding.js +++ b/test/parallel/test-trace-events-binding.js @@ -31,7 +31,8 @@ const proc = cp.spawn(process.execPath, proc.once('exit', common.mustCall(() => { assert(common.fileExists(FILE_NAME)); fs.readFile(FILE_NAME, common.mustCall((err, data) => { - const traces = JSON.parse(data.toString()).traceEvents; + const traces = JSON.parse(data.toString()).traceEvents + .filter((trace) => trace.cat !== '__metadata'); assert.strictEqual(traces.length, 3); assert.strictEqual(traces[0].pid, proc.pid); diff --git a/test/parallel/test-trace-events-bootstrap.js b/test/parallel/test-trace-events-bootstrap.js index a0bfcf123e7233..6f8c76564a8ac4 100644 --- a/test/parallel/test-trace-events-bootstrap.js +++ b/test/parallel/test-trace-events-bootstrap.js @@ -42,7 +42,8 @@ if (process.argv[2] === 'child') { assert(common.fileExists(file)); fs.readFile(file, common.mustCall((err, data) => { - const traces = JSON.parse(data.toString()).traceEvents; + const traces = JSON.parse(data.toString()).traceEvents + .filter((trace) => trace.cat !== '__metadata'); traces.forEach((trace) => { assert.strictEqual(trace.pid, proc.pid); assert(names.includes(trace.name)); diff --git a/test/parallel/test-trace-events-metadata.js b/test/parallel/test-trace-events-metadata.js new file mode 100644 index 00000000000000..eccec1ecf0f1a2 --- /dev/null +++ b/test/parallel/test-trace-events-metadata.js @@ -0,0 +1,29 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const cp = require('child_process'); +const fs = require('fs'); + +const CODE = + 'setTimeout(() => { for (var i = 0; i < 100000; i++) { "test" + i } }, 1)'; +const FILE_NAME = 'node_trace.1.log'; + +const tmpdir = require('../common/tmpdir'); +tmpdir.refresh(); +process.chdir(tmpdir.path); + +const proc = cp.spawn(process.execPath, + [ '--trace-events-enabled', '-e', CODE ]); +proc.once('exit', common.mustCall(() => { + assert(common.fileExists(FILE_NAME)); + fs.readFile(FILE_NAME, common.mustCall((err, data) => { + const traces = JSON.parse(data.toString()).traceEvents; + assert(traces.length > 0); + assert(traces.some((trace) => + trace.cat === '__metadata' && trace.name === 'thread_name' && + trace.args.name === 'JavaScriptMainThread')); + assert(traces.some((trace) => + trace.cat === '__metadata' && trace.name === 'thread_name' && + trace.args.name === 'BackgroundTaskRunner')); + })); +})); diff --git a/test/parallel/test-trace-events-none.js b/test/parallel/test-trace-events-none.js index 6b60ce999ac118..a3f0338f28af35 100644 --- a/test/parallel/test-trace-events-none.js +++ b/test/parallel/test-trace-events-none.js @@ -2,6 +2,7 @@ const common = require('../common'); const assert = require('assert'); const cp = require('child_process'); +const fs = require('fs'); const CODE = 'setTimeout(() => { for (var i = 0; i < 100000; i++) { "test" + i } }, 1)'; @@ -17,5 +18,10 @@ const proc_no_categories = cp.spawn( ); proc_no_categories.once('exit', common.mustCall(() => { - assert(!common.fileExists(FILE_NAME)); + assert(common.fileExists(FILE_NAME)); + // Only __metadata categories should have been emitted. + fs.readFile(FILE_NAME, common.mustCall((err, data) => { + assert.ok(JSON.parse(data.toString()).traceEvents.every( + (trace) => trace.cat === '__metadata')); + })); })); diff --git a/test/parallel/test-trace-events-perf.js b/test/parallel/test-trace-events-perf.js index 5758082b6efa43..57ac0e3142f66d 100644 --- a/test/parallel/test-trace-events-perf.js +++ b/test/parallel/test-trace-events-perf.js @@ -49,7 +49,8 @@ if (process.argv[2] === 'child') { assert(common.fileExists(file)); fs.readFile(file, common.mustCall((err, data) => { - const traces = JSON.parse(data.toString()).traceEvents; + const traces = JSON.parse(data.toString()).traceEvents + .filter((trace) => trace.cat !== '__metadata'); assert.strictEqual(traces.length, expectedMarks.length + expectedBegins.length + diff --git a/test/parallel/test-trace-events-vm.js b/test/parallel/test-trace-events-vm.js new file mode 100644 index 00000000000000..3dc6e263e1b6a1 --- /dev/null +++ b/test/parallel/test-trace-events-vm.js @@ -0,0 +1,43 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const cp = require('child_process'); +const path = require('path'); +const fs = require('fs'); +const tmpdir = require('../common/tmpdir'); + +const names = [ + 'ContextifyScript::New', + 'RunInThisContext', + 'RunInContext' +]; + +if (process.argv[2] === 'child') { + const vm = require('vm'); + vm.runInNewContext('1 + 1'); +} else { + tmpdir.refresh(); + process.chdir(tmpdir.path); + + const proc = cp.fork(__filename, + [ 'child' ], { + execArgv: [ + '--trace-event-categories', + 'node.vm.script' + ] + }); + + proc.once('exit', common.mustCall(() => { + const file = path.join(tmpdir.path, 'node_trace.1.log'); + + assert(common.fileExists(file)); + fs.readFile(file, common.mustCall((err, data) => { + const traces = JSON.parse(data.toString()).traceEvents + .filter((trace) => trace.cat !== '__metadata'); + traces.forEach((trace) => { + assert.strictEqual(trace.pid, proc.pid); + assert(names.includes(trace.name)); + }); + })); + })); +} diff --git a/test/parallel/test-util-format-shared-arraybuffer.js b/test/parallel/test-util-format-shared-arraybuffer.js index c910c1f1b4e044..27dfad3c91fd16 100644 --- a/test/parallel/test-util-format-shared-arraybuffer.js +++ b/test/parallel/test-util-format-shared-arraybuffer.js @@ -2,7 +2,5 @@ require('../common'); const assert = require('assert'); const util = require('util'); - -/* global SharedArrayBuffer */ const sab = new SharedArrayBuffer(4); assert.strictEqual(util.format(sab), 'SharedArrayBuffer { byteLength: 4 }'); diff --git a/test/parallel/test-util-format.js b/test/parallel/test-util-format.js index fd686cb6d355ad..f99f85b78c853b 100644 --- a/test/parallel/test-util-format.js +++ b/test/parallel/test-util-format.js @@ -126,7 +126,7 @@ assert.strictEqual( util.format('%o', obj), '{ foo: \'bar\',\n' + ' foobar: 1,\n' + - ' func: \n' + + ' func:\n' + ' { [Function: func]\n' + ' [length]: 0,\n' + ' [name]: \'func\',\n' + @@ -135,8 +135,8 @@ assert.strictEqual( util.format('%o', nestedObj2), '{ foo: \'bar\',\n' + ' foobar: 1,\n' + - ' func: \n' + - ' [ { a: \n' + + ' func:\n' + + ' [ { a:\n' + ' { [Function: a]\n' + ' [length]: 0,\n' + ' [name]: \'a\',\n' + @@ -145,9 +145,9 @@ assert.strictEqual( assert.strictEqual( util.format('%o', nestedObj), '{ foo: \'bar\',\n' + - ' foobar: \n' + + ' foobar:\n' + ' { foo: \'bar\',\n' + - ' func: \n' + + ' func:\n' + ' { [Function: func]\n' + ' [length]: 0,\n' + ' [name]: \'func\',\n' + @@ -156,14 +156,14 @@ assert.strictEqual( util.format('%o %o', obj, obj), '{ foo: \'bar\',\n' + ' foobar: 1,\n' + - ' func: \n' + + ' func:\n' + ' { [Function: func]\n' + ' [length]: 0,\n' + ' [name]: \'func\',\n' + ' [prototype]: func { [constructor]: [Circular] } } }' + ' { foo: \'bar\',\n' + ' foobar: 1,\n' + - ' func: \n' + + ' func:\n' + ' { [Function: func]\n' + ' [length]: 0,\n' + ' [name]: \'func\',\n' + @@ -172,7 +172,7 @@ assert.strictEqual( util.format('%o %o', obj), '{ foo: \'bar\',\n' + ' foobar: 1,\n' + - ' func: \n' + + ' func:\n' + ' { [Function: func]\n' + ' [length]: 0,\n' + ' [name]: \'func\',\n' + diff --git a/test/parallel/test-util-inspect-namespace.js b/test/parallel/test-util-inspect-namespace.js new file mode 100644 index 00000000000000..fddbcdb34697d9 --- /dev/null +++ b/test/parallel/test-util-inspect-namespace.js @@ -0,0 +1,22 @@ +'use strict'; + +// Flags: --experimental-vm-modules + +const common = require('../common'); +const assert = require('assert'); + +common.crashOnUnhandledRejection(); + +const { Module } = require('vm'); +const { inspect } = require('util'); + +(async () => { + const m = new Module('export const a = 1; export var b = 2'); + await m.link(() => 0); + m.instantiate(); + assert.strictEqual( + inspect(m.namespace), + '[Module] { a: , b: undefined }'); + await m.evaluate(); + assert.strictEqual(inspect(m.namespace), '[Module] { a: 1, b: 2 }'); +})(); diff --git a/test/parallel/test-util-inspect.js b/test/parallel/test-util-inspect.js index 5cd051299d7f06..2899beecf64346 100644 --- a/test/parallel/test-util-inspect.js +++ b/test/parallel/test-util-inspect.js @@ -19,14 +19,13 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. -// Flags: --expose_internals 'use strict'; const common = require('../common'); const assert = require('assert'); const JSStream = process.binding('js_stream').JSStream; const util = require('util'); const vm = require('vm'); -const { previewMapIterator } = require('internal/v8'); +const { previewEntries } = process.binding('util'); assert.strictEqual(util.inspect(1), '1'); assert.strictEqual(util.inspect(false), 'false'); @@ -448,7 +447,7 @@ assert.strictEqual(util.inspect(-5e-324), '-5e-324'); { const map = new Map(); map.set(1, 2); - const vals = previewMapIterator(map.entries()); + const vals = previewEntries(map.entries()); const valsOutput = []; for (const o of vals) { valsOutput.push(o); @@ -497,12 +496,12 @@ assert.strictEqual(util.inspect(-5e-324), '-5e-324'); // Exceptions should print the error message, not '{}'. { - const errors = []; - errors.push(new Error()); - errors.push(new Error('FAIL')); - errors.push(new TypeError('FAIL')); - errors.push(new SyntaxError('FAIL')); - errors.forEach((err) => { + [ + new Error(), + new Error('FAIL'), + new TypeError('FAIL'), + new SyntaxError('FAIL') + ].forEach((err) => { assert.strictEqual(util.inspect(err), err.stack); }); try { @@ -516,6 +515,56 @@ assert.strictEqual(util.inspect(-5e-324), '-5e-324'); assert(ex.includes('[message]')); } +{ + const tmp = Error.stackTraceLimit; + Error.stackTraceLimit = 0; + const err = new Error('foo'); + const err2 = new Error('foo\nbar'); + assert.strictEqual(util.inspect(err, { compact: true }), '[Error: foo]'); + assert(err.stack); + delete err.stack; + assert(!err.stack); + assert.strictEqual(util.inspect(err, { compact: true }), '[Error: foo]'); + assert.strictEqual( + util.inspect(err2, { compact: true }), + '[Error: foo\nbar]' + ); + + err.bar = true; + err2.bar = true; + + assert.strictEqual( + util.inspect(err, { compact: true }), + '{ [Error: foo] bar: true }' + ); + assert.strictEqual( + util.inspect(err2, { compact: true }), + '{ [Error: foo\nbar] bar: true }' + ); + assert.strictEqual( + util.inspect(err, { compact: true, breakLength: 5 }), + '{ [Error: foo]\n bar: true }' + ); + assert.strictEqual( + util.inspect(err, { compact: true, breakLength: 1 }), + '{ [Error: foo]\n bar:\n true }' + ); + assert.strictEqual( + util.inspect(err2, { compact: true, breakLength: 5 }), + '{ [Error: foo\nbar]\n bar: true }' + ); + assert.strictEqual( + util.inspect(err, { compact: false }), + '[Error: foo] {\n bar: true\n}' + ); + assert.strictEqual( + util.inspect(err2, { compact: false }), + '[Error: foo\nbar] {\n bar: true\n}' + ); + + Error.stackTraceLimit = tmp; +} + // Doesn't capture stack trace. { function BadCustomError(msg) { @@ -935,8 +984,7 @@ if (typeof Symbol !== 'undefined') { const aSet = new Set([1, 3]); assert.strictEqual(util.inspect(aSet.keys()), '[Set Iterator] { 1, 3 }'); assert.strictEqual(util.inspect(aSet.values()), '[Set Iterator] { 1, 3 }'); - assert.strictEqual(util.inspect(aSet.entries()), - '[Set Iterator] { [ 1, 1 ], [ 3, 3 ] }'); + assert.strictEqual(util.inspect(aSet.entries()), '[Set Iterator] { 1, 3 }'); // Make sure the iterator doesn't get consumed. const keys = aSet.keys(); assert.strictEqual(util.inspect(keys), '[Set Iterator] { 1, 3 }'); @@ -1227,7 +1275,7 @@ util.inspect(process); let out = util.inspect(o, { compact: true, depth: 5, breakLength: 80 }); let expect = [ - '{ a: ', + '{ a:', ' [ 1,', ' 2,', " [ [ 'Lorem ipsum dolor\\nsit amet,\\tconsectetur adipiscing elit, " + @@ -1374,7 +1422,8 @@ util.inspect(process); expect = 'WeakMap { [ [length]: 0 ] => {}, ... more items, extra: true }'; const expectAlt = 'WeakMap { {} => [ [length]: 0 ], ... more items, ' + 'extra: true }'; - assert(out === expect || out === expectAlt); + assert(out === expect || out === expectAlt, + `Found "${out}" rather than "${expect}" or "${expectAlt}"`); } { // Test WeakSet @@ -1397,10 +1446,23 @@ util.inspect(process); expect = 'WeakSet { {}, ... more items, extra: true }'; const expectAlt = 'WeakSet { [ 1, [length]: 1 ], ... more items, ' + 'extra: true }'; - assert(out === expect || out === expectAlt); + assert(out === expect || out === expectAlt, + `Found "${out}" rather than "${expect}" or "${expectAlt}"`); } { // Test argument objects. const args = (function() { return arguments; })('a'); assert.strictEqual(util.inspect(args), "[Arguments] { '0': 'a' }"); } + +{ + // Test that a long linked list can be inspected without throwing an error. + const list = {}; + let head = list; + // The real cutoff value is closer to 1400 stack frames as of May 2018, + // but let's be generous here – even a linked listed of length 100k should be + // inspectable in some way. + for (let i = 0; i < 100000; i++) + head = head.next = {}; + util.inspect(list); +} diff --git a/test/parallel/test-util-types.js b/test/parallel/test-util-types.js index 924869896869c0..24f613cc0b25ad 100644 --- a/test/parallel/test-util-types.js +++ b/test/parallel/test-util-types.js @@ -1,5 +1,4 @@ // Flags: --harmony-bigint --experimental-vm-modules -/* global SharedArrayBuffer */ 'use strict'; const common = require('../common'); const fixtures = require('../common/fixtures'); diff --git a/test/parallel/test-vm-new-script-this-context.js b/test/parallel/test-vm-new-script-this-context.js index 6da47e67249c2b..2c0c21690e1821 100644 --- a/test/parallel/test-vm-new-script-this-context.js +++ b/test/parallel/test-vm-new-script-this-context.js @@ -24,8 +24,6 @@ const common = require('../common'); const assert = require('assert'); const Script = require('vm').Script; -common.globalCheck = false; - // Run a string let script = new Script('\'passed\';'); const result = script.runInThisContext(script); @@ -60,3 +58,11 @@ global.f = function() { global.foo = 100; }; script = new Script('f()'); script.runInThisContext(script); assert.strictEqual(100, global.foo); + +common.allowGlobals( + global.hello, + global.code, + global.foo, + global.obj, + global.f +); diff --git a/test/parallel/test-vm-run-in-new-context.js b/test/parallel/test-vm-run-in-new-context.js index 1edb061ea6a871..e844cd6816bba3 100644 --- a/test/parallel/test-vm-run-in-new-context.js +++ b/test/parallel/test-vm-run-in-new-context.js @@ -29,8 +29,6 @@ const vm = require('vm'); assert.strictEqual(typeof global.gc, 'function', 'Run this test with --expose-gc'); -common.globalCheck = false; - // Run a string const result = vm.runInNewContext('\'passed\';'); assert.strictEqual(result, 'passed'); @@ -93,3 +91,10 @@ fn(); return true; }); } + +common.allowGlobals( + global.hello, + global.code, + global.foo, + global.obj +); diff --git a/test/parallel/test-vm-static-this.js b/test/parallel/test-vm-static-this.js index 5306e31dc0e4a7..d4530604dc06f0 100644 --- a/test/parallel/test-vm-static-this.js +++ b/test/parallel/test-vm-static-this.js @@ -24,8 +24,6 @@ const common = require('../common'); const assert = require('assert'); const vm = require('vm'); -common.globalCheck = false; - // Run a string const result = vm.runInThisContext('\'passed\';'); assert.strictEqual('passed', result); @@ -58,3 +56,10 @@ assert.strictEqual(1, global.foo); global.f = function() { global.foo = 100; }; vm.runInThisContext('f()'); assert.strictEqual(100, global.foo); + +common.allowGlobals( + global.hello, + global.foo, + global.obj, + global.f +); diff --git a/test/parallel/test-whatwg-url-inspect.js b/test/parallel/test-whatwg-url-inspect.js index 5758b39b8af83d..1265428d4ca811 100644 --- a/test/parallel/test-whatwg-url-inspect.js +++ b/test/parallel/test-whatwg-url-inspect.js @@ -16,7 +16,8 @@ const url = new URL('https://username:password@host.name:8080/path/name/?que=ry# assert.strictEqual( util.inspect(url), `URL { - href: 'https://username:password@host.name:8080/path/name/?que=ry#hash', + href: + 'https://username:password@host.name:8080/path/name/?que=ry#hash', origin: 'https://host.name:8080', protocol: 'https:', username: 'username', @@ -32,7 +33,8 @@ assert.strictEqual( assert.strictEqual( util.inspect(url, { showHidden: true }), `URL { - href: 'https://username:password@host.name:8080/path/name/?que=ry#hash', + href: + 'https://username:password@host.name:8080/path/name/?que=ry#hash', origin: 'https://host.name:8080', protocol: 'https:', username: 'username', @@ -46,7 +48,7 @@ assert.strictEqual( hash: '#hash', cannotBeBase: false, special: true, - [Symbol(context)]:\x20 + [Symbol(context)]: URLContext { flags: 2032, scheme: 'https:', diff --git a/test/parallel/test-whatwg-url-parsing.js b/test/parallel/test-whatwg-url-parsing.js index fd34fee1954d8c..fd8570eb720831 100644 --- a/test/parallel/test-whatwg-url-parsing.js +++ b/test/parallel/test-whatwg-url-parsing.js @@ -12,7 +12,10 @@ const fixtures = require('../common/fixtures'); // Tests below are not from WPT. const tests = require(fixtures.path('url-tests')); -const failureTests = tests.filter((test) => test.failure).concat([ + +const originalFailures = tests.filter((test) => test.failure); + +const typeFailures = [ { input: '' }, { input: 'test' }, { input: undefined }, @@ -25,7 +28,23 @@ const failureTests = tests.filter((test) => test.failure).concat([ { input: 'test', base: null }, { input: 'http://nodejs.org', base: null }, { input: () => {} } -]); +]; + +// See https://github.com/w3c/web-platform-tests/pull/10955 +// > If `failure` is true, parsing `about:blank` against `base` +// > must give failure. This tests that the logic for converting +// > base URLs into strings properly fails the whole parsing +// > algorithm if the base URL cannot be parsed. +const aboutBlankFailures = originalFailures + .map((test) => ({ + input: 'about:blank', + base: test.input, + failure: true + })); + +const failureTests = originalFailures + .concat(typeFailures) + .concat(aboutBlankFailures); const expectedError = common.expectsError( { code: 'ERR_INVALID_URL', type: TypeError }, failureTests.length); diff --git a/test/sequential/test-benchmark-tls.js b/test/sequential/test-benchmark-tls.js index 3545955e3ab5b0..40c14af8302bdb 100644 --- a/test/sequential/test-benchmark-tls.js +++ b/test/sequential/test-benchmark-tls.js @@ -20,6 +20,7 @@ runBenchmark('tls', 'dur=0.1', 'n=1', 'size=2', + 'securing=SecurePair', 'type=asc' ], { diff --git a/test/sequential/test-http2-max-session-memory.js b/test/sequential/test-http2-max-session-memory.js index d6d3bf935db801..644a20a3c88a50 100644 --- a/test/sequential/test-http2-max-session-memory.js +++ b/test/sequential/test-http2-max-session-memory.js @@ -13,6 +13,10 @@ const largeBuffer = Buffer.alloc(1e6); const server = http2.createServer({ maxSessionMemory: 1 }); server.on('stream', common.mustCall((stream) => { + stream.on('error', (err) => { + if (err.code !== 'ECONNRESET') + throw err; + }); stream.respond(); stream.end(largeBuffer); })); diff --git a/test/sequential/test-http2-session-timeout.js b/test/sequential/test-http2-session-timeout.js index fce4570563c584..48e98998c700b6 100644 --- a/test/sequential/test-http2-session-timeout.js +++ b/test/sequential/test-http2-session-timeout.js @@ -7,7 +7,6 @@ const h2 = require('http2'); const serverTimeout = common.platformTimeout(200); const callTimeout = common.platformTimeout(20); -const minRuns = Math.ceil(serverTimeout / callTimeout) * 2; const mustNotCall = common.mustNotCall(); const server = h2.createServer(); @@ -21,9 +20,10 @@ server.listen(0, common.mustCall(() => { const url = `http://localhost:${port}`; const client = h2.connect(url); - makeReq(minRuns); + const startTime = process.hrtime(); + makeReq(); - function makeReq(attempts) { + function makeReq() { const request = client.request({ ':path': '/foobar', ':method': 'GET', @@ -34,12 +34,14 @@ server.listen(0, common.mustCall(() => { request.end(); request.on('end', () => { - if (attempts) { - setTimeout(() => makeReq(attempts - 1), callTimeout); + const diff = process.hrtime(startTime); + const milliseconds = (diff[0] * 1e3 + diff[1] / 1e6); + if (milliseconds < serverTimeout * 2) { + setTimeout(makeReq, callTimeout); } else { server.removeListener('timeout', mustNotCall); - client.close(); server.close(); + client.close(); } }); } diff --git a/test/sequential/test-performance.js b/test/sequential/test-performance.js index ea7e17e18dbe99..c5065227a6a410 100644 --- a/test/sequential/test-performance.js +++ b/test/sequential/test-performance.js @@ -60,7 +60,9 @@ function checkNodeTiming(props) { const delta = performance.nodeTiming[prop] - props[prop].around; assert(Math.abs(delta) < 1000); } else { - assert.strictEqual(performance.nodeTiming[prop], props[prop]); + assert.strictEqual(performance.nodeTiming[prop], props[prop], + `mismatch for performance property ${prop}: ` + + `${performance.nodeTiming[prop]} vs ${props[prop]}`); } } } @@ -72,7 +74,7 @@ checkNodeTiming({ duration: { around: performance.now() }, nodeStart: { around: 0 }, v8Start: { around: 0 }, - bootstrapComplete: -1, + bootstrapComplete: { around: inited }, environment: { around: 0 }, loopStart: -1, loopExit: -1, diff --git a/test/sequential/test-timers-blocking-callback.js b/test/sequential/test-timers-blocking-callback.js index 22697cbd780238..435b69d1fa81b3 100644 --- a/test/sequential/test-timers-blocking-callback.js +++ b/test/sequential/test-timers-blocking-callback.js @@ -3,7 +3,7 @@ /* * This is a regression test for * https://github.com/nodejs/node-v0.x-archive/issues/15447 and - * and https://github.com/nodejs/node-v0.x-archive/issues/9333. + * https://github.com/nodejs/node-v0.x-archive/issues/9333. * * When a timer is added in another timer's callback, its underlying timer * handle was started with a timeout that was actually incorrect. diff --git a/tools/cpplint.py b/tools/cpplint.py index 460c1ecbfeb02f..ee103ef7161ba1 100644 --- a/tools/cpplint.py +++ b/tools/cpplint.py @@ -4230,6 +4230,10 @@ def CheckStyle(filename, clean_lines, linenum, file_extension, nesting_state, error(filename, linenum, 'whitespace/tab', 1, 'Tab found; better to use spaces') + if line.find('template<') != -1: + error(filename, linenum, 'whitespace/template', 1, + 'Leave a single space after template, as in `template <...>`') + # One or three blank spaces at the beginning of the line is weird; it's # hard to reconcile that with 2-space indents. # NOTE: here are the conditions rob pike used for his tests. Mine aren't diff --git a/tools/doc/common.js b/tools/doc/common.js index 553b52935fd709..813935f23b84f4 100644 --- a/tools/doc/common.js +++ b/tools/doc/common.js @@ -1,6 +1,7 @@ 'use strict'; -const yaml = require('js-yaml'); +const yaml = + require(`${__dirname}/../node_modules/eslint/node_modules/js-yaml`); function isYAMLBlock(text) { return /^/; - -// Customized heading without id attribute. +// Make `marked` to not automatically insert id attributes in headings. const renderer = new marked.Renderer(); -renderer.heading = function(text, level) { - return `${text}\n`; -}; -marked.setOptions({ - renderer: renderer -}); +renderer.heading = (text, level) => `${text}\n`; +marked.setOptions({ renderer }); const docPath = path.resolve(__dirname, '..', '..', 'doc'); @@ -47,91 +40,39 @@ const gtocPath = path.join(docPath, 'api', '_toc.md'); const gtocMD = fs.readFileSync(gtocPath, 'utf8').replace(/^@\/\/.*$/gm, ''); const gtocHTML = marked(gtocMD).replace( / ` ` type === 'heading'); + const section = firstHeading ? firstHeading.text : 'Index'; - parseText(lexed); - lexed = preprocessElements(lexed); - - // Generate the table of contents. - // This mutates the lexed contents in-place. - buildToc(lexed, filename, function(er, toc) { - if (er) return cb(er); - - const id = toID(path.basename(filename)); - - template = template.replace(/__ID__/g, id); - template = template.replace(/__FILENAME__/g, filename); - template = template.replace(/__SECTION__/g, section || 'Index'); - template = template.replace(/__VERSION__/g, nodeVersion); - template = template.replace(/__TOC__/g, toc); - template = template.replace( - /__GTOC__/g, - gtocHTML.replace(`class="nav-${id}`, `class="nav-${id} active`) - ); - - if (opts.analytics) { - template = template.replace( - '', - analyticsScript(opts.analytics) - ); - } + preprocessText(lexed); + preprocessElements(lexed, filename); - template = template.replace(/__ALTDOCS__/, altDocs(filename)); + // Generate the table of contents. This mutates the lexed contents in-place. + const toc = buildToc(lexed, filename); - // Content has to be the last thing we do with the lexed tokens, - // because it's destructive. - const content = marked.parser(lexed); - template = template.replace(/__CONTENT__/g, content); + const id = filename.replace(/\W+/g, '-'); - cb(null, template); - }); -} + let HTML = template.replace('__ID__', id) + .replace(/__FILENAME__/g, filename) + .replace('__SECTION__', section) + .replace(/__VERSION__/g, nodeVersion) + .replace('__TOC__', toc) + .replace('__GTOC__', gtocHTML.replace( + `class="nav-${id}`, `class="nav-${id} active`)); -function analyticsScript(analytics) { - return ` + if (analytics) { + HTML = HTML.replace('', ` - `; -} - -// Replace placeholders in text tokens. -function replaceInText(text) { - return linkJsTypeDocs(linkManPages(text)); -} - -function altDocs(filename) { - if (!docCreated) { - console.error(`Failed to add alternative version links to ${filename}`); - return ''; - } - - function lte(v) { - const ns = v.num.split('.'); - if (docCreated[1] > +ns[0]) - return false; - if (docCreated[1] < +ns[0]) - return true; - return docCreated[2] <= +ns[1]; + `); } - const versions = [ - { num: '10.x' }, - { num: '9.x' }, - { num: '8.x', lts: true }, - { num: '7.x' }, - { num: '6.x', lts: true }, - { num: '5.x' }, - { num: '4.x', lts: true }, - { num: '0.12.x' }, - { num: '0.10.x' } - ]; - - const host = 'https://nodejs.org'; - const href = (v) => `${host}/docs/latest-v${v.num}/api/${filename}.html`; - - function li(v) { - let html = `
  • ${v.num}`; - - if (v.lts) - html += ' LTS'; - - return html + '
  • '; + const docCreated = input.match( + //); + if (docCreated) { + HTML = HTML.replace('__ALTDOCS__', altDocs(filename, docCreated)); + } else { + console.error(`Failed to add alternative version links to ${filename}`); + HTML = HTML.replace('__ALTDOCS__', ''); } - const lis = versions.filter(lte).map(li).join('\n'); + // Content insertion has to be the last thing we do with the lexed tokens, + // because it's destructive. + HTML = HTML.replace('__CONTENT__', marked.parser(lexed)); - if (!lis.length) - return ''; - - return ` -
  • - View another version -
      ${lis}
    -
  • - `; + cb(null, HTML); } // Handle general body-text replacements. // For example, link man page references to the actual page. -function parseText(lexed) { - lexed.forEach(function(tok) { - if (tok.type === 'table') { - if (tok.cells) { - tok.cells.forEach((row, x) => { - row.forEach((_, y) => { - if (tok.cells[x] && tok.cells[x][y]) { - tok.cells[x][y] = replaceInText(tok.cells[x][y]); - } - }); - }); +function preprocessText(lexed) { + lexed.forEach((token) => { + if (token.type === 'table') { + if (token.header) { + token.header = token.header.map(replaceInText); } - if (tok.header) { - tok.header.forEach((_, i) => { - if (tok.header[i]) { - tok.header[i] = replaceInText(tok.header[i]); - } + if (token.cells) { + token.cells.forEach((row, i) => { + token.cells[i] = row.map(replaceInText); }); } - } else if (tok.text && tok.type !== 'code') { - tok.text = replaceInText(tok.text); + } else if (token.text && token.type !== 'code') { + token.text = replaceInText(token.text); } }); } +// Replace placeholders in text tokens. +function replaceInText(text) { + if (text === '') return text; + return linkJsTypeDocs(linkManPages(text)); +} + +// Syscalls which appear in the docs, but which only exist in BSD / macOS. +const BSD_ONLY_SYSCALLS = new Set(['lchmod']); +const MAN_PAGE = /(^|\s)([a-z.]+)\((\d)([a-z]?)\)/gm; + +// Handle references to man pages, eg "open(2)" or "lchmod(2)". +// Returns modified text, with such refs replaced with HTML links, for example +// 'open(2)'. +function linkManPages(text) { + return text.replace( + MAN_PAGE, (match, beginning, name, number, optionalCharacter) => { + // Name consists of lowercase letters, + // number is a single digit with an optional lowercase letter. + const displayAs = `${name}(${number}${optionalCharacter})`; + + if (BSD_ONLY_SYSCALLS.has(name)) { + return `${beginning}${displayAs}`; + } + return `${beginning}${displayAs}`; + }); +} + +const TYPE_SIGNATURE = /\{[^}]+\}/g; +function linkJsTypeDocs(text) { + const parts = text.split('`'); + + // Handle types, for example the source Markdown might say + // "This argument should be a {number} or {string}". + for (let i = 0; i < parts.length; i += 2) { + const typeMatches = parts[i].match(TYPE_SIGNATURE); + if (typeMatches) { + typeMatches.forEach((typeMatch) => { + parts[i] = parts[i].replace(typeMatch, typeParser.toLink(typeMatch)); + }); + } + } + + return parts.join('`'); +} + // Preprocess stability blockquotes and YAML blocks. -function preprocessElements(input) { - var state = null; - const output = []; +function preprocessElements(lexed, filename) { + const STABILITY_RE = /(.*:)\s*(\d)([\s\S]*)/; + let state = null; let headingIndex = -1; let heading = null; - output.links = input.links; - input.forEach(function(tok, index) { - if (tok.type === 'heading') { + lexed.forEach((token, index) => { + if (token.type === 'heading') { headingIndex = index; - heading = tok; + heading = token; } - if (tok.type === 'html' && common.isYAMLBlock(tok.text)) { - tok.text = parseYAML(tok.text); + if (token.type === 'html' && common.isYAMLBlock(token.text)) { + token.text = parseYAML(token.text); } - if (tok.type === 'blockquote_start') { + if (token.type === 'blockquote_start') { state = 'MAYBE_STABILITY_BQ'; - return; + lexed[index] = { type: 'space' }; } - if (tok.type === 'blockquote_end' && state === 'MAYBE_STABILITY_BQ') { + if (token.type === 'blockquote_end' && state === 'MAYBE_STABILITY_BQ') { state = null; - return; + lexed[index] = { type: 'space' }; } - if ((tok.type === 'paragraph' && state === 'MAYBE_STABILITY_BQ') || - tok.type === 'code') { - if (tok.text.match(/Stability:.*/g)) { - const stabilityMatch = tok.text.match(STABILITY_TEXT_REG_EXP); - const stability = Number(stabilityMatch[2]); + if (token.type === 'paragraph' && state === 'MAYBE_STABILITY_BQ') { + if (token.text.includes('Stability:')) { + const [, prefix, number, explication] = token.text.match(STABILITY_RE); const isStabilityIndex = index - 2 === headingIndex || // General. index - 3 === headingIndex; // With api_metadata block. if (heading && isStabilityIndex) { - heading.stability = stability; + heading.stability = number; headingIndex = -1; heading = null; } - tok.text = parseAPIHeader(tok.text).replace(/\n/g, ' '); - output.push({ type: 'html', text: tok.text }); - return; + + // Do not link to the section we are already in. + const noLinking = filename === 'documentation' && + heading !== null && heading.text === 'Stability Index'; + token.text = `
    ` + + (noLinking ? '' : + '') + + `${prefix} ${number}${noLinking ? '' : ''}${explication}
    ` + .replace(/\n/g, ' '); + + lexed[index] = { type: 'html', text: token.text }; } else if (state === 'MAYBE_STABILITY_BQ') { - output.push({ type: 'blockquote_start' }); state = null; + lexed[index - 1] = { type: 'blockquote_start' }; } } - output.push(tok); }); - - return output; } function parseYAML(text) { const meta = common.extractAndParseYAML(text); - const html = [''; + return html; } -function parseAPIHeader(text) { - const classNames = 'api_stability api_stability_$2'; - const docsUrl = 'documentation.html#documentation_stability_index'; - - text = text.replace( - STABILITY_TEXT_REG_EXP, - `` - ); - return text; -} - -// Section is just the first heading. -function getSection(lexed) { - for (var i = 0, l = lexed.length; i < l; i++) { - var tok = lexed[i]; - if (tok.type === 'heading') return tok.text; - } - return ''; -} - -function getMark(anchor) { - return `#`; +const numberRe = /^\d*/; +function versionSort(a, b) { + a = a.trim(); + b = b.trim(); + let i = 0; // Common prefix length. + while (i < a.length && i < b.length && a[i] === b[i]) i++; + a = a.substr(i); + b = b.substr(i); + return +b.match(numberRe)[0] - +a.match(numberRe)[0]; } -function buildToc(lexed, filename, cb) { - var toc = []; - var depth = 0; - +function buildToc(lexed, filename) { const startIncludeRefRE = /^\s*\s*$/; - const endIncludeRefRE = /^\s*\s*$/; + const endIncludeRefRE = /^\s*\s*$/; const realFilenames = [filename]; - - lexed.forEach(function(tok) { - // Keep track of the current filename along @include directives. - if (tok.type === 'html') { - let match; - if ((match = tok.text.match(startIncludeRefRE)) !== null) - realFilenames.unshift(match[1]); - else if (tok.text.match(endIncludeRefRE)) + const idCounters = Object.create(null); + let toc = ''; + let depth = 0; + + lexed.forEach((token) => { + // Keep track of the current filename along comment wrappers of inclusions. + if (token.type === 'html') { + const [, includedFileName] = token.text.match(startIncludeRefRE) || []; + if (includedFileName !== undefined) + realFilenames.unshift(includedFileName); + else if (endIncludeRefRE.test(token.text)) realFilenames.shift(); } - if (tok.type !== 'heading') return; - if (tok.depth - depth > 1) { - return cb(new Error('Inappropriate heading level\n' + - JSON.stringify(tok))); + if (token.type !== 'heading') return; + + if (token.depth - depth > 1) { + throw new Error(`Inappropriate heading level:\n${JSON.stringify(token)}`); } - depth = tok.depth; + depth = token.depth; const realFilename = path.basename(realFilenames[0], '.md'); - const apiName = tok.text.trim(); - const id = getId(`${realFilename}_${apiName}`); - toc.push(new Array((depth - 1) * 2 + 1).join(' ') + - `* ` + - `${tok.text}`); - tok.text += getMark(id); - if (realFilename === 'errors' && apiName.startsWith('ERR_')) { - tok.text += getMark(apiName); + const headingText = token.text.trim(); + const id = getId(`${realFilename}_${headingText}`, idCounters); + + const hasStability = token.stability !== undefined; + toc += ' '.repeat((depth - 1) * 2) + + (hasStability ? `* ` : '* ') + + `${token.text}${hasStability ? '' : ''}\n`; + + token.text += `#`; + if (realFilename === 'errors' && headingText.startsWith('ERR_')) { + token.text += `#`; } }); - toc = marked.parse(toc.join('\n')); - cb(null, toc); + return marked(toc); } -const idCounters = {}; -function getId(text) { - text = text.toLowerCase(); - text = text.replace(/[^a-z0-9]+/g, '_'); - text = text.replace(/^_+|_+$/, ''); - text = text.replace(/^([^a-z])/, '_$1'); - if (idCounters.hasOwnProperty(text)) { - text += `_${++idCounters[text]}`; - } else { - idCounters[text] = 0; +const notAlphaNumerics = /[^a-z0-9]+/g; +const edgeUnderscores = /^_+|_+$/g; +const notAlphaStart = /^[^a-z]/; +function getId(text, idCounters) { + text = text.toLowerCase() + .replace(notAlphaNumerics, '_') + .replace(edgeUnderscores, '') + .replace(notAlphaStart, '_$&'); + if (idCounters[text] !== undefined) { + return `${text}_${++idCounters[text]}`; } + idCounters[text] = 0; return text; } -const numberRe = /^(\d*)/; -function versionSort(a, b) { - a = a.trim(); - b = b.trim(); - let i = 0; // Common prefix length. - while (i < a.length && i < b.length && a[i] === b[i]) i++; - a = a.substr(i); - b = b.substr(i); - return +b.match(numberRe)[1] - +a.match(numberRe)[1]; +function altDocs(filename, docCreated) { + const [, docCreatedMajor, docCreatedMinor] = docCreated.map(Number); + const host = 'https://nodejs.org'; + const versions = [ + { num: '10.x' }, + { num: '9.x' }, + { num: '8.x', lts: true }, + { num: '7.x' }, + { num: '6.x', lts: true }, + { num: '5.x' }, + { num: '4.x', lts: true }, + { num: '0.12.x' }, + { num: '0.10.x' } + ]; + + const getHref = (versionNum) => + `${host}/docs/latest-v${versionNum}/api/${filename}.html`; + + const wrapInListItem = (version) => + `
  • ${version.num}` + + `${version.lts ? ' LTS' : ''}
  • `; + + function isDocInVersion(version) { + const [versionMajor, versionMinor] = version.num.split('.').map(Number); + if (docCreatedMajor > versionMajor) return false; + if (docCreatedMajor < versionMajor) return true; + return docCreatedMinor <= versionMinor; + } + + const list = versions.filter(isDocInVersion).map(wrapInListItem).join('\n'); + + return list ? ` +
  • + View another version +
      ${list}
    +
  • + ` : ''; } diff --git a/tools/doc/node_modules/js-yaml/index.js b/tools/doc/node_modules/js-yaml/index.js deleted file mode 100644 index 476b3a0d487c4a..00000000000000 --- a/tools/doc/node_modules/js-yaml/index.js +++ /dev/null @@ -1,16 +0,0 @@ -'use strict'; - -// Hack to load the js-yaml module from eslint. -// No other reason than that it’s huge. - -const path = require('path'); - -const realJSYaml = path.resolve( - __dirname, '..', '..', '..', // tools/ - 'node_modules', - 'eslint', - 'node_modules', - 'js-yaml' -); - -module.exports = require(realJSYaml); diff --git a/tools/eslint-rules/require-buffer.js b/tools/eslint-rules/require-buffer.js deleted file mode 100644 index b12b9ce04e7cfc..00000000000000 --- a/tools/eslint-rules/require-buffer.js +++ /dev/null @@ -1,35 +0,0 @@ -'use strict'; -const BUFFER_REQUIRE = 'const { Buffer } = require(\'buffer\');'; - -module.exports = function(context) { - - function flagIt(reference) { - const msg = `Use ${BUFFER_REQUIRE} at the beginning of this file`; - - context.report({ - node: reference.identifier, - message: msg, - fix: (fixer) => { - const sourceCode = context.getSourceCode(); - - const useStrict = /'use strict';\n\n?/g; - const hasUseStrict = !!useStrict.exec(sourceCode.text); - const firstLOC = sourceCode.ast.range[0]; - const rangeNeedle = hasUseStrict ? useStrict.lastIndex : firstLOC; - - return fixer.insertTextBeforeRange([rangeNeedle], - `${BUFFER_REQUIRE}\n`); - } - }); - } - - return { - 'Program:exit': function() { - const globalScope = context.getScope(); - const variable = globalScope.set.get('Buffer'); - if (variable) { - variable.references.forEach(flagIt); - } - } - }; -}; diff --git a/tools/eslint-rules/require-globals.js b/tools/eslint-rules/require-globals.js new file mode 100644 index 00000000000000..bc49ff6c8746ed --- /dev/null +++ b/tools/eslint-rules/require-globals.js @@ -0,0 +1,50 @@ +'use strict'; + +// This rule makes sure that no Globals are going to be used in /lib. +// That could otherwise result in problems with the repl. + +module.exports = function(context) { + + function flagIt(msg, fix) { + return (reference) => { + context.report({ + node: reference.identifier, + message: msg, + fix: (fixer) => { + const sourceCode = context.getSourceCode(); + + const useStrict = /'use strict';\n\n?/g; + const hasUseStrict = !!useStrict.exec(sourceCode.text); + const firstLOC = sourceCode.ast.range[0]; + const rangeNeedle = hasUseStrict ? useStrict.lastIndex : firstLOC; + + return fixer.insertTextBeforeRange([rangeNeedle], `${fix}\n`); + } + }); + }; + } + + return { + 'Program:exit': function() { + const globalScope = context.getScope(); + let variable = globalScope.set.get('Buffer'); + if (variable) { + const fix = "const { Buffer } = require('buffer');"; + const msg = `Use ${fix} at the beginning of this file`; + variable.references.forEach(flagIt(msg, fix)); + } + variable = globalScope.set.get('URL'); + if (variable) { + const fix = "const { URL } = require('url');"; + const msg = `Use ${fix} at the beginning of this file`; + variable.references.forEach(flagIt(msg, fix)); + } + variable = globalScope.set.get('URLSearchParams'); + if (variable) { + const fix = "const { URLSearchParams } = require('url');"; + const msg = `Use ${fix} at the beginning of this file`; + variable.references.forEach(flagIt(msg, fix)); + } + } + }; +}; diff --git a/tools/gyp/pylib/gyp/MSVSSettings.py b/tools/gyp/pylib/gyp/MSVSSettings.py index 8ae19180ea271b..99c53a857008cc 100644 --- a/tools/gyp/pylib/gyp/MSVSSettings.py +++ b/tools/gyp/pylib/gyp/MSVSSettings.py @@ -417,7 +417,7 @@ def FixVCMacroSlashes(s): def ConvertVCMacrosToMSBuild(s): - """Convert the the MSVS macros found in the string to the MSBuild equivalent. + """Convert the MSVS macros found in the string to the MSBuild equivalent. This list is probably not exhaustive. Add as needed. """ diff --git a/tools/gyp/pylib/gyp/generator/make.py b/tools/gyp/pylib/gyp/generator/make.py index f7f519b3e6b848..5870ed67be5fe2 100644 --- a/tools/gyp/pylib/gyp/generator/make.py +++ b/tools/gyp/pylib/gyp/generator/make.py @@ -19,7 +19,7 @@ # # Global settings and utility functions are currently stuffed in the # toplevel Makefile. It may make sense to generate some .mk files on -# the side to keep the the files readable. +# the side to keep the files readable. import os import re diff --git a/tools/gyp/pylib/gyp/generator/ninja.py b/tools/gyp/pylib/gyp/generator/ninja.py index 163281b3e3f12b..6140df9513096c 100644 --- a/tools/gyp/pylib/gyp/generator/ninja.py +++ b/tools/gyp/pylib/gyp/generator/ninja.py @@ -140,7 +140,7 @@ def __init__(self, type): # On Windows, incremental linking requires linking against all the .objs # that compose a .lib (rather than the .lib itself). That list is stored # here. In this case, we also need to save the compile_deps for the target, - # so that the the target that directly depends on the .objs can also depend + # so that the target that directly depends on the .objs can also depend # on those. self.component_objs = None self.compile_deps = None diff --git a/tools/js2c.py b/tools/js2c.py index bcfc4764a97df5..8685722c13cdc5 100755 --- a/tools/js2c.py +++ b/tools/js2c.py @@ -183,8 +183,12 @@ def ReadMacros(lines): namespace node {{ +namespace {{ + {definitions} +}} // anonymous namespace + v8::Local LoadersBootstrapperSource(Environment* env) {{ return internal_bootstrap_loaders_value.ToStringChecked(env->isolate()); }} diff --git a/tools/macosx-firewall.sh b/tools/macos-firewall.sh similarity index 100% rename from tools/macosx-firewall.sh rename to tools/macos-firewall.sh diff --git a/tools/msvs/msi/i18n/en-us.wxl b/tools/msvs/msi/i18n/en-us.wxl index fd23724b562990..86da6ecc40ecaf 100644 --- a/tools/msvs/msi/i18n/en-us.wxl +++ b/tools/msvs/msi/i18n/en-us.wxl @@ -22,7 +22,7 @@ Install npm, the recommended package manager for [ProductName]. Online documentation shortcuts - Add start menu entries that link the the online documentation for [ProductName] [FullVersion] and the [ProductName] website. + Add start menu entries that link the online documentation for [ProductName] [FullVersion] and the [ProductName] website. Add to PATH Add [ProductName], npm, and modules that were globally installed by npm to the PATH environment variable. diff --git a/tools/remark-cli/package-lock.json b/tools/remark-cli/package-lock.json index e47a22823d9e8f..bf869643901f2c 100644 --- a/tools/remark-cli/package-lock.json +++ b/tools/remark-cli/package-lock.json @@ -2,7 +2,6 @@ "name": "remark-cli", "version": "4.0.0", "lockfileVersion": 1, - "preserveSymlinks": "1", "requires": true, "dependencies": { "ansi-regex": { @@ -11,9 +10,9 @@ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "requires": { "color-convert": "1.9.1" } @@ -28,9 +27,9 @@ } }, "argparse": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", - "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "requires": { "sprintf-js": "1.0.3" } @@ -49,9 +48,9 @@ "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" }, "array-iterate": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-1.1.1.tgz", - "integrity": "sha1-hlv3+K851rCYLGCQKRSsdrwBCPY=" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-1.1.2.tgz", + "integrity": "sha512-1hWSHTIlG/8wtYD+PPX5AOBtKWngpDFjrsrHgZpe+JdgNGz0udYu6ZIkAa/xuenIUEqFv7DvE2Yr60jxweJSrQ==" }, "array-unique": { "version": "0.2.1", @@ -64,9 +63,9 @@ "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=" }, "bail": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.2.tgz", - "integrity": "sha1-99bBcxYwqfnw1NNe0fli4gdKF2Q=" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.3.tgz", + "integrity": "sha512-1X8CnjFVQ+a+KW36uBNMTU5s8+v5FzeqrP7hTG5aTb4aPreSbZJlhwPon9VKMuEVgV++JM+SQrALY3kr7eswdg==" }, "balanced-match": { "version": "1.0.0", @@ -74,14 +73,14 @@ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "binary-extensions": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.10.0.tgz", - "integrity": "sha1-muuabF6IY4qtFx4Wf1kAq+JINdA=" + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", + "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=" }, "brace-expansion": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", - "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "requires": { "balanced-match": "1.0.0", "concat-map": "0.0.1" @@ -97,45 +96,50 @@ "repeat-element": "1.1.2" } }, + "buffer-from": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.0.0.tgz", + "integrity": "sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA==" + }, "camelcase": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" }, "ccount": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.0.2.tgz", - "integrity": "sha1-U7ai+BW7d7nChx97mnLDol8djok=" + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.0.3.tgz", + "integrity": "sha512-Jt9tIBkRc9POUof7QA/VwWd+58fKkEEfI+/t1/eOlxKM7ZhrczNzMFefge7Ai+39y1pR/pP6cI19guHy3FSLmw==" }, "chalk": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "requires": { - "ansi-styles": "3.2.0", + "ansi-styles": "3.2.1", "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" + "supports-color": "5.4.0" } }, "character-entities": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.1.tgz", - "integrity": "sha1-92hxvl72bdt/j440eOzDdMJ9bco=" + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.2.tgz", + "integrity": "sha512-sMoHX6/nBiy3KKfC78dnEalnpn0Az0oSNvqUWYTtYrhRI5iUIYsROU48G+E+kMFQzqXaJ8kHJZ85n7y6/PHgwQ==" }, "character-entities-html4": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.1.tgz", - "integrity": "sha1-NZoqSg9+KdPcKsmb2+Ie45Q46lA=" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.2.tgz", + "integrity": "sha512-sIrXwyna2+5b0eB9W149izTPJk/KkJTg6mEzDGibwBUkyH1SbDa+nf515Ppdi3MaH35lW0JFJDWeq9Luzes1Iw==" }, "character-entities-legacy": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.1.tgz", - "integrity": "sha1-9Ad53xoQGHK7UQo9KV4fzPFHIC8=" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.2.tgz", + "integrity": "sha512-9NB2VbXtXYWdXzqrvAHykE/f0QJxzaKIpZ5QzNZrrgQ7Iyxr2vnfS8fCBNVW9nUEZE0lo57nxKRqnzY/dKrwlA==" }, "character-reference-invalid": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.1.tgz", - "integrity": "sha1-lCg191Dk7GGjCOYMLvjMEBEgLvw=" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.2.tgz", + "integrity": "sha512-7I/xceXfKyUJmSAn/jw8ve/9DyOP7XxufNYLI9Px7CmsKgEUaZLUTax6nZxGQtaoiZCjpu6cHPj20xC/vqRReQ==" }, "chokidar": { "version": "1.7.0", @@ -158,9 +162,9 @@ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, "collapse-white-space": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.3.tgz", - "integrity": "sha1-S5BvZw5aljqHt2sOFolkM0G2Ajw=" + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.4.tgz", + "integrity": "sha512-YfQ1tAUZm561vpYD+5eyWN8+UsceQbSrqqlc/6zDY2gtAE+uZLSdkkovhnGpmCThsvKBFakq4EdY/FF93E8XIw==" }, "color-convert": { "version": "1.9.1", @@ -181,12 +185,13 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "concat-stream": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", - "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "requires": { + "buffer-from": "1.0.0", "inherits": "2.0.3", - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "typedarray": "0.0.6" } }, @@ -204,9 +209,9 @@ } }, "deep-extend": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", - "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=" + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.5.1.tgz", + "integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==" }, "error-ex": { "version": "1.3.1", @@ -239,7 +244,7 @@ "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", "requires": { - "fill-range": "2.2.3" + "fill-range": "2.2.4" } }, "extend": { @@ -256,9 +261,9 @@ } }, "fault": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.1.tgz", - "integrity": "sha1-3o01Df1IviS13BsChn4IcbkTUJI=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/fault/-/fault-1.0.2.tgz", + "integrity": "sha512-o2eo/X2syzzERAtN5LcGbiVQ0WwZSlN3qLtadwAz3X8Bu+XWD16dja/KMsjZLiQr+BLGPDnHGkc4yUJf1Xpkpw==", "requires": { "format": "0.2.2" } @@ -269,13 +274,13 @@ "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=" }, "fill-range": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", - "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", + "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", "requires": { "is-number": "2.1.0", "isobject": "2.1.0", - "randomatic": "1.1.7", + "randomatic": "3.0.0", "repeat-element": "1.1.2", "repeat-string": "1.6.1" } @@ -344,14 +349,14 @@ "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" }, "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, "ignore": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", - "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==" + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.8.tgz", + "integrity": "sha512-pUh+xUQQhQzevjRHHFqqcTy0/dP/kS9I8HSrUydhihjuD09W6ldVWFtIrwhXdUJHis3i2rZNqEHpZH/cbinFbg==" }, "inflight": { "version": "1.0.6", @@ -368,14 +373,14 @@ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "ini": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", - "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=" + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" }, "is-alphabetical": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.1.tgz", - "integrity": "sha1-x3B5zJHU76x3W+EDS/LSQ/lebwg=" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.2.tgz", + "integrity": "sha512-V0xN4BYezDHcBSKb1QHUFMlR4as/XEuCZBzMJUU4n7+Cbt33SmUnSol+pnXFvLxSHNq2CemUXNdaXV6Flg7+xg==" }, "is-alphanumeric": { "version": "1.0.0", @@ -383,12 +388,12 @@ "integrity": "sha1-Spzvcdr0wAHB2B1j0UDPU/1oifQ=" }, "is-alphanumerical": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.1.tgz", - "integrity": "sha1-37SqTRCF4zvbYcLe6cgOnGwZ9Ts=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.2.tgz", + "integrity": "sha512-pyfU/0kHdISIgslFfZN9nfY1Gk3MquQgUm1mJTjdkEPpkAKNWuBTSqFwewOpR7N351VkErCiyV71zX7mlQQqsg==", "requires": { - "is-alphabetical": "1.0.1", - "is-decimal": "1.0.1" + "is-alphabetical": "1.0.2", + "is-decimal": "1.0.2" } }, "is-arrayish": { @@ -401,7 +406,7 @@ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "requires": { - "binary-extensions": "1.10.0" + "binary-extensions": "1.11.0" } }, "is-buffer": { @@ -410,9 +415,9 @@ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, "is-decimal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.1.tgz", - "integrity": "sha1-9ftqlJlq2ejjdh+/vQkfH8qMToI=" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.2.tgz", + "integrity": "sha512-TRzl7mOCchnhchN+f3ICUCzYvL9ul7R+TYOsZ8xia++knyZAJfv/uA1FvQXsAnYIl1T3B2X5E/J7Wb1QXiIBXg==" }, "is-dotfile": { "version": "1.0.3", @@ -459,9 +464,9 @@ } }, "is-hexadecimal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.1.tgz", - "integrity": "sha1-bghLvJIGH7sJcexYts5tQE4k2mk=" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.2.tgz", + "integrity": "sha512-but/G3sapV3MNyqiDBLrOi4x8uCIw0RY3o/Vb5GT0sMFHrVV7731wFSVy41T5FO1og7G0gXLJh0MkgPRouko/A==" }, "is-hidden": { "version": "1.1.1", @@ -497,14 +502,14 @@ "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" }, "is-whitespace-character": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.1.tgz", - "integrity": "sha1-muAXbzKCtlRXoZks2whPil+DPjs=" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.2.tgz", + "integrity": "sha512-SzM+T5GKUCtLhlHFKt2SDAX2RFzfS6joT91F2/WSi9LxgFdsnhfPK/UIA+JhRR2xuyLdrCys2PiFDrtn1fU5hQ==" }, "is-word-character": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.1.tgz", - "integrity": "sha1-WgP6HqkazopusMfNdw64bWXIvvs=" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.2.tgz", + "integrity": "sha512-T3FlsX8rCHAH8e7RE7PfOPZVFQlcV3XRF9eOOBQ1uf70OxO7CjjSOjeImMPCADBdYWcStAbVbYvJ1m2D3tb+EA==" }, "isarray": { "version": "1.0.0", @@ -520,11 +525,11 @@ } }, "js-yaml": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", - "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz", + "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==", "requires": { - "argparse": "1.0.9", + "argparse": "1.0.10", "esprima": "4.0.0" } }, @@ -537,12 +542,12 @@ } }, "load-plugin": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/load-plugin/-/load-plugin-2.2.1.tgz", - "integrity": "sha512-raqInsJNdPGpzZyb+FjjJYmXsjIm8fIiOjOmqmUTGPyCXDMeEK3p4x4Xm1ZCNp43UmfDTWvo7pZkB2fKbD5AAA==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/load-plugin/-/load-plugin-2.2.2.tgz", + "integrity": "sha512-FYzamtURIJefQykZGtiClYuZkJBUKzmx8Tc74y8JGAulDzbzVm/C+w/MbAljHRr+REL0cRzy3WgnHE+T8gce5g==", "requires": { "npm-prefix": "1.2.0", - "resolve-from": "2.0.0" + "resolve-from": "4.0.0" } }, "longest-streak": { @@ -551,27 +556,32 @@ "integrity": "sha512-TmYTeEYxiAmSVdpbnQDXGtvYOIRsCMg89CVZzwzc2o7GFL1CjoiRPjH5ec0NFAVlAx3fVof9dX/t6KKRAo2OWA==" }, "markdown-escapes": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.1.tgz", - "integrity": "sha1-GZTfLTr0gR3lmmcUk0wrIpJzRRg=" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.2.tgz", + "integrity": "sha512-lbRZ2mE3Q9RtLjxZBZ9+IMl68DKIXaVAhwvwn9pmjnPLS0h/6kyBMgNhqi1xFJ/2yv6cSyv0jbiZavZv93JkkA==" }, "markdown-extensions": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-1.1.0.tgz", - "integrity": "sha1-+6Dxouu09BI9JbepO8NXksEfUE4=" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-1.1.1.tgz", + "integrity": "sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q==" }, "markdown-table": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.1.tgz", - "integrity": "sha1-Sz3ToTPRUYuO8NvHCb8qG0gkvIw=" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.2.tgz", + "integrity": "sha512-NcWuJFHDA8V3wkDgR/j4+gZx+YQwstPgfQDV8ndUeWWzta3dnDTBxpVzqS9lkmJAuV5YX35lmyojl6HO5JXAgw==" + }, + "math-random": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz", + "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=" }, "mdast-util-compact": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mdast-util-compact/-/mdast-util-compact-1.0.1.tgz", "integrity": "sha1-zbX4TitqLTEU3zO9BdnLMuPECDo=", "requires": { - "unist-util-modify-children": "1.1.1", - "unist-util-visit": "1.1.3" + "unist-util-modify-children": "1.1.2", + "unist-util-visit": "1.3.1" } }, "micromatch": { @@ -599,7 +609,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "requires": { - "brace-expansion": "1.1.8" + "brace-expansion": "1.1.11" } }, "minimist": { @@ -625,7 +635,7 @@ "resolved": "https://registry.npmjs.org/npm-prefix/-/npm-prefix-1.2.0.tgz", "integrity": "sha1-5hlFX3B0ulTMZtbQ033Z8b5ry8A=", "requires": { - "rc": "1.2.2", + "rc": "1.2.7", "shellsubstitute": "1.2.0", "untildify": "2.1.0" } @@ -658,16 +668,16 @@ "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" }, "parse-entities": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.1.1.tgz", - "integrity": "sha1-gRLYhHExnyerrk1klksSL+ThuJA=", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.1.2.tgz", + "integrity": "sha512-5N9lmQ7tmxfXf+hO3X6KRG6w7uYO/HL9fHalSySTdyn63C3WNvTM/1R8tn1u1larNcEbo3Slcy2bsVDQqvEpUg==", "requires": { - "character-entities": "1.2.1", - "character-entities-legacy": "1.1.1", - "character-reference-invalid": "1.1.1", - "is-alphanumerical": "1.0.1", - "is-decimal": "1.0.1", - "is-hexadecimal": "1.0.1" + "character-entities": "1.2.2", + "character-entities-legacy": "1.1.2", + "character-reference-invalid": "1.1.2", + "is-alphanumerical": "1.0.2", + "is-decimal": "1.0.2", + "is-hexadecimal": "1.0.2" } }, "parse-glob": { @@ -700,69 +710,54 @@ "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=" }, "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" }, "randomatic": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", - "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.0.0.tgz", + "integrity": "sha512-VdxFOIEY3mNO5PtSRkkle/hPJDHvQhK21oa73K4yAc9qmp6N429gAyF1gZMOTMeS0/AYzaV/2Trcef+NaIonSA==", "requires": { - "is-number": "3.0.0", - "kind-of": "4.0.0" + "is-number": "4.0.0", + "kind-of": "6.0.2", + "math-random": "1.0.1" }, "dependencies": { "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "1.1.6" - } - } - } + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==" }, "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "requires": { - "is-buffer": "1.1.6" - } + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" } } }, "rc": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.2.tgz", - "integrity": "sha1-2M6ctX6NZNnHut2YdsfDTL48cHc=", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.7.tgz", + "integrity": "sha512-LdLD8xD4zzLsAT5xyushXDNscEjB7+2ulnl8+r1pnESlYtlJtVSoCMBGr30eDRJ3+2Gq89jK9P9e4tCEH1+ywA==", "requires": { - "deep-extend": "0.4.2", - "ini": "1.3.4", + "deep-extend": "0.5.1", + "ini": "1.3.5", "minimist": "1.2.0", "strip-json-comments": "2.0.1" } }, "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "requires": { "core-util-is": "1.0.2", "inherits": "2.0.3", "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.2", + "string_decoder": "1.1.1", "util-deprecate": "1.0.2" } }, @@ -773,7 +768,7 @@ "requires": { "graceful-fs": "4.1.11", "minimatch": "3.0.4", - "readable-stream": "2.3.3", + "readable-stream": "2.3.6", "set-immediate-shim": "1.0.1" } }, @@ -792,7 +787,7 @@ "requires": { "remark-parse": "4.0.0", "remark-stringify": "4.0.0", - "unified": "6.1.5" + "unified": "6.2.0" } }, "remark-parse": { @@ -800,20 +795,20 @@ "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-4.0.0.tgz", "integrity": "sha512-XZgICP2gJ1MHU7+vQaRM+VA9HEL3X253uwUM/BGgx3iv6TH2B3bF3B8q00DKcyP9YrJV+/7WOWEWBFF/u8cIsw==", "requires": { - "collapse-white-space": "1.0.3", - "is-alphabetical": "1.0.1", - "is-decimal": "1.0.1", - "is-whitespace-character": "1.0.1", - "is-word-character": "1.0.1", - "markdown-escapes": "1.0.1", - "parse-entities": "1.1.1", + "collapse-white-space": "1.0.4", + "is-alphabetical": "1.0.2", + "is-decimal": "1.0.2", + "is-whitespace-character": "1.0.2", + "is-word-character": "1.0.2", + "markdown-escapes": "1.0.2", + "parse-entities": "1.1.2", "repeat-string": "1.6.1", - "state-toggle": "1.0.0", + "state-toggle": "1.0.1", "trim": "0.0.1", - "trim-trailing-lines": "1.1.0", - "unherit": "1.1.0", - "unist-util-remove-position": "1.1.1", - "vfile-location": "2.0.2", + "trim-trailing-lines": "1.1.1", + "unherit": "1.1.1", + "unist-util-remove-position": "1.1.2", + "vfile-location": "2.0.3", "xtend": "4.0.1" } }, @@ -822,19 +817,19 @@ "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-4.0.0.tgz", "integrity": "sha512-xLuyKTnuQer3ke9hkU38SUYLiTmS078QOnoFavztmbt/pAJtNSkNtFgR0U//uCcmG0qnyxao+PDuatQav46F1w==", "requires": { - "ccount": "1.0.2", + "ccount": "1.0.3", "is-alphanumeric": "1.0.0", - "is-decimal": "1.0.1", - "is-whitespace-character": "1.0.1", + "is-decimal": "1.0.2", + "is-whitespace-character": "1.0.2", "longest-streak": "2.0.2", - "markdown-escapes": "1.0.1", - "markdown-table": "1.1.1", + "markdown-escapes": "1.0.2", + "markdown-table": "1.1.2", "mdast-util-compact": "1.0.1", - "parse-entities": "1.1.1", + "parse-entities": "1.1.2", "repeat-string": "1.6.1", - "state-toggle": "1.0.0", - "stringify-entities": "1.3.1", - "unherit": "1.1.0", + "state-toggle": "1.0.1", + "stringify-entities": "1.3.2", + "unherit": "1.1.1", "xtend": "4.0.1" } }, @@ -859,14 +854,14 @@ "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=" }, "resolve-from": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", - "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" }, "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, "set-immediate-shim": { "version": "1.0.1", @@ -884,9 +879,9 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, "state-toggle": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.0.tgz", - "integrity": "sha1-0g+aYWu08MO5i5GSLSW2QKorxCU=" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.1.tgz", + "integrity": "sha512-Qe8QntFrrpWTnHwvwj2FZTgv+PKIsp0B9VxLzLLbSpPXWOgRgc5LVj/aTiSfK1RqIeF9jeC1UeOH8Q8y60A7og==" }, "string-width": { "version": "1.0.2", @@ -899,22 +894,22 @@ } }, "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "requires": { - "safe-buffer": "5.1.1" + "safe-buffer": "5.1.2" } }, "stringify-entities": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-1.3.1.tgz", - "integrity": "sha1-sVDsLXKsTBtfMktR+2soyc3/BYw=", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-1.3.2.tgz", + "integrity": "sha512-nrBAQClJAPN2p+uGCVJRPIPakKeKWZ9GtBCmormE7pWOSlHat7+x5A8gx85M7HM5Dt0BP3pP5RhVW77WdbJJ3A==", "requires": { - "character-entities-html4": "1.1.1", - "character-entities-legacy": "1.1.1", - "is-alphanumerical": "1.0.1", - "is-hexadecimal": "1.0.1" + "character-entities-html4": "1.1.2", + "character-entities-legacy": "1.1.2", + "is-alphanumerical": "1.0.2", + "is-hexadecimal": "1.0.2" } }, "strip-ansi": { @@ -931,11 +926,11 @@ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" }, "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "requires": { - "has-flag": "2.0.0" + "has-flag": "3.0.0" } }, "text-table": { @@ -944,12 +939,13 @@ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" }, "to-vfile": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/to-vfile/-/to-vfile-2.1.2.tgz", - "integrity": "sha512-o8o2CXU2LDxh4OsvG9bGRXkIhcvk+bWKqWQECLcjfMNy2b8rl4kuFAZeTcPM5obK1mrvQ4iS3AcdopFDluq1jQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/to-vfile/-/to-vfile-2.2.0.tgz", + "integrity": "sha512-saGC8/lWdGrEoBMLUtgzhRHWAkQMP8gdldA3MOAUhBwTGEb1RSMVcflHGSx4ZJsdEZ9o1qDBCPp47LCPrbZWow==", "requires": { "is-buffer": "1.1.6", - "vfile": "2.2.0" + "vfile": "2.3.0", + "x-is-function": "1.0.4" } }, "trim": { @@ -958,14 +954,14 @@ "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=" }, "trim-trailing-lines": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.0.tgz", - "integrity": "sha1-eu+7eAjfnWafbaLkOMrIxGradoQ=" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.1.tgz", + "integrity": "sha512-bWLv9BbWbbd7mlqqs2oQYnLD/U/ZqeJeJwbO0FG2zA1aTq+HTvxfHNKFa/HGCVyJpDiioUYaBhfiT6rgk+l4mg==" }, "trough": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.1.tgz", - "integrity": "sha1-qf2LA5Swro//guBjOgo2zK1bX4Y=" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.2.tgz", + "integrity": "sha512-FHkoUZvG6Egrv9XZAyYGKEyb1JMsFphgPjoczkZC2y6W93U1jswcVURB8MUvtsahEPEVACyxD47JAL63vF4JsQ==" }, "typedarray": { "version": "0.0.6", @@ -973,25 +969,24 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, "unherit": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.0.tgz", - "integrity": "sha1-a5qu379z3xdWrZ4xbdmBiFhAzX0=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.1.tgz", + "integrity": "sha512-+XZuV691Cn4zHsK0vkKYwBEwB74T3IZIcxrgn2E4rKwTfFyI1zCh7X7grwh9Re08fdPlarIdyWgI8aVB3F5A5g==", "requires": { "inherits": "2.0.3", "xtend": "4.0.1" } }, "unified": { - "version": "6.1.5", - "resolved": "https://registry.npmjs.org/unified/-/unified-6.1.5.tgz", - "integrity": "sha1-cWk3hyYhpjE15iztLzrGoGPG+4c=", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-6.2.0.tgz", + "integrity": "sha512-1k+KPhlVtqmG99RaTbAv/usu85fcSRu3wY8X+vnsEhIxNP5VbVIDiXnLqyKIG+UMdyTg0ZX9EI6k2AfjJkHPtA==", "requires": { - "bail": "1.0.2", + "bail": "1.0.3", "extend": "3.0.1", "is-plain-obj": "1.1.0", - "trough": "1.0.1", - "vfile": "2.2.0", - "x-is-function": "1.0.4", + "trough": "1.0.2", + "vfile": "2.3.0", "x-is-string": "0.1.0" } }, @@ -1001,7 +996,7 @@ "integrity": "sha1-jZubitNHvrN/QwVipixNNhtCIg8=", "requires": { "camelcase": "4.1.0", - "chalk": "2.3.0", + "chalk": "2.4.1", "chokidar": "1.7.0", "minimist": "1.2.0", "text-table": "0.2.0", @@ -1013,52 +1008,60 @@ "resolved": "https://registry.npmjs.org/unified-engine/-/unified-engine-4.0.1.tgz", "integrity": "sha1-lpKql/1cTsNoiXeeElFL746GP8M=", "requires": { - "concat-stream": "1.6.0", + "concat-stream": "1.6.2", "debug": "2.6.9", - "fault": "1.0.1", + "fault": "1.0.2", "fn-name": "2.0.1", "glob": "7.1.2", - "ignore": "3.3.7", + "ignore": "3.3.8", "is-empty": "1.2.0", "is-hidden": "1.1.1", "is-object": "1.0.1", - "js-yaml": "3.10.0", - "load-plugin": "2.2.1", + "js-yaml": "3.11.0", + "load-plugin": "2.2.2", "parse-json": "2.2.0", - "to-vfile": "2.1.2", - "trough": "1.0.1", + "to-vfile": "2.2.0", + "trough": "1.0.2", "vfile-reporter": "4.0.0", - "vfile-statistics": "1.1.0", + "vfile-statistics": "1.1.1", "x-is-function": "1.0.4", "x-is-string": "0.1.0", "xtend": "4.0.1" } }, + "unist-util-is": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-2.1.2.tgz", + "integrity": "sha512-YkXBK/H9raAmG7KXck+UUpnKiNmUdB+aBGrknfQ4EreE1banuzrKABx3jP6Z5Z3fMSPMQQmeXBlKpCbMwBkxVw==" + }, "unist-util-modify-children": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unist-util-modify-children/-/unist-util-modify-children-1.1.1.tgz", - "integrity": "sha1-ZtfmpEnm9nIguXarPLi166w55R0=", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/unist-util-modify-children/-/unist-util-modify-children-1.1.2.tgz", + "integrity": "sha512-GRi04yhng1WqBf5RBzPkOtWAadcZS2gvuOgNn/cyJBYNxtTuyYqTKN0eg4rC1YJwGnzrqfRB3dSKm8cNCjNirg==", "requires": { - "array-iterate": "1.1.1" + "array-iterate": "1.1.2" } }, "unist-util-remove-position": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.1.tgz", - "integrity": "sha1-WoXBVV/BugwQG4ZwfRXlD6TIcbs=", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.2.tgz", + "integrity": "sha512-XxoNOBvq1WXRKXxgnSYbtCF76TJrRoe5++pD4cCBsssSiWSnPEktyFrFLE8LTk3JW5mt9hB0Sk5zn4x/JeWY7Q==", "requires": { - "unist-util-visit": "1.1.3" + "unist-util-visit": "1.3.1" } }, "unist-util-stringify-position": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.1.tgz", - "integrity": "sha1-PMvcU2ee7W7PN3fdf14yKcG2qjw=" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz", + "integrity": "sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==" }, "unist-util-visit": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.1.3.tgz", - "integrity": "sha1-7CaOcxudJ3p5pbWqBkOZDkBdYAs=" + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.3.1.tgz", + "integrity": "sha512-0fdB9EQJU0tho5tK0VzOJzAQpPv2LyLZ030b10GxuzAWEfvd54mpY7BMjQ1L69k2YNvL+SvxRzH0yUIehOO8aA==", + "requires": { + "unist-util-is": "2.1.2" + } }, "untildify": { "version": "2.1.0", @@ -1074,19 +1077,28 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "vfile": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-2.2.0.tgz", - "integrity": "sha1-zkek+zNZIrIz5TXbD32BIdj87U4=", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-2.3.0.tgz", + "integrity": "sha512-ASt4mBUHcTpMKD/l5Q+WJXNtshlWxOogYyGYYrg4lt/vuRjC1EFQtlAofL5VmtVNIZJzWYFJjzGWZ0Gw8pzW1w==", "requires": { "is-buffer": "1.1.6", "replace-ext": "1.0.0", - "unist-util-stringify-position": "1.1.1" + "unist-util-stringify-position": "1.1.2", + "vfile-message": "1.0.1" } }, "vfile-location": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.2.tgz", - "integrity": "sha1-02dcWch3SY5JK0dW/2Xkrxp1IlU=" + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.3.tgz", + "integrity": "sha512-zM5/l4lfw1CBoPx3Jimxoc5RNDAHHpk6AM6LM0pTIkm5SUSsx8ZekZ0PVdf0WEZ7kjlhSt7ZlqbRL6Cd6dBs6A==" + }, + "vfile-message": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-1.0.1.tgz", + "integrity": "sha512-vSGCkhNvJzO6VcWC6AlJW4NtYOVtS+RgCaqFIYUjoGIlHnFL+i0LbtYvonDWOMcB97uTPT4PRsyYY7REWC9vug==", + "requires": { + "unist-util-stringify-position": "1.1.2" + } }, "vfile-reporter": { "version": "4.0.0", @@ -1096,14 +1108,29 @@ "repeat-string": "1.6.1", "string-width": "1.0.2", "supports-color": "4.5.0", - "unist-util-stringify-position": "1.1.1", - "vfile-statistics": "1.1.0" + "unist-util-stringify-position": "1.1.2", + "vfile-statistics": "1.1.1" + }, + "dependencies": { + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" + }, + "supports-color": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", + "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "requires": { + "has-flag": "2.0.0" + } + } } }, "vfile-statistics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vfile-statistics/-/vfile-statistics-1.1.0.tgz", - "integrity": "sha1-AhBMYP3u0dEbH3OtZTMLdjSz2JU=" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/vfile-statistics/-/vfile-statistics-1.1.1.tgz", + "integrity": "sha512-dxUM6IYvGChHuwMT3dseyU5BHprNRXzAV0OHx1A769lVGsTiT50kU7BbpRFV+IE6oWmU+PwHdsTKfXhnDIRIgQ==" }, "wrappy": { "version": "1.0.2", diff --git a/tools/remark-preset-lint-node/package-lock.json b/tools/remark-preset-lint-node/package-lock.json index 55f29b9aba9e73..766164d64aaa9b 100644 --- a/tools/remark-preset-lint-node/package-lock.json +++ b/tools/remark-preset-lint-node/package-lock.json @@ -42,7 +42,7 @@ "resolved": "https://registry.npmjs.org/remark-lint/-/remark-lint-6.0.1.tgz", "integrity": "sha512-wvTTuB5O5pF8SxqahQjjrU3dtuhygYjaGcOZTw+4ACgSE4RBINDlNqN46HjcV3X0ib5GmObJUt5a2mmhtmuTqw==", "requires": { - "remark-message-control": "4.0.1" + "remark-message-control": "4.1.0" } }, "remark-lint-blockquote-indentation": { @@ -53,9 +53,9 @@ "mdast-util-to-string": "1.0.4", "plur": "2.1.2", "unified-lint-rule": "1.0.2", - "unist-util-generated": "1.1.1", - "unist-util-position": "3.0.0", - "unist-util-visit": "1.2.0" + "unist-util-generated": "1.1.2", + "unist-util-position": "3.0.1", + "unist-util-visit": "1.3.1" } }, "remark-lint-checkbox-character-style": { @@ -64,10 +64,10 @@ "integrity": "sha512-AF+1UrsVyrYYbK8Mg5TXr/IxaepgMspejPKuflK+TKOYKmMxOHUjdk2kIBBulj+hZCp+yz7lq3ifr8N2Vqg9BA==", "requires": { "unified-lint-rule": "1.0.2", - "unist-util-generated": "1.1.1", - "unist-util-position": "3.0.0", - "unist-util-visit": "1.2.0", - "vfile-location": "2.0.2" + "unist-util-generated": "1.1.2", + "unist-util-position": "3.0.1", + "unist-util-visit": "1.3.1", + "vfile-location": "2.0.3" } }, "remark-lint-checkbox-content-indent": { @@ -76,10 +76,10 @@ "integrity": "sha512-cCPzu1HSQUevFsfJ7mmwj/v76ZWYBSbBu/GmFJE57G10BCEv1pCHuxJYjGKbXPcQXU5NTvIH9fuHWRVdM3hwdA==", "requires": { "unified-lint-rule": "1.0.2", - "unist-util-generated": "1.1.1", - "unist-util-position": "3.0.0", - "unist-util-visit": "1.2.0", - "vfile-location": "2.0.2" + "unist-util-generated": "1.1.2", + "unist-util-position": "3.0.1", + "unist-util-visit": "1.3.1", + "vfile-location": "2.0.3" } }, "remark-lint-code-block-style": { @@ -88,9 +88,9 @@ "integrity": "sha512-FRUMhhKwCruH4vkatdMhVO4WlYpysV1NmMILVoK/k+/7uFLSfgvlqo66nzhpMdWL8TQHqdo0LhiXuetGC2WjsQ==", "requires": { "unified-lint-rule": "1.0.2", - "unist-util-generated": "1.1.1", - "unist-util-position": "3.0.0", - "unist-util-visit": "1.2.0" + "unist-util-generated": "1.1.2", + "unist-util-position": "3.0.1", + "unist-util-visit": "1.3.1" } }, "remark-lint-definition-spacing": { @@ -99,9 +99,9 @@ "integrity": "sha512-ewzdlFfpTSP11ZuiOln0yfz6Y03aWtgJmLVQNfF1spaT1gURaShjs8Hiilbo719bz96DgvXSZLP6UnkSiZL1vg==", "requires": { "unified-lint-rule": "1.0.2", - "unist-util-generated": "1.1.1", - "unist-util-position": "3.0.0", - "unist-util-visit": "1.2.0" + "unist-util-generated": "1.1.2", + "unist-util-position": "3.0.1", + "unist-util-visit": "1.3.1" } }, "remark-lint-fenced-code-flag": { @@ -110,9 +110,9 @@ "integrity": "sha512-P24T9DRe/nnywPFRpE1UAXAVzN1CX6HmINr15UHbQZo1Cy8KYt7uV9YOR0/XzphtnO/AFenAqZyf7tchW5AUNQ==", "requires": { "unified-lint-rule": "1.0.2", - "unist-util-generated": "1.1.1", - "unist-util-position": "3.0.0", - "unist-util-visit": "1.2.0" + "unist-util-generated": "1.1.2", + "unist-util-position": "3.0.1", + "unist-util-visit": "1.3.1" } }, "remark-lint-fenced-code-marker": { @@ -121,9 +121,9 @@ "integrity": "sha512-mX7xAMl5m7xGX+YtOtyXIyv+egD4IQAm6DPGdfunI734QwODwcoBydtpTD56jrY+48nVcQ/anFYT1Blg3Xk3sQ==", "requires": { "unified-lint-rule": "1.0.2", - "unist-util-generated": "1.1.1", - "unist-util-position": "3.0.0", - "unist-util-visit": "1.2.0" + "unist-util-generated": "1.1.2", + "unist-util-position": "3.0.1", + "unist-util-visit": "1.3.1" } }, "remark-lint-file-extension": { @@ -140,9 +140,9 @@ "integrity": "sha512-DK6bphJdQ0xSOQAn+8wOyLIVc3SZW2+ZzCMCLkQnVtHiQ9GHMzFiCkeE3Cq+OClsMI5Yn8wFTHZHPUn58VhNEQ==", "requires": { "unified-lint-rule": "1.0.2", - "unist-util-generated": "1.1.1", - "unist-util-position": "3.0.0", - "unist-util-visit": "1.2.0" + "unist-util-generated": "1.1.2", + "unist-util-position": "3.0.1", + "unist-util-visit": "1.3.1" } }, "remark-lint-final-newline": { @@ -159,8 +159,8 @@ "integrity": "sha512-R11L8arXZy+uAZIioSRVWhp4f6Oere/Q071INTX8g4uvuZrC/uKDjxa3iZ6dlWCfLijC0z/s2JbeqwYbV5QrCA==", "requires": { "unified-lint-rule": "1.0.2", - "unist-util-generated": "1.1.1", - "unist-util-visit": "1.2.0" + "unist-util-generated": "1.1.2", + "unist-util-visit": "1.3.1" } }, "remark-lint-hard-break-spaces": { @@ -169,9 +169,9 @@ "integrity": "sha512-uh7LqHgRPCphiCvRzBVA4D0Ml2IqPaw89lWJdQ6HvYiV8ChB/OFLBapHi6OKW7NVVVPPJsElPMB/UPUsKFaPTg==", "requires": { "unified-lint-rule": "1.0.2", - "unist-util-generated": "1.1.1", - "unist-util-position": "3.0.0", - "unist-util-visit": "1.2.0" + "unist-util-generated": "1.1.2", + "unist-util-position": "3.0.1", + "unist-util-visit": "1.3.1" } }, "remark-lint-heading-style": { @@ -181,8 +181,8 @@ "requires": { "mdast-util-heading-style": "1.0.3", "unified-lint-rule": "1.0.2", - "unist-util-generated": "1.1.1", - "unist-util-visit": "1.2.0" + "unist-util-generated": "1.1.2", + "unist-util-visit": "1.3.1" } }, "remark-lint-maximum-line-length": { @@ -191,9 +191,9 @@ "integrity": "sha512-M4UIXAAbtLgoQbTDVwdKOEFbTKtJSZ+pCW7ZqMFs+cbIN0Svm32LM9+xpVfVU0hLYt3Ypl++EAPfguBNe1PZEw==", "requires": { "unified-lint-rule": "1.0.2", - "unist-util-generated": "1.1.1", - "unist-util-position": "3.0.0", - "unist-util-visit": "1.2.0" + "unist-util-generated": "1.1.2", + "unist-util-position": "3.0.1", + "unist-util-visit": "1.3.1" } }, "remark-lint-no-auto-link-without-protocol": { @@ -203,9 +203,9 @@ "requires": { "mdast-util-to-string": "1.0.4", "unified-lint-rule": "1.0.2", - "unist-util-generated": "1.1.1", - "unist-util-position": "3.0.0", - "unist-util-visit": "1.2.0" + "unist-util-generated": "1.1.2", + "unist-util-position": "3.0.1", + "unist-util-visit": "1.3.1" } }, "remark-lint-no-blockquote-without-caret": { @@ -214,10 +214,10 @@ "integrity": "sha1-gd0i3V8EVOupwqU3u6Jgh0ShrW8=", "requires": { "unified-lint-rule": "1.0.2", - "unist-util-generated": "1.1.1", - "unist-util-position": "3.0.0", - "unist-util-visit": "1.2.0", - "vfile-location": "2.0.2" + "unist-util-generated": "1.1.2", + "unist-util-position": "3.0.1", + "unist-util-visit": "1.3.1", + "vfile-location": "2.0.3" } }, "remark-lint-no-duplicate-definitions": { @@ -226,9 +226,9 @@ "integrity": "sha512-3I0V3UVJ0gkDKZahSZ0xdFmklecr5SMwXcWbVBzXvHR59LqgjMVHFI7G/QZ6k2imOl1X22YVRz+mpMjacu2Ipw==", "requires": { "unified-lint-rule": "1.0.2", - "unist-util-generated": "1.1.1", - "unist-util-position": "3.0.0", - "unist-util-visit": "1.2.0" + "unist-util-generated": "1.1.2", + "unist-util-position": "3.0.1", + "unist-util-visit": "1.3.1" } }, "remark-lint-no-file-name-articles": { @@ -263,9 +263,9 @@ "mdast-util-heading-style": "1.0.3", "plur": "2.1.2", "unified-lint-rule": "1.0.2", - "unist-util-generated": "1.1.1", - "unist-util-position": "3.0.0", - "unist-util-visit": "1.2.0" + "unist-util-generated": "1.1.2", + "unist-util-position": "3.0.1", + "unist-util-visit": "1.3.1" } }, "remark-lint-no-heading-indent": { @@ -275,9 +275,9 @@ "requires": { "plur": "2.1.2", "unified-lint-rule": "1.0.2", - "unist-util-generated": "1.1.1", - "unist-util-position": "3.0.0", - "unist-util-visit": "1.2.0" + "unist-util-generated": "1.1.2", + "unist-util-position": "3.0.1", + "unist-util-visit": "1.3.1" } }, "remark-lint-no-inline-padding": { @@ -287,8 +287,8 @@ "requires": { "mdast-util-to-string": "1.0.4", "unified-lint-rule": "1.0.2", - "unist-util-generated": "1.1.1", - "unist-util-visit": "1.2.0" + "unist-util-generated": "1.1.2", + "unist-util-visit": "1.3.1" } }, "remark-lint-no-multiple-toplevel-headings": { @@ -297,9 +297,9 @@ "integrity": "sha512-LFfgjF3NKFkt0tGNnJ8Exf8+DrVcMRwek5qu5mvh2KrZnmSpm5flYWzUy2UnnIyicDL3CZYC/r3Fjz6CeBYgZA==", "requires": { "unified-lint-rule": "1.0.2", - "unist-util-generated": "1.1.1", - "unist-util-position": "3.0.0", - "unist-util-visit": "1.2.0" + "unist-util-generated": "1.1.2", + "unist-util-position": "3.0.1", + "unist-util-visit": "1.3.1" } }, "remark-lint-no-shell-dollars": { @@ -308,8 +308,8 @@ "integrity": "sha512-YryHem73PTxjCkuC4HONJWHsmrLyXmF7r+cCH36Ys3vuWsfAbwkbOwpyuPB4KXn+6fHaTUfz/B5BPp3iwzJwyA==", "requires": { "unified-lint-rule": "1.0.2", - "unist-util-generated": "1.1.1", - "unist-util-visit": "1.2.0" + "unist-util-generated": "1.1.2", + "unist-util-visit": "1.3.1" } }, "remark-lint-no-shortcut-reference-image": { @@ -318,8 +318,8 @@ "integrity": "sha512-nUQ+4xB5hKZTCl9gvg7c+W1T3ddsnjgu4zwRza2Bn+21cKmUzx+z9dvlZ4aVuNGmxuWHbKI8/ZkKuB8Eu27vJw==", "requires": { "unified-lint-rule": "1.0.2", - "unist-util-generated": "1.1.1", - "unist-util-visit": "1.2.0" + "unist-util-generated": "1.1.2", + "unist-util-visit": "1.3.1" } }, "remark-lint-no-table-indentation": { @@ -328,9 +328,9 @@ "integrity": "sha512-QrtT1GvJmAoNsWh+gmHFajFlM+ubm9rd3Cbz2OYPix8ZM6g907aIfG2NusJFXL9D8/CExQWYhlBvelFBbHgqbQ==", "requires": { "unified-lint-rule": "1.0.2", - "unist-util-generated": "1.1.1", - "unist-util-position": "3.0.0", - "unist-util-visit": "1.2.0" + "unist-util-generated": "1.1.2", + "unist-util-position": "3.0.1", + "unist-util-visit": "1.3.1" } }, "remark-lint-no-tabs": { @@ -339,7 +339,7 @@ "integrity": "sha512-sFNCjz3MpX2TKo4vvo9s6iX8C0MsTmw10iC0F6mk3FKZ694bkHnEQOPhz5oyZIodV+QJ2wKqpZkuyXruIshjtA==", "requires": { "unified-lint-rule": "1.0.2", - "vfile-location": "2.0.2" + "vfile-location": "2.0.3" } }, "remark-lint-no-unused-definitions": { @@ -348,17 +348,17 @@ "integrity": "sha512-weNwWXvoSBmB3L2Yh8oxY0ylF6L5b/PjFbOhzBU4SlnpFOMfTn3rwNxOxbTrDS8MG2JTPVTaFn4ajXr/zkbH0Q==", "requires": { "unified-lint-rule": "1.0.2", - "unist-util-generated": "1.1.1", - "unist-util-visit": "1.2.0" + "unist-util-generated": "1.1.2", + "unist-util-visit": "1.3.1" } }, "remark-lint-prohibited-strings": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/remark-lint-prohibited-strings/-/remark-lint-prohibited-strings-1.0.0.tgz", - "integrity": "sha512-FXqOBjU36+67l3y3RwtACrXdMUusANgyj+kDx6vlXYP8OfaRRjYNse51AcCiNQKR3XHgbGKxEklUHMJFKWfe7A==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/remark-lint-prohibited-strings/-/remark-lint-prohibited-strings-1.0.3.tgz", + "integrity": "sha512-XgxDXQrNjnHd4+cGavdiW8y5ipN+DwJxWIZDUIWuWjEhmRmgUl8nJHXOKjIYZ8inYxuhVit9m1Y9kX12wO3Edw==", "requires": { "unified-lint-rule": "1.0.2", - "unist-util-visit": "1.2.0" + "unist-util-visit": "1.3.1" } }, "remark-lint-rule-style": { @@ -367,9 +367,9 @@ "integrity": "sha512-dzH+K6DcPIIMBq6LUQgE4dR9TiQGZrQOoULD7m0Y0lIb2EoR2FK5Zd4TgZg/LnvTs6fid37t0xFoaY4/lXV/5Q==", "requires": { "unified-lint-rule": "1.0.2", - "unist-util-generated": "1.1.1", - "unist-util-position": "3.0.0", - "unist-util-visit": "1.2.0" + "unist-util-generated": "1.1.2", + "unist-util-position": "3.0.1", + "unist-util-visit": "1.3.1" } }, "remark-lint-strong-marker": { @@ -378,9 +378,9 @@ "integrity": "sha512-+bwWKWAqDwqd21Vw+ndqVFh5V27Dp4MKhk9AUlKmcvgJYHuvQ8UfWQdpZcP218ps/4EbwTfyi33TaPyXqOTlXA==", "requires": { "unified-lint-rule": "1.0.2", - "unist-util-generated": "1.1.1", - "unist-util-position": "3.0.0", - "unist-util-visit": "1.2.0" + "unist-util-generated": "1.1.2", + "unist-util-position": "3.0.1", + "unist-util-visit": "1.3.1" } }, "remark-lint-table-cell-padding": { @@ -389,9 +389,9 @@ "integrity": "sha512-o3WwC9YysXbQKf0D5nvhhJPcLagqedLwGdifukdgyaKvuIQVbtWbNv1/UOdB3LL+D+2fUrwrCmnQ8J3E1r0lBw==", "requires": { "unified-lint-rule": "1.0.2", - "unist-util-generated": "1.1.1", - "unist-util-position": "3.0.0", - "unist-util-visit": "1.2.0" + "unist-util-generated": "1.1.2", + "unist-util-position": "3.0.1", + "unist-util-visit": "1.3.1" } }, "remark-lint-table-pipes": { @@ -400,20 +400,19 @@ "integrity": "sha512-VHfDRvcovLBl/cvSjwDoA0xRizdZU33A6F2qFD9A5hu1sDWgGxMLg5m2MOvFlRkUVxSwUv47cuD0/yxB4THYXQ==", "requires": { "unified-lint-rule": "1.0.2", - "unist-util-generated": "1.1.1", - "unist-util-position": "3.0.0", - "unist-util-visit": "1.2.0" + "unist-util-generated": "1.1.2", + "unist-util-position": "3.0.1", + "unist-util-visit": "1.3.1" } }, "remark-message-control": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-message-control/-/remark-message-control-4.0.1.tgz", - "integrity": "sha1-KRPNYLMW2fnzkKp/NGOdIM9VmW0=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/remark-message-control/-/remark-message-control-4.1.0.tgz", + "integrity": "sha512-e1dszks4YKY7hLAkhS2367jBjBpAfvi+kVgSN/tOFrdp3qxITjiNR5fOFnyYF8vvorkQ9uxlKJoZUOW8T7rKDg==", "requires": { "mdast-comment-marker": "1.0.2", - "trim": "0.0.1", - "unist-util-visit": "1.2.0", - "vfile-location": "2.0.2" + "unified-message-control": "1.0.4", + "xtend": "4.0.1" } }, "sliced": { @@ -434,33 +433,43 @@ "wrapped": "1.0.1" } }, + "unified-message-control": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unified-message-control/-/unified-message-control-1.0.4.tgz", + "integrity": "sha512-e1dEtN4Z/TvLn/qHm+xeZpzqhJTtfZusFErk336kkZVpqrJYiV9ptxq+SbRPFMlN0OkjDYHmVJ929KYjsMTo3g==", + "requires": { + "trim": "0.0.1", + "unist-util-visit": "1.3.1", + "vfile-location": "2.0.3" + } + }, "unist-util-generated": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.1.tgz", - "integrity": "sha1-mfFseJWayFTe58YVwpGSTIv03n8=" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.2.tgz", + "integrity": "sha512-1HcwiEO62dr0XWGT+abVK4f0aAm8Ik8N08c5nAYVmuSxfvpA9rCcNyX/le8xXj1pJK5nBrGlZefeWB6bN8Pstw==" }, "unist-util-is": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-2.1.1.tgz", - "integrity": "sha1-DDEmKeP5YMZukx6BLT2A53AQlHs=" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-2.1.2.tgz", + "integrity": "sha512-YkXBK/H9raAmG7KXck+UUpnKiNmUdB+aBGrknfQ4EreE1banuzrKABx3jP6Z5Z3fMSPMQQmeXBlKpCbMwBkxVw==" }, "unist-util-position": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.0.0.tgz", - "integrity": "sha1-5uHgPu64HF4a/lU+jUrfvXwNj4I=" + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.0.1.tgz", + "integrity": "sha512-05QfJDPI7PE1BIUtAxeSV+cDx21xP7+tUZgSval5CA7tr0pHBwybF7OnEa1dOFqg6BfYH/qiMUnWwWj+Frhlww==" }, "unist-util-visit": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.2.0.tgz", - "integrity": "sha512-lI+jyPlDztHZ2CJhUchcRMQ7MNc0yASgYFxwRTxs0EZ+9HbYFBLVGDJ2FchTBy+pra0O1LVEn0Wkgf19mDVDzw==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.3.1.tgz", + "integrity": "sha512-0fdB9EQJU0tho5tK0VzOJzAQpPv2LyLZ030b10GxuzAWEfvd54mpY7BMjQ1L69k2YNvL+SvxRzH0yUIehOO8aA==", "requires": { - "unist-util-is": "2.1.1" + "unist-util-is": "2.1.2" } }, "vfile-location": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.2.tgz", - "integrity": "sha1-02dcWch3SY5JK0dW/2Xkrxp1IlU=" + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.3.tgz", + "integrity": "sha512-zM5/l4lfw1CBoPx3Jimxoc5RNDAHHpk6AM6LM0pTIkm5SUSsx8ZekZ0PVdf0WEZ7kjlhSt7ZlqbRL6Cd6dBs6A==" }, "wrapped": { "version": "1.0.1", @@ -470,6 +479,11 @@ "co": "3.1.0", "sliced": "1.0.1" } + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" } } } diff --git a/tools/run-valgrind.py b/tools/run-valgrind.py index ae1a3194cac4a6..cad3e7ec6954d2 100755 --- a/tools/run-valgrind.py +++ b/tools/run-valgrind.py @@ -37,9 +37,6 @@ 'valgrind', '--error-exitcode=1', '--smc-check=all', - # Node.js does not clean up on exit so don't complain about - # memory leaks but do complain about invalid memory access. - '--quiet', ] if len(sys.argv) < 2: diff --git a/tools/test.py b/tools/test.py index 66b9c7291f36af..e5581e8da41c44 100755 --- a/tools/test.py +++ b/tools/test.py @@ -1382,6 +1382,9 @@ def BuildOptions(): result.add_option("--flaky-tests", help="Regard tests marked as flaky (run|skip|dontcare)", default="run") + result.add_option("--skip-tests", + help="Tests that should not be executed (comma-separated)", + default="") result.add_option("--warn-unused", help="Report unused rules", default=False, action="store_true") result.add_option("-j", help="The number of parallel tasks to run", @@ -1424,6 +1427,7 @@ def ProcessOptions(options): options.arch = options.arch.split(',') options.mode = options.mode.split(',') options.run = options.run.split(',') + options.skip_tests = options.skip_tests.split(',') if options.run == [""]: options.run = None elif len(options.run) != 2: @@ -1710,6 +1714,11 @@ def Main(): result = None def DoSkip(case): + # A list of tests that should be skipped can be provided. This is + # useful for tests that fail in some environments, e.g., under coverage. + if options.skip_tests != [""]: + if [ st for st in options.skip_tests if st in case.case.file ]: + return True if SKIP in case.outcomes or SLOW in case.outcomes: return True return FLAKY in case.outcomes and options.flaky_tests == SKIP