diff --git a/.eslintrc.js b/.eslintrc.js
index d0aa8955351e5e..e504e085eb387f 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -17,7 +17,7 @@ Module._findPath = (request, paths, isMain) => {
if (!r && hacks.includes(request)) {
try {
return require.resolve(`./tools/node_modules/${request}`);
- } catch (err) {
+ } catch {
return require.resolve(
`./tools/node_modules/eslint/node_modules/${request}`);
}
@@ -212,7 +212,7 @@ module.exports = {
'no-unsafe-finally': 'error',
'no-unsafe-negation': 'error',
'no-unused-labels': 'error',
- 'no-unused-vars': ['error', { args: 'none' }],
+ 'no-unused-vars': ['error', { args: 'none', caughtErrors: 'all' }],
'no-use-before-define': ['error', {
classes: true,
functions: false,
diff --git a/.gitignore b/.gitignore
index f652a2c74c37d6..dad5a3efd8bcae 100644
--- a/.gitignore
+++ b/.gitignore
@@ -133,3 +133,5 @@ deps/uv/docs/src/guide/
deps/v8/gypfiles/Debug/
deps/v8/gypfiles/Release/
deps/v8/third_party/eu-strip/
+
+.DS_Store
diff --git a/.travis.yml b/.travis.yml
index fad2e7f0c77509..80c729a772fed5 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,26 +1,30 @@
language: cpp
-compiler:
- - clang
sudo: false
cache: ccache
os: linux
matrix:
include:
- name: "Linter"
- node_js: "latest"
+ language: node_js
+ node_js: "node"
env:
- NODE=$(which node)
script:
- make lint
# Lint the first commit in the PR.
- - git log $TRAVIS_COMMIT_RANGE --pretty=format:'%h' --no-merges | tail -1 | xargs npx core-validate-commit --no-validate-metadata
+ - if [ "${TRAVIS_PULL_REQUEST}" != "false" ]; then
+ bash tools/lint-pr-commit-message.sh ${TRAVIS_PULL_REQUEST} || true;
+ fi
- name: "Test Suite"
+ addons:
+ apt:
+ sources:
+ - ubuntu-toolchain-r-test
+ packages:
+ - g++-4.9
install:
+ - export CC='ccache gcc-4.9' CXX='ccache g++-4.9' JOBS=2
- ./configure
- make -j2 V=
script:
- - make -j2 test
- before_install:
- - export CXX="ccache clang++ -Qunused-arguments"
- - export CC="ccache clang -Qunused-arguments -Wno-unknown-warning-option"
- - export JOBS=2
+ - PARALLEL_ARGS='--flaky-tests=skip' make -j1 test
diff --git a/BUILDING.md b/BUILDING.md
index 839480eec38a88..efe39e656b383a 100644
--- a/BUILDING.md
+++ b/BUILDING.md
@@ -48,30 +48,28 @@ file a new issue.
## Supported platforms
This list of supported platforms is current as of the branch/release to
-which it is attached.
+which it belongs.
### Input
-Node.js relies on V8 and libuv. Therefore, we adopt a subset of their
-supported platforms.
+Node.js relies on V8 and libuv. We adopt a subset of their supported platforms.
### Strategy
-Support is divided into three tiers:
+There are three support tiers:
* **Tier 1**: Full test coverage and maintenance by the Node.js core team and
the broader community.
-* **Tier 2**: Full test coverage but more limited maintenance,
- often provided by the vendor of the platform.
-* **Experimental**: May not compile reliably or test suite may not pass.
- These are often working to be promoted to Tier 2 but are not quite ready.
- There is at least one individual actively providing maintenance and the team
- is striving to broaden quality and reliability of support.
+* **Tier 2**: Full test coverage. Limited maintenance, often provided by the
+ vendor of the platform.
+* **Experimental**: May not compile or test suite may not pass.
+ These are often approaching Tier 2 support but are not quite ready.
+ There is at least one individual providing maintenance.
### Supported platforms
The community does not build or test against end-of-life distributions (EoL).
-Thus, we do not recommend that you use Node on end-of-life or unsupported
+Thus, we do not recommend that you use Node.js on end-of-life or unsupported
platforms in production.
| System | Support type | Version | Architectures | Notes |
@@ -97,8 +95,8 @@ platforms in production.
by Joyent. SmartOS images >= 16.4 are not supported because
GCC 4.8 runtime libraries are not available in their pkgsrc repository
-2: Tier 1 support for building on Windows is only on 64 bit
- hosts. Support is experimental for 32 bit hosts.
+2: Tier 1 support for building on Windows is only on 64-bit
+ hosts. Support is experimental for 32-bit hosts.
3: On Windows, running Node.js in Windows terminal emulators
like `mintty` requires the usage of [winpty](https://github.com/rprichard/winpty)
@@ -111,12 +109,12 @@ platforms in production.
community will only address issues that reproduce on native GNU/Linux
systems. Issues that only reproduce on WSL should be reported in the
[WSL issue tracker](https://github.com/Microsoft/WSL/issues). Running the
- Windows binary (`node.exe`) in WSL is not recommended, and will not work
- without adjustment (such as stdio redirection).
+ Windows binary (`node.exe`) in WSL is not recommended. It will not work
+ without workarounds such as stdio redirection.
### Supported toolchains
-Depending on host platform, the selection of toolchains may vary.
+Depending on the host platform, the selection of toolchains may vary.
#### Unix
@@ -128,11 +126,11 @@ Depending on host platform, the selection of toolchains may vary.
#### Windows
-* Visual Studio 2017 with the Windows 10 SDK on a 64 bit host.
+* Visual Studio 2017 with the Windows 10 SDK on a 64-bit host.
#### OpenSSL asm support
-OpenSSL-1.1.0 requires the following asssembler version for use of asm
+OpenSSL-1.1.0 requires the following assembler version for use of asm
support on x86_64 and ia32.
* gas (GNU assembler) version 2.23 or higher
@@ -144,10 +142,8 @@ Otherwise `configure` will fail with an error. This can be avoided by
either providing a newer assembler as per the list above or by
using the `--openssl-no-asm` flag.
-*Note:* The forthcoming OpenSSL-1.1.1 will require higher
- version. Please refer
- https://www.openssl.org/docs/man1.1.1/man3/OPENSSL_ia32cap.html for
- details.
+The forthcoming OpenSSL-1.1.1 will have different requirements. Please refer to
+ https://www.openssl.org/docs/man1.1.1/man3/OPENSSL_ia32cap.html for details.
## Building Node.js on supported platforms
@@ -216,7 +212,7 @@ $ make test-only
At this point, you are ready to make code changes and re-run the tests.
-If you are running tests prior to submitting a Pull Request, the recommended
+If you are running tests before submitting a Pull Request, the recommended
command is:
```console
@@ -318,7 +314,7 @@ These core dumps are useful for debugging when provided with the
corresponding original debug binary and system information.
Reading the core dump requires `gdb` built on the same platform the core dump
-was captured on (i.e. 64 bit `gdb` for `node` built on a 64 bit system, Linux
+was captured on (i.e. 64-bit `gdb` for `node` built on a 64-bit system, Linux
`gdb` for `node` built on Linux) otherwise you will get errors like
`not in executable format: File format not recognized`.
@@ -344,7 +340,7 @@ Prerequisites:
and tools which can be included in the global `PATH`.
* The [NetWide Assembler](http://www.nasm.us/), for OpenSSL assembler modules.
If not installed in the default location, it needs to be manually added
- to `PATH`. Build with `openssl-no-asm` option does not require this.
+ to `PATH`. A build with the `openssl-no-asm` option does not need this.
* **Optional** (to build the MSI): the [WiX Toolset v3.11](http://wixtoolset.org/releases/)
and the [Wix Toolset Visual Studio 2017 Extension](https://marketplace.visualstudio.com/items?itemName=RobMensching.WixToolsetVisualStudio2017Extension).
@@ -369,12 +365,10 @@ To test if Node.js was built correctly:
### Android/Android-based devices (e.g. Firefox OS)
-Although these instructions for building on Android are provided, please note
-that Android is not an officially supported platform at this time. Patches to
-improve the Android build are accepted. However, there is no testing on Android
-in the current continuous integration environment. The participation of people
-dedicated and determined to improve Android building, testing, and support is
-encouraged.
+Android is not a supported platform. Patches to improve the Android build are
+welcome. There is no testing on Android in the current continuous integration
+environment. The participation of people dedicated and determined to improve
+Android building, testing, and support is encouraged.
Be sure you have downloaded and extracted
[Android NDK](https://developer.android.com/tools/sdk/ndk/index.html) before in
@@ -439,7 +433,7 @@ $ ./configure --without-intl
$ pkg-config --modversion icu-i18n && ./configure --with-intl=system-icu
```
-If you are cross compiling, your `pkg-config` must be able to supply a path
+If you are cross-compiling, your `pkg-config` must be able to supply a path
that works for both your host and target environments.
#### Build with a specific ICU:
@@ -449,6 +443,10 @@ You can find other ICU releases at
Download the file named something like `icu4c-**##.#**-src.tgz` (or
`.zip`).
+To check the minimum recommended ICU, run `./configure --help` and see
+the help for the `--with-icu-source` option. A warning will be printed
+during configuration if the ICU version is too old.
+
##### Unix/macOS
From an already-unpacked ICU:
@@ -483,7 +481,7 @@ This version of Node.js does not support FIPS.
## Building Node.js with external core modules
It is possible to specify one or more JavaScript text files to be bundled in
-the binary as builtin modules when building Node.js.
+the binary as built-in modules when building Node.js.
### Unix/macOS
@@ -503,3 +501,14 @@ To make `./myModule.js` available via `require('myModule')` and
```console
> .\vcbuild link-module './myModule.js' link-module './myModule2.js'
```
+
+## Note for downstream distributors of Node.js
+
+The Node.js ecosystem is reliant on ABI compatibility within a major
+release. To maintain ABI compatibility it is required that production
+builds of Node.js will be built against the same version of dependencies as the
+project vendors. If Node.js is to be built against a different version of a
+dependency please create a custom `NODE_MODULE_VERSION` to ensure ecosystem
+compatibility. Please consult with the TSC by opening an issue at
+https://github.com/nodejs/tsc/issues if you decide to create a custom
+`NODE_MODULE_VERSION` so we can avoid duplication in the ecosystem.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ffc341d69a8820..6d05bd8013ad19 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,11 +1,5 @@
# Node.js Changelog
-
-
-To make the changelog easier to both use and manage, it has been split into
-multiple files organized according to significant major and minor Node.js
-release lines.
-
Select a Node.js version below to view the changelog history:
* [Node.js 10](doc/changelogs/CHANGELOG_V10.md) — **Long Term Support**
@@ -23,6 +17,7 @@ Select a Node.js version below to view the changelog history:
Please use the following table to find the changelog for a specific Node.js
release.
+
-10.14.1
+10.14.2
+10.14.1 10.14.0 10.13.0 10.12.0
@@ -119,10 +115,9 @@ release.
### Notes
-* Release streams marked with `LTS` are currently covered by the
- [Node.js Long Term Support plan](https://github.com/nodejs/Release).
-* Release versions displayed in **bold** text represent the most
- recent actively supported release.
+* The [Node.js Long Term Support plan](https://github.com/nodejs/Release) covers
+ LTS releases.
+* Release versions in **bold** text are the most recent supported releases.
----
----
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
index 5a935352a1f9f0..4c211405596cb4 100644
--- a/CODE_OF_CONDUCT.md
+++ b/CODE_OF_CONDUCT.md
@@ -1,8 +1,4 @@
# Code of Conduct
-The Node.js Code of Conduct document has moved to
-https://github.com/nodejs/admin/blob/master/CODE_OF_CONDUCT.md. Please update
-links to this document accordingly.
-
-The Node.js Moderation policy can be found at
-https://github.com/nodejs/admin/blob/master/Moderation-Policy.md
+* [Node.js Code of Conduct](https://github.com/nodejs/admin/blob/master/CODE_OF_CONDUCT.md)
+* [Node.js Moderation Policy](https://github.com/nodejs/admin/blob/master/Moderation-Policy.md)
diff --git a/COLLABORATOR_GUIDE.md b/COLLABORATOR_GUIDE.md
index 7a435c6478bf45..7fa6fee197aabc 100644
--- a/COLLABORATOR_GUIDE.md
+++ b/COLLABORATOR_GUIDE.md
@@ -28,7 +28,7 @@
- [Using `git-node`](#using-git-node)
- [Technical HOWTO](#technical-howto)
- [Troubleshooting](#troubleshooting)
- - [I Just Made a Mistake](#i-just-made-a-mistake)
+ - [I Made a Mistake](#i-made-a-mistake)
- [Long Term Support](#long-term-support)
- [What is LTS?](#what-is-lts)
- [How does LTS work?](#how-does-lts-work)
@@ -38,13 +38,10 @@
- [How is an LTS release cut?](#how-is-an-lts-release-cut)
* [Who to CC in the issue tracker](#who-to-cc-in-the-issue-tracker)
-This document contains information for Collaborators of the Node.js
-project regarding managing the project's code, documentation, and issue tracker.
-
-Collaborators should be familiar with the guidelines for new
-contributors in [CONTRIBUTING.md](./CONTRIBUTING.md) and also
-understand the project governance model as outlined in
-[GOVERNANCE.md](./GOVERNANCE.md).
+This document explains how Collaborators manage the Node.js project.
+Collaborators should understand the
+[guidelines for new contributors](CONTRIBUTING.md) and the
+[project governance model](GOVERNANCE.md).
## Issues and Pull Requests
@@ -100,7 +97,8 @@ As soon as the PR is ready to land, please do so. Landing your own pull requests
allows other Collaborators to focus on other pull requests. If your pull request
is still awaiting the [minimum time to land](#waiting-for-approvals), add the
`author ready` label so other Collaborators know it can land as soon as the time
-ends.
+ends. If instead you wish to land the PR yourself, indicate this intent by using
+the "assign yourself" button, to self-assign the PR.
## Accepting Modifications
@@ -139,30 +137,26 @@ the CI outcome.
### Consensus Seeking
-If there is no disagreement amongst Collaborators, a pull request should be
-landed given appropriate review, a green CI, and the minimum
-[waiting time](#waiting-for-approvals) for a PR. If it is still awaiting the
-[minimum time to land](#waiting-for-approvals), please add the `author ready`
-label to it so it is obvious that the PR can land as soon as the time ends.
-
-Where there is discussion amongst Collaborators, consensus should be sought if
-possible. The lack of consensus may indicate the need to elevate discussion to
-the TSC for resolution.
-
-If any Collaborator objects to a change *without giving any additional
-explanation or context*, and the objecting Collaborator fails to respond to
-explicit requests for explanation or context within a reasonable period of
-time, the objection may be dismissed. Note that this does not apply to
-objections that are explained.
-
-Note that breaking changes (that is, pull requests that require an increase in
-the major version number, known as `semver-major` changes) must be [elevated for
-review by the TSC](#involving-the-tsc). This does not necessarily mean that the
-PR must be put onto the TSC meeting agenda. If multiple TSC members approve
-(`LGTM`) the PR and no Collaborators oppose the PR, it should be landed. Where
-there is disagreement among TSC members or objections from one or more
-Collaborators, `semver-major` pull requests may be put on the TSC meeting
-agenda.
+If there are no objecting Collaborators, a pull request may land if it has the
+needed [approvals](#code-reviews), [CI](#testing-and-ci), and
+[wait time](#waiting-for-approvals). If a pull request meets all requirements
+except the [wait time](#waiting-for-approvals), please add the
+[`author ready`](#author-ready-pull-requests) label.
+
+Where there is disagreement among Collaborators, consensus should be sought if
+possible. If reaching consensus is not possible, a Collaborator may escalate the
+issue to the TSC.
+
+Collaborators should not block a pull request without providing a reason.
+Another Collaborator may ask an objecting Collaborator to explain their
+objection. If the objector is unresponsive, another Collaborator may dismiss the
+objection.
+
+[Breaking changes](#breaking-changes) must receive
+[TSC review](#involving-the-tsc). If two TSC members approve the pull request
+and no Collaborators object, then it may land. If there are objections, a
+Collaborator may apply the `tsc-agenda` label. That will put the pull request on
+the TSC meeting agenda.
#### Helpful resources
@@ -190,7 +184,9 @@ Collaborators that previously approved the pull request. If someone disagrees
with the fast-tracking request, remove the label and leave a comment indicating
why the pull request should not be fast-tracked. The pull request can be landed
once two or more Collaborators approve both the pull request and the
-fast-tracking request, and the necessary CI testing is done.
+fast-tracking request, and the necessary CI testing is done. A request to
+fast-track a PR made by a different Collaborator than the pull-request author
+counts as a fast-track approval.
### Testing and CI
@@ -498,19 +494,23 @@ This should be done where a pull request:
Assign the `tsc-review` label or @-mention the
`@nodejs/tsc` GitHub team if you want to elevate an issue to the [TSC][].
-Do not use the GitHub UI on the right hand side to assign to
+Do not use the GitHub UI on the right-hand side to assign to
`@nodejs/tsc` or request a review from `@nodejs/tsc`.
The TSC should serve as the final arbiter where required.
## Landing Pull Requests
+1. Avoid landing PRs that are assigned to someone else. Authors who wish to land
+ their own PRs will self-assign them, or delegate to someone else. If in
+ doubt, ask the assignee whether it is okay to land.
1. Never use GitHub's green ["Merge Pull Request"][] button. Reasons for not
using the web interface button:
- * The merge method will add an unnecessary merge commit.
- * The squash & merge method can add metadata (the PR #) to the commit title.
- * If more than one author has contributed to the PR, keep the most recent
- author when squashing.
+ * The "Create a merge commit" method will add an unnecessary merge commit.
+ * The "Squash and merge" method will add metadata (the PR #) to the commit
+ title. If more than one author has contributed to the PR, squashing will
+ only keep the most recent author.
+ * The "Rebase and merge" method has no way of adding metadata to the commit.
1. Make sure the CI is done and the result is green. If the CI is not green,
check for flaky tests and infrastructure failures. Please check if those were
already reported in the appropriate repository ([node][flaky tests] and
@@ -521,13 +521,12 @@ The TSC should serve as the final arbiter where required.
present.
1. Review the commit message to ensure that it adheres to the guidelines
outlined in the [contributing][] guide.
-1. Add all necessary [metadata](#metadata) to commit messages before landing.
- See the commit log for examples such as [this
- one](https://github.com/nodejs/node/commit/b636ba8186) if unsure exactly how
- to format your commit messages.
+1. Add all necessary [metadata](#metadata) to commit messages before landing. If
+ you are unsure exactly how to format the commit messages, use the commit log
+ as a reference. See [this commit][commit-example] as an example.
-Check PRs from new contributors to make sure the person's name and email address
-are correct before merging.
+For PRs from first-time contributors, be [welcoming](#welcoming-first-time-contributors).
+Also, verify that their git settings are to their liking.
All commits should be self-contained, meaning every commit should pass all
tests. This makes it much easier when bisecting to find a breaking change.
@@ -745,7 +744,7 @@ make -j4 test
git push upstream master
```
-### I Just Made a Mistake
+### I Made a Mistake
* Ping a TSC member.
* `#node-dev` on freenode
@@ -905,6 +904,7 @@ If you cannot find who to cc for a file, `git shortlog -n -s ` may help.
[`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
+[commit-example]: https://github.com/nodejs/node/commit/b636ba8186
[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
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 684277980a8ee6..1a3babf8405ea2 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,18 +1,5 @@
# Contributing to Node.js
-Contributions to Node.js include code, documentation, answering user questions,
-running the project's infrastructure, and advocating for all types of Node.js
-users.
-
-The Node.js project welcomes all contributions from anyone willing to work in
-good faith with other contributors and the community. No contribution is too
-small and all contributions are valued.
-
-This guide explains the process for contributing to the Node.js project's core
-`nodejs/node` GitHub Repository and describes what to expect at each step.
-
-## Contents
-
* [Code of Conduct](#code-of-conduct)
* [Issues](#issues)
* [Pull Requests](#pull-requests)
@@ -22,16 +9,12 @@ This guide explains the process for contributing to the Node.js project's core
The Node.js project has a
[Code of Conduct](https://github.com/nodejs/admin/blob/master/CODE_OF_CONDUCT.md)
-that *all* contributors are expected to follow. This code describes the
-*minimum* behavior expectations for all contributors.
+to which all contributors must adhere.
See [details on our policy on Code of Conduct](./doc/guides/contributing/coc.md).
## [Issues](./doc/guides/contributing/issues.md)
-Issues in `nodejs/node` are the primary means by which bug reports and
-general discussions are made.
-
* [How to Contribute in Issues](./doc/guides/contributing/issues.md#how-to-contribute-in-issues)
* [Asking for General Help](./doc/guides/contributing/issues.md#asking-for-general-help)
* [Discussing non-technical topics](./doc/guides/contributing/issues.md#discussing-non-technical-topics)
@@ -41,14 +24,11 @@ general discussions are made.
## [Pull Requests](./doc/guides/contributing/pull-requests.md)
-Pull Requests are the way concrete changes are made to the code, documentation,
-dependencies, and tools contained in the `nodejs/node` repository.
-
* [Dependencies](./doc/guides/contributing/pull-requests.md#dependencies)
* [Setting up your local environment](./doc/guides/contributing/pull-requests.md#setting-up-your-local-environment)
* [The Process of Making Changes](./doc/guides/contributing/pull-requests.md#the-process-of-making-changes)
* [Reviewing Pull Requests](./doc/guides/contributing/pull-requests.md#reviewing-pull-requests)
-* [Additional Notes](./doc/guides/contributing/pull-requests.md#additional-notes)
+* [Notes](./doc/guides/contributing/pull-requests.md#notes)
## Developer's Certificate of Origin 1.1
diff --git a/CPP_STYLE_GUIDE.md b/CPP_STYLE_GUIDE.md
index ae0135b5c0bdff..5099f34ea866c9 100644
--- a/CPP_STYLE_GUIDE.md
+++ b/CPP_STYLE_GUIDE.md
@@ -2,6 +2,7 @@
## Table of Contents
+* [Guides and References](#guides-and-references)
* [Formatting](#formatting)
* [Left-leaning (C++ style) asterisks for pointer declarations](#left-leaning-c-style-asterisks-for-pointer-declarations)
* [C++ style comments](#c-style-comments)
@@ -17,7 +18,9 @@
* [Memory Management](#memory-management)
* [Memory allocation](#memory-allocation)
* [Use `nullptr` instead of `NULL` or `0`](#use-nullptr-instead-of-null-or-0)
+ * [Use explicit pointer comparisons](#use-explicit-pointer-comparisons)
* [Ownership and Smart Pointers](#ownership-and-smart-pointers)
+ * [Avoid non-const references](#avoid-non-const-references)
* [Others](#others)
* [Type casting](#type-casting)
* [Using `auto`](#using-auto)
@@ -25,14 +28,30 @@
* [Avoid throwing JavaScript errors in C++ methods](#avoid-throwing-javascript-errors-in-c)
* [Avoid throwing JavaScript errors in nested C++ methods](#avoid-throwing-javascript-errors-in-nested-c-methods)
-Unfortunately, the C++ linter (based on
-[Google’s `cpplint`](https://github.com/google/styleguide)), which can be run
-explicitly via `make lint-cpp`, does not currently catch a lot of rules that are
-specific to the Node.js C++ code base. This document explains the most common of
-these rules:
+
+## Guides and References
+
+The Node.js C++ codebase strives to be consistent in its use of language
+features and idioms, as well as have some specific guidelines for the use of
+runtime features.
+
+Coding guidelines are based on the following guides (highest priority first):
+1. This document
+2. The [Google C++ Style Guide][]
+3. The ISO [C++ Core Guidelines][]
+
+In general code should follow the C++ Core Guidelines, unless overridden by the
+Google C++ Style Guide or this document. At the moment these guidelines are
+checked manually by reviewers, with the goal to validate this with automatic
+tools.
## Formatting
+Unfortunately, the C++ linter (based on [Google’s `cpplint`][]), which can be
+run explicitly via `make lint-cpp`, does not currently catch a lot of rules that
+are specific to the Node.js C++ code base. This document explains the most
+common of these rules:
+
### Left-leaning (C++ style) asterisks for pointer declarations
`char* buffer;` instead of `char *buffer;`
@@ -175,40 +194,82 @@ class FancyContainer {
### Use `nullptr` instead of `NULL` or `0`
-What it says in the title.
+Further reading in the [C++ Core Guidelines][ES.47].
+
+### Use explicit pointer comparisons
+
+Use explicit comparisons to `nullptr` when testing pointers, i.e.
+`if (foo == nullptr)` instead of `if (foo)` and
+`foo != nullptr` instead of `!foo`.
### Ownership and Smart Pointers
-"Smart" pointers are classes that act like pointers, e.g.
-by overloading the `*` and `->` operators. Some smart pointer types can be
-used to automate ownership bookkeeping, to ensure these responsibilities are
-met. `std::unique_ptr` is a smart pointer type introduced in C++11, which
-expresses exclusive ownership of a dynamically allocated object; the object
-is deleted when the `std::unique_ptr` goes out of scope. It cannot be
-copied, but can be moved to represent ownership transfer.
-`std::shared_ptr` is a smart pointer type that expresses shared ownership of a
-dynamically allocated object. `std::shared_ptr`s can be copied; ownership
-of the object is shared among all copies, and the object
-is deleted when the last `std::shared_ptr` is destroyed.
-
-Prefer to use `std::unique_ptr` to make ownership
-transfer explicit. For example:
+* [R.20]: Use `std::unique_ptr` or `std::shared_ptr` to represent ownership
+* [R.21]: Prefer `unique_ptr` over `shared_ptr` unless you need to share
+ ownership
+
+Use `std::unique_ptr` to make ownership transfer explicit. For example:
```cpp
std::unique_ptr FooFactory();
void FooConsumer(std::unique_ptr ptr);
```
-Never use `std::auto_ptr`. Instead, use `std::unique_ptr`.
+Since `std::unique_ptr` has only move semantics, passing one by value transfers
+ownership to the callee and invalidates the caller's instance.
+
+Don't use `std::auto_ptr`, it is deprecated ([Reference][cppref_auto_ptr]).
+
+### Avoid non-const references
+
+Using non-const references often obscures which values are changed by an
+assignment. Consider using a pointer instead, which requires more explicit
+syntax to indicate that modifications take place.
+
+```c++
+class ExampleClass {
+ public:
+ explicit ExampleClass(OtherClass* other_ptr) : pointer_to_other_(other_ptr) {}
+
+ void SomeMethod(const std::string& input_param,
+ std::string* in_out_param); // Pointer instead of reference
+
+ const std::string& get_foo() const { return foo_string_; }
+ void set_foo(const std::string& new_value) { foo_string_ = new_value; }
+
+ void ReplaceCharacterInFoo(char from, char to) {
+ // A non-const reference is okay here, because the method name already tells
+ // users that this modifies 'foo_string_' -- if that is not the case,
+ // it can still be better to use an indexed for loop, or leave appropriate
+ // comments.
+ for (char& character : foo_string_) {
+ if (character == from)
+ character = to;
+ }
+ }
+
+ private:
+ std::string foo_string_;
+ // Pointer instead of reference. If this object 'owns' the other object,
+ // this should be a `std::unique_ptr`; a
+ // `std::shared_ptr` can also be a better choice.
+ OtherClass* pointer_to_other_;
+};
+```
## Others
### Type casting
-- Always avoid C-style casts (`(type)value`)
-- `dynamic_cast` does not work because RTTI is not enabled
-- Use `static_cast` for casting whenever it works
-- `reinterpret_cast` is okay if `static_cast` is not appropriate
+- Use `static_cast` if casting is required, and it is valid
+- Use `reinterpret_cast` only when it is necessary
+- Avoid C-style casts (`(type)value`)
+- `dynamic_cast` does not work because Node.js is built without
+ [Run Time Type Information][]
+
+Further reading:
+* [ES.48]: Avoid casts
+* [ES.49]: If you must use a cast, use a named cast
### Using `auto`
@@ -299,9 +360,25 @@ exports.foo = function(str) {
#### Avoid throwing JavaScript errors in nested C++ methods
-When you have to throw the errors from C++, try to do it at the top level and
-not inside of nested calls.
+When you need to throw a JavaScript exception from C++ (i.e.
+`isolate()->ThrowException()`) prefer to do it as close to the return to JS as
+possible, and not inside of nested C++ calls. Since this changes the JS
+execution state doing it closest to where it is consumed reduces the chances of
+side effects.
+
+Node.js is built [without C++ exception handling][], so code using `throw` or
+even `try` and `catch` **will** break.
-Using C++ `throw` is not allowed.
+[C++ Core Guidelines]: http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines
+[Google C++ Style Guide]: https://google.github.io/styleguide/cppguide.html
+[Google’s `cpplint`]: https://github.com/google/styleguide
[errors]: https://github.com/nodejs/node/blob/master/doc/guides/using-internal-errors.md
+[ES.47]: http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-nullptr
+[ES.48]: http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-casts
+[ES.49]: http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-casts-named
+[R.20]: http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rr-owner
+[R.21]: http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rr-unique
+[Run Time Type Information]: https://en.wikipedia.org/wiki/Run-time_type_information
+[cppref_auto_ptr]: https://en.cppreference.com/w/cpp/memory/auto_ptr
+[without C++ exception handling]: https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_exceptions.html#intro.using.exception.no
diff --git a/GOVERNANCE.md b/GOVERNANCE.md
index 40ef6e7bbe5fcb..d92d3c821e85b3 100644
--- a/GOVERNANCE.md
+++ b/GOVERNANCE.md
@@ -45,7 +45,7 @@ be accepted unless:
* Discussions and/or additional changes result in no Collaborators objecting to
the change. Previously-objecting Collaborators do not necessarily have to
- sign-off on the change, but they should not be opposed to it.
+ sign off on the change, but they should not be opposed to it.
* The change is escalated to the TSC and the TSC votes to approve the change.
This should only happen if disagreements between Collaborators cannot be
resolved through discussion.
@@ -123,8 +123,8 @@ The meeting chair is responsible for ensuring that minutes are taken and that a
pull request with the minutes is submitted after the meeting.
Due to the challenges of scheduling a global meeting with participants in
-several timezones, the TSC will seek to resolve as many agenda items as possible
-outside of meetings using
+several time zones, the TSC will seek to resolve as many agenda items as
+possible outside of meetings using
[the TSC issue tracker](https://github.com/nodejs/TSC/issues). The process in
the issue tracker is:
@@ -196,7 +196,7 @@ completed within a month after the nomination is accepted.
## Consensus Seeking Process
-The TSC follows a [Consensus Seeking][] decision making model as described by
+The TSC follows a [Consensus Seeking][] decision-making model as described by
the [TSC Charter][].
[collaborators-discussions]: https://github.com/orgs/nodejs/teams/collaborators/discussions
diff --git a/Makefile b/Makefile
index a98772faea6dca..ae3830ddd40e00 100644
--- a/Makefile
+++ b/Makefile
@@ -203,9 +203,9 @@ coverage: coverage-test ## Run the tests and generate a coverage report.
coverage-build: all
mkdir -p node_modules
if [ ! -d node_modules/nyc ]; then \
- $(NODE) ./deps/npm install nyc --no-save --no-package-lock; fi
+ $(NODE) ./deps/npm install nyc@13 --no-save --no-package-lock; fi
if [ ! -d gcovr ]; then git clone -b 3.4 --depth=1 \
- --single-branch git://github.com/gcovr/gcovr.git; fi
+ --single-branch https://github.com/gcovr/gcovr.git; fi
if [ ! -d build ]; then git clone --depth=1 \
--single-branch https://github.com/nodejs/build.git; fi
if [ ! -f gcovr/scripts/gcovr.orig ]; then \
@@ -234,8 +234,9 @@ coverage-test: coverage-build
$(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 "$(CURDIR)/coverage")
+ --temp-dir "$(CURDIR)/.cov_tmp" \
+ --report-dir "$(CURDIR)/coverage" \
+ --reporter html)
-(cd out && "../gcovr/scripts/gcovr" --gcov-exclude='.*deps' \
--gcov-exclude='.*usr' -v -r Release/obj.target \
--html --html-detail -o ../coverage/cxxcoverage.html \
@@ -269,7 +270,7 @@ v8:
tools/make-v8.sh $(V8_ARCH).$(BUILDTYPE_LOWER) $(V8_BUILD_OPTIONS)
.PHONY: jstest
-jstest: build-addons build-addons-napi ## Runs addon tests and JS tests
+jstest: build-addons build-addons-napi bench-addons-build ## Runs addon tests and JS tests
$(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=$(BUILDTYPE_LOWER) \
--skip-tests=$(CI_SKIP_TESTS) \
$(CI_JS_SUITES) \
@@ -307,19 +308,19 @@ test-valgrind: all
test-check-deopts: all
$(PYTHON) tools/test.py $(PARALLEL_ARGS) --mode=$(BUILDTYPE_LOWER) --check-deopts parallel sequential
-benchmark/napi/function_call/build/Release/binding.node: all \
+benchmark/napi/function_call/build/Release/binding.node: \
benchmark/napi/function_call/napi_binding.c \
benchmark/napi/function_call/binding.cc \
- benchmark/napi/function_call/binding.gyp
+ benchmark/napi/function_call/binding.gyp | all
$(NODE) deps/npm/node_modules/node-gyp/bin/node-gyp rebuild \
--python="$(PYTHON)" \
--directory="$(shell pwd)/benchmark/napi/function_call" \
--nodedir="$(shell pwd)"
-benchmark/napi/function_args/build/Release/binding.node: all \
+benchmark/napi/function_args/build/Release/binding.node: \
benchmark/napi/function_args/napi_binding.c \
benchmark/napi/function_args/binding.cc \
- benchmark/napi/function_args/binding.gyp
+ benchmark/napi/function_args/binding.gyp | all
$(NODE) deps/npm/node_modules/node-gyp/bin/node-gyp rebuild \
--python="$(PYTHON)" \
--directory="$(shell pwd)/benchmark/napi/function_args" \
@@ -413,7 +414,7 @@ clear-stalled:
echo $${PS_OUT} | xargs kill -9; \
fi
-test-build: | all build-addons build-addons-napi
+test-build: | all build-addons build-addons-napi bench-addons-build
test-build-addons-napi: all build-addons-napi
@@ -443,7 +444,7 @@ test-ci-native: | test/addons/.buildstamp test/addons-napi/.buildstamp
test-ci-js: | clear-stalled
$(PYTHON) tools/test.py $(PARALLEL_ARGS) -p tap --logfile test.tap \
--mode=$(BUILDTYPE_LOWER) --flaky-tests=$(FLAKY_TESTS) \
- $(TEST_CI_ARGS) $(CI_JS_SUITES)
+ $(TEST_CI_ARGS) $(CI_JS_SUITES) --skip-tests=sequential/test-benchmark-napi
@echo "Clean up any leftover processes, error if found."
ps awwx | grep Release/node | grep -v grep | cat
@PS_OUT=`ps awwx | grep Release/node | grep -v grep | awk '{print $$1}'`; \
@@ -454,7 +455,7 @@ test-ci-js: | clear-stalled
.PHONY: test-ci
# Related CI jobs: most CI tests, excluding node-test-commit-arm-fanned
test-ci: LOGLEVEL := info
-test-ci: | clear-stalled build-addons build-addons-napi doc-only
+test-ci: | clear-stalled build-addons build-addons-napi doc-only bench-addons-build
out/Release/cctest --gtest_output=tap:cctest.tap
$(PYTHON) tools/test.py $(PARALLEL_ARGS) -p tap --logfile test.tap \
--mode=$(BUILDTYPE_LOWER) --flaky-tests=$(FLAKY_TESTS) \
@@ -495,7 +496,7 @@ test-debug: test-build
test-message: test-build
$(PYTHON) tools/test.py $(PARALLEL_ARGS) message
-test-simple: | cctest # Depends on 'all'.
+test-simple: | cctest bench-addons-build # Depends on 'all'.
$(PYTHON) tools/test.py $(PARALLEL_ARGS) parallel sequential
test-pummel: all
@@ -809,12 +810,11 @@ MACOSOUTDIR=out/macos
.PHONY: release-only
release-only:
- @if [ "$(DISTTYPE)" != "nightly" ] && [ "$(DISTTYPE)" != "next-nightly" ] && \
- `grep -q REPLACEME doc/api/*.md`; then \
+ @if [ "$(DISTTYPE)" = "release" ] && `grep -q REPLACEME doc/api/*.md`; then \
echo 'Please update REPLACEME in Added: tags in doc/api/*.md (See doc/releases.md)' ; \
exit 1 ; \
fi
- @if [ "$(DISTTYPE)" != "nightly" ] && [ "$(DISTTYPE)" != "next-nightly" ] && \
+ @if [ "$(DISTTYPE)" = "release" ] && \
`grep -q DEP...X doc/api/deprecations.md`; then \
echo 'Please update DEP...X in doc/api/deprecations.md (See doc/releases.md)' ; \
exit 1 ; \
@@ -1207,6 +1207,28 @@ lint-addon-docs: test/addons/.docbuildstamp
cpplint: lint-cpp
@echo "Please use lint-cpp instead of cpplint"
+.PHONY: lint-py-build
+# python -m pip install flake8
+# Try with '--system' is to overcome systems that blindly set '--user'
+lint-py-build:
+ @echo "Pip installing flake8 linter on $(shell $(PYTHON) --version)..."
+ $(PYTHON) -m pip install --upgrade -t tools/pip/site-packages flake8 || \
+ $(PYTHON) -m pip install --upgrade --system -t tools/pip/site-packages flake8
+
+ifneq ("","$(wildcard tools/pip/site-packages)")
+.PHONY: lint-py
+# Lints the Python code with flake8.
+# Flag the build if there are Python syntax errors or undefined names
+lint-py:
+ PYTHONPATH=tools/pip $(PYTHON) -m flake8 . \
+ --count --show-source --statistics --select=E901,E999,F821,F822,F823 \
+ --exclude=deps,lib,src,tools/*_macros.py,tools/gyp,tools/jinja2,tools/pip
+else
+lint-py:
+ @echo "Python linting with flake8 is not avalible"
+ @echo "Run 'make lint-py-build'"
+endif
+
.PHONY: lint
.PHONY: lint-ci
ifneq ("","$(wildcard tools/node_modules/eslint/)")
@@ -1220,7 +1242,7 @@ lint: ## Run JS, C++, MD and doc linters.
CONFLICT_RE=^>>>>>>> [0-9A-Fa-f]+|^<<<<<<< [A-Za-z]+
# Related CI job: node-test-linter
-lint-ci: lint-js-ci lint-cpp lint-md lint-addon-docs
+lint-ci: lint-js-ci lint-cpp lint-py lint-md lint-addon-docs
@if ! ( grep -IEqrs "$(CONFLICT_RE)" benchmark deps doc lib src test tools ) \
&& ! ( find . -maxdepth 1 -type f | xargs grep -IEqs "$(CONFLICT_RE)" ); then \
exit 0 ; \
diff --git a/README.md b/README.md
index 47e178845d1dbf..79b12e289a58f4 100644
--- a/README.md
+++ b/README.md
@@ -31,7 +31,7 @@ The Node.js project uses an [open governance model](./GOVERNANCE.md). The
* [Current Project Team Members](#current-project-team-members)
* [TSC (Technical Steering Committee)](#tsc-technical-steering-committee)
* [Collaborators](#collaborators)
- * [Release Team](#release-team)
+ * [Release Keys](#release-keys)
* [Contributing to Node.js](#contributing-to-nodejs)
## Support
@@ -81,7 +81,7 @@ your expectations.
changes. Use with caution.
Current and LTS releases follow [Semantic Versioning](https://semver.org). A
-member of the [Release Team](#release-team) signs each Current and LTS release.
+member of the Release Team [signs](#release-keys) each Current and LTS release.
For more information, see the
[Release README](https://github.com/nodejs/Release).
@@ -133,9 +133,9 @@ $ grep node-vx.y.z.tar.gz SHASUMS256.txt | sha256sum -c -
For Current and LTS, the GPG detached signature of `SHASUMS256.txt` is in
`SHASUMS256.txt.sig`. You can use it with `gpg` to verify the integrity of
-`SHASUM256.txt`. You will first need to import all the GPG keys of individuals
-authorized to create releases. They are at the bottom of this README under
-[Release Team](#release-team). To import the keys:
+`SHASUM256.txt`. You will first need to import
+[the GPG keys of individuals authorized to create releases](#release-keys). To
+import the keys:
```console
$ gpg --keyserver pool.sks-keyservers.net --recv-keys DD8F2338BAE7501E3DD5AC78C273792F7D83545D
@@ -159,64 +159,12 @@ source and a list of supported platforms.
## Security
-Security flaws in Node.js should be reported by emailing security@nodejs.org.
-Please do not disclose security bugs publicly until they have been handled by
-the security team.
-
-Your email will be acknowledged within 24 hours, and you will receive a more
-detailed response to your email within 48 hours indicating the next steps in
-handling your report.
-
-There are no hard and fast rules to determine if a bug is worth reporting as
-a security issue. The general rule is an issue worth reporting should allow an
-attacker to compromise the confidentiality, integrity, or availability of the
-Node.js application or its system for which the attacker does not already have
-the capability.
-
-To illustrate the point, here are some examples of past issues and what the
-Security Response Team thinks of them. When in doubt, however, please do send
-us a report nonetheless.
-
-
-### Public disclosure preferred
-
-- [#14519](https://github.com/nodejs/node/issues/14519): _Internal domain
- function can be used to cause segfaults_. Causing program termination using
- either the public JavaScript APIs or the private bindings layer APIs requires
- the ability to execute arbitrary JavaScript code, which is already the highest
- level of privilege possible.
-
-- [#12141](https://github.com/nodejs/node/pull/12141): _buffer: zero fill
- Buffer(num) by default_. The buffer constructor behavior was documented,
- but found to be prone to [mis-use](https://snyk.io/blog/exploiting-buffer/).
- It has since been changed, but despite much debate, was not considered misuse
- prone enough to justify fixing in older release lines and breaking our
- API stability contract.
-
-### Private disclosure preferred
-
-- [CVE-2016-7099](https://nodejs.org/en/blog/vulnerability/september-2016-security-releases/):
- _Fix invalid wildcard certificate validation check_. This is a high severity
- defect that would allow a malicious TLS server to serve an invalid wildcard
- certificate for its hostname and be improperly validated by a Node.js client.
-
-- [#5507](https://github.com/nodejs/node/pull/5507): _Fix a defect that makes
- the CacheBleed Attack possible_. Many, though not all, OpenSSL vulnerabilities
- in the TLS/SSL protocols also affect Node.js.
-
-- [CVE-2016-2216](https://nodejs.org/en/blog/vulnerability/february-2016-security-releases/):
- _Fix defects in HTTP header parsing for requests and responses that can allow
- response splitting_. While the impact of this vulnerability is application and
- network dependent, it is remotely exploitable in the HTTP protocol.
-
-When in doubt, please do send us a report.
-
+For information on reporting security vulnerabilities in Node.js, see
+[SECURITY.md](./SECURITY.md).
## Current Project Team Members
-The Node.js project team comprises a group of core collaborators and a sub-group
-that forms the _Technical Steering Committee_ (TSC) which governs the project.
-For more information about the governance of the Node.js project, see
+For information about the governance of the Node.js project, see
[GOVERNANCE.md](./GOVERNANCE.md).
### TSC (Technical Steering Committee)
@@ -453,12 +401,12 @@ For more information about the governance of the Node.js project, see
**Alexis Campailla** <orangemocha@nodejs.org>
* [othiym23](https://github.com/othiym23) -
**Forrest L Norvell** <ogd@aoaioxxysz.net> (he/him)
-* [phillipj](https://github.com/phillipj) -
-**Phillip Johnsen** <johphi@gmail.com>
* [pmq20](https://github.com/pmq20) -
**Minqi Pan** <pmq2001@gmail.com>
* [princejwesley](https://github.com/princejwesley) -
**Prince John Wesley** <princejohnwesley@gmail.com>
+* [psmarshall](https://github.com/psmarshall) -
+**Peter Marshall** <petermarshall@chromium.org> (he/him)
* [Qard](https://github.com/Qard) -
**Stephen Belanger** <admin@stephenbelanger.com> (he/him)
* [refack](https://github.com/refack) -
@@ -487,6 +435,8 @@ For more information about the governance of the Node.js project, see
**Nikolai Vavilov** <vvnicholas@gmail.com>
* [shigeki](https://github.com/shigeki) -
**Shigeki Ohtsu** <ohtsu@ohtsu.org> (he/him)
+* [shisama](https://github.com/shisama) -
+**Masashi Hirano** <shisama07@gmail.com> (he/him)
* [silverwind](https://github.com/silverwind) -
**Roman Reiss** <me@silverwind.io>
* [srl295](https://github.com/srl295) -
@@ -554,6 +504,8 @@ For more information about the governance of the Node.js project, see
**Oleg Elifantiev** <oleg@elifantiev.ru>
* [petkaantonov](https://github.com/petkaantonov) -
**Petka Antonov** <petka_antonov@hotmail.com>
+* [phillipj](https://github.com/phillipj) -
+**Phillip Johnsen** <johphi@gmail.com>
* [piscisaureus](https://github.com/piscisaureus) -
**Bert Belder** <bertbelder@gmail.com>
* [rlidwka](https://github.com/rlidwka) -
@@ -572,9 +524,9 @@ For more information about the governance of the Node.js project, see
Collaborators follow the [COLLABORATOR_GUIDE.md](./COLLABORATOR_GUIDE.md) in
maintaining the Node.js project.
-### Release Team
+### Release Keys
-Node.js releases are signed with one of the following GPG keys:
+GPG keys used to sign Node.js releases:
* **Colin Ihrig** <cjihrig@gmail.com>
`94AE36675C464D64BAFA68DD7434390BDBE9B9C5`
@@ -593,7 +545,7 @@ Node.js releases are signed with one of the following GPG keys:
* **Rod Vagg** <rod@vagg.org>
`DD8F2338BAE7501E3DD5AC78C273792F7D83545D`
-The full set of trusted release keys can be imported by running:
+To import the full set of trusted release keys:
```shell
gpg --keyserver pool.sks-keyservers.net --recv-keys 94AE36675C464D64BAFA68DD7434390BDBE9B9C5
@@ -609,7 +561,7 @@ gpg --keyserver pool.sks-keyservers.net --recv-keys DD8F2338BAE7501E3DD5AC78C273
See the section above on [Verifying Binaries](#verifying-binaries) for how to
use these keys to verify a downloaded file.
-Previous releases may also have been signed with one of the following GPG keys:
+Other keys used to sign some previous releases:
* **Chris Dickinson** <christopher.s.dickinson@gmail.com>
`9554F04D7259F04124DE6B476D5A82AC7E37093B`
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 00000000000000..5f1e3e2cc7d563
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,37 @@
+# Security
+
+If you find a security vulnerability in Node.js, please report it to
+security@nodejs.org. Please withhold public disclosure until after the security
+team has addressed the vulnerability.
+
+The security team will acknowledge your email within 24 hours. You will receive
+a more detailed response within 48 hours.
+
+There are no hard and fast rules to determine if a bug is worth reporting as a
+security issue. Here are some examples of past issues and what the Security
+Response Team thinks of them. When in doubt, please do send us a report
+nonetheless.
+
+## Public disclosure preferred
+
+- [#14519](https://github.com/nodejs/node/issues/14519): _Internal domain
+ function can be used to cause segfaults_. Requires the ability to execute
+ arbitrary JavaScript code. That is already the highest level of privilege
+ possible.
+
+## Private disclosure preferred
+
+- [CVE-2016-7099](https://nodejs.org/en/blog/vulnerability/september-2016-security-releases/):
+ _Fix invalid wildcard certificate validation check_. This was a high-severity
+ defect. It caused Node.js TLS clients to accept invalid wildcard certificates.
+
+- [#5507](https://github.com/nodejs/node/pull/5507): _Fix a defect that makes
+ the CacheBleed Attack possible_. Many, though not all, OpenSSL vulnerabilities
+ in the TLS/SSL protocols also affect Node.js.
+
+- [CVE-2016-2216](https://nodejs.org/en/blog/vulnerability/february-2016-security-releases/):
+ _Fix defects in HTTP header parsing for requests and responses that can allow
+ response splitting_. This was a remotely-exploitable defect in the Node.js
+ HTTP implementation.
+
+When in doubt, please do send us a report.
diff --git a/benchmark/_http-benchmarkers.js b/benchmark/_http-benchmarkers.js
index 76e02504b27ec1..c0e85316be7634 100644
--- a/benchmark/_http-benchmarkers.js
+++ b/benchmark/_http-benchmarkers.js
@@ -8,7 +8,7 @@ const requirementsURL =
'https://github.com/nodejs/node/blob/master/doc/guides/writing-and-running-benchmarks.md#http-benchmark-requirements';
// The port used by servers and wrk
-exports.PORT = process.env.PORT || 12346;
+exports.PORT = Number(process.env.PORT) || 12346;
class AutocannonBenchmarker {
constructor() {
@@ -35,7 +35,7 @@ class AutocannonBenchmarker {
let result;
try {
result = JSON.parse(output);
- } catch (err) {
+ } catch {
return undefined;
}
if (!result || !result.requests || !result.requests.average) {
@@ -105,7 +105,7 @@ class TestDoubleBenchmarker {
let result;
try {
result = JSON.parse(output);
- } catch (err) {
+ } catch {
return undefined;
}
return result.throughput;
diff --git a/benchmark/child_process/child-process-exec-stdout.js b/benchmark/child_process/child-process-exec-stdout.js
index a891026b86971f..88c02533f605c2 100644
--- a/benchmark/child_process/child-process-exec-stdout.js
+++ b/benchmark/child_process/child-process-exec-stdout.js
@@ -30,7 +30,7 @@ function childProcessExecStdout({ dur, len }) {
// Sometimes there's a yes.exe process left hanging around on Windows.
try {
execSync(`taskkill /f /t /pid ${child.pid}`);
- } catch (_) {
+ } catch {
// this is a best effort kill. stderr is piped to parent for tracing.
}
} else {
diff --git a/benchmark/fs/bench-mkdirp.js b/benchmark/fs/bench-mkdirp.js
index 96a792c35a48e4..b9e62045f6cf50 100644
--- a/benchmark/fs/bench-mkdirp.js
+++ b/benchmark/fs/bench-mkdirp.js
@@ -16,7 +16,7 @@ function main({ n }) {
if (cntr-- <= 0)
return bench.end(n);
const pathname = `${tmpdir.path}/${++dirc}/${++dirc}/${++dirc}/${++dirc}`;
- fs.mkdir(pathname, { createParents: true }, (err) => {
+ fs.mkdir(pathname, { recursive: true }, (err) => {
r(cntr);
});
}(n));
diff --git a/benchmark/fs/read-stream-throughput.js b/benchmark/fs/read-stream-throughput.js
index 3af80132725ec0..7f290a310b592c 100644
--- a/benchmark/fs/read-stream-throughput.js
+++ b/benchmark/fs/read-stream-throughput.js
@@ -55,7 +55,7 @@ function runTest() {
});
rs.on('end', function() {
- try { fs.unlinkSync(filename); } catch (e) {}
+ try { fs.unlinkSync(filename); } catch {}
// MB/sec
bench.end(bytes / (1024 * 1024));
});
@@ -74,7 +74,7 @@ function makeFile() {
buf.fill('x');
}
- try { fs.unlinkSync(filename); } catch (e) {}
+ try { fs.unlinkSync(filename); } catch {}
var w = 1024;
const ws = fs.createWriteStream(filename);
ws.on('close', runTest);
diff --git a/benchmark/fs/readfile-partitioned.js b/benchmark/fs/readfile-partitioned.js
index be3b7fd057bbe0..6e355c158da850 100644
--- a/benchmark/fs/readfile-partitioned.js
+++ b/benchmark/fs/readfile-partitioned.js
@@ -24,7 +24,7 @@ const bench = common.createBenchmark(main, {
function main(conf) {
const len = +conf.len;
- try { fs.unlinkSync(filename); } catch (e) {}
+ try { fs.unlinkSync(filename); } catch {}
var data = Buffer.alloc(len, 'x');
fs.writeFileSync(filename, data);
data = null;
@@ -39,7 +39,7 @@ function main(conf) {
const totalOps = reads + zips;
benchEnded = true;
bench.end(totalOps);
- try { fs.unlinkSync(filename); } catch (e) {}
+ try { fs.unlinkSync(filename); } catch {}
}, +conf.dur * 1000);
function read() {
diff --git a/benchmark/fs/readfile.js b/benchmark/fs/readfile.js
index 282b4ac7621340..36439bdf909f1d 100644
--- a/benchmark/fs/readfile.js
+++ b/benchmark/fs/readfile.js
@@ -17,7 +17,7 @@ const bench = common.createBenchmark(main, {
});
function main({ len, dur, concurrent }) {
- try { fs.unlinkSync(filename); } catch (e) {}
+ try { fs.unlinkSync(filename); } catch {}
var data = Buffer.alloc(len, 'x');
fs.writeFileSync(filename, data);
data = null;
@@ -28,7 +28,7 @@ function main({ len, dur, concurrent }) {
setTimeout(function() {
benchEnded = true;
bench.end(reads);
- try { fs.unlinkSync(filename); } catch (e) {}
+ try { fs.unlinkSync(filename); } catch {}
process.exit(0);
}, dur * 1000);
diff --git a/benchmark/fs/write-stream-throughput.js b/benchmark/fs/write-stream-throughput.js
index 60ad47bc4eabe1..baf98f849fed07 100644
--- a/benchmark/fs/write-stream-throughput.js
+++ b/benchmark/fs/write-stream-throughput.js
@@ -33,7 +33,7 @@ function main({ dur, encodingType, size }) {
throw new Error(`invalid encodingType: ${encodingType}`);
}
- try { fs.unlinkSync(filename); } catch (e) {}
+ try { fs.unlinkSync(filename); } catch {}
var started = false;
var ended = false;
@@ -45,7 +45,7 @@ function main({ dur, encodingType, size }) {
f.on('finish', function() {
ended = true;
const written = fs.statSync(filename).size / 1024;
- try { fs.unlinkSync(filename); } catch (e) {}
+ try { fs.unlinkSync(filename); } catch {}
bench.end(written / 1024);
});
diff --git a/benchmark/http/bench-parser.js b/benchmark/http/bench-parser.js
index d629fe67e59e76..fdf4ec0d1eda14 100644
--- a/benchmark/http/bench-parser.js
+++ b/benchmark/http/bench-parser.js
@@ -31,7 +31,7 @@ function processHeader(header, n) {
bench.start();
for (var i = 0; i < n; i++) {
parser.execute(header, 0, header.length);
- parser.reinitialize(REQUEST);
+ parser.reinitialize(REQUEST, i > 0);
}
bench.end(n);
}
diff --git a/benchmark/misc/freelist.js b/benchmark/misc/freelist.js
index 8c3281cc407363..7fa9af4f3ddb7f 100644
--- a/benchmark/misc/freelist.js
+++ b/benchmark/misc/freelist.js
@@ -9,7 +9,7 @@ const bench = common.createBenchmark(main, {
});
function main({ n }) {
- const FreeList = require('internal/freelist');
+ const { FreeList } = require('internal/freelist');
const poolSize = 1000;
const list = new FreeList('test', poolSize, Object);
var j;
diff --git a/benchmark/misc/punycode.js b/benchmark/misc/punycode.js
index 369adcf17d3973..dc8df58ef38185 100644
--- a/benchmark/misc/punycode.js
+++ b/benchmark/misc/punycode.js
@@ -4,7 +4,7 @@ const common = require('../common.js');
let icu;
try {
icu = process.binding('icu');
-} catch (err) {}
+} catch {}
const punycode = require('punycode');
const bench = common.createBenchmark(main, {
diff --git a/benchmark/module/module-loader.js b/benchmark/module/module-loader.js
index c79e1a73d4f21a..e780d6376b5e8d 100644
--- a/benchmark/module/module-loader.js
+++ b/benchmark/module/module-loader.js
@@ -14,7 +14,7 @@ const bench = common.createBenchmark(main, {
function main({ n, fullPath, useCache }) {
tmpdir.refresh();
- try { fs.mkdirSync(benchmarkDirectory); } catch (e) {}
+ try { fs.mkdirSync(benchmarkDirectory); } catch {}
for (var i = 0; i <= n; i++) {
fs.mkdirSync(`${benchmarkDirectory}${i}`);
fs.writeFileSync(
diff --git a/benchmark/napi/function_args/index.js b/benchmark/napi/function_args/index.js
index 4beab531c17301..c41b5d78abadd9 100644
--- a/benchmark/napi/function_args/index.js
+++ b/benchmark/napi/function_args/index.js
@@ -11,14 +11,14 @@ let napi;
try {
v8 = require('./build/Release/binding');
-} catch (err) {
+} catch {
console.error(`${__filename}: V8 Binding failed to load`);
process.exit(0);
}
try {
napi = require('./build/Release/napi_binding');
-} catch (err) {
+} catch {
console.error(`${__filename}: NAPI-Binding failed to load`);
process.exit(0);
}
diff --git a/benchmark/napi/function_args/napi_binding.c b/benchmark/napi/function_args/napi_binding.c
index b697644ca441e9..1a3a0f1cd2b96e 100644
--- a/benchmark/napi/function_args/napi_binding.c
+++ b/benchmark/napi/function_args/napi_binding.c
@@ -50,7 +50,8 @@ static napi_value CallWithArray(napi_env env, napi_callback_info info) {
status = napi_get_array_length(env, array, &length);
assert(status == napi_ok);
- for (uint32_t i = 0; i < length; ++i) {
+ uint32_t i;
+ for (i = 0; i < length; ++i) {
napi_value v;
status = napi_get_element(env, array, i, &v);
assert(status == napi_ok);
@@ -173,7 +174,8 @@ static napi_value CallWithArguments(napi_env env, napi_callback_info info) {
status = napi_get_value_uint32(env, args[0], &loop);
assert(status == napi_ok);
- for (uint32_t i = 1; i < loop; ++i) {
+ uint32_t i;
+ for (i = 1; i < loop; ++i) {
assert(i < argc);
status = napi_typeof(env, args[i], types);
assert(status == napi_ok);
diff --git a/benchmark/napi/function_call/index.js b/benchmark/napi/function_call/index.js
index cbc512c9729137..272c41662d2830 100644
--- a/benchmark/napi/function_call/index.js
+++ b/benchmark/napi/function_call/index.js
@@ -13,7 +13,7 @@ const common = require('../../common.js');
try {
var binding = require('./build/Release/binding');
-} catch (er) {
+} catch {
console.error('misc/function_call.js Binding failed to load');
process.exit(0);
}
@@ -22,7 +22,7 @@ const cxx = binding.hello;
let napi_binding;
try {
napi_binding = require('./build/Release/napi_binding');
-} catch (er) {
+} catch {
console.error('misc/function_call/index.js NAPI-Binding failed to load');
process.exit(0);
}
diff --git a/common.gypi b/common.gypi
index 14c6b5ae9f8463..e2295ee35de832 100644
--- a/common.gypi
+++ b/common.gypi
@@ -33,7 +33,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.36',
+ 'v8_embedder_string': '-node.45',
# Enable disassembler for `--print-code` v8 options
'v8_enable_disassembler': 1,
diff --git a/configure.py b/configure.py
index b98e37d944d7f0..a5075bd9d8a60b 100755
--- a/configure.py
+++ b/configure.py
@@ -1,3 +1,4 @@
+import json
import sys
import errno
import optparse
@@ -50,6 +51,8 @@
valid_mips_fpu = ('fp32', 'fp64', 'fpxx')
valid_mips_float_abi = ('soft', 'hard')
valid_intl_modes = ('none', 'small-icu', 'full-icu', 'system-icu')
+with open ('tools/icu/icu_versions.json') as f:
+ icu_versions = json.load(f)
# create option groups
shared_optgroup = optparse.OptionGroup(parser, "Shared libraries",
@@ -387,6 +390,12 @@
dest='with_etw',
help='build with ETW (default is true on Windows)')
+parser.add_option('--use-largepages',
+ action='store_true',
+ dest='node_use_large_pages',
+ help='build with Large Pages support. This feature is supported only on Linux kernel' +
+ '>= 2.6.38 with Transparent Huge pages enabled')
+
intl_optgroup.add_option('--with-intl',
action='store',
dest='with_intl',
@@ -418,7 +427,9 @@
intl_optgroup.add_option('--with-icu-source',
action='store',
dest='with_icu_source',
- help='Intl mode: optional local path to icu/ dir, or path/URL of icu source archive.')
+ help='Intl mode: optional local path to icu/ dir, or path/URL of '
+ 'the icu4c source archive. '
+ 'v%d.x or later recommended.' % icu_versions["minimum_icu"])
parser.add_option('--with-ltcg',
action='store_true',
@@ -1007,6 +1018,24 @@ def configure_node(o):
else:
o['variables']['node_use_dtrace'] = 'false'
+ if options.node_use_large_pages and flavor != 'linux':
+ raise Exception(
+ 'Large pages are supported only on Linux Systems.')
+ if options.node_use_large_pages and flavor == 'linux':
+ if options.shared or options.enable_static:
+ raise Exception(
+ 'Large pages are supported only while creating node executable.')
+ if target_arch!="x64":
+ raise Exception(
+ 'Large pages are supported only x64 platform.')
+ # Example full version string: 2.6.32-696.28.1.el6.x86_64
+ FULL_KERNEL_VERSION=os.uname()[2]
+ KERNEL_VERSION=FULL_KERNEL_VERSION.split('-')[0]
+ if KERNEL_VERSION < "2.6.38":
+ raise Exception(
+ 'Large pages need Linux kernel version >= 2.6.38')
+ o['variables']['node_use_large_pages'] = b(options.node_use_large_pages)
+
if options.no_ifaddrs:
o['defines'] += ['SUNOS_NO_IFADDRS']
@@ -1252,13 +1281,9 @@ def glob_to_var(dir_base, dir_sub, patch_dir):
return list
def configure_intl(o):
- icus = [
- {
- 'url': 'https://sourceforge.net/projects/icu/files/ICU4C/62.1/icu4c-62_1-src.zip',
- 'md5': '408854f7b9b58311b68fab4b4dfc80be',
- },
- ]
def icu_download(path):
+ with open('tools/icu/current_ver.dep') as f:
+ icus = json.load(f)
# download ICU, if needed
if not os.access(options.download_path, os.W_OK):
error('''Cannot write to desired download path.
@@ -1449,6 +1474,9 @@ def write_config(data, name):
icu_ver_major = m.group(1)
if not icu_ver_major:
error('Could not read U_ICU_VERSION_SHORT version from %s' % uvernum_h)
+ elif int(icu_ver_major) < icu_versions["minimum_icu"]:
+ error('icu4c v%d.x is too old, v%d.x or later is required.' % (int(icu_ver_major),
+ icu_versions["minimum_icu"]))
icu_endianness = sys.byteorder[0];
o['variables']['icu_ver_major'] = icu_ver_major
o['variables']['icu_endianness'] = icu_endianness
diff --git a/deps/cares/LICENSE.md b/deps/cares/LICENSE.md
index 86b520b91d3705..ad6bb52b729ed4 100644
--- a/deps/cares/LICENSE.md
+++ b/deps/cares/LICENSE.md
@@ -1,6 +1,6 @@
# c-ares license
-Copyright (c) 2007 - 2016, Daniel Stenberg with many contributors, see AUTHORS
+Copyright (c) 2007 - 2018, Daniel Stenberg with many contributors, see AUTHORS
file.
Copyright 1998 by the Massachusetts Institute of Technology.
diff --git a/deps/cares/Makefile b/deps/cares/Makefile
deleted file mode 100644
index 069c67e542fa74..00000000000000
--- a/deps/cares/Makefile
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright Joyent, Inc. and other Node contributors. All rights reserved.
-#
-# 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.
-
-SRCDIR ?= $(CURDIR)
-
-ifeq (,$(builddir_name))
-
-VPATH := $(SRCDIR)
-include $(SRCDIR)/build.mk
-
-else # Out of tree build.
-
-# Drop all built-in rules.
-.SUFFIXES:
-
-.PHONY: $(builddir_name)
-$(builddir_name): $(builddir_name)/.buildstamp
- $(MAKE) -C $@ -f $(CURDIR)/Makefile $(MAKECMDGOALS) \
- SRCDIR=$(CURDIR) builddir_name=
-
-$(builddir_name)/.buildstamp:
- mkdir -p $(dir $@)
- touch $@
-
-# Add no-op rules for Makefiles to stop make from trying to rebuild them.
-Makefile:: ;
-%.mk:: ;
-
-# Turn everything else into a no-op rule that depends on the build directory.
-%:: $(builddir_name) ;
-
-.PHONY: clean
-clean:
- $(RM) -fr $(builddir_name)
-
-endif
diff --git a/deps/cares/android-configure b/deps/cares/android-configure
deleted file mode 100755
index 5299e5c718a9bd..00000000000000
--- a/deps/cares/android-configure
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/bash
-
-export TOOLCHAIN=$PWD/android-toolchain
-mkdir -p $TOOLCHAIN
-$1/build/tools/make-standalone-toolchain.sh \
- --toolchain=arm-linux-androideabi-4.7 \
- --arch=arm \
- --install-dir=$TOOLCHAIN \
- --platform=android-9
-export PATH=$TOOLCHAIN/bin:$PATH
-export AR=arm-linux-androideabi-ar
-export CC=arm-linux-androideabi-gcc
-export CXX=arm-linux-androideabi-g++
-export LINK=arm-linux-androideabi-g++
-export PLATFORM=android
-export OS=android
-
-if [ $2 -a $2 == 'gyp' ]
- then
- ./gyp_cares -DOS=android -Dtarget_arch=arm
-fi
diff --git a/deps/cares/build.mk b/deps/cares/build.mk
deleted file mode 100644
index 91af512721ce8d..00000000000000
--- a/deps/cares/build.mk
+++ /dev/null
@@ -1,147 +0,0 @@
-# Copyright Joyent, Inc. and other Node contributors. All rights reserved.
-#
-# 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.
-
-OS ?= $(shell sh -c 'uname -s | tr "[A-Z]" "[a-z]"')
-
-OBJS= \
- src/ares_cancel.o \
- src/ares__close_sockets.o \
- src/ares_create_query.o \
- src/ares_data.o \
- src/ares_destroy.o \
- src/ares_expand_name.o \
- src/ares_expand_string.o \
- src/ares_fds.o \
- src/ares_free_hostent.o \
- src/ares_free_string.o \
- src/ares_gethostbyaddr.o \
- src/ares_gethostbyname.o \
- src/ares__get_hostent.o \
- src/ares_getnameinfo.o \
- src/ares_getopt.o \
- src/ares_getsock.o \
- src/ares_init.o \
- src/ares_library_init.o \
- src/ares_llist.o \
- src/ares_mkquery.o \
- src/ares_nowarn.o \
- src/ares_options.o \
- src/ares_parse_aaaa_reply.o \
- src/ares_parse_a_reply.o \
- src/ares_parse_mx_reply.o \
- src/ares_parse_naptr_reply.o \
- src/ares_parse_ns_reply.o \
- src/ares_parse_ptr_reply.o \
- src/ares_parse_soa_reply.o \
- src/ares_parse_srv_reply.o \
- src/ares_parse_txt_reply.o \
- src/ares_process.o \
- src/ares_query.o \
- src/ares__read_line.o \
- src/ares_search.o \
- src/ares_send.o \
- src/ares_strcasecmp.o \
- src/ares_strdup.o \
- src/ares_strerror.o \
- src/ares_timeout.o \
- src/ares__timeval.o \
- src/ares_version.o \
- src/ares_writev.o \
- src/bitncmp.o \
- src/inet_net_pton.o \
- src/inet_ntop.o \
-
-CFLAGS += -I. -I$(SRCDIR)/include -DHAVE_CONFIG_H
-
-ARES_CONFIG_OS = $(OS)
-SOEXT = so
-
-# if on windows
-ifneq (,$(findstring mingw,$(OS)))
-ARES_CONFIG_OS = win32
-OBJS += src/windows_port.o
-OBJS += src/ares_getenv.o
-OBJS += src/ares_platform.o
-
-LDFLAGS += -lws2_32.lib -liphlpapi.lib
-else # else a posix system
-CFLAGS += -g --std=gnu89 -pedantic
-CFLAGS += -Wall -Wextra -Wno-unused-parameter
-CFLAGS += -D_LARGEFILE_SOURCE
-CFLAGS += -D_FILE_OFFSET_BITS=64
-endif
-
-ifneq (,$(findstring cygwin,$(OS)))
-ARES_CONFIG_OS = cygwin
-CFLAGS += -D_GNU_SOURCE
-endif
-
-ifeq (dragonflybsd,$(OS))
-ARES_CONFIG_OS = freebsd
-endif
-
-ifeq (darwin,$(OS))
-CFLAGS += -D_DARWIN_USE_64_BIT_INODE=1
-LDFLAGS += -dynamiclib -install_name "@rpath/libcares.dylib"
-SOEXT = dylib
-endif
-
-ifeq (linux,$(OS))
-CFLAGS += -D_GNU_SOURCE
-endif
-
-ifeq (android,$(OS))
-CFLAGS += -D_GNU_SOURCE
-endif
-
-ifeq (sunos,$(OS))
-LDFLAGS += -lsocket -lnsl
-CFLAGS += -D__EXTENSIONS__ -D_XOPEN_SOURCE=500
-endif
-
-CFLAGS += -I$(SRCDIR)/config/$(ARES_CONFIG_OS)
-
-ifneq (,$(findstring libcares.$(SOEXT),$(MAKECMDGOALS)))
-CFLAGS += -DCARES_BUILDING_LIBRARY
-else
-CFLAGS += -DCARES_STATICLIB
-endif
-
-all: libcares.a
-
-src/.buildstamp:
- mkdir -p $(dir $@)
- touch $@
-
-libcares.a: $(OBJS)
- $(AR) rcs $@ $^
-
-libcares.$(SOEXT): override CFLAGS += -fPIC
-libcares.$(SOEXT): $(OBJS:%.o=%.pic.o)
- $(CC) -shared -o $@ $^ $(LDFLAGS)
-
-src/%.o src/%.pic.o: src/%.c include/ares.h include/ares_version.h \
- include/nameser.h src/.buildstamp \
- $(SRCDIR)/config/$(ARES_CONFIG_OS)/ares_config.h
- $(CC) $(CFLAGS) -c $< -o $@
-
-.PHONY: clean
-clean:
- $(RM) -f libcares.a libcares.$(SOEXT) src/*.o src/.buildstamp
diff --git a/deps/cares/build/gcc_version.py b/deps/cares/build/gcc_version.py
deleted file mode 100644
index da019e866114b0..00000000000000
--- a/deps/cares/build/gcc_version.py
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/env python
-
-import os
-import re
-import subprocess
-import sys
-
-
-def DoMain(*args):
- cc = os.environ.get('CC', 'gcc')
- stdin, stderr = os.pipe()
- subprocess.call([cc, '-v'], stderr=stderr)
- output = os.read(stdin, 4096)
- match = re.search("\ngcc version (\d+\.\d+\.\d+)", output)
- if match:
- print(match.group(1))
-
-
-if __name__ == '__main__':
- DoMain(*sys.argv)
diff --git a/deps/cares/cares.gyp b/deps/cares/cares.gyp
index fce52acb31f495..be7931f7743db1 100644
--- a/deps/cares/cares.gyp
+++ b/deps/cares/cares.gyp
@@ -35,7 +35,6 @@
'include_dirs': [ 'include' ]
},
'sources': [
- 'common.gypi',
'include/ares.h',
'include/ares_rules.h',
'include/ares_version.h',
@@ -93,6 +92,7 @@
'src/ares_strdup.c',
'src/ares_strdup.h',
'src/ares_strerror.c',
+ 'src/ares_strsplit.c',
'src/ares_timeout.c',
'src/ares__timeval.c',
'src/ares_version.c',
diff --git a/deps/cares/common.gypi b/deps/cares/common.gypi
deleted file mode 100644
index 609ad62a3965d0..00000000000000
--- a/deps/cares/common.gypi
+++ /dev/null
@@ -1,172 +0,0 @@
-{
- 'variables': {
- 'visibility%': 'hidden',
- 'library%': 'static_library', # allow override to 'shared_library' for DLL/.so builds
- 'component%': 'static_library',
- 'host_arch%': '',
- 'target_arch%': ''
- },
-
- 'target_defaults': {
- 'default_configuration': 'Debug',
- 'configurations': {
-
- 'Debug': {
- 'defines': [ 'DEBUG', '_DEBUG' ],
- 'cflags': [ '-g', '-O0' ],
- 'msvs_settings': {
- 'VCCLCompilerTool': {
- 'target_conditions': [
- ['library=="static_library"', {
- 'RuntimeLibrary': 1 # static debug
- }, {
- 'RuntimeLibrary': 3 # DLL debug
- }]
- ],
- 'Optimization': 0, # /Od, no optimization
- 'MinimalRebuild': 'false',
- 'OmitFramePointers': 'false',
- 'BasicRuntimeChecks': 3 # /RTC1
- },
- 'VCLinkerTool': {
- 'LinkIncremental': 2 # enable incremental linking
- }
- },
- 'xcode_settings': {
- 'GCC_OPTIMIZATION_LEVEL': '0'
- }
- },
-
- 'Release': {
- 'defines': [ 'NDEBUG' ],
- 'cflags': [
- '-O3',
- '-fomit-frame-pointer',
- '-fdata-sections',
- '-ffunction-sections'
- ],
- 'msvs_settings': {
- 'VCCLCompilerTool': {
- 'target_conditions': [
- ['library=="static_library"', {
- 'RuntimeLibrary': 0, # static release
- }, {
- 'RuntimeLibrary': 2, # debug release
- }],
- ],
- 'Optimization': 3, # /Ox, full optimization
- 'FavorSizeOrSpeed': 1, # /Ot, favour speed over size
- 'InlineFunctionExpansion': 2, # /Ob2, inline anything eligible
- 'WholeProgramOptimization': 'true', # /GL, whole program optimization, needed for LTCG
- 'OmitFramePointers': 'true',
- 'EnableFunctionLevelLinking': 'true',
- 'EnableIntrinsicFunctions': 'true'
- },
- 'VCLibrarianTool': {
- 'AdditionalOptions': [
- '/LTCG' # link time code generation
- ]
- },
- 'VCLinkerTool': {
- 'LinkTimeCodeGeneration': 1, # link-time code generation
- 'OptimizeReferences': 2, # /OPT:REF
- 'EnableCOMDATFolding': 2, # /OPT:ICF
- 'LinkIncremental': 1 # disable incremental linking
- },
- },
- }
- },
-
- 'msvs_settings': {
- 'VCCLCompilerTool': {
- 'StringPooling': 'true', # pool string literals
- 'DebugInformationFormat': 3, # Generate a PDB
- 'WarningLevel': 3,
- 'BufferSecurityCheck': 'true',
- 'ExceptionHandling': 1, # /EHsc
- 'SuppressStartupBanner': 'true',
- 'WarnAsError': 'false',
- 'AdditionalOptions': [
- '/MP', # compile across multiple CPUs
- ],
- },
- 'VCLinkerTool': {
- 'GenerateDebugInformation': 'true',
- 'RandomizedBaseAddress': 2, # enable ASLR
- 'DataExecutionPrevention': 2, # enable DEP
- 'AllowIsolation': 'true',
- 'SuppressStartupBanner': 'true',
- 'target_conditions': [
- ['_type=="executable"', {
- 'SubSystem': 1, # console executable
- }],
- ],
- },
- },
-
- 'xcode_settings': {
- 'ALWAYS_SEARCH_USER_PATHS': 'NO',
- 'GCC_CW_ASM_SYNTAX': 'NO', # No -fasm-blocks
- 'GCC_ENABLE_CPP_EXCEPTIONS': 'NO', # -fno-exceptions
- 'GCC_ENABLE_CPP_RTTI': 'NO', # -fno-rtti
- 'GCC_ENABLE_PASCAL_STRINGS': 'NO', # No -mpascal-strings
- # GCC_INLINES_ARE_PRIVATE_EXTERN maps to -fvisibility-inlines-hidden
- 'GCC_INLINES_ARE_PRIVATE_EXTERN': 'YES',
- 'GCC_SYMBOLS_PRIVATE_EXTERN': 'YES', # -fvisibility=hidden
- 'GCC_THREADSAFE_STATICS': 'NO', # -fno-threadsafe-statics
- 'GCC_WARN_ABOUT_MISSING_NEWLINE': 'YES', # -Wnewline-eof
- 'PREBINDING': 'NO', # No -Wl,-prebind
- 'USE_HEADERMAP': 'NO',
- 'WARNING_CFLAGS': [
- '-Wall',
- '-Wendif-labels',
- '-W',
- '-Wno-unused-parameter'
- ]
- },
-
- 'conditions': [
- ['OS == "win"', {
- 'msvs_cygwin_shell': 0, # prevent actions from trying to use cygwin
- 'defines': [
- 'WIN32',
- # we don't want VC++ warning us about how dangerous C functions are.
- '_CRT_SECURE_NO_DEPRECATE',
- # ... or that C implementations shouldn't use POSIX names
- '_CRT_NONSTDC_NO_DEPRECATE'
- ],
- }],
-
- [ 'OS in "linux freebsd openbsd solaris android aix"', {
- 'variables': {
- 'gcc_version%': ')'
- },
- 'cflags': [ '-Wall' ],
- 'cflags_cc': [ '-fno-rtti', '-fno-exceptions' ],
- 'conditions': [
- [ 'host_arch != target_arch and target_arch=="ia32"', {
- 'cflags': [ '-m32' ],
- 'ldflags': [ '-m32' ]
- }],
- [ 'OS=="linux"', {
- 'cflags': [ '-ansi' ]
- }],
- [ 'visibility=="hidden" and gcc_version >= "4.0.0"', {
- 'cflags': [ '-fvisibility=hidden' ]
- }],
- ]
- }]
- ],
-
- 'target_conditions': [
- ['_type!="static_library"', {
- 'cflags': [ '-fPIC' ],
- 'xcode_settings': {
- 'GCC_DYNAMIC_NO_PIC': 'NO', # No -mdynamic-no-pic
- # (Equivalent to -fPIC)
- 'OTHER_LDFLAGS': [ '-Wl,-search_paths_first' ]
- }
- }]
- ]
- }
-}
diff --git a/deps/cares/get_ver.awk b/deps/cares/get_ver.awk
deleted file mode 100644
index f9929b73614ba3..00000000000000
--- a/deps/cares/get_ver.awk
+++ /dev/null
@@ -1,26 +0,0 @@
-# ***************************************************************************
-# * Project: c-ares
-# *
-# ***************************************************************************
-# awk script which fetches c-ares version number and string from input
-# file and writes them to STDOUT. Here you can get an awk version for Win32:
-# http://www.gknw.net/development/prgtools/awk-20100523.zip
-#
-BEGIN {
- while ((getline < ARGV[1]) > 0) {
- sub("\r", "") # make MSYS gawk work with CRLF header input.
- if (match ($0, /^#define ARES_COPYRIGHT "[^"]+"$/))
- copyright_string = substr($0, 25, length($0)-25)
- else if (match ($0, /^#define ARES_VERSION_STR "[^"]+"$/))
- version_string = substr($3, 2, length($3)-2)
- else if (match ($0, /^#define ARES_VERSION_MAJOR [0-9]+$/))
- version_major = $3
- else if (match ($0, /^#define ARES_VERSION_MINOR [0-9]+$/))
- version_minor = $3
- else if (match ($0, /^#define ARES_VERSION_PATCH [0-9]+$/))
- version_patch = $3
- }
- print "LIBCARES_VERSION = " version_major "," version_minor "," version_patch
- print "LIBCARES_VERSION_STR = " version_string
- print "LIBCARES_COPYRIGHT_STR = " copyright_string
-}
diff --git a/deps/cares/gyp_cares b/deps/cares/gyp_cares
deleted file mode 100755
index d1f1640e015706..00000000000000
--- a/deps/cares/gyp_cares
+++ /dev/null
@@ -1,98 +0,0 @@
-#!/usr/bin/env python
-
-import glob
-import platform
-import os
-import subprocess
-import sys
-
-CC = os.environ.get('CC', 'cc')
-script_dir = os.path.dirname(__file__)
-cares_root = os.path.normpath(script_dir)
-output_dir = os.path.join(os.path.abspath(cares_root), 'out')
-
-sys.path.insert(0, os.path.join(cares_root, 'build', 'gyp', 'pylib'))
-try:
- import gyp
-except ImportError:
- print('You need to install gyp in build/gyp first. See the README.')
- sys.exit(42)
-
-
-def host_arch():
- machine = platform.machine()
- if machine == 'i386': return 'ia32'
- if machine == 'x86_64': return 'x64'
- if machine.startswith('arm'): return 'arm'
- return machine # Return as-is and hope for the best.
-
-
-def compiler_version():
- proc = subprocess.Popen(CC.split() + ['--version'], stdout=subprocess.PIPE)
- is_clang = 'clang' in proc.communicate()[0].split('\n')[0]
- proc = subprocess.Popen(CC.split() + ['-dumpversion'], stdout=subprocess.PIPE)
- version = proc.communicate()[0].split('.')
- version = map(int, version[:2])
- version = tuple(version)
- return (version, is_clang)
-
-
-def run_gyp(args):
- rc = gyp.main(args)
- if rc != 0:
- print 'Error running GYP'
- sys.exit(rc)
-
-
-if __name__ == '__main__':
- args = sys.argv[1:]
-
- # GYP bug.
- # On msvs it will crash if it gets an absolute path.
- # On Mac/make it will crash if it doesn't get an absolute path.
- if sys.platform == 'win32':
- args.append(os.path.join(cares_root, 'cares.gyp'))
- common_fn = os.path.join(cares_root, 'common.gypi')
- options_fn = os.path.join(cares_root, 'options.gypi')
- # we force vs 2010 over 2008 which would otherwise be the default for gyp
- if not os.environ.get('GYP_MSVS_VERSION'):
- os.environ['GYP_MSVS_VERSION'] = '2010'
- else:
- args.append(os.path.join(os.path.abspath(cares_root), 'cares.gyp'))
- common_fn = os.path.join(os.path.abspath(cares_root), 'common.gypi')
- options_fn = os.path.join(os.path.abspath(cares_root), 'options.gypi')
-
- if os.path.exists(common_fn):
- args.extend(['-I', common_fn])
-
- if os.path.exists(options_fn):
- args.extend(['-I', options_fn])
-
- args.append('--depth=' + cares_root)
-
- # There's a bug with windows which doesn't allow this feature.
- if sys.platform != 'win32':
- if '-f' not in args:
- args.extend('-f make'.split())
- if 'ninja' not in args:
- args.extend(['-Goutput_dir=' + output_dir])
- args.extend(['--generator-output', output_dir])
- (major, minor), is_clang = compiler_version()
- args.append('-Dgcc_version=%d' % (10 * major + minor))
- args.append('-Dclang=%d' % int(is_clang))
-
- if not any(a.startswith('-Dhost_arch=') for a in args):
- args.append('-Dhost_arch=%s' % host_arch())
-
- if not any(a.startswith('-Dtarget_arch=') for a in args):
- args.append('-Dtarget_arch=%s' % host_arch())
-
- if not any(a.startswith('-Dlibrary=') for a in args):
- args.append('-Dlibrary=static_library')
-
- if not any(a.startswith('-Dcomponent=') for a in args):
- args.append('-Dcomponent=static_library')
-
- gyp_args = list(args)
- print gyp_args
- run_gyp(gyp_args)
diff --git a/deps/cares/include/ares.h b/deps/cares/include/ares.h
index 65a82cb5b7eb47..06f60b33304b80 100644
--- a/deps/cares/include/ares.h
+++ b/deps/cares/include/ares.h
@@ -164,6 +164,7 @@ extern "C" {
#define ARES_OPT_ROTATE (1 << 14)
#define ARES_OPT_EDNSPSZ (1 << 15)
#define ARES_OPT_NOROTATE (1 << 16)
+#define ARES_OPT_RESOLVCONF (1 << 17)
/* Nameinfo flag values */
#define ARES_NI_NOFQDN (1 << 0)
@@ -270,6 +271,7 @@ struct ares_options {
struct apattern *sortlist;
int nsort;
int ednspsz;
+ char *resolvconf_path;
};
struct hostent;
diff --git a/deps/cares/include/ares_build.h b/deps/cares/include/ares_build.h
index f5535b38493fcb..5e3ba9f0d8cb0c 100644
--- a/deps/cares/include/ares_build.h
+++ b/deps/cares/include/ares_build.h
@@ -194,16 +194,14 @@
/* Data type definition of ares_ssize_t. */
#ifdef _WIN32
# ifdef _WIN64
- typedef __int64 ares_ssize_t;
+# define CARES_TYPEOF_ARES_SSIZE_T __int64
# else
- typedef long ares_ssize_t;
+# define CARES_TYPEOF_ARES_SSIZE_T long
# endif
#else
-# ifdef CARES_TYPEOF_ARES_SSIZE_T
- typedef CARES_TYPEOF_ARES_SSIZE_T ares_ssize_t;
-# else
- typedef ssize_t ares_ssize_t;
-# endif
+# define CARES_TYPEOF_ARES_SSIZE_T ssize_t
#endif
+typedef CARES_TYPEOF_ARES_SSIZE_T ares_ssize_t;
+
#endif /* __CARES_BUILD_H */
diff --git a/deps/cares/include/ares_rules.h b/deps/cares/include/ares_rules.h
index e617fdc6daaa49..cac23cf2e32db3 100644
--- a/deps/cares/include/ares_rules.h
+++ b/deps/cares/include/ares_rules.h
@@ -83,7 +83,7 @@
/*
* Verify that the size previously defined and expected for
- * ares_socklen_t is actually the the same as the one reported
+ * ares_socklen_t is actually the same as the one reported
* by sizeof() at compile time.
*/
diff --git a/deps/cares/include/ares_version.h b/deps/cares/include/ares_version.h
index 61b2b98a8d3683..3fe5b00a1171c2 100644
--- a/deps/cares/include/ares_version.h
+++ b/deps/cares/include/ares_version.h
@@ -3,15 +3,15 @@
#define ARES__VERSION_H
/* This is the global package copyright */
-#define ARES_COPYRIGHT "2004 - 2017 Daniel Stenberg, ."
+#define ARES_COPYRIGHT "2004 - 2018 Daniel Stenberg, ."
#define ARES_VERSION_MAJOR 1
-#define ARES_VERSION_MINOR 14
+#define ARES_VERSION_MINOR 15
#define ARES_VERSION_PATCH 0
#define ARES_VERSION ((ARES_VERSION_MAJOR<<16)|\
(ARES_VERSION_MINOR<<8)|\
(ARES_VERSION_PATCH))
-#define ARES_VERSION_STR "1.14.0"
+#define ARES_VERSION_STR "1.15.0"
#if (ARES_VERSION >= 0x010700)
# define CARES_HAVE_ARES_LIBRARY_INIT 1
diff --git a/deps/cares/src/RELEASE-NOTES b/deps/cares/src/RELEASE-NOTES
index 91230a325b9a73..62276fdf4e38c6 100644
--- a/deps/cares/src/RELEASE-NOTES
+++ b/deps/cares/src/RELEASE-NOTES
@@ -1,47 +1,43 @@
-c-ares version 1.14.0
+c-ares version 1.15.0
Changes:
- o android: Introduce new ares_library_init_android() call for Oreo support. [5]
+ o Add ares_init_options() configurability for path to resolv.conf file [1]
+ o Ability to exclude building of tools (adig, ahost, acountry) in CMake [3]
+ o Android: Support for domain search suffix [4]
+ o Report ARES_ENOTFOUND for .onion domain names as per RFC7686. [13]
Bug fixes:
-
- o Fix patch for CVE-2017-1000381 to not be overly aggressive. [1]
- o win32: Preserve DNS server order returned by Windows when sorting and exclude
- DNS servers in legacy subnets. [2] [4]
- o win32: Support most recent Visual Studio 2017
- o gethostbyaddr should fail with ECANCELLED not ENOTFOUND when ares_cancel
- is called. [3]
- o win32: Exclude legacy ipv6 subnets [4]
- o android: Applications compiled for Oreo can no longer use
- __system_property_get and must use Java calls to retrieve DNS servers.
- [5] [7]
- o win32: Force use of ANSI functions [6]
- o CMake minimum version is now 3.1
- o ares_gethostbyname.3: fix callback status values [8]
- o docs: Document WSAStartup requirement [9]
- o Fix a typo in init_by_resolv_conf [10]
- o Android JNI code leaks local references in some cases [11]
- o Force using the ANSI versions of WinAPI functions [12]
+ o AIX build fix for trying to include both nameser_compat.h and
+ onameser_compat.h [2]
+ o Windows: Improve DNS suffixes extracting from WinNT registry [5]
+ o Fix modern GCC warnings [6]
+ o Apply the IPv6 server blacklist to all nameserver sources, not just Windows
+ [7]
+ o Fix warnings emitted by MSVC when using -W4 [8]
+ o Prevent changing name servers while queries are outstanding [9]
+ o Harden and rationalize c-ares timeout computation [10]
+ o Distribute ares_android.h [11]
+ o ares_set_servers_csv() on failure should not leave channel in a bad state
+ [12]
+ o Add missing docs to distribution
Thanks go to these friendly people for their efforts and contributions:
-
- AC Thompson, Anna Henningsen, Antonio Tajuelo, Brad House, Brad Spencer,
- Christian Ammer, Daniel Stenberg, David Drysdale, David Hotham, Felix Yan,
- Gergely Nagy, Gregor Jasny, Jakub Hrozek, John Schember,
- Konstantinos Sofokleous, Roman Teterin, Sergey Kolomenkin, Sheel Bedi,
- (18 contributors)
+ @afalin, Andi Schnebinger, Ben Noordhuis, Brad House, Brad Spencer,
+ David Hotham, @flyingdutchman23, John Schember, Ruslan Baratov,
+ Sarat Addepalli, Tobias Nießen (11 contributors)
References to bug reports and discussions on issues:
+ [1] = https://github.com/c-ares/c-ares/issues/220
+ [2] = https://github.com/c-ares/c-ares/issues/224
+ [3] = https://github.com/c-ares/c-ares/issues/200
+ [4] = https://github.com/c-ares/c-ares/issues/207
+ [5] = https://github.com/c-ares/c-ares/pull/202
+ [6] = https://github.com/c-ares/c-ares/pull/201
+ [7] = https://github.com/c-ares/c-ares/pull/193
+ [8] = https://github.com/c-ares/c-ares/pull/192
+ [9] = https://github.com/c-ares/c-ares/pull/191
+ [10] = https://github.com/c-ares/c-ares/pull/187
+ [11] = https://c-ares.haxx.se/mail/c-ares-archive-2018-04/0000.shtml
+ [12] = https://c-ares.haxx.se/mail/c-ares-archive-2018-03/0000.shtml
+ [13] = https://github.com/c-ares/c-ares/issues/196
- [1] = https://github.com/c-ares/c-ares/commit/18ea99
- [2] = https://github.com/c-ares/c-ares/issues/150
- [3] = https://github.com/c-ares/c-ares/pull/138
- [4] = https://github.com/c-ares/c-ares/pull/144
- [5] = https://github.com/c-ares/c-ares/pull/148
- [6] = https://github.com/c-ares/c-ares/pull/142
- [7] = https://github.com/c-ares/c-ares/pull/175
- [8] = https://c-ares.haxx.se/mail/c-ares-archive-2011-06/0012.shtml
- [9] = https://github.com/c-ares/c-ares/pull/180
- [10] = https://github.com/c-ares/c-ares/pull/160
- [11] = https://github.com/c-ares/c-ares/pull/175
- [12] = https://github.com/c-ares/c-ares/pull/142
diff --git a/deps/cares/src/ares_android.c b/deps/cares/src/ares_android.c
index ab388110bdeff9..bf77131b58cf84 100644
--- a/deps/cares/src/ares_android.c
+++ b/deps/cares/src/ares_android.c
@@ -30,6 +30,8 @@ static jmethodID android_cm_active_net_mid = NULL;
static jmethodID android_cm_link_props_mid = NULL;
/* LinkProperties.getDnsServers */
static jmethodID android_lp_dns_servers_mid = NULL;
+/* LinkProperties.getDomains */
+static jmethodID android_lp_domains_mid = NULL;
/* List.size */
static jmethodID android_list_size_mid = NULL;
/* List.get */
@@ -139,6 +141,12 @@ int ares_library_init_android(jobject connectivity_manager)
if (android_lp_dns_servers_mid == NULL)
goto cleanup;
+ /* getDomains in API 21. */
+ android_lp_domains_mid = jni_get_method_id(env, obj_cls, "getDomains",
+ "()Ljava/lang/String;");
+ if (android_lp_domains_mid == NULL)
+ goto cleanup;
+
(*env)->DeleteLocalRef(env, obj_cls);
obj_cls = jni_get_class(env, "java/util/List");
if (obj_cls == NULL)
@@ -173,6 +181,7 @@ int ares_library_init_android(jobject connectivity_manager)
android_cm_active_net_mid = NULL;
android_cm_link_props_mid = NULL;
android_lp_dns_servers_mid = NULL;
+ android_lp_domains_mid = NULL;
android_list_size_mid = NULL;
android_list_get_mid = NULL;
android_ia_host_addr_mid = NULL;
@@ -213,6 +222,7 @@ void ares_library_cleanup_android(void)
android_cm_active_net_mid = NULL;
android_cm_link_props_mid = NULL;
android_lp_dns_servers_mid = NULL;
+ android_lp_domains_mid = NULL;
android_list_size_mid = NULL;
android_list_get_mid = NULL;
android_ia_host_addr_mid = NULL;
@@ -341,6 +351,95 @@ char **ares_get_android_server_list(size_t max_servers,
(*android_jvm)->DetachCurrentThread(android_jvm);
return dns_list;
}
+
+char *ares_get_android_search_domains_list(void)
+{
+ JNIEnv *env = NULL;
+ jobject active_network = NULL;
+ jobject link_properties = NULL;
+ jstring domains = NULL;
+ const char *domain;
+ int res;
+ size_t i;
+ size_t cnt = 0;
+ char *domain_list = NULL;
+ int need_detatch = 0;
+
+ if (android_jvm == NULL || android_connectivity_manager == NULL)
+ {
+ return NULL;
+ }
+
+ if (android_cm_active_net_mid == NULL || android_cm_link_props_mid == NULL ||
+ android_lp_domains_mid == NULL)
+ {
+ return NULL;
+ }
+
+ res = (*android_jvm)->GetEnv(android_jvm, (void **)&env, JNI_VERSION_1_6);
+ if (res == JNI_EDETACHED)
+ {
+ env = NULL;
+ res = (*android_jvm)->AttachCurrentThread(android_jvm, &env, NULL);
+ need_detatch = 1;
+ }
+ if (res != JNI_OK || env == NULL)
+ goto done;
+
+ /* JNI below is equivalent to this Java code.
+ import android.content.Context;
+ import android.net.ConnectivityManager;
+ import android.net.LinkProperties;
+
+ ConnectivityManager cm = (ConnectivityManager)this.getApplicationContext()
+ .getSystemService(Context.CONNECTIVITY_SERVICE);
+ Network an = cm.getActiveNetwork();
+ LinkProperties lp = cm.getLinkProperties(an);
+ String domains = lp.getDomains();
+ for (String domain: domains.split(",")) {
+ String d = domain;
+ }
+
+ Note: The JNI ConnectivityManager object and all method IDs were previously
+ initialized in ares_library_init_android.
+ */
+
+ active_network = (*env)->CallObjectMethod(env, android_connectivity_manager,
+ android_cm_active_net_mid);
+ if (active_network == NULL)
+ goto done;
+
+ link_properties =
+ (*env)->CallObjectMethod(env, android_connectivity_manager,
+ android_cm_link_props_mid, active_network);
+ if (link_properties == NULL)
+ goto done;
+
+ /* Get the domains. It is a common separated list of domains to search. */
+ domains = (*env)->CallObjectMethod(env, link_properties,
+ android_lp_domains_mid);
+ if (domains == NULL)
+ goto done;
+
+ /* Split on , */
+ domain = (*env)->GetStringUTFChars(env, domains, 0);
+ domain_list = ares_strdup(domain);
+ (*env)->ReleaseStringUTFChars(env, domains, domain);
+ (*env)->DeleteLocalRef(env, domains);
+
+done:
+ if ((*env)->ExceptionOccurred(env))
+ (*env)->ExceptionClear(env);
+
+ if (link_properties != NULL)
+ (*env)->DeleteLocalRef(env, link_properties);
+ if (active_network != NULL)
+ (*env)->DeleteLocalRef(env, active_network);
+
+ if (need_detatch)
+ (*android_jvm)->DetachCurrentThread(android_jvm);
+ return domain_list;
+}
#else
/* warning: ISO C forbids an empty translation unit */
typedef int dummy_make_iso_compilers_happy;
diff --git a/deps/cares/src/ares_android.h b/deps/cares/src/ares_android.h
new file mode 100644
index 00000000000000..93fb75f585057e
--- /dev/null
+++ b/deps/cares/src/ares_android.h
@@ -0,0 +1,27 @@
+/* Copyright (C) 2017 by John Schember
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#ifndef __ARES_ANDROID_H__
+#define __ARES_ANDROID_H__
+
+#if defined(ANDROID) || defined(__ANDROID__)
+
+char **ares_get_android_server_list(size_t max_servers, size_t *num_servers);
+char *ares_get_android_search_domains_list(void);
+void ares_library_cleanup_android(void);
+
+#endif
+
+#endif /* __ARES_ANDROID_H__ */
diff --git a/deps/cares/src/ares_create_query.c b/deps/cares/src/ares_create_query.c
index 07d7570114403b..1606b1a1004706 100644
--- a/deps/cares/src/ares_create_query.c
+++ b/deps/cares/src/ares_create_query.c
@@ -94,6 +94,10 @@ int ares_create_query(const char *name, int dnsclass, int type,
size_t buflen;
unsigned char *buf;
+ /* Per RFC 7686, reject queries for ".onion" domain names with NXDOMAIN. */
+ if (ares__is_onion_domain(name))
+ return ARES_ENOTFOUND;
+
/* Set our results early, in case we bail out early with an error. */
*buflenp = 0;
*bufp = NULL;
@@ -188,7 +192,7 @@ int ares_create_query(const char *name, int dnsclass, int type,
* specified in RFC 1035 ("To simplify implementations, the total length of
* a domain name (i.e., label octets and label length octets) is restricted
* to 255 octets or less."). */
- if (buflen > (MAXCDNAME + HFIXEDSZ + QFIXEDSZ +
+ if (buflen > (size_t)(MAXCDNAME + HFIXEDSZ + QFIXEDSZ +
(max_udp_size ? EDNSFIXEDSZ : 0))) {
ares_free (buf);
return ARES_EBADNAME;
diff --git a/deps/cares/src/ares_destroy.c b/deps/cares/src/ares_destroy.c
index 8aa42236aecffe..fed2009ab324ff 100644
--- a/deps/cares/src/ares_destroy.c
+++ b/deps/cares/src/ares_destroy.c
@@ -36,6 +36,8 @@ void ares_destroy_options(struct ares_options *options)
ares_free(options->sortlist);
if(options->lookups)
ares_free(options->lookups);
+ if(options->resolvconf_path)
+ ares_free(options->resolvconf_path);
}
void ares_destroy(ares_channel channel)
@@ -44,7 +46,7 @@ void ares_destroy(ares_channel channel)
struct query *query;
struct list_node* list_head;
struct list_node* list_node;
-
+
if (!channel)
return;
@@ -85,6 +87,9 @@ void ares_destroy(ares_channel channel)
if (channel->lookups)
ares_free(channel->lookups);
+ if (channel->resolvconf_path)
+ ares_free(channel->resolvconf_path);
+
ares_free(channel);
}
diff --git a/deps/cares/src/ares_gethostbyname.c b/deps/cares/src/ares_gethostbyname.c
index 7c46d96ceaf214..8187746bb14c7f 100644
--- a/deps/cares/src/ares_gethostbyname.c
+++ b/deps/cares/src/ares_gethostbyname.c
@@ -95,6 +95,13 @@ void ares_gethostbyname(ares_channel channel, const char *name, int family,
return;
}
+ /* Per RFC 7686, reject queries for ".onion" domain names with NXDOMAIN. */
+ if (ares__is_onion_domain(name))
+ {
+ callback(arg, ARES_ENOTFOUND, 0, NULL);
+ return;
+ }
+
if (fake_hostent(name, family, callback, arg))
return;
@@ -339,6 +346,10 @@ static int file_lookup(const char *name, int family, struct hostent **host)
int status;
int error;
+ /* Per RFC 7686, reject queries for ".onion" domain names with NXDOMAIN. */
+ if (ares__is_onion_domain(name))
+ return ARES_ENOTFOUND;
+
#ifdef WIN32
char PATH_HOSTS[MAX_PATH];
win_platform platform;
diff --git a/deps/cares/src/ares_getnameinfo.c b/deps/cares/src/ares_getnameinfo.c
index c77b1f81537834..aa089417060fec 100644
--- a/deps/cares/src/ares_getnameinfo.c
+++ b/deps/cares/src/ares_getnameinfo.c
@@ -440,3 +440,14 @@ STATIC_TESTABLE char *ares_striendstr(const char *s1, const char *s2)
}
return (char *)c1_begin;
}
+
+int ares__is_onion_domain(const char *name)
+{
+ if (ares_striendstr(name, ".onion"))
+ return 1;
+
+ if (ares_striendstr(name, ".onion."))
+ return 1;
+
+ return 0;
+}
diff --git a/deps/cares/src/ares_init.c b/deps/cares/src/ares_init.c
index 90cfcabdd33a9e..c2c00d65237072 100644
--- a/deps/cares/src/ares_init.c
+++ b/deps/cares/src/ares_init.c
@@ -169,6 +169,7 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
channel->sock_config_cb_data = NULL;
channel->sock_funcs = NULL;
channel->sock_func_cb_data = NULL;
+ channel->resolvconf_path = NULL;
channel->last_server = 0;
channel->last_timeout_processed = (time_t)now.tv_sec;
@@ -236,16 +237,14 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
/* Something failed; clean up memory we may have allocated. */
if (channel->servers)
ares_free(channel->servers);
- if (channel->domains)
- {
- for (i = 0; i < channel->ndomains; i++)
- ares_free(channel->domains[i]);
- ares_free(channel->domains);
- }
+ if (channel->ndomains != -1)
+ ares_strsplit_free(channel->domains, channel->ndomains);
if (channel->sortlist)
ares_free(channel->sortlist);
if(channel->lookups)
ares_free(channel->lookups);
+ if(channel->resolvconf_path)
+ ares_free(channel->resolvconf_path);
ares_free(channel);
return status;
}
@@ -299,7 +298,7 @@ int ares_dup(ares_channel *dest, ares_channel src)
(*dest)->sock_func_cb_data = src->sock_func_cb_data;
strncpy((*dest)->local_dev_name, src->local_dev_name,
- sizeof(src->local_dev_name));
+ sizeof((*dest)->local_dev_name));
(*dest)->local_ip4 = src->local_ip4;
memcpy((*dest)->local_ip6, src->local_ip6, sizeof(src->local_ip6));
@@ -354,6 +353,9 @@ int ares_save_options(ares_channel channel, struct ares_options *options,
ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS);
(*optmask) |= (channel->rotate ? ARES_OPT_ROTATE : ARES_OPT_NOROTATE);
+ if (channel->resolvconf_path)
+ (*optmask) |= ARES_OPT_RESOLVCONF;
+
/* Copy easy stuff */
options->flags = channel->flags;
@@ -426,6 +428,13 @@ int ares_save_options(ares_channel channel, struct ares_options *options,
}
options->nsort = channel->nsort;
+ /* copy path for resolv.conf file */
+ if (channel->resolvconf_path) {
+ options->resolvconf_path = ares_strdup(channel->resolvconf_path);
+ if (!options->resolvconf_path)
+ return ARES_ENOMEM;
+ }
+
return ARES_SUCCESS;
}
@@ -534,6 +543,14 @@ static int init_by_options(ares_channel channel,
channel->nsort = options->nsort;
}
+ /* Set path for resolv.conf file, if given. */
+ if ((optmask & ARES_OPT_RESOLVCONF) && !channel->resolvconf_path)
+ {
+ channel->resolvconf_path = ares_strdup(options->resolvconf_path);
+ if (!channel->resolvconf_path && options->resolvconf_path)
+ return ARES_ENOMEM;
+ }
+
channel->optmask = optmask;
return ARES_SUCCESS;
@@ -997,63 +1014,6 @@ static int compareAddresses(const void *arg1,
return 0;
}
-/* Validate that the ip address matches the subnet (network base and network
- * mask) specified. Addresses are specified in standard Network Byte Order as
- * 16 bytes, and the netmask is 0 to 128 (bits).
- */
-static int ares_ipv6_subnet_matches(const unsigned char netbase[16],
- unsigned char netmask,
- const unsigned char ipaddr[16])
-{
- unsigned char mask[16] = { 0 };
- unsigned char i;
-
- /* Misuse */
- if (netmask > 128)
- return 0;
-
- /* Quickly set whole bytes */
- memset(mask, 0xFF, netmask / 8);
-
- /* Set remaining bits */
- if(netmask % 8) {
- mask[netmask / 8] = (unsigned char)(0xff << (8 - (netmask % 8)));
- }
-
- for (i=0; i<16; i++) {
- if ((netbase[i] & mask[i]) != (ipaddr[i] & mask[i]))
- return 0;
- }
-
- return 1;
-}
-
-static int ares_ipv6_server_blacklisted(const unsigned char ipaddr[16])
-{
- const struct {
- const char *netbase;
- unsigned char netmask;
- } blacklist[] = {
- /* Deprecated by [RFC3879] in September 2004. Formerly a Site-Local scoped
- * address prefix. Causes known issues on Windows as these are not valid DNS
- * servers. */
- { "fec0::", 10 },
- { NULL, 0 }
- };
- size_t i;
-
- for (i=0; blacklist[i].netbase != NULL; i++) {
- unsigned char netbase[16];
-
- if (ares_inet_pton(AF_INET6, blacklist[i].netbase, netbase) != 1)
- continue;
-
- if (ares_ipv6_subnet_matches(netbase, blacklist[i].netmask, ipaddr))
- return 1;
- }
- return 0;
-}
-
/* There can be multiple routes to "the Internet". And there can be different
* DNS servers associated with each of the interfaces that offer those routes.
* We have to assume that any DNS server can serve any request. But, some DNS
@@ -1257,7 +1217,7 @@ static int get_DNS_AdaptersAddresses(char **outptr)
}
else
{
- addresses[addressesIndex].metric = -1;
+ addresses[addressesIndex].metric = (ULONG)-1;
}
/* Record insertion index to make qsort stable */
@@ -1272,20 +1232,10 @@ static int get_DNS_AdaptersAddresses(char **outptr)
}
else if (namesrvr.sa->sa_family == AF_INET6)
{
- /* Windows apparently always reports some IPv6 DNS servers that
- * prefixed with fec0:0:0:ffff. These ususally do not point to
- * working DNS servers, so we ignore them. */
- if (strncmp(addresses[addressesIndex].text, "fec0:0:0:ffff:", 14) == 0)
- continue;
if (memcmp(&namesrvr.sa6->sin6_addr, &ares_in6addr_any,
sizeof(namesrvr.sa6->sin6_addr)) == 0)
continue;
- if (ares_ipv6_server_blacklisted(
- (const unsigned char *)&namesrvr.sa6->sin6_addr)
- )
- continue;
-
/* Allocate room for another address, if necessary, else skip. */
if(addressesIndex == addressesSize) {
const size_t newSize = addressesSize + 4;
@@ -1309,7 +1259,7 @@ static int get_DNS_AdaptersAddresses(char **outptr)
}
else
{
- addresses[addressesIndex].metric = -1;
+ addresses[addressesIndex].metric = (ULONG)-1;
}
/* Record insertion index to make qsort stable */
@@ -1394,59 +1344,6 @@ static int get_DNS_Windows(char **outptr)
return get_DNS_Registry(outptr);
}
-static void replace_comma_by_space(char* str)
-{
- /* replace ',' by ' ' to coincide with resolv.conf search parameter */
- char *p;
- for (p = str; *p != '\0'; p++)
- {
- if (*p == ',')
- *p = ' ';
- }
-}
-
-/* Search if 'suffix' is containted in the 'searchlist'. Returns true if yes,
- * otherwise false. 'searchlist' is a comma separated list of domain suffixes,
- * 'suffix' is one domain suffix, 'len' is the length of 'suffix'.
- * The search ignores case. E.g.:
- * contains_suffix("abc.def,ghi.jkl", "ghi.JKL") returns true */
-static bool contains_suffix(const char* const searchlist,
- const char* const suffix, const size_t len)
-{
- const char* beg = searchlist;
- const char* end;
- if (!*suffix)
- return true;
- for (;;)
- {
- while (*beg && (ISSPACE(*beg) || (*beg == ',')))
- ++beg;
- if (!*beg)
- return false;
- end = beg;
- while (*end && !ISSPACE(*end) && (*end != ','))
- ++end;
- if (len == (end - beg) && !strnicmp(beg, suffix, len))
- return true;
- beg = end;
- }
-}
-
-/* advances list to the next suffix within a comma separated search list.
- * len is the length of the next suffix. */
-static size_t next_suffix(const char** list, const size_t advance)
-{
- const char* beg = *list + advance;
- const char* end;
- while (*beg && (ISSPACE(*beg) || (*beg == ',')))
- ++beg;
- end = beg;
- while (*end && !ISSPACE(*end) && (*end != ','))
- ++end;
- *list = beg;
- return end - beg;
-}
-
/*
* get_SuffixList_Windows()
*
@@ -1467,8 +1364,6 @@ static int get_SuffixList_Windows(char **outptr)
DWORD keyNameBuffSize;
DWORD keyIdx = 0;
char *p = NULL;
- const char *pp;
- size_t len = 0;
*outptr = NULL;
@@ -1479,11 +1374,26 @@ static int get_SuffixList_Windows(char **outptr)
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
KEY_READ, &hKey) == ERROR_SUCCESS)
{
- if (get_REG_SZ(hKey, SEARCHLIST_KEY, outptr))
- replace_comma_by_space(*outptr);
+ get_REG_SZ(hKey, SEARCHLIST_KEY, outptr);
+ if (get_REG_SZ(hKey, DOMAIN_KEY, &p))
+ {
+ commajoin(outptr, p);
+ ares_free(p);
+ p = NULL;
+ }
+ RegCloseKey(hKey);
+ }
+
+ if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NT_DNSCLIENT, 0,
+ KEY_READ, &hKey) == ERROR_SUCCESS)
+ {
+ if (get_REG_SZ(hKey, SEARCHLIST_KEY, &p))
+ {
+ commajoin(outptr, p);
+ ares_free(p);
+ p = NULL;
+ }
RegCloseKey(hKey);
- if (*outptr)
- return 1;
}
/* 2. Connection Specific Search List composed of:
@@ -1491,45 +1401,53 @@ static int get_SuffixList_Windows(char **outptr)
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_DNSCLIENT, 0,
KEY_READ, &hKey) == ERROR_SUCCESS)
{
- get_REG_SZ(hKey, PRIMARYDNSSUFFIX_KEY, outptr);
+ if (get_REG_SZ(hKey, PRIMARYDNSSUFFIX_KEY, &p))
+ {
+ commajoin(outptr, p);
+ ares_free(p);
+ p = NULL;
+ }
RegCloseKey(hKey);
}
- if (!*outptr)
- return 0;
/* b. Interface SearchList, Domain, DhcpDomain */
- if (!RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY "\\" INTERFACES_KEY, 0,
+ if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY "\\" INTERFACES_KEY, 0,
KEY_READ, &hKey) == ERROR_SUCCESS)
- return 0;
- for(;;)
{
- keyNameBuffSize = sizeof(keyName);
- if (RegEnumKeyExA(hKey, keyIdx++, keyName, &keyNameBuffSize,
- 0, NULL, NULL, NULL)
- != ERROR_SUCCESS)
- break;
- if (RegOpenKeyExA(hKey, keyName, 0, KEY_QUERY_VALUE, &hKeyEnum)
- != ERROR_SUCCESS)
- continue;
- if (get_REG_SZ(hKeyEnum, SEARCHLIST_KEY, &p) ||
- get_REG_SZ(hKeyEnum, DOMAIN_KEY, &p) ||
- get_REG_SZ(hKeyEnum, DHCPDOMAIN_KEY, &p))
+ for(;;)
{
+ keyNameBuffSize = sizeof(keyName);
+ if (RegEnumKeyExA(hKey, keyIdx++, keyName, &keyNameBuffSize,
+ 0, NULL, NULL, NULL)
+ != ERROR_SUCCESS)
+ break;
+ if (RegOpenKeyExA(hKey, keyName, 0, KEY_QUERY_VALUE, &hKeyEnum)
+ != ERROR_SUCCESS)
+ continue;
/* p can be comma separated (SearchList) */
- pp = p;
- while ((len = next_suffix(&pp, len)) != 0)
+ if (get_REG_SZ(hKeyEnum, SEARCHLIST_KEY, &p))
{
- if (!contains_suffix(*outptr, pp, len))
- commanjoin(outptr, pp, len);
+ commajoin(outptr, p);
+ ares_free(p);
+ p = NULL;
}
- ares_free(p);
- p = NULL;
+ if (get_REG_SZ(hKeyEnum, DOMAIN_KEY, &p))
+ {
+ commajoin(outptr, p);
+ ares_free(p);
+ p = NULL;
+ }
+ if (get_REG_SZ(hKeyEnum, DHCPDOMAIN_KEY, &p))
+ {
+ commajoin(outptr, p);
+ ares_free(p);
+ p = NULL;
+ }
+ RegCloseKey(hKeyEnum);
}
- RegCloseKey(hKeyEnum);
+ RegCloseKey(hKey);
}
- RegCloseKey(hKey);
- if (*outptr)
- replace_comma_by_space(*outptr);
+
return *outptr != NULL;
}
@@ -1628,6 +1546,7 @@ static int init_by_resolv_conf(ares_channel channel)
char propname[PROP_NAME_MAX];
char propvalue[PROP_VALUE_MAX]="";
char **dns_servers;
+ char *domains;
size_t num_servers;
/* Use the Android connectivity manager to get a list
@@ -1652,6 +1571,12 @@ static int init_by_resolv_conf(ares_channel channel)
}
ares_free(dns_servers);
}
+ if (channel->ndomains == -1)
+ {
+ domains = ares_get_android_search_domains_list();
+ set_search(channel, domains);
+ ares_free(domains);
+ }
# ifdef HAVE___SYSTEM_PROPERTY_GET
/* Old way using the system property still in place as
@@ -1740,6 +1665,7 @@ static int init_by_resolv_conf(ares_channel channel)
size_t linesize;
int error;
int update_domains;
+ const char *resolvconf_path;
/* Don't read resolv.conf and friends if we don't have to */
if (ARES_CONFIG_CHECK(channel))
@@ -1748,7 +1674,14 @@ static int init_by_resolv_conf(ares_channel channel)
/* Only update search domains if they're not already specified */
update_domains = (channel->ndomains == -1);
- fp = fopen(PATH_RESOLV_CONF, "r");
+ /* Support path for resolvconf filename set by ares_init_options */
+ if(channel->resolvconf_path) {
+ resolvconf_path = channel->resolvconf_path;
+ } else {
+ resolvconf_path = PATH_RESOLV_CONF;
+ }
+
+ fp = fopen(resolvconf_path, "r");
if (fp) {
while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
{
@@ -1759,10 +1692,10 @@ static int init_by_resolv_conf(ares_channel channel)
else if ((p = try_config(line, "search", ';')) && update_domains)
status = set_search(channel, p);
else if ((p = try_config(line, "nameserver", ';')) &&
- channel->nservers == -1)
+ channel->nservers == -1)
status = config_nameserver(&servers, &nservers, p);
else if ((p = try_config(line, "sortlist", ';')) &&
- channel->nsort == -1)
+ channel->nsort == -1)
status = config_sortlist(&sortlist, &nsort, p);
else if ((p = try_config(line, "options", ';')))
status = set_options(channel, p);
@@ -1782,7 +1715,7 @@ static int init_by_resolv_conf(ares_channel channel)
break;
default:
DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
- error, strerror(error)));
+ error, strerror(error)));
DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
status = ARES_EFILE;
}
@@ -2050,6 +1983,11 @@ static int init_by_defaults(ares_channel channel)
ares_free(channel->lookups);
channel->lookups = NULL;
}
+
+ if(channel->resolvconf_path) {
+ ares_free(channel->resolvconf_path);
+ channel->resolvconf_path = NULL;
+ }
}
if(hostname)
@@ -2114,6 +2052,76 @@ static int config_lookup(ares_channel channel, const char *str,
#endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ & !CARES_USE_LIBRESOLV */
#ifndef WATT32
+/* Validate that the ip address matches the subnet (network base and network
+ * mask) specified. Addresses are specified in standard Network Byte Order as
+ * 16 bytes, and the netmask is 0 to 128 (bits).
+ */
+static int ares_ipv6_subnet_matches(const unsigned char netbase[16],
+ unsigned char netmask,
+ const unsigned char ipaddr[16])
+{
+ unsigned char mask[16] = { 0 };
+ unsigned char i;
+
+ /* Misuse */
+ if (netmask > 128)
+ return 0;
+
+ /* Quickly set whole bytes */
+ memset(mask, 0xFF, netmask / 8);
+
+ /* Set remaining bits */
+ if(netmask % 8) {
+ mask[netmask / 8] = (unsigned char)(0xff << (8 - (netmask % 8)));
+ }
+
+ for (i=0; i<16; i++) {
+ if ((netbase[i] & mask[i]) != (ipaddr[i] & mask[i]))
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Return true iff the IPv6 ipaddr is blacklisted. */
+static int ares_ipv6_server_blacklisted(const unsigned char ipaddr[16])
+{
+ /* A list of blacklisted IPv6 subnets. */
+ const struct {
+ const unsigned char netbase[16];
+ unsigned char netmask;
+ } blacklist[] = {
+ /* fec0::/10 was deprecated by [RFC3879] in September 2004. Formerly a
+ * Site-Local scoped address prefix. These are never valid DNS servers,
+ * but are known to be returned at least sometimes on Windows and Android.
+ */
+ {
+ {
+ 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ },
+ 10
+ }
+ };
+ size_t i;
+
+ /* See if ipaddr matches any of the entries in the blacklist. */
+ for (i = 0; i < sizeof(blacklist) / sizeof(blacklist[0]); ++i) {
+ if (ares_ipv6_subnet_matches(
+ blacklist[i].netbase, blacklist[i].netmask, ipaddr))
+ return 1;
+ }
+ return 0;
+}
+
+/* Add the IPv4 or IPv6 nameservers in str (separated by commas) to the
+ * servers list, updating servers and nservers as required.
+ *
+ * This will silently ignore blacklisted IPv6 nameservers as detected by
+ * ares_ipv6_server_blacklisted().
+ *
+ * Returns an error code on failure, else ARES_SUCCESS.
+ */
static int config_nameserver(struct server_state **servers, int *nservers,
char *str)
{
@@ -2148,7 +2156,10 @@ static int config_nameserver(struct server_state **servers, int *nservers,
/* Convert textual address to binary format. */
if (ares_inet_pton(AF_INET, txtaddr, &host.addrV4) == 1)
host.family = AF_INET;
- else if (ares_inet_pton(AF_INET6, txtaddr, &host.addrV6) == 1)
+ else if (ares_inet_pton(AF_INET6, txtaddr, &host.addrV6) == 1
+ /* Silently skip blacklisted IPv6 servers. */
+ && !ares_ipv6_server_blacklisted(
+ (const unsigned char *)&host.addrV6))
host.family = AF_INET6;
else
continue;
@@ -2271,61 +2282,22 @@ static int config_sortlist(struct apattern **sortlist, int *nsort,
static int set_search(ares_channel channel, const char *str)
{
- int n;
- const char *p, *q;
+ size_t cnt;
if(channel->ndomains != -1) {
/* LCOV_EXCL_START: all callers check ndomains == -1 */
/* if we already have some domains present, free them first */
- for(n=0; n < channel->ndomains; n++)
- ares_free(channel->domains[n]);
- ares_free(channel->domains);
+ ares_strsplit_free(channel->domains, channel->ndomains);
channel->domains = NULL;
channel->ndomains = -1;
} /* LCOV_EXCL_STOP */
- /* Count the domains given. */
- n = 0;
- p = str;
- while (*p)
- {
- while (*p && !ISSPACE(*p))
- p++;
- while (ISSPACE(*p))
- p++;
- n++;
- }
-
- if (!n)
- {
- channel->ndomains = 0;
- return ARES_SUCCESS;
- }
-
- channel->domains = ares_malloc(n * sizeof(char *));
- if (!channel->domains)
- return ARES_ENOMEM;
-
- /* Now copy the domains. */
- n = 0;
- p = str;
- while (*p)
- {
- channel->ndomains = n;
- q = p;
- while (*q && !ISSPACE(*q))
- q++;
- channel->domains[n] = ares_malloc(q - p + 1);
- if (!channel->domains[n])
- return ARES_ENOMEM;
- memcpy(channel->domains[n], p, q - p);
- channel->domains[n][q - p] = 0;
- p = q;
- while (ISSPACE(*p))
- p++;
- n++;
- }
- channel->ndomains = n;
+ channel->domains = ares_strsplit(str, ", ", 1, &cnt);
+ channel->ndomains = (int)cnt;
+ if (channel->domains == NULL || channel->ndomains == 0) {
+ channel->domains = NULL;
+ channel->ndomains = -1;
+ }
return ARES_SUCCESS;
}
diff --git a/deps/cares/src/ares_library_init.c b/deps/cares/src/ares_library_init.c
index 88e7a537480813..67563499bec276 100644
--- a/deps/cares/src/ares_library_init.c
+++ b/deps/cares/src/ares_library_init.c
@@ -40,9 +40,19 @@ static unsigned int ares_initialized;
static int ares_init_flags;
/* library-private global vars with visibility across the whole library */
-void *(*ares_malloc)(size_t size) = malloc;
-void *(*ares_realloc)(void *ptr, size_t size) = realloc;
-void (*ares_free)(void *ptr) = free;
+#if defined(WIN32)
+/* We need indirections to handle Windows DLL rules. */
+static void *default_malloc(size_t size) { return malloc(size); }
+static void *default_realloc(void *p, size_t size) { return realloc(p, size); }
+static void default_free(void *p) { free(p); }
+#else
+# define default_malloc malloc
+# define default_realloc realloc
+# define default_free free
+#endif
+void *(*ares_malloc)(size_t size) = default_malloc;
+void *(*ares_realloc)(void *ptr, size_t size) = default_realloc;
+void (*ares_free)(void *ptr) = default_free;
#ifdef USE_WINSOCK
static HMODULE hnd_iphlpapi;
diff --git a/deps/cares/src/ares_options.c b/deps/cares/src/ares_options.c
index c3cbd1df707566..de49de4625996f 100644
--- a/deps/cares/src/ares_options.c
+++ b/deps/cares/src/ares_options.c
@@ -153,6 +153,9 @@ int ares_set_servers(ares_channel channel,
if (!channel)
return ARES_ENODATA;
+ if (!ares__is_list_empty(&channel->all_queries))
+ return ARES_ENOTIMP;
+
ares__destroy_servers_state(channel);
for (srvr = servers; srvr; srvr = srvr->next)
@@ -202,6 +205,9 @@ int ares_set_servers_ports(ares_channel channel,
if (!channel)
return ARES_ENODATA;
+ if (!ares__is_list_empty(&channel->all_queries))
+ return ARES_ENOTIMP;
+
ares__destroy_servers_state(channel);
for (srvr = servers; srvr; srvr = srvr->next)
@@ -258,8 +264,6 @@ static int set_servers_csv(ares_channel channel,
if (!channel)
return ARES_ENODATA;
- ares__destroy_servers_state(channel);
-
i = strlen(_csv);
if (i == 0)
return ARES_SUCCESS; /* blank all servers */
diff --git a/deps/cares/src/ares_parse_ptr_reply.c b/deps/cares/src/ares_parse_ptr_reply.c
index 976a5311a24d79..29e22cb17b6bd6 100644
--- a/deps/cares/src/ares_parse_ptr_reply.c
+++ b/deps/cares/src/ares_parse_ptr_reply.c
@@ -52,6 +52,7 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
int aliascnt = 0;
int alias_alloc = 8;
char ** aliases;
+ size_t rr_data_len;
/* Set *host to NULL for all failure cases. */
*host = NULL;
@@ -124,14 +125,15 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr,
if (hostname)
ares_free(hostname);
hostname = rr_data;
- aliases[aliascnt] = ares_malloc((strlen(rr_data)+1) * sizeof(char));
+ rr_data_len = strlen(rr_data)+1;
+ aliases[aliascnt] = ares_malloc(rr_data_len * sizeof(char));
if (!aliases[aliascnt])
{
ares_free(rr_name);
status = ARES_ENOMEM;
break;
}
- strncpy(aliases[aliascnt], rr_data, strlen(rr_data)+1);
+ strncpy(aliases[aliascnt], rr_data, rr_data_len);
aliascnt++;
if (aliascnt >= alias_alloc) {
char **ptr;
diff --git a/deps/cares/src/ares_private.h b/deps/cares/src/ares_private.h
index 5d773869c72a97..1990f6902fc75e 100644
--- a/deps/cares/src/ares_private.h
+++ b/deps/cares/src/ares_private.h
@@ -52,18 +52,19 @@
#if defined(WIN32) && !defined(WATT32)
-#define WIN_NS_9X "System\\CurrentControlSet\\Services\\VxD\\MSTCP"
-#define WIN_NS_NT_KEY "System\\CurrentControlSet\\Services\\Tcpip\\Parameters"
-#define WIN_DNSCLIENT "Software\\Policies\\Microsoft\\System\\DNSClient"
-#define NAMESERVER "NameServer"
-#define DHCPNAMESERVER "DhcpNameServer"
-#define DATABASEPATH "DatabasePath"
-#define WIN_PATH_HOSTS "\\hosts"
-#define SEARCHLIST_KEY "SearchList"
+#define WIN_NS_9X "System\\CurrentControlSet\\Services\\VxD\\MSTCP"
+#define WIN_NS_NT_KEY "System\\CurrentControlSet\\Services\\Tcpip\\Parameters"
+#define WIN_DNSCLIENT "Software\\Policies\\Microsoft\\System\\DNSClient"
+#define WIN_NT_DNSCLIENT "Software\\Policies\\Microsoft\\Windows NT\\DNSClient"
+#define NAMESERVER "NameServer"
+#define DHCPNAMESERVER "DhcpNameServer"
+#define DATABASEPATH "DatabasePath"
+#define WIN_PATH_HOSTS "\\hosts"
+#define SEARCHLIST_KEY "SearchList"
#define PRIMARYDNSSUFFIX_KEY "PrimaryDNSSuffix"
-#define INTERFACES_KEY "Interfaces"
-#define DOMAIN_KEY "Domain"
-#define DHCPDOMAIN_KEY "DhcpDomain"
+#define INTERFACES_KEY "Interfaces"
+#define DOMAIN_KEY "Domain"
+#define DHCPDOMAIN_KEY "DhcpDomain"
#elif defined(WATT32)
@@ -100,6 +101,7 @@
#endif
#include "ares_strdup.h"
+#include "ares_strsplit.h"
#ifndef HAVE_STRCASECMP
# include "ares_strcasecmp.h"
@@ -323,8 +325,14 @@ struct ares_channeldata {
const struct ares_socket_functions * sock_funcs;
void *sock_func_cb_data;
+
+ /* Path for resolv.conf file, configurable via ares_options */
+ char *resolvconf_path;
};
+/* Does the domain end in ".onion" or ".onion."? Case-insensitive. */
+int ares__is_onion_domain(const char *name);
+
/* Memory management functions */
extern void *(*ares_malloc)(size_t size);
extern void *(*ares_realloc)(void *ptr, size_t size);
diff --git a/deps/cares/src/ares_process.c b/deps/cares/src/ares_process.c
index df85524f624cfd..df9f290bb133a6 100644
--- a/deps/cares/src/ares_process.c
+++ b/deps/cares/src/ares_process.c
@@ -53,6 +53,7 @@
#include
#include
+#include
#include "ares.h"
#include "ares_dns.h"
@@ -871,8 +872,32 @@ void ares__send_query(ares_channel channel, struct query *query,
return;
}
}
- timeplus = channel->timeout << (query->try_count / channel->nservers);
- timeplus = (timeplus * (9 + (rand () & 7))) / 16;
+
+ /* For each trip through the entire server list, double the channel's
+ * assigned timeout, avoiding overflow. If channel->timeout is negative,
+ * leave it as-is, even though that should be impossible here.
+ */
+ timeplus = channel->timeout;
+ {
+ /* How many times do we want to double it? Presume sane values here. */
+ const int shift = query->try_count / channel->nservers;
+
+ /* Is there enough room to shift timeplus left that many times?
+ *
+ * To find out, confirm that all of the bits we'll shift away are zero.
+ * Stop considering a shift if we get to the point where we could shift
+ * a 1 into the sign bit (i.e. when shift is within two of the bit
+ * count).
+ *
+ * This has the side benefit of leaving negative numbers unchanged.
+ */
+ if(shift <= (int)(sizeof(int) * CHAR_BIT - 1)
+ && (timeplus >> (sizeof(int) * CHAR_BIT - 1 - shift)) == 0)
+ {
+ timeplus <<= shift;
+ }
+ }
+
query->timeout = *now;
timeadd(&query->timeout, timeplus);
/* Keep track of queries bucketed by timeout, so we can process
diff --git a/deps/cares/src/ares_search.c b/deps/cares/src/ares_search.c
index 68e852574f0909..001c3482a7dd5d 100644
--- a/deps/cares/src/ares_search.c
+++ b/deps/cares/src/ares_search.c
@@ -54,6 +54,13 @@ void ares_search(ares_channel channel, const char *name, int dnsclass,
const char *p;
int status, ndots;
+ /* Per RFC 7686, reject queries for ".onion" domain names with NXDOMAIN. */
+ if (ares__is_onion_domain(name))
+ {
+ callback(arg, ARES_ENOTFOUND, 0, NULL, 0);
+ return;
+ }
+
/* If name only yields one domain to search, then we don't have
* to keep extra state, so just do an ares_query().
*/
diff --git a/deps/cares/src/ares_send.c b/deps/cares/src/ares_send.c
index 88c0035520c504..f4f1f951197de8 100644
--- a/deps/cares/src/ares_send.c
+++ b/deps/cares/src/ares_send.c
@@ -60,6 +60,12 @@ void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen,
callback(arg, ARES_ENOMEM, 0, NULL, 0);
return;
}
+ if (channel->nservers < 1)
+ {
+ ares_free(query);
+ callback(arg, ARES_ESERVFAIL, 0, NULL, 0);
+ return;
+ }
query->server_info = ares_malloc(channel->nservers *
sizeof(query->server_info[0]));
if (!query->server_info)
diff --git a/deps/cares/src/ares_strsplit.c b/deps/cares/src/ares_strsplit.c
new file mode 100644
index 00000000000000..b57a30f2a99c35
--- /dev/null
+++ b/deps/cares/src/ares_strsplit.c
@@ -0,0 +1,174 @@
+/* Copyright (C) 2018 by John Schember
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+#include "ares_strsplit.h"
+#include "ares.h"
+#include "ares_private.h"
+
+static int list_contains(char * const *list, size_t num_elem, const char *str, int insensitive)
+{
+ size_t len;
+ size_t i;
+
+ len = strlen(str);
+ for (i=0; i
+ *
+ * Permission to use, copy, modify, and distribute this
+ * software and its documentation for any purpose and without
+ * fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in
+ * advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ */
+
+#include "ares_setup.h"
+
+/* Split a string on delem skipping empty elements.
+ *
+ * param in String to split.
+ * param delims String of characters to treat as a delimitor.
+ * Each character in the string is a delimitor so
+ * there can be multiple delimitors to split on.
+ * E.g. ", " will split on all comma's and spaces.
+ * param make_set Have the list be a Set where there are no
+ * duplicate entries. 1 for true, 0 or false.
+ * param num_elm Return parameter of the number of elements
+ * in the result array.
+ *
+ * returns an allocated array of allocated string elements.
+ *
+ */
+char **ares_strsplit(const char *in, const char *delms, int make_set, size_t *num_elm);
+
+/* Frees the result returned from ares_strsplit(). */
+void ares_strsplit_free(char **elms, size_t num_elm);
+
+
+#endif /* HEADER_CARES_STRSPLIT_H */
diff --git a/deps/cares/src/inet_ntop.c b/deps/cares/src/inet_ntop.c
index ce3ce588d3c0bd..1935a871cede6d 100644
--- a/deps/cares/src/inet_ntop.c
+++ b/deps/cares/src/inet_ntop.c
@@ -180,8 +180,7 @@ inet_ntop6(const unsigned char *src, char *dst, size_t size)
tp += sprintf(tp, "%x", words[i]);
}
/* Was it a trailing run of 0x00's? */
- if (best.base != -1 && (best.base + best.len) ==
- (NS_IN6ADDRSZ / NS_INT16SZ))
+ if (best.base != -1 && (best.base + best.len) == (NS_IN6ADDRSZ / NS_INT16SZ))
*tp++ = ':';
*tp++ = '\0';
diff --git a/deps/v8/gypfiles/d8.gyp b/deps/v8/gypfiles/d8.gyp
index f593a2b044ee4a..9611dfccf8aff0 100644
--- a/deps/v8/gypfiles/d8.gyp
+++ b/deps/v8/gypfiles/d8.gyp
@@ -23,6 +23,7 @@
'include_dirs+': [
'..',
'<(DEPTH)',
+ '<(SHARED_INTERMEDIATE_DIR)',
],
'sources': [
'../src/d8.h',
diff --git a/deps/v8/include/v8.h b/deps/v8/include/v8.h
index 55ad7c8cf220cc..a5aaf2d6842dde 100644
--- a/deps/v8/include/v8.h
+++ b/deps/v8/include/v8.h
@@ -1019,9 +1019,9 @@ class V8_EXPORT PrimitiveArray {
public:
static Local New(Isolate* isolate, int length);
int Length() const;
- V8_DEPRECATED("Use Isolate* version",
+ V8_DEPRECATE_SOON("Use Isolate* version",
void Set(int index, Local item));
- V8_DEPRECATED("Use Isolate* version",
+ V8_DEPRECATE_SOON("Use Isolate* version",
Local Get(int index));
void Set(Isolate* isolate, int index, Local item);
Local Get(Isolate* isolate, int index);
@@ -1739,8 +1739,8 @@ class V8_EXPORT StackTrace {
/**
* Returns a StackFrame at a particular index.
*/
- V8_DEPRECATED("Use Isolate version",
- Local GetFrame(uint32_t index) const);
+ V8_DEPRECATE_SOON("Use Isolate version",
+ Local GetFrame(uint32_t index) const);
Local GetFrame(Isolate* isolate, uint32_t index) const;
/**
@@ -2451,7 +2451,7 @@ class V8_EXPORT Value : public Data {
inline V8_DEPRECATED("Use maybe version",
Local ToBoolean() const);
- inline V8_DEPRECATED("Use maybe version", Local ToString() const);
+ inline V8_DEPRECATE_SOON("Use maybe version", Local ToString() const);
inline V8_DEPRECATED("Use maybe version", Local