diff --git a/.eslintrc.yaml b/.eslintrc.yaml index b2201aa41ff2a4..9167f21c5dd00f 100644 --- a/.eslintrc.yaml +++ b/.eslintrc.yaml @@ -13,7 +13,6 @@ parserOptions: rules: # Possible Errors # http://eslint.org/docs/rules/#possible-errors - comma-dangle: [2, only-multiline] no-control-regex: 2 no-debugger: 2 no-dupe-args: 2 @@ -28,7 +27,6 @@ rules: no-invalid-regexp: 2 no-irregular-whitespace: 2 no-obj-calls: 2 - no-proto: 2 no-template-curly-in-string: 2 no-unexpected-multiline: 2 no-unreachable: 2 @@ -44,7 +42,23 @@ rules: no-global-assign: 2 no-multi-spaces: 2 no-octal: 2 + no-proto: 2 no-redeclare: 2 + no-restricted-properties: + - 2 + - object: assert + property: deepEqual + message: Use assert.deepStrictEqual(). + - object: assert + property: equal + message: Use assert.strictEqual() rather than assert.equal(). + - object: assert + property: notEqual + message: Use assert.notStrictEqual() rather than assert.notEqual(). + - property: __defineGetter__ + message: __defineGetter__ is deprecated. + - property: __defineSetter__ + message: __defineSetter__ is deprecated. no-self-assign: 2 no-throw-literal: 2 no-unused-labels: 2 @@ -71,26 +85,12 @@ rules: no-new-require: 2 no-path-concat: 2 no-restricted-modules: [2, sys] - no-restricted-properties: - - 2 - - object: assert - property: deepEqual - message: Use assert.deepStrictEqual(). - - object: assert - property: equal - message: Use assert.strictEqual() rather than assert.equal(). - - object: assert - property: notEqual - message: Use assert.notStrictEqual() rather than assert.notEqual(). - - property: __defineGetter__ - message: __defineGetter__ is deprecated. - - property: __defineSetter__, - message: __defineSetter__ is deprecated. # Stylistic Issues # http://eslint.org/docs/rules/#stylistic-issues block-spacing: 2 brace-style: [2, 1tbs, {allowSingleLine: true}] + comma-dangle: [2, only-multiline] comma-spacing: 2 comma-style: 2 computed-property-spacing: 2 diff --git a/.gitignore b/.gitignore index b4ba0e2983f12c..dea969504a90f1 100644 --- a/.gitignore +++ b/.gitignore @@ -110,3 +110,8 @@ icu_config.gypi # Xcode workspaces and project folders *.xcodeproj *.xcworkspace + +# libuv book and GitHub template +deps/uv/.github/ +deps/uv/docs/code/ +deps/uv/docs/src/guide/ diff --git a/BUILDING.md b/BUILDING.md index 5cac93621c1523..a00b00a5f8bc44 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -35,7 +35,7 @@ Support is divided into three tiers: | System | Support type | Version | Architectures | Notes | |--------------|--------------|----------------------------------|----------------------|------------------| -| GNU/Linux | Tier 1 | kernel >= 2.6.18, glibc >= 2.5 | x86, x64, arm, arm64 | | +| GNU/Linux | Tier 1 | kernel >= 2.6.32, glibc >= 2.12 | x86, x64, arm, arm64 | | | macOS | Tier 1 | >= 10.10 | x64 | | | Windows | Tier 1 | >= Windows 7 / 2008 R2 | x86, x64 | vs2015 or vs2017 | | SmartOS | Tier 2 | >= 15 < 16.4 | x86, x64 | see note1 | @@ -81,13 +81,12 @@ Prerequisites: * Python 2.6 or 2.7 * GNU Make 3.81 or newer -On macOS, you will also need: -* [Xcode](https://developer.apple.com/xcode/download/) - - You also need to install the `Command Line Tools` via Xcode. You can find - this under the menu `Xcode -> Preferences -> Downloads` - - This step will install `gcc` and the related toolchain containing `make` - -* After building, you may want to setup [firewall rules](tools/macosx-firewall.sh) +On macOS you will need to install the `Xcode Command Line Tools` by running +`xcode-select --install`. Alternatively, if you already have the full Xcode +installed, you can find them under the menu `Xcode -> Open Developer Tool -> +More Developer Tools...`. This step will install `clang`, `clang++`, and +`make`. +* You may want to setup [firewall rules](tools/macosx-firewall.sh) to avoid popups asking to accept incoming network connections when running tests: ```console @@ -119,7 +118,7 @@ and not a newer version. To run the tests: -``` +```console $ make test ``` @@ -167,7 +166,7 @@ Prerequisites: including the Community edition (remember to select "Common Tools for Visual C++ 2015" feature during installation). * [Visual Studio 2017](https://www.visualstudio.com/downloads/), any edition (including the Build Tools SKU). - __Required Components:__ "MSbuild", "VC++ 2017 v141 toolset" and one of the Windows SDKs (10 or 8.1). + **Required Components:** "MSbuild", "VC++ 2017 v141 toolset" and one of the Windows SDKs (10 or 8.1). * Basic Unix tools required for some tests, [Git for Windows](http://git-scm.com/download/win) includes Git Bash and tools which can be included in the global `PATH`. diff --git a/CHANGELOG.md b/CHANGELOG.md index 80110b95659352..2339e11e484f00 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,7 +27,8 @@ release. -8.0.0
+8.1.0
+8.0.0
7.10.0
diff --git a/Makefile b/Makefile index 5c9beb48c94bac..da37eab4550069 100644 --- a/Makefile +++ b/Makefile @@ -197,8 +197,8 @@ test: all $(MAKE) build-addons-napi $(MAKE) cctest $(PYTHON) tools/test.py --mode=release -J \ - doctool inspector known_issues message pseudo-tty parallel sequential \ - async-hooks $(CI_NATIVE_SUITES) + $(CI_JS_SUITES) \ + $(CI_NATIVE_SUITES) $(MAKE) lint test-parallel: all @@ -328,7 +328,7 @@ test-all-valgrind: test-build $(PYTHON) tools/test.py --mode=debug,release --valgrind CI_NATIVE_SUITES := addons addons-napi -CI_JS_SUITES := doctool inspector known_issues message parallel pseudo-tty sequential async-hooks +CI_JS_SUITES := async-hooks doctool inspector known_issues message parallel pseudo-tty sequential # Build and test addons without building anything else test-ci-native: LOGLEVEL := info @@ -712,9 +712,9 @@ pkg: $(PKG) pkg-upload: pkg ssh $(STAGINGSERVER) "mkdir -p nodejs/$(DISTTYPEDIR)/$(FULLVERSION)" - chmod 664 node-$(FULLVERSION).pkg - scp -p node-$(FULLVERSION).pkg $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/node-$(FULLVERSION).pkg - ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/node-$(FULLVERSION).pkg.done" + chmod 664 $(TARNAME).pkg + scp -p $(TARNAME).pkg $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).pkg + ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).pkg.done" $(TARBALL): release-only $(NODE_EXE) doc git checkout-index -a -f --prefix=$(TARNAME)/ @@ -744,13 +744,13 @@ tar: $(TARBALL) tar-upload: tar ssh $(STAGINGSERVER) "mkdir -p nodejs/$(DISTTYPEDIR)/$(FULLVERSION)" - chmod 664 node-$(FULLVERSION).tar.gz - scp -p node-$(FULLVERSION).tar.gz $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/node-$(FULLVERSION).tar.gz - ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/node-$(FULLVERSION).tar.gz.done" + chmod 664 $(TARNAME).tar.gz + scp -p $(TARNAME).tar.gz $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).tar.gz + ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).tar.gz.done" ifeq ($(XZ), 0) - chmod 664 node-$(FULLVERSION).tar.xz - scp -p node-$(FULLVERSION).tar.xz $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/node-$(FULLVERSION).tar.xz - ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/node-$(FULLVERSION).tar.xz.done" + chmod 664 $(TARNAME).tar.xz + scp -p $(TARNAME).tar.xz $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).tar.xz + ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME).tar.xz.done" endif doc-upload: doc @@ -814,13 +814,13 @@ binary: $(BINARYTAR) binary-upload: binary ssh $(STAGINGSERVER) "mkdir -p nodejs/$(DISTTYPEDIR)/$(FULLVERSION)" - chmod 664 node-$(FULLVERSION)-$(OSTYPE)-$(ARCH).tar.gz - scp -p node-$(FULLVERSION)-$(OSTYPE)-$(ARCH).tar.gz $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/node-$(FULLVERSION)-$(OSTYPE)-$(ARCH).tar.gz - ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/node-$(FULLVERSION)-$(OSTYPE)-$(ARCH).tar.gz.done" + chmod 664 $(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz + scp -p $(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz + ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz.done" ifeq ($(XZ), 0) - chmod 664 node-$(FULLVERSION)-$(OSTYPE)-$(ARCH).tar.xz - scp -p node-$(FULLVERSION)-$(OSTYPE)-$(ARCH).tar.xz $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/node-$(FULLVERSION)-$(OSTYPE)-$(ARCH).tar.xz - ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/node-$(FULLVERSION)-$(OSTYPE)-$(ARCH).tar.xz.done" + chmod 664 $(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz + scp -p $(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz + ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz.done" endif bench-net: all diff --git a/README.md b/README.md index e2c4a15862417d..e014085c69e56e 100644 --- a/README.md +++ b/README.md @@ -381,6 +381,8 @@ more information about the governance of the Node.js project, see **Thorsten Lorenz** <thlorenz@gmx.de> * [TimothyGu](https://github.com/TimothyGu) - **Timothy Gu** <timothygu99@gmail.com> (he/him) +* [tniessen](https://github.com/tniessen) - +**Tobias Nießen** <tniessen@tnie.de> * [tunniclm](https://github.com/tunniclm) - **Mike Tunnicliffe** <m.j.tunnicliffe@gmail.com> * [vkurchatkin](https://github.com/vkurchatkin) - diff --git a/benchmark/dns/lookup.js b/benchmark/dns/lookup.js new file mode 100644 index 00000000000000..ebe9d05695ef23 --- /dev/null +++ b/benchmark/dns/lookup.js @@ -0,0 +1,38 @@ +'use strict'; + +const common = require('../common.js'); +const lookup = require('dns').lookup; + +const bench = common.createBenchmark(main, { + name: ['', '127.0.0.1', '::1'], + all: [true, false], + n: [5e6] +}); + +function main(conf) { + const name = conf.name; + const n = +conf.n; + const all = !!conf.all; + var i = 0; + + if (all) { + const opts = { all: true }; + bench.start(); + (function cb(err, results) { + if (i++ === n) { + bench.end(n); + return; + } + lookup(name, opts, cb); + })(); + } else { + bench.start(); + (function cb(err, result) { + if (i++ === n) { + bench.end(n); + return; + } + lookup(name, cb); + })(); + } +} diff --git a/deps/npm/.travis.yml b/deps/npm/.travis.yml index dbf67611c454d1..95255d8d8072bb 100644 --- a/deps/npm/.travis.yml +++ b/deps/npm/.travis.yml @@ -17,9 +17,11 @@ matrix: # previous LTS is next most important - node_js: "4" env: DEPLOY_VERSION=testing - # then master - node_js: "7" env: DEPLOY_VERSION=testing + # then master + - node_js: "8" + env: DEPLOY_VERSION=testing before_install: # required by test/tap/registry.js - "mkdir -p /var/run/couchdb" diff --git a/deps/npm/AUTHORS b/deps/npm/AUTHORS index 64d9c2d0616c46..7357c4a1bd5bdd 100644 --- a/deps/npm/AUTHORS +++ b/deps/npm/AUTHORS @@ -464,3 +464,14 @@ J F Pavlo Liulia Ján Dzurek Lucas Theisen +Mike Sherov +薛定谔的猫 +Paweł Lula +Jakob Krigovsky +George Rawlinson +Jack Nagel +Andreas Kohn +Jason Wohlgemuth +Ryan Graham +Hirse +Colin Rotherham diff --git a/deps/npm/CHANGELOG.md b/deps/npm/CHANGELOG.md index e2a8004b8d9b37..03b7e29d91e869 100644 --- a/deps/npm/CHANGELOG.md +++ b/deps/npm/CHANGELOG.md @@ -1,3 +1,238 @@ +## v5.0.3 (2017-06-05) + +Happy Monday, y'all! We've got another npm release for you with the fruits of +our ongoing bugsquashing efforts. You can expect at least one more this week, +but probably more -- and as we announced last week, we'll be merging fixes more +rapidly into the `npmc` canary so you can get everything as soon as possible! + +Hope y'all are enjoying npm5 in the meantime, and don't hesitate to file issues +for anything you find! The goal is to get this release rock-solid as soon as we +can. 💚 + +* [`6e12a5cc0`](https://github.com/npm/npm/commit/6e12a5cc022cb5a157a37df7283b6d7b3d49bdab) + Bump several dependencies to get improvements and bugfixes: + * `cacache`: content files (the tarballs) are now read-only. + * `pacote`: fix failing clones with bad heads, send extra TLS-related opts to proxy, enable global auth configurations and `_auth`-based auth. + * `ssri`: stop crashing with `can't call method find of undefined` when running into a weird `opts.integrity`/`opts.algorithms` conflict during verification. + ([@zkat](https://github.com/zkat)) +* [`89cc8e3e1`](https://github.com/npm/npm/commit/89cc8e3e12dad67fd9844accf4d41deb4c180c5c) + [#16917](https://github.com/npm/npm/pull/16917) + Send `ca`, `cert` and `key` config through to network layer. + ([@colinrotherham](https://github.com/colinrotherham)) +* [`6a9b51c67`](https://github.com/npm/npm/commit/6a9b51c67ba3df0372991631992748329b84f2e7) + [#16929](https://github.com/npm/npm/pull/16929) + Send `npm-session` header value with registry requests again. + ([@zarenner](https://github.com/zarenner)) +* [`662a15ab7`](https://github.com/npm/npm/commit/662a15ab7e790e87f5e5a35252f05d5a4a0724a1) + Fix `npm doctor` so it stop complaining about read-only content files in the + cache. + ([@zkat](https://github.com/zkat)) +* [`191d10a66`](https://github.com/npm/npm/commit/191d10a6616d72e26d89fd00f5a4f6158bfbc526) + [#16918](https://github.com/npm/npm/pull/16918) + Clarify prepublish deprecation message. + ([@Hirse](https://github.com/Hirse)) + +## v5.0.2 (2017-06-02) + +Here's another patch release, soon after the other! + +This particular release includes a slew of fixes to npm's git support, which was +causing some issues for a chunk of people, specially those who were using +self-hosted/Enterprise repos. All of those should be back in working condition +now. + +There's another shiny thing you might wanna know about: npm has a Canary release +now! The `npm5` experiment we did during our beta proved to be incredibly +successful: users were able to have a tight feedback loop between reports and +getting the bugfixes they needed, and the CLI team was able to roll out +experimental patches and have the community try them out right away. So we want +to keep doing that. + +From now on, you'll be able to install the 'npm canary' with `npm i -g npmc`. +This release will be a separate binary (`npmc`. Because canary. Get it?), which +will update independently of the main CLI. Most of the time, this will track +`release-next` or something close to it. We might occasionally toss experimental +branches in there to see if our more adventurous users run into anything +interesting with it. For example, the current canary (`npmc@5.0.1-canary.6`) +includes an [experimental multiproc +branch](https://github.com/npm/npm/pull/16633) that parallelizes tarball +extraction across multiple processes. + +If you find any issues while running the canary version, please report them and +let us know it came from `npmc`! It would be tremendously helpful, and finding +things early is a huge reason to have it there. Happy hacking! + +### A NOTE ABOUT THE ISSUE TRACKER + +Just a heads up: We're preparing to do a massive cleanup of the issue tracker. +It's been a long time since it was something we could really keep up with, and +we didn't have a process for dealing with it that could actually be sustainable. + +We're still sussing the details out, and we'll talk about it more when we're +about to do it, but the plan is essentially to close old, abandoned issues and +start over. We will also [add some automation](https://github.com/probot) around +issue management so that things that we can't keep up with don't just stay +around forever. + +Stay tuned! + +### GIT YOLO + +* [`1f26e9567`](https://github.com/npm/npm/commit/1f26e9567a6d14088704e121ebe787c38b6849a4) + `pacote@2.7.27`: Fixes installing committishes that look like semver, even + though they're not using the required `#semver:` syntax. + ([@zkat](https://github.com/zkat)) +* [`85ea1e0b9`](https://github.com/npm/npm/commit/85ea1e0b9478551265d03d545e7dc750b9edf547) + `npm-package-arg@5.1.1`: This includes the npa git-parsing patch to make it so + non-hosted SCP-style identifiers are correctly handled. Previously, npa would + mangle them (even though hosted-git-info is doing the right thing for them). + ([@zkat](https://github.com/zkat)) + +### COOL NEW OUTPUT + +The new summary output has been really well received! One downside that reared +its head as more people used it, though, is that it doesn't really tell you +anything about the toplevel versions it installed. So, if you did `npm i -g +foo`, it would just say "added 1 package". This patch by +[@rmg](https://github.com/rmg) keeps things concise while still telling you +what you got! So now, you'll see something like this: + +``` +$ npm i -g foo bar ++ foo@1.2.3 ++ bar@3.2.1 +added 234 packages in .005ms +``` + +* [`362f9fd5b`](https://github.com/npm/npm/commit/362f9fd5bec65301082416b4292b8fe3eb7f824a) + [#16899](https://github.com/npm/npm/pull/16899) + For every package that is given as an argument to install, print the name and + version that was actually installed. + ([@rmg](https://github.com/rmg)) + +### OTHER BUGFIXES + +* [`a47593a98`](https://github.com/npm/npm/commit/a47593a98a402143081d7077d2ac677d13083010) + [#16835](https://github.com/npm/npm/pull/16835) + Fix a crash while installing with `--no-shrinkwrap`. + ([@jacknagel](https://github.com/jacknagel)) + +### DOC UPATES + +* [`89e0cb816`](https://github.com/npm/npm/commit/89e0cb8165dd9c3c7ac74d531617f367099608f4) + [#16818](https://github.com/npm/npm/pull/16818) + Fixes a spelling error in the docs. Because the CLI team has trouble spelling + "package", I guess. + ([@ankon](https://github.com/ankon)) +* [`c01fbc46e`](https://github.com/npm/npm/commit/c01fbc46e151bcfb359fd68dd7faa392789b4f55) + [#16895](https://github.com/npm/npm/pull/16895) + Remove `--save` from `npm init` instructions, since it's now the default. + ([@jhwohlgemuth](https://github.com/jhwohlgemuth)) +* [`80c42d218`](https://github.com/npm/npm/commit/80c42d2181dd4d1b79fcee4e9233df268dfb30b7) + Guard against cycles when inflating bundles, as symlinks are bundles now. + ([@iarna](https://github.com/iarna)) +* [`7fe7f8665`](https://github.com/npm/npm/commit/7fe7f86658798db6667df89afc75588c0e43bc94) + [#16674](https://github.com/npm/npm/issues/16674) + Write the builtin config for `npmc`, not just `npm`. This is hardcoded for npm + self-installations and is needed for Canary to work right. + ([@zkat](https://github.com/zkat)) + +### DEP UPDATES + +* [`63df4fcdd`](https://github.com/npm/npm/commit/63df4fcddc7445efb50cc7d8e09cdd45146d3e39) + [#16894](https://github.com/npm/npm/pull/16894) + [`node-gyp@3.6.2`](https://github.com/nodejs/node-gyp/blob/master/CHANGELOG.md#v362-2017-06-01): + Fixes an issue parsing SDK versions on Windows, among other things. + ([@refack](https://github.com/refack)) +* [`5bb15c3c4`](https://github.com/npm/npm/commit/5bb15c3c4f0d7d77c73fd6dafa38ac36549b6e00) + `read-package-tree@5.1.6`: Fixes some racyness while reading the tree. + ([@iarna](https://github.com/iarna)) +* [`a6f7a52e7`](https://github.com/npm/npm/commit/a6f7a52e7) + `aproba@1.1.2`: Remove nested function declaration for speed up + ([@mikesherov](https://github.com/mikesherov)) + +## v5.0.1 (2017-05-31): + +Hey y'all! Hope you're enjoying the new npm! + +As you all know, fresh software that's gone through major overhauls tends to +miss a lot of spots the old one used to handle well enough, and `npm@5` is no +exception. The CLI team will be doing faster release cycles that go directly to +the `latest` tag for a couple of weeks while 5 stabilizes a bit and we're +confident the common low-hanging fruit people are running into are all taken +care of. + +With that said: this is our first patch release! The biggest focus is fixing up +a number of git-related issues that folks ran into right out the door. It also +fixes other things, like some proxy/auth-related issues, and even has a neat +speed boost! (You can expect more speed bumps in the coming releases as pending +work starts landing, too!) + +Thanks everyone who's been reporting issues and submitting patches! + +### BUGFIXES + +* [`e61e68dac`](https://github.com/npm/npm/commit/e61e68dac4fa51c0540a064204a75b19f8052e58) + [#16762](https://github.com/npm/npm/pull/16762) + Make `npm publish` obey the `--tag` flag again. + ([@zkat](https://github.com/zkat)) +* [`923fd58d3`](https://github.com/npm/npm/commit/923fd58d312f40f8c17b232ad1dfc8e2ff622dbd) + [#16749](https://github.com/npm/npm/pull/16749) + Speed up installations by nearly 20% by... removing one line of code. (hah) + ([@mikesherov](https://github.com/mikesherov)) +* [`9aac984cb`](https://github.com/npm/npm/commit/9aac984cbbfef22182ee42b51a193c0b47146ad6) + Guard against a particular failure mode for a bug still being hunted down. + ([@iarna](https://github.com/iarna)) +* [`80ab521f1`](https://github.com/npm/npm/commit/80ab521f18d34df109de0c5dc9eb1cde5ff6d7e8) + Pull in dependency updates for various core deps: + * New `pacote` fixes several git-related bugs. + * `ssri` update fixes crash on early node@4 versions. + * `make-fetch-happen` update fixes proxy authentication issue. + * `npm-user-validate` adds regex for blocking usernames with illegal chars. + ([@zkat](https://github.com/zkat)) +* [`7e5ce87b8`](https://github.com/npm/npm/commit/7e5ce87b84880c7433ee4c07d2dd6ce8806df436) + `pacote@2.7.26`: + Fixes various other git issues related to commit hashes. + ([@zkat](https://github.com/zkat)) +* [`acbe85bfc`](https://github.com/npm/npm/commit/acbe85bfc1a68d19ca339a3fb71da0cffbf58926) + [#16791](https://github.com/npm/npm/pull/16791) + `npm view` was calling `cb` prematurely and giving partial output when called + in a child process. + ([@zkat](https://github.com/zkat)) +* [`ebafe48af`](https://github.com/npm/npm/commit/ebafe48af91f702ccefc8c619d52fed3b8dfd3c7) + [#16750](https://github.com/npm/npm/pull/16750) + Hamilpatch the Musical: Talk less, complete more. + ([@aredridel](https://github.com/aredridel)) + +### DOCUMENTATION + +* [`dc2823a6c`](https://github.com/npm/npm/commit/dc2823a6c5fc098041e61515c643570819d059d2) + [#16799](https://github.com/npm/npm/pull/16799) + Document that `package-lock.json` is never allowed in tarballs. + ([@sonicdoe](https://github.com/sonicdoe)) +* [`f3cb84b44`](https://github.com/npm/npm/commit/f3cb84b446c51d628ee0033cdf13752c15b31a29) + [#16771](https://github.com/npm/npm/pull/16771) + Fix `npm -l` usage information for the `test` command. + ([@grawlinson](https://github.com/grawlinson)) + +### OTHER CHANGES + +* [`661262309`](https://github.com/npm/npm/commit/66126230912ab5ab35287b40a9908e036fa73994) + [#16756](https://github.com/npm/npm/pull/16756) + remove unused argument + ([@Aladdin-ADD](https://github.com/Aladdin-ADD)) +* [`c3e0b4287`](https://github.com/npm/npm/commit/c3e0b4287ea69735cc367aa7bb7e7aa9a6d9804b) + [#16296](https://github.com/npm/npm/pull/16296) + preserve same name convention for command + ([@desfero](https://github.com/desfero)) +* [`9f814831d`](https://github.com/npm/npm/commit/9f814831d330dde7702973186aea06caaa77ff31) + [#16757](https://github.com/npm/npm/pull/16757) + remove unused argument + ([@Aladdin-ADD](https://github.com/Aladdin-ADD)) +* [`3cb843239`](https://github.com/npm/npm/commit/3cb8432397b3666d88c31131dbb4599016a983ff) + minor linter fix + ([@zkat](https://github.com/zkat)) + ## v5.0.0 (2017-05-25) Wowowowowow npm@5! diff --git a/deps/npm/appveyor.yml b/deps/npm/appveyor.yml index d808b2dbcca4eb..7b97e79d626efc 100644 --- a/deps/npm/appveyor.yml +++ b/deps/npm/appveyor.yml @@ -4,8 +4,9 @@ environment: - nodejs_version: "6" # previous LTS is next most important - nodejs_version: "4" - # then master - nodejs_version: "7" + # then master + - nodejs_version: "8" COVERALLS_REPO_TOKEN: secure: XdC0aySefK0HLh1GNk6aKrzZPbCfPQLyA4mYtFGEp4DrTuZA/iuCUS0LDqFYO8JQ platform: diff --git a/deps/npm/bin/npm-cli.js b/deps/npm/bin/npm-cli.js index c8c426f4ada83e..e2c013b5df8637 100755 --- a/deps/npm/bin/npm-cli.js +++ b/deps/npm/bin/npm-cli.js @@ -83,7 +83,7 @@ if (er) return errorHandler(er) npm.commands[npm.command](npm.argv, function (err) { // https://www.youtube.com/watch?v=7nfPu8qTiQU - if (!err && npm.config.get('ham-it-up') && !npm.config.get('json') && !npm.config.get('parseable')) { + if (!err && npm.config.get('ham-it-up') && !npm.config.get('json') && !npm.config.get('parseable') && npm.command !== 'completion') { output('\n 🎵 I Have the Honour to Be Your Obedient Servant,🎵 ~ npm 📜🖋\n') } errorHandler.apply(this, arguments) diff --git a/deps/npm/doc/files/package-lock.json.md b/deps/npm/doc/files/package-lock.json.md index dad219b4a14dd9..f6dde3649237b0 100644 --- a/deps/npm/doc/files/package-lock.json.md +++ b/deps/npm/doc/files/package-lock.json.md @@ -50,7 +50,7 @@ whose semantics were used when generating this `package-lock.json`. This is a [subresource integrity](https://w3c.github.io/webappsec/specs/subresourceintegrity/) value -created from the `pacakge.json`. No preprocessing of the `package.json` should +created from the `package.json`. No preprocessing of the `package.json` should be done. Subresource integrity strings can be produced by modules like [`ssri`](https://www.npmjs.com/package/ssri). diff --git a/deps/npm/doc/files/package.json.md b/deps/npm/doc/files/package.json.md index 193caa9240911c..1a06ff794b6784 100644 --- a/deps/npm/doc/files/package.json.md +++ b/deps/npm/doc/files/package.json.md @@ -204,6 +204,7 @@ Conversely, some files are always ignored: * `node_modules` * `config.gypi` * `*.orig` +* `package-lock.json` (use shrinkwrap instead) ## main diff --git a/deps/npm/html/doc/README.html b/deps/npm/html/doc/README.html index eb4f72947d74b7..6668429083910b 100644 --- a/deps/npm/html/doc/README.html +++ b/deps/npm/html/doc/README.html @@ -126,5 +126,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-access.html b/deps/npm/html/doc/cli/npm-access.html index f015aacdbc89db..4fcfc87ccda4ea 100644 --- a/deps/npm/html/doc/cli/npm-access.html +++ b/deps/npm/html/doc/cli/npm-access.html @@ -84,5 +84,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-adduser.html b/deps/npm/html/doc/cli/npm-adduser.html index 46385d7295f33d..905c01acb0d24d 100644 --- a/deps/npm/html/doc/cli/npm-adduser.html +++ b/deps/npm/html/doc/cli/npm-adduser.html @@ -81,5 +81,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-bin.html b/deps/npm/html/doc/cli/npm-bin.html index 962a3282d81901..131dff4dd2da70 100644 --- a/deps/npm/html/doc/cli/npm-bin.html +++ b/deps/npm/html/doc/cli/npm-bin.html @@ -35,5 +35,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-bugs.html b/deps/npm/html/doc/cli/npm-bugs.html index 79e11b018ec61b..e73b582a191f75 100644 --- a/deps/npm/html/doc/cli/npm-bugs.html +++ b/deps/npm/html/doc/cli/npm-bugs.html @@ -55,5 +55,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-build.html b/deps/npm/html/doc/cli/npm-build.html index ba59bba643ab0a..99f846f55f2a91 100644 --- a/deps/npm/html/doc/cli/npm-build.html +++ b/deps/npm/html/doc/cli/npm-build.html @@ -40,5 +40,5 @@

DESCRIPTION

       - + diff --git a/deps/npm/html/doc/cli/npm-bundle.html b/deps/npm/html/doc/cli/npm-bundle.html index 8f3510f5b8f2a5..3898c9c0a8465f 100644 --- a/deps/npm/html/doc/cli/npm-bundle.html +++ b/deps/npm/html/doc/cli/npm-bundle.html @@ -31,5 +31,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-cache.html b/deps/npm/html/doc/cli/npm-cache.html index fdcf22363880ac..ff6f6cb556f5a5 100644 --- a/deps/npm/html/doc/cli/npm-cache.html +++ b/deps/npm/html/doc/cli/npm-cache.html @@ -89,5 +89,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-completion.html b/deps/npm/html/doc/cli/npm-completion.html index 18d659ea837761..9322d0a096cd77 100644 --- a/deps/npm/html/doc/cli/npm-completion.html +++ b/deps/npm/html/doc/cli/npm-completion.html @@ -43,5 +43,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-config.html b/deps/npm/html/doc/cli/npm-config.html index 2ef422bd74f928..6d1f6fcc20809b 100644 --- a/deps/npm/html/doc/cli/npm-config.html +++ b/deps/npm/html/doc/cli/npm-config.html @@ -67,5 +67,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-dedupe.html b/deps/npm/html/doc/cli/npm-dedupe.html index d6ff8ce7608475..21c85e73b8def2 100644 --- a/deps/npm/html/doc/cli/npm-dedupe.html +++ b/deps/npm/html/doc/cli/npm-dedupe.html @@ -61,5 +61,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-deprecate.html b/deps/npm/html/doc/cli/npm-deprecate.html index 6741f7478b7cda..5b3e33d42288cb 100644 --- a/deps/npm/html/doc/cli/npm-deprecate.html +++ b/deps/npm/html/doc/cli/npm-deprecate.html @@ -38,5 +38,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-dist-tag.html b/deps/npm/html/doc/cli/npm-dist-tag.html index 8fa52c2b33be05..1325853d76517f 100644 --- a/deps/npm/html/doc/cli/npm-dist-tag.html +++ b/deps/npm/html/doc/cli/npm-dist-tag.html @@ -86,5 +86,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-docs.html b/deps/npm/html/doc/cli/npm-docs.html index 530a784ed9c307..7100b563c5faa2 100644 --- a/deps/npm/html/doc/cli/npm-docs.html +++ b/deps/npm/html/doc/cli/npm-docs.html @@ -56,5 +56,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-doctor.html b/deps/npm/html/doc/cli/npm-doctor.html index b75fcc561869f3..41125d789078c4 100644 --- a/deps/npm/html/doc/cli/npm-doctor.html +++ b/deps/npm/html/doc/cli/npm-doctor.html @@ -103,4 +103,4 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-edit.html b/deps/npm/html/doc/cli/npm-edit.html index 8860c492adc420..b4291160b65839 100644 --- a/deps/npm/html/doc/cli/npm-edit.html +++ b/deps/npm/html/doc/cli/npm-edit.html @@ -49,5 +49,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-explore.html b/deps/npm/html/doc/cli/npm-explore.html index 115d43584cb63c..1e5208e496f0bc 100644 --- a/deps/npm/html/doc/cli/npm-explore.html +++ b/deps/npm/html/doc/cli/npm-explore.html @@ -49,5 +49,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-help-search.html b/deps/npm/html/doc/cli/npm-help-search.html index a9cb77652bbf3d..528e70cbab6e7f 100644 --- a/deps/npm/html/doc/cli/npm-help-search.html +++ b/deps/npm/html/doc/cli/npm-help-search.html @@ -45,5 +45,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-help.html b/deps/npm/html/doc/cli/npm-help.html index bd72e9471ef38b..5f2a04a159dc2d 100644 --- a/deps/npm/html/doc/cli/npm-help.html +++ b/deps/npm/html/doc/cli/npm-help.html @@ -50,5 +50,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-init.html b/deps/npm/html/doc/cli/npm-init.html index 6f053ddb1b522e..215fdb40a9e70a 100644 --- a/deps/npm/html/doc/cli/npm-init.html +++ b/deps/npm/html/doc/cli/npm-init.html @@ -48,5 +48,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-install-test.html b/deps/npm/html/doc/cli/npm-install-test.html index 02866f73743fb8..83325a82891158 100644 --- a/deps/npm/html/doc/cli/npm-install-test.html +++ b/deps/npm/html/doc/cli/npm-install-test.html @@ -42,5 +42,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-install.html b/deps/npm/html/doc/cli/npm-install.html index 55eaabcfd33b20..b41029e7c99afc 100644 --- a/deps/npm/html/doc/cli/npm-install.html +++ b/deps/npm/html/doc/cli/npm-install.html @@ -365,5 +365,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-link.html b/deps/npm/html/doc/cli/npm-link.html index b279ab4d3a85a4..54b41d91dcbedf 100644 --- a/deps/npm/html/doc/cli/npm-link.html +++ b/deps/npm/html/doc/cli/npm-link.html @@ -74,5 +74,5 @@

SYNOPSIS

       - + diff --git a/deps/npm/html/doc/cli/npm-logout.html b/deps/npm/html/doc/cli/npm-logout.html index 3ecde84cc3e4e4..d3a544534ebaa6 100644 --- a/deps/npm/html/doc/cli/npm-logout.html +++ b/deps/npm/html/doc/cli/npm-logout.html @@ -51,5 +51,5 @@

scope

       - + diff --git a/deps/npm/html/doc/cli/npm-ls.html b/deps/npm/html/doc/cli/npm-ls.html index af4103febf0d3c..500ca033e576ed 100644 --- a/deps/npm/html/doc/cli/npm-ls.html +++ b/deps/npm/html/doc/cli/npm-ls.html @@ -21,7 +21,7 @@

SYNOPSIS

limit the results to only the paths to the packages named. Note that nested packages will also show the paths to the specified packages. For example, running npm ls promzard in npm's source tree will show:

-
npm@5.0.0 /path/to/npm
+
npm@5.0.3 /path/to/npm
 └─┬ init-package-json@0.0.4
   └── promzard@0.1.5
 

It will print out extraneous, missing, and invalid packages.

@@ -104,5 +104,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-outdated.html b/deps/npm/html/doc/cli/npm-outdated.html index 7b36dc7f5bc999..1c862a8ba7a7e1 100644 --- a/deps/npm/html/doc/cli/npm-outdated.html +++ b/deps/npm/html/doc/cli/npm-outdated.html @@ -116,5 +116,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-owner.html b/deps/npm/html/doc/cli/npm-owner.html index aeaa8acb89269a..e4cc4d7de89d11 100644 --- a/deps/npm/html/doc/cli/npm-owner.html +++ b/deps/npm/html/doc/cli/npm-owner.html @@ -51,5 +51,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-pack.html b/deps/npm/html/doc/cli/npm-pack.html index d40a92437a4c63..25982014e3593a 100644 --- a/deps/npm/html/doc/cli/npm-pack.html +++ b/deps/npm/html/doc/cli/npm-pack.html @@ -41,5 +41,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-ping.html b/deps/npm/html/doc/cli/npm-ping.html index e9a9f97b200173..666ba97c7cefd6 100644 --- a/deps/npm/html/doc/cli/npm-ping.html +++ b/deps/npm/html/doc/cli/npm-ping.html @@ -32,5 +32,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-prefix.html b/deps/npm/html/doc/cli/npm-prefix.html index 99dacb66606c7a..30c3172493f57b 100644 --- a/deps/npm/html/doc/cli/npm-prefix.html +++ b/deps/npm/html/doc/cli/npm-prefix.html @@ -38,5 +38,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-prune.html b/deps/npm/html/doc/cli/npm-prune.html index 56e8b8ab293350..52b2ba78e4ee4e 100644 --- a/deps/npm/html/doc/cli/npm-prune.html +++ b/deps/npm/html/doc/cli/npm-prune.html @@ -40,5 +40,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-publish.html b/deps/npm/html/doc/cli/npm-publish.html index 9b9cca3cb090b7..3fca992169342d 100644 --- a/deps/npm/html/doc/cli/npm-publish.html +++ b/deps/npm/html/doc/cli/npm-publish.html @@ -79,5 +79,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-rebuild.html b/deps/npm/html/doc/cli/npm-rebuild.html index a2a1ad03ab1682..7ec9923cb8bb63 100644 --- a/deps/npm/html/doc/cli/npm-rebuild.html +++ b/deps/npm/html/doc/cli/npm-rebuild.html @@ -35,5 +35,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-repo.html b/deps/npm/html/doc/cli/npm-repo.html index 83ec73d5f56083..38990dc8e96f3b 100644 --- a/deps/npm/html/doc/cli/npm-repo.html +++ b/deps/npm/html/doc/cli/npm-repo.html @@ -41,5 +41,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-restart.html b/deps/npm/html/doc/cli/npm-restart.html index c4d3296c251de2..6847b24387ce83 100644 --- a/deps/npm/html/doc/cli/npm-restart.html +++ b/deps/npm/html/doc/cli/npm-restart.html @@ -53,5 +53,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-root.html b/deps/npm/html/doc/cli/npm-root.html index 9b115bb0036fde..af03619a5d683c 100644 --- a/deps/npm/html/doc/cli/npm-root.html +++ b/deps/npm/html/doc/cli/npm-root.html @@ -35,5 +35,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-run-script.html b/deps/npm/html/doc/cli/npm-run-script.html index 07e1c514d6270f..2f61d63aece01e 100644 --- a/deps/npm/html/doc/cli/npm-run-script.html +++ b/deps/npm/html/doc/cli/npm-run-script.html @@ -66,5 +66,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-search.html b/deps/npm/html/doc/cli/npm-search.html index 02dc30d68e3675..cc95846328a2e4 100644 --- a/deps/npm/html/doc/cli/npm-search.html +++ b/deps/npm/html/doc/cli/npm-search.html @@ -109,5 +109,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-shrinkwrap.html b/deps/npm/html/doc/cli/npm-shrinkwrap.html index a1809977c592d2..44388546d8a2c4 100644 --- a/deps/npm/html/doc/cli/npm-shrinkwrap.html +++ b/deps/npm/html/doc/cli/npm-shrinkwrap.html @@ -41,5 +41,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-star.html b/deps/npm/html/doc/cli/npm-star.html index 8fce9194617a37..aacae893619a59 100644 --- a/deps/npm/html/doc/cli/npm-star.html +++ b/deps/npm/html/doc/cli/npm-star.html @@ -36,5 +36,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-stars.html b/deps/npm/html/doc/cli/npm-stars.html index db7f2e06332197..8252aa8f21ae80 100644 --- a/deps/npm/html/doc/cli/npm-stars.html +++ b/deps/npm/html/doc/cli/npm-stars.html @@ -36,5 +36,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-start.html b/deps/npm/html/doc/cli/npm-start.html index 756bc34e680068..8c8dd3bb39d16e 100644 --- a/deps/npm/html/doc/cli/npm-start.html +++ b/deps/npm/html/doc/cli/npm-start.html @@ -39,5 +39,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-stop.html b/deps/npm/html/doc/cli/npm-stop.html index 31c18f4ba2500e..b55a285de775fa 100644 --- a/deps/npm/html/doc/cli/npm-stop.html +++ b/deps/npm/html/doc/cli/npm-stop.html @@ -34,5 +34,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-team.html b/deps/npm/html/doc/cli/npm-team.html index 13fd9474881f4b..8bf5fdea1ed99b 100644 --- a/deps/npm/html/doc/cli/npm-team.html +++ b/deps/npm/html/doc/cli/npm-team.html @@ -67,5 +67,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-test.html b/deps/npm/html/doc/cli/npm-test.html index 798519122a0123..e099df218cb603 100644 --- a/deps/npm/html/doc/cli/npm-test.html +++ b/deps/npm/html/doc/cli/npm-test.html @@ -36,5 +36,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-uninstall.html b/deps/npm/html/doc/cli/npm-uninstall.html index 147b6e563e3ab4..37bb0bd71f771d 100644 --- a/deps/npm/html/doc/cli/npm-uninstall.html +++ b/deps/npm/html/doc/cli/npm-uninstall.html @@ -60,5 +60,5 @@

SYNOPSIS

       - + diff --git a/deps/npm/html/doc/cli/npm-unpublish.html b/deps/npm/html/doc/cli/npm-unpublish.html index 587dad4259c8f8..36d0d328616187 100644 --- a/deps/npm/html/doc/cli/npm-unpublish.html +++ b/deps/npm/html/doc/cli/npm-unpublish.html @@ -51,5 +51,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-update.html b/deps/npm/html/doc/cli/npm-update.html index ee1c38dc692c26..197aa41870f128 100644 --- a/deps/npm/html/doc/cli/npm-update.html +++ b/deps/npm/html/doc/cli/npm-update.html @@ -118,5 +118,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-version.html b/deps/npm/html/doc/cli/npm-version.html index 00361d5174f551..bc29ed75ac1b90 100644 --- a/deps/npm/html/doc/cli/npm-version.html +++ b/deps/npm/html/doc/cli/npm-version.html @@ -114,5 +114,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-view.html b/deps/npm/html/doc/cli/npm-view.html index 9fa968fd636f2f..70bf31e435975a 100644 --- a/deps/npm/html/doc/cli/npm-view.html +++ b/deps/npm/html/doc/cli/npm-view.html @@ -86,5 +86,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm-whoami.html b/deps/npm/html/doc/cli/npm-whoami.html index c25ad77e591243..8f84bc8ab62e5b 100644 --- a/deps/npm/html/doc/cli/npm-whoami.html +++ b/deps/npm/html/doc/cli/npm-whoami.html @@ -33,5 +33,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/cli/npm.html b/deps/npm/html/doc/cli/npm.html index 55495142954b77..4e4d97b2350736 100644 --- a/deps/npm/html/doc/cli/npm.html +++ b/deps/npm/html/doc/cli/npm.html @@ -13,7 +13,7 @@

npm

javascript package manager

SYNOPSIS

npm <command> [args]
 

VERSION

-

5.0.0

+

5.0.3

DESCRIPTION

npm is the package manager for the Node JavaScript platform. It puts modules in place so that node can find them, and manages dependency @@ -126,7 +126,7 @@

AUTHOR

Isaac Z. Schlueter :: isaacs :: @izs :: -i@izs.me

+i@izs.me

SEE ALSO

  • npm-help(1)
  • @@ -150,5 +150,5 @@

    SEE ALSO

           - + diff --git a/deps/npm/html/doc/files/npm-folders.html b/deps/npm/html/doc/files/npm-folders.html index 4f9656a922b0a4..300df680e1afb2 100644 --- a/deps/npm/html/doc/files/npm-folders.html +++ b/deps/npm/html/doc/files/npm-folders.html @@ -182,5 +182,5 @@

    SEE ALSO

           - + diff --git a/deps/npm/html/doc/files/npm-global.html b/deps/npm/html/doc/files/npm-global.html index 4f9656a922b0a4..300df680e1afb2 100644 --- a/deps/npm/html/doc/files/npm-global.html +++ b/deps/npm/html/doc/files/npm-global.html @@ -182,5 +182,5 @@

    SEE ALSO

           - + diff --git a/deps/npm/html/doc/files/npm-json.html b/deps/npm/html/doc/files/npm-json.html index 7d6ed1c78a18e4..e0f2df86f29360 100644 --- a/deps/npm/html/doc/files/npm-json.html +++ b/deps/npm/html/doc/files/npm-json.html @@ -162,6 +162,7 @@

    files

  • node_modules
  • config.gypi
  • *.orig
  • +
  • package-lock.json (use shrinkwrap instead)

main

The main field is a module ID that is the primary entry point to your program. @@ -586,5 +587,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/files/npm-package-locks.html b/deps/npm/html/doc/files/npm-package-locks.html index 7f8851781ba030..56bf73fbf86e6a 100644 --- a/deps/npm/html/doc/files/npm-package-locks.html +++ b/deps/npm/html/doc/files/npm-package-locks.html @@ -145,4 +145,4 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/files/npm-shrinkwrap.json.html b/deps/npm/html/doc/files/npm-shrinkwrap.json.html index 3498af79217053..1437a6807ee6f6 100644 --- a/deps/npm/html/doc/files/npm-shrinkwrap.json.html +++ b/deps/npm/html/doc/files/npm-shrinkwrap.json.html @@ -42,4 +42,4 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/files/npmrc.html b/deps/npm/html/doc/files/npmrc.html index ef6d01b6119952..9dd6e18b10c0e6 100644 --- a/deps/npm/html/doc/files/npmrc.html +++ b/deps/npm/html/doc/files/npmrc.html @@ -85,5 +85,5 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/files/package-lock.json.html b/deps/npm/html/doc/files/package-lock.json.html index 57423161bd84b2..ea9439e8418ee2 100644 --- a/deps/npm/html/doc/files/package-lock.json.html +++ b/deps/npm/html/doc/files/package-lock.json.html @@ -47,7 +47,7 @@

lockfileVersion

packageIntegrity

This is a subresource integrity value -created from the pacakge.json. No preprocessing of the package.json should +created from the package.json. No preprocessing of the package.json should be done. Subresource integrity strings can be produced by modules like ssri.

@@ -124,4 +124,4 @@

SEE ALSO

       - + diff --git a/deps/npm/html/doc/files/package.json.html b/deps/npm/html/doc/files/package.json.html index 7d6ed1c78a18e4..e0f2df86f29360 100644 --- a/deps/npm/html/doc/files/package.json.html +++ b/deps/npm/html/doc/files/package.json.html @@ -162,6 +162,7 @@

files

  • node_modules
  • config.gypi
  • *.orig
  • +
  • package-lock.json (use shrinkwrap instead)
  • main

    The main field is a module ID that is the primary entry point to your program. @@ -586,5 +587,5 @@

    SEE ALSO

           - + diff --git a/deps/npm/html/doc/index.html b/deps/npm/html/doc/index.html index 75891616b89116..9e300e85bf23b6 100644 --- a/deps/npm/html/doc/index.html +++ b/deps/npm/html/doc/index.html @@ -168,5 +168,5 @@

    semver(7)

           - + diff --git a/deps/npm/html/doc/misc/npm-coding-style.html b/deps/npm/html/doc/misc/npm-coding-style.html index 0048979e908ad1..081d89f4945cff 100644 --- a/deps/npm/html/doc/misc/npm-coding-style.html +++ b/deps/npm/html/doc/misc/npm-coding-style.html @@ -153,5 +153,5 @@

    SEE ALSO

           - + diff --git a/deps/npm/html/doc/misc/npm-config.html b/deps/npm/html/doc/misc/npm-config.html index bed7aa07367ea7..c6fc5cad3cb289 100644 --- a/deps/npm/html/doc/misc/npm-config.html +++ b/deps/npm/html/doc/misc/npm-config.html @@ -981,5 +981,5 @@

    SEE ALSO

           - + diff --git a/deps/npm/html/doc/misc/npm-developers.html b/deps/npm/html/doc/misc/npm-developers.html index d87e8c05fcd4be..7d27bd2bc19724 100644 --- a/deps/npm/html/doc/misc/npm-developers.html +++ b/deps/npm/html/doc/misc/npm-developers.html @@ -194,5 +194,5 @@

    SEE ALSO

           - + diff --git a/deps/npm/html/doc/misc/npm-disputes.html b/deps/npm/html/doc/misc/npm-disputes.html index e5d95529e6be02..351539c60b87a7 100644 --- a/deps/npm/html/doc/misc/npm-disputes.html +++ b/deps/npm/html/doc/misc/npm-disputes.html @@ -20,7 +20,7 @@

    npm-disputes

    Handling Module

    TL;DR

    1. Get the author email with npm owner ls <pkgname>
    2. -
    3. Email the author, CC support@npmjs.com
    4. +
    5. Email the author, CC support@npmjs.com
    6. After a few weeks, if there's no resolution, we'll sort it out.

    Don't squat on package names. Publish code or move out of the way.

    @@ -55,12 +55,12 @@

    DESCRIPTION

  • Alice emails Yusuf, explaining the situation as respectfully as possible, and what she would like to do with the module name. She adds the npm support -staff support@npmjs.com to the CC list of the email. Mention in the email +staff support@npmjs.com to the CC list of the email. Mention in the email that Yusuf can run npm owner add alice foo to add Alice as an owner of the foo package.
  • After a reasonable amount of time, if Yusuf has not responded, or if Yusuf and Alice can't come to any sort of resolution, email support -support@npmjs.com and we'll sort it out. ("Reasonable" is usually at least +support@npmjs.com and we'll sort it out. ("Reasonable" is usually at least 4 weeks.)
  • REASONING

    @@ -96,12 +96,12 @@

    EXCEPTIONS

    Code of Conduct such as hateful language, pornographic content, or harassment. -

    If you see bad behavior like this, please report it to abuse@npmjs.com right +

    If you see bad behavior like this, please report it to abuse@npmjs.com right away. You are never expected to resolve abusive behavior on your own. We are here to help.

    TRADEMARKS

    If you think another npm publisher is infringing your trademark, such as by -using a confusingly similar package name, email abuse@npmjs.com with a link to +using a confusingly similar package name, email abuse@npmjs.com with a link to the package or user account on https://npmjs.com. Attach a copy of your trademark registration certificate.

    If we see that the package's publisher is intentionally misleading others by @@ -134,5 +134,5 @@

    SEE ALSO

           - + diff --git a/deps/npm/html/doc/misc/npm-index.html b/deps/npm/html/doc/misc/npm-index.html index 75956cc368a495..4888d872841e05 100644 --- a/deps/npm/html/doc/misc/npm-index.html +++ b/deps/npm/html/doc/misc/npm-index.html @@ -168,5 +168,5 @@

    semver(7)

           - + diff --git a/deps/npm/html/doc/misc/npm-orgs.html b/deps/npm/html/doc/misc/npm-orgs.html index 1c769d1495d728..f3aab6e8517a29 100644 --- a/deps/npm/html/doc/misc/npm-orgs.html +++ b/deps/npm/html/doc/misc/npm-orgs.html @@ -86,5 +86,5 @@

    Team Admins create teams

           - + diff --git a/deps/npm/html/doc/misc/npm-registry.html b/deps/npm/html/doc/misc/npm-registry.html index aca3dc550c74af..7c6445b4cf4a18 100644 --- a/deps/npm/html/doc/misc/npm-registry.html +++ b/deps/npm/html/doc/misc/npm-registry.html @@ -90,5 +90,5 @@

    SEE ALSO

           - + diff --git a/deps/npm/html/doc/misc/npm-scope.html b/deps/npm/html/doc/misc/npm-scope.html index f15285ba784eae..98595501fad131 100644 --- a/deps/npm/html/doc/misc/npm-scope.html +++ b/deps/npm/html/doc/misc/npm-scope.html @@ -99,5 +99,5 @@

    SEE ALSO

           - + diff --git a/deps/npm/html/doc/misc/npm-scripts.html b/deps/npm/html/doc/misc/npm-scripts.html index 976695a05cc878..ea3ecc321d8145 100644 --- a/deps/npm/html/doc/misc/npm-scripts.html +++ b/deps/npm/html/doc/misc/npm-scripts.html @@ -243,5 +243,5 @@

    SEE ALSO

           - + diff --git a/deps/npm/html/doc/misc/removing-npm.html b/deps/npm/html/doc/misc/removing-npm.html index 8a7a51e4b0629d..98404d073c88ad 100644 --- a/deps/npm/html/doc/misc/removing-npm.html +++ b/deps/npm/html/doc/misc/removing-npm.html @@ -57,5 +57,5 @@

    SEE ALSO

           - + diff --git a/deps/npm/html/doc/misc/semver.html b/deps/npm/html/doc/misc/semver.html index 5a8b556bcabcd4..44c208b217d82c 100644 --- a/deps/npm/html/doc/misc/semver.html +++ b/deps/npm/html/doc/misc/semver.html @@ -325,5 +325,5 @@

    Ranges

           - + diff --git a/deps/npm/lib/build.js b/deps/npm/lib/build.js index 5dd243a7953aac..c2acc0066235e2 100644 --- a/deps/npm/lib/build.js +++ b/deps/npm/lib/build.js @@ -79,7 +79,8 @@ var writeBuiltinConf = build.writeBuiltinConf = function (pkg, folder, cb) { var parent = path.dirname(folder) var dir = npm.globalDir - if (pkg.name !== 'npm' || + // Make this count for canary, too + if ((pkg.name !== 'npm' && pkg.name !== 'npmc') || !npm.config.get('global') || !npm.config.usingBuiltin || dir !== parent) { diff --git a/deps/npm/lib/config/pacote.js b/deps/npm/lib/config/pacote.js index 705544fe3cbad2..2d2dda59fa3ee2 100644 --- a/deps/npm/lib/config/pacote.js +++ b/deps/npm/lib/config/pacote.js @@ -2,6 +2,7 @@ const Buffer = require('safe-buffer').Buffer +const crypto = require('crypto') const npm = require('../npm') const log = require('npmlog') let pack @@ -9,6 +10,9 @@ const path = require('path') let effectiveOwner +const npmSession = crypto.randomBytes(8).toString('hex') +log.verbose('npm-session', npmSession) + module.exports = pacoteOpts function pacoteOpts (moreOpts) { if (!pack) { @@ -17,13 +21,17 @@ function pacoteOpts (moreOpts) { const ownerStats = calculateOwner() const opts = { cache: path.join(npm.config.get('cache'), '_cacache'), + ca: npm.config.get('ca'), + cert: npm.config.get('cert'), defaultTag: npm.config.get('tag'), dirPacker: pack.packGitDep, hashAlgorithm: 'sha1', + key: npm.config.get('key'), localAddress: npm.config.get('local-address'), log: log, maxAge: npm.config.get('cache-min'), maxSockets: npm.config.get('maxsockets'), + npmSession: npmSession, offline: npm.config.get('offline'), preferOffline: npm.config.get('prefer-offline') || npm.config.get('cache-min') > 9999, preferOnline: npm.config.get('prefer-online') || npm.config.get('cache-max') <= 0, diff --git a/deps/npm/lib/config/reg-client.js b/deps/npm/lib/config/reg-client.js new file mode 100644 index 00000000000000..d4e2417097fa09 --- /dev/null +++ b/deps/npm/lib/config/reg-client.js @@ -0,0 +1,29 @@ +'use strict' + +module.exports = regClientConfig +function regClientConfig (npm, log, config) { + return { + proxy: { + http: config.get('proxy'), + https: config.get('https-proxy'), + localAddress: config.get('local-address') + }, + ssl: { + certificate: config.get('cert'), + key: config.get('key'), + ca: config.get('ca'), + strict: config.get('strict-ssl') + }, + retry: { + retries: config.get('fetch-retries'), + factor: config.get('fetch-retry-factor'), + minTimeout: config.get('fetch-retry-mintimeout'), + maxTimeout: config.get('fetch-retry-maxtimeout') + }, + userAgent: config.get('user-agent'), + log: log, + defaultTag: config.get('tag'), + maxSockets: config.get('maxsockets'), + scope: npm.projectScope + } +} diff --git a/deps/npm/lib/doctor.js b/deps/npm/lib/doctor.js index 357ba91a5ac7de..95ede1bc872429 100644 --- a/deps/npm/lib/doctor.js +++ b/deps/npm/lib/doctor.js @@ -39,9 +39,9 @@ function doctor (args, silent, cb) { [getLatestNpmVersion], [getLatestNodejsVersion, args['node-url']], [getGitPath], - [checkFilesPermission, npm.cache, 6], - [checkFilesPermission, globalNodeModules, 4], - [checkFilesPermission, localNodeModules, 6], + [checkFilesPermission, npm.cache, 4, 6], + [checkFilesPermission, globalNodeModules, 4, 4], + [checkFilesPermission, localNodeModules, 6, 6], [verifyCachedFiles, path.join(npm.cache, '_cacache')] ] diff --git a/deps/npm/lib/doctor/check-files-permission.js b/deps/npm/lib/doctor/check-files-permission.js index 50014fd232eb72..1cefb6e64cea51 100644 --- a/deps/npm/lib/doctor/check-files-permission.js +++ b/deps/npm/lib/doctor/check-files-permission.js @@ -6,7 +6,7 @@ var log = require('npmlog') var npm = require('../npm.js') var fileCompletion = require('../utils/completion/file-completion.js') -function checkFilesPermission (root, mask, cb) { +function checkFilesPermission (root, fmask, dmask, cb) { if (process.platform === 'win32') return cb(null, true) getUid(npm.config.get('user'), npm.config.get('group'), function (e, uid, gid) { var tracker = log.newItem('checkFilePermissions', 1) @@ -37,10 +37,10 @@ function checkFilesPermission (root, mask, cb) { fs.lstat(file, function (e, stat) { tracker.completeWork(1) if (e) return next(e) - if (!stat.isFile()) return next() + if (!stat.isDirectory() && !stat.isFile()) return next() // 6 = fs.constants.R_OK | fs.constants.W_OK // constants aren't available on v4 - fs.access(file, 6, (err) => { + fs.access(file, stat.isFile() ? fmask : dmask, (err) => { if (err) { tracker.error('checkFilePermissions', `Missing permissions on ${file}`) return next(new Error('Missing permissions for ' + file)) diff --git a/deps/npm/lib/init.js b/deps/npm/lib/init.js index df5615e47632fd..000fa1a5b689e9 100644 --- a/deps/npm/lib/init.js +++ b/deps/npm/lib/init.js @@ -22,7 +22,7 @@ function init (args, cb) { 'See `npm help json` for definitive documentation on these fields', 'and exactly what they do.', '', - 'Use `npm install --save` afterwards to install a package and', + 'Use `npm install ` afterwards to install a package and', 'save it as a dependency in the package.json file.', '', 'Press ^C at any time to quit.' diff --git a/deps/npm/lib/install.js b/deps/npm/lib/install.js index 5d111b32c8b699..67dcf98b70d797 100644 --- a/deps/npm/lib/install.js +++ b/deps/npm/lib/install.js @@ -741,6 +741,11 @@ Installer.prototype.printInstalledForHuman = function (diffs, cb) { } }) var report = '' + if (this.args.length && (added || updated)) { + report += this.args.map((p) => { + return `+ ${p.name}@${p.version}` + }).join('\n') + '\n' + } var actions = [] if (added) actions.push('added ' + packages(added)) if (removed) actions.push('removed ' + packages(removed)) diff --git a/deps/npm/lib/install/action/finalize.js b/deps/npm/lib/install/action/finalize.js index ba38e602f82d8d..ded2350dff7155 100644 --- a/deps/npm/lib/install/action/finalize.js +++ b/deps/npm/lib/install/action/finalize.js @@ -90,6 +90,6 @@ module.exports = function (staging, pkg, log) { module.exports.rollback = function (top, staging, pkg, next) { const requested = pkg.package._requested || getRequested(pkg) - if (requested.type === 'directory') return next() + if (requested && requested.type === 'directory') return next() gentlyRm(pkg.realpath, false, top, next) } diff --git a/deps/npm/lib/install/action/prepare.js b/deps/npm/lib/install/action/prepare.js index 771a2a9399533a..5e4333a5b51c6f 100644 --- a/deps/npm/lib/install/action/prepare.js +++ b/deps/npm/lib/install/action/prepare.js @@ -11,8 +11,8 @@ module.exports = function (staging, pkg, log, next) { // see https://github.com/npm/npm/issues/10074 for details if (pkg.package && pkg.package.scripts && pkg.package.scripts.prepublish) { prepublishWarning([ - 'As of npm@5, `prepublish` scripts will run only for `npm publish`.', - '(In npm@4 and previous versions, it also runs for `npm install`.)', + 'As of npm@5, `prepublish` scripts are deprecated.', + 'Use `prepare` for build steps and `prepublishOnly` for upload-only.', 'See the deprecation note in `npm help scripts` for more information.' ]) } diff --git a/deps/npm/lib/install/inflate-bundled.js b/deps/npm/lib/install/inflate-bundled.js index 70da583df4e4f2..66bbb44a33de37 100644 --- a/deps/npm/lib/install/inflate-bundled.js +++ b/deps/npm/lib/install/inflate-bundled.js @@ -1,11 +1,11 @@ 'use strict' -var validate = require('aproba') + var childPath = require('../utils/child-path.js') var reset = require('./node.js').reset module.exports = function inflateBundled (bundler, parent, children) { - validate('OOA', arguments) children.forEach(function (child) { + if (child.fromBundle === bundler) return reset(child) child.fromBundle = bundler child.isInLink = bundler.isLink diff --git a/deps/npm/lib/install/inflate-shrinkwrap.js b/deps/npm/lib/install/inflate-shrinkwrap.js index 8cb75626bb5d77..7ad966ea0a90e8 100644 --- a/deps/npm/lib/install/inflate-shrinkwrap.js +++ b/deps/npm/lib/install/inflate-shrinkwrap.js @@ -19,13 +19,13 @@ module.exports = function (tree, swdeps, opts, finishInflating) { fetchPackageMetadata = BB.promisify(require('../fetch-package-metadata.js')) addBundled = BB.promisify(fetchPackageMetadata.addBundled) } - if (!npm.config.get('shrinkwrap') || !npm.config.get('package-lock')) { - return finishInflating() - } if (arguments.length === 3) { finishInflating = opts opts = {} } + if (!npm.config.get('shrinkwrap') || !npm.config.get('package-lock')) { + return finishInflating() + } tree.loaded = true return inflateShrinkwrap(tree.path, tree, swdeps, opts).then( () => finishInflating(), diff --git a/deps/npm/lib/ls.js b/deps/npm/lib/ls.js index b993dd6235ebc6..3e2f2ce8fadef8 100644 --- a/deps/npm/lib/ls.js +++ b/deps/npm/lib/ls.js @@ -429,7 +429,7 @@ function makeArchy_ (data, long, dir, depth, parent, d) { if (long) { if (dir === data.path) out.label += '\n' + dir - out.label += '\n' + getExtras(data, dir) + out.label += '\n' + getExtras(data) } else if (dir === data.path) { if (out.label) out.label += ' ' out.label += dir diff --git a/deps/npm/lib/npm.js b/deps/npm/lib/npm.js index dbd8e97150a763..990d8c51098593 100644 --- a/deps/npm/lib/npm.js +++ b/deps/npm/lib/npm.js @@ -33,6 +33,7 @@ var rimraf = require('rimraf') var lazyProperty = require('lazy-property') var parseJSON = require('./utils/parse-json.js') + var clientConfig = require('./config/reg-client.js') var aliases = require('./config/cmd-list').aliases var cmdList = require('./config/cmd-list').cmdList var plumbing = require('./config/cmd-list').plumbing @@ -344,7 +345,7 @@ lazyProperty(npm, 'registry', function () { registryLoaded = true var RegClient = require('npm-registry-client') - var registry = new RegClient(adaptClientConfig(npm.config)) + var registry = new RegClient(clientConfig(npm, log, npm.config)) registry.version = npm.version registry.refer = registryRefer return registry @@ -467,31 +468,4 @@ return '' } } - - function adaptClientConfig (config) { - return { - proxy: { - http: config.get('proxy'), - https: config.get('https-proxy'), - localAddress: config.get('local-address') - }, - ssl: { - certificate: config.get('cert'), - key: config.get('key'), - ca: config.get('ca'), - strict: config.get('strict-ssl') - }, - retry: { - retries: config.get('fetch-retries'), - factor: config.get('fetch-retry-factor'), - minTimeout: config.get('fetch-retry-mintimeout'), - maxTimeout: config.get('fetch-retry-maxtimeout') - }, - userAgent: config.get('user-agent'), - log: log, - defaultTag: config.get('tag'), - maxSockets: config.get('maxsockets'), - scope: npm.projectScope - } - } })() diff --git a/deps/npm/lib/pack.js b/deps/npm/lib/pack.js index 075a672d66f212..4552bbc498986b 100644 --- a/deps/npm/lib/pack.js +++ b/deps/npm/lib/pack.js @@ -92,8 +92,8 @@ function prepareDirectory (dir) { if (pkg.scripts && pkg.scripts.prepublish) { prepublishWarning([ 'As of npm@5, `prepublish` scripts are deprecated.', - 'Use `prepare` for build steps and `prepublishOnly` for upload-only', - 'See the deprecation note in `npm help scripts` for more information' + 'Use `prepare` for build steps and `prepublishOnly` for upload-only.', + 'See the deprecation note in `npm help scripts` for more information.' ]) } if (npm.config.get('ignore-prepublish')) { diff --git a/deps/npm/lib/test.js b/deps/npm/lib/test.js index cbc75821708b12..4ef025c4bac50c 100644 --- a/deps/npm/lib/test.js +++ b/deps/npm/lib/test.js @@ -1,6 +1,12 @@ module.exports = test -var testCmd = require('./utils/lifecycle.js').cmd('test') +const testCmd = require('./utils/lifecycle.js').cmd('test') +const usage = require('./utils/usage') + +test.usage = usage( + 'test', + 'npm test [-- ]' +) function test (args, cb) { testCmd(args, function (er) { diff --git a/deps/npm/lib/utils/error-handler.js b/deps/npm/lib/utils/error-handler.js index 5374d1feeca078..b13d42e1df451f 100644 --- a/deps/npm/lib/utils/error-handler.js +++ b/deps/npm/lib/utils/error-handler.js @@ -120,7 +120,7 @@ function exit (code, noLog) { }) rollbacks.length = 0 } else if (code && !noLog) { - writeLogFile(reallyExit) + writeLogFile() } else { reallyExit() } diff --git a/deps/npm/lib/utils/get-publish-config.js b/deps/npm/lib/utils/get-publish-config.js index fa475434ff61bc..ac0ef0934201ad 100644 --- a/deps/npm/lib/utils/get-publish-config.js +++ b/deps/npm/lib/utils/get-publish-config.js @@ -1,12 +1,16 @@ -var Conf = require('../config/core.js').Conf -var RegClient = require('npm-registry-client') -var log = require('npmlog') +'use strict' + +const clientConfig = require('../config/reg-client.js') +const Conf = require('../config/core.js').Conf +const log = require('npmlog') +const npm = require('../npm.js') +const RegClient = require('npm-registry-client') module.exports = getPublishConfig function getPublishConfig (publishConfig, defaultConfig, defaultClient) { - var config = defaultConfig - var client = defaultClient + let config = defaultConfig + let client = defaultClient log.verbose('getPublishConfig', publishConfig) if (publishConfig) { config = new Conf(defaultConfig) @@ -18,7 +22,7 @@ function getPublishConfig (publishConfig, defaultConfig, defaultClient) { s[k] = publishConfig[k] return s }, {})) - client = new RegClient(config) + client = new RegClient(clientConfig(npm, log, config)) } return { config: config, client: client } diff --git a/deps/npm/lib/utils/module-name.js b/deps/npm/lib/utils/module-name.js index 649dfac01bd51b..43e0f5fb128e53 100644 --- a/deps/npm/lib/utils/module-name.js +++ b/deps/npm/lib/utils/module-name.js @@ -1,6 +1,5 @@ 'use strict' var path = require('path') -var validate = require('aproba') module.exports = moduleName module.exports.test = {} @@ -22,7 +21,6 @@ function isNotEmpty (str) { var unknown = 0 function moduleName (tree) { - validate('O', arguments) var pkg = tree.package || tree if (isNotEmpty(pkg.name)) return pkg.name var pkgName = pathToPackageName(tree.path) diff --git a/deps/npm/man/man1/npm-README.1 b/deps/npm/man/man1/npm-README.1 index ac6cb0f4cca5b7..0c2fbb6faa2483 100644 --- a/deps/npm/man/man1/npm-README.1 +++ b/deps/npm/man/man1/npm-README.1 @@ -1,4 +1,4 @@ -.TH "NPM" "1" "May 2017" "" "" +.TH "NPM" "1" "June 2017" "" "" .SH "NAME" \fBnpm\fR \- a JavaScript package manager .P diff --git a/deps/npm/man/man1/npm-access.1 b/deps/npm/man/man1/npm-access.1 index a0004f7ed35db5..d2a7a9fa00d160 100644 --- a/deps/npm/man/man1/npm-access.1 +++ b/deps/npm/man/man1/npm-access.1 @@ -1,4 +1,4 @@ -.TH "NPM\-ACCESS" "1" "May 2017" "" "" +.TH "NPM\-ACCESS" "1" "June 2017" "" "" .SH "NAME" \fBnpm-access\fR \- Set access level on published packages .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-adduser.1 b/deps/npm/man/man1/npm-adduser.1 index 0d2426de56df71..64b037402f0d22 100644 --- a/deps/npm/man/man1/npm-adduser.1 +++ b/deps/npm/man/man1/npm-adduser.1 @@ -1,4 +1,4 @@ -.TH "NPM\-ADDUSER" "1" "May 2017" "" "" +.TH "NPM\-ADDUSER" "1" "June 2017" "" "" .SH "NAME" \fBnpm-adduser\fR \- Add a registry user account .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-bin.1 b/deps/npm/man/man1/npm-bin.1 index 6dd28b8615f4ed..e6a15a467c3311 100644 --- a/deps/npm/man/man1/npm-bin.1 +++ b/deps/npm/man/man1/npm-bin.1 @@ -1,4 +1,4 @@ -.TH "NPM\-BIN" "1" "May 2017" "" "" +.TH "NPM\-BIN" "1" "June 2017" "" "" .SH "NAME" \fBnpm-bin\fR \- Display npm bin folder .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-bugs.1 b/deps/npm/man/man1/npm-bugs.1 index 949412ae0c64e3..860d5299ca0891 100644 --- a/deps/npm/man/man1/npm-bugs.1 +++ b/deps/npm/man/man1/npm-bugs.1 @@ -1,4 +1,4 @@ -.TH "NPM\-BUGS" "1" "May 2017" "" "" +.TH "NPM\-BUGS" "1" "June 2017" "" "" .SH "NAME" \fBnpm-bugs\fR \- Bugs for a package in a web browser maybe .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-build.1 b/deps/npm/man/man1/npm-build.1 index f0f629d3343c30..322d8c069e7e7f 100644 --- a/deps/npm/man/man1/npm-build.1 +++ b/deps/npm/man/man1/npm-build.1 @@ -1,4 +1,4 @@ -.TH "NPM\-BUILD" "1" "May 2017" "" "" +.TH "NPM\-BUILD" "1" "June 2017" "" "" .SH "NAME" \fBnpm-build\fR \- Build a package .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-bundle.1 b/deps/npm/man/man1/npm-bundle.1 index ca564836cc1759..c8d8f8686b3e2f 100644 --- a/deps/npm/man/man1/npm-bundle.1 +++ b/deps/npm/man/man1/npm-bundle.1 @@ -1,4 +1,4 @@ -.TH "NPM\-BUNDLE" "1" "May 2017" "" "" +.TH "NPM\-BUNDLE" "1" "June 2017" "" "" .SH "NAME" \fBnpm-bundle\fR \- REMOVED .SH DESCRIPTION diff --git a/deps/npm/man/man1/npm-cache.1 b/deps/npm/man/man1/npm-cache.1 index cc8b1e2fae490a..41d84cba055dd3 100644 --- a/deps/npm/man/man1/npm-cache.1 +++ b/deps/npm/man/man1/npm-cache.1 @@ -1,4 +1,4 @@ -.TH "NPM\-CACHE" "1" "May 2017" "" "" +.TH "NPM\-CACHE" "1" "June 2017" "" "" .SH "NAME" \fBnpm-cache\fR \- Manipulates packages cache .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-completion.1 b/deps/npm/man/man1/npm-completion.1 index e2f0217b77841f..11b4d11b1f1df2 100644 --- a/deps/npm/man/man1/npm-completion.1 +++ b/deps/npm/man/man1/npm-completion.1 @@ -1,4 +1,4 @@ -.TH "NPM\-COMPLETION" "1" "May 2017" "" "" +.TH "NPM\-COMPLETION" "1" "June 2017" "" "" .SH "NAME" \fBnpm-completion\fR \- Tab Completion for npm .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-config.1 b/deps/npm/man/man1/npm-config.1 index 491401e0b1b266..265aff01c6cd01 100644 --- a/deps/npm/man/man1/npm-config.1 +++ b/deps/npm/man/man1/npm-config.1 @@ -1,4 +1,4 @@ -.TH "NPM\-CONFIG" "1" "May 2017" "" "" +.TH "NPM\-CONFIG" "1" "June 2017" "" "" .SH "NAME" \fBnpm-config\fR \- Manage the npm configuration files .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-dedupe.1 b/deps/npm/man/man1/npm-dedupe.1 index 19d20cb3ceb048..d0962471d801b9 100644 --- a/deps/npm/man/man1/npm-dedupe.1 +++ b/deps/npm/man/man1/npm-dedupe.1 @@ -1,4 +1,4 @@ -.TH "NPM\-DEDUPE" "1" "May 2017" "" "" +.TH "NPM\-DEDUPE" "1" "June 2017" "" "" .SH "NAME" \fBnpm-dedupe\fR \- Reduce duplication .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-deprecate.1 b/deps/npm/man/man1/npm-deprecate.1 index d8c806dd18fd31..2b26e9fc56fe18 100644 --- a/deps/npm/man/man1/npm-deprecate.1 +++ b/deps/npm/man/man1/npm-deprecate.1 @@ -1,4 +1,4 @@ -.TH "NPM\-DEPRECATE" "1" "May 2017" "" "" +.TH "NPM\-DEPRECATE" "1" "June 2017" "" "" .SH "NAME" \fBnpm-deprecate\fR \- Deprecate a version of a package .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-dist-tag.1 b/deps/npm/man/man1/npm-dist-tag.1 index 049ad0d868b546..3142da944ff0e5 100644 --- a/deps/npm/man/man1/npm-dist-tag.1 +++ b/deps/npm/man/man1/npm-dist-tag.1 @@ -1,4 +1,4 @@ -.TH "NPM\-DIST\-TAG" "1" "May 2017" "" "" +.TH "NPM\-DIST\-TAG" "1" "June 2017" "" "" .SH "NAME" \fBnpm-dist-tag\fR \- Modify package distribution tags .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-docs.1 b/deps/npm/man/man1/npm-docs.1 index 9ae6826c22d20c..c97b912e184337 100644 --- a/deps/npm/man/man1/npm-docs.1 +++ b/deps/npm/man/man1/npm-docs.1 @@ -1,4 +1,4 @@ -.TH "NPM\-DOCS" "1" "May 2017" "" "" +.TH "NPM\-DOCS" "1" "June 2017" "" "" .SH "NAME" \fBnpm-docs\fR \- Docs for a package in a web browser maybe .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-doctor.1 b/deps/npm/man/man1/npm-doctor.1 index 7ef3c91d09e251..787b9d42198cd9 100644 --- a/deps/npm/man/man1/npm-doctor.1 +++ b/deps/npm/man/man1/npm-doctor.1 @@ -1,4 +1,4 @@ -.TH "NPM\-DOCTOR" "1" "May 2017" "" "" +.TH "NPM\-DOCTOR" "1" "June 2017" "" "" .SH "NAME" \fBnpm-doctor\fR \- Check your environments .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-edit.1 b/deps/npm/man/man1/npm-edit.1 index c495f292c48349..978a4e54f3e680 100644 --- a/deps/npm/man/man1/npm-edit.1 +++ b/deps/npm/man/man1/npm-edit.1 @@ -1,4 +1,4 @@ -.TH "NPM\-EDIT" "1" "May 2017" "" "" +.TH "NPM\-EDIT" "1" "June 2017" "" "" .SH "NAME" \fBnpm-edit\fR \- Edit an installed package .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-explore.1 b/deps/npm/man/man1/npm-explore.1 index 03986814eecc54..d5cf964ecb2a71 100644 --- a/deps/npm/man/man1/npm-explore.1 +++ b/deps/npm/man/man1/npm-explore.1 @@ -1,4 +1,4 @@ -.TH "NPM\-EXPLORE" "1" "May 2017" "" "" +.TH "NPM\-EXPLORE" "1" "June 2017" "" "" .SH "NAME" \fBnpm-explore\fR \- Browse an installed package .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-help-search.1 b/deps/npm/man/man1/npm-help-search.1 index f4512cb7d0456d..d54f316542229a 100644 --- a/deps/npm/man/man1/npm-help-search.1 +++ b/deps/npm/man/man1/npm-help-search.1 @@ -1,4 +1,4 @@ -.TH "NPM\-HELP\-SEARCH" "1" "May 2017" "" "" +.TH "NPM\-HELP\-SEARCH" "1" "June 2017" "" "" .SH "NAME" \fBnpm-help-search\fR \- Search npm help documentation .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-help.1 b/deps/npm/man/man1/npm-help.1 index 3028ac419596cf..a102985b9f240a 100644 --- a/deps/npm/man/man1/npm-help.1 +++ b/deps/npm/man/man1/npm-help.1 @@ -1,4 +1,4 @@ -.TH "NPM\-HELP" "1" "May 2017" "" "" +.TH "NPM\-HELP" "1" "June 2017" "" "" .SH "NAME" \fBnpm-help\fR \- Get help on npm .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-init.1 b/deps/npm/man/man1/npm-init.1 index 99d1bad04ea55f..c8ccd94b7b866d 100644 --- a/deps/npm/man/man1/npm-init.1 +++ b/deps/npm/man/man1/npm-init.1 @@ -1,4 +1,4 @@ -.TH "NPM\-INIT" "1" "May 2017" "" "" +.TH "NPM\-INIT" "1" "June 2017" "" "" .SH "NAME" \fBnpm-init\fR \- Interactively create a package\.json file .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-install-test.1 b/deps/npm/man/man1/npm-install-test.1 index 9b7094591c36ff..3bdd4c632b95f0 100644 --- a/deps/npm/man/man1/npm-install-test.1 +++ b/deps/npm/man/man1/npm-install-test.1 @@ -1,4 +1,4 @@ -.TH "NPM" "" "May 2017" "" "" +.TH "NPM" "" "June 2017" "" "" .SH "NAME" \fBnpm\fR .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-install.1 b/deps/npm/man/man1/npm-install.1 index 2dca6a4b8fe56a..e90cc4f8f40c68 100644 --- a/deps/npm/man/man1/npm-install.1 +++ b/deps/npm/man/man1/npm-install.1 @@ -1,4 +1,4 @@ -.TH "NPM\-INSTALL" "1" "May 2017" "" "" +.TH "NPM\-INSTALL" "1" "June 2017" "" "" .SH "NAME" \fBnpm-install\fR \- Install a package .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-link.1 b/deps/npm/man/man1/npm-link.1 index ae6e6b3b1e9884..b5b1d25098f32a 100644 --- a/deps/npm/man/man1/npm-link.1 +++ b/deps/npm/man/man1/npm-link.1 @@ -1,4 +1,4 @@ -.TH "NPM\-LINK" "1" "May 2017" "" "" +.TH "NPM\-LINK" "1" "June 2017" "" "" .SH "NAME" \fBnpm-link\fR \- Symlink a package folder .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-logout.1 b/deps/npm/man/man1/npm-logout.1 index c594d22fa082c9..1bb0d25ce53c70 100644 --- a/deps/npm/man/man1/npm-logout.1 +++ b/deps/npm/man/man1/npm-logout.1 @@ -1,4 +1,4 @@ -.TH "NPM\-LOGOUT" "1" "May 2017" "" "" +.TH "NPM\-LOGOUT" "1" "June 2017" "" "" .SH "NAME" \fBnpm-logout\fR \- Log out of the registry .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-ls.1 b/deps/npm/man/man1/npm-ls.1 index 31cbd387aa695f..bf339ee70ca67b 100644 --- a/deps/npm/man/man1/npm-ls.1 +++ b/deps/npm/man/man1/npm-ls.1 @@ -1,4 +1,4 @@ -.TH "NPM\-LS" "1" "May 2017" "" "" +.TH "NPM\-LS" "1" "June 2017" "" "" .SH "NAME" \fBnpm-ls\fR \- List installed packages .SH SYNOPSIS @@ -22,7 +22,7 @@ For example, running \fBnpm ls promzard\fP in npm's source tree will show: .P .RS 2 .nf -npm@5.0.0 /path/to/npm +npm@5.0.3 /path/to/npm └─┬ init\-package\-json@0\.0\.4 └── promzard@0\.1\.5 .fi diff --git a/deps/npm/man/man1/npm-outdated.1 b/deps/npm/man/man1/npm-outdated.1 index c43306fcb8615b..992c359dcbabb9 100644 --- a/deps/npm/man/man1/npm-outdated.1 +++ b/deps/npm/man/man1/npm-outdated.1 @@ -1,4 +1,4 @@ -.TH "NPM\-OUTDATED" "1" "May 2017" "" "" +.TH "NPM\-OUTDATED" "1" "June 2017" "" "" .SH "NAME" \fBnpm-outdated\fR \- Check for outdated packages .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-owner.1 b/deps/npm/man/man1/npm-owner.1 index 29a9d54bfc40e7..9eb713bd666d00 100644 --- a/deps/npm/man/man1/npm-owner.1 +++ b/deps/npm/man/man1/npm-owner.1 @@ -1,4 +1,4 @@ -.TH "NPM\-OWNER" "1" "May 2017" "" "" +.TH "NPM\-OWNER" "1" "June 2017" "" "" .SH "NAME" \fBnpm-owner\fR \- Manage package owners .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-pack.1 b/deps/npm/man/man1/npm-pack.1 index 9e80b63ea9c899..634d3e84094c59 100644 --- a/deps/npm/man/man1/npm-pack.1 +++ b/deps/npm/man/man1/npm-pack.1 @@ -1,4 +1,4 @@ -.TH "NPM\-PACK" "1" "May 2017" "" "" +.TH "NPM\-PACK" "1" "June 2017" "" "" .SH "NAME" \fBnpm-pack\fR \- Create a tarball from a package .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-ping.1 b/deps/npm/man/man1/npm-ping.1 index 1df2ee8a520aaa..e14fa450d97268 100644 --- a/deps/npm/man/man1/npm-ping.1 +++ b/deps/npm/man/man1/npm-ping.1 @@ -1,4 +1,4 @@ -.TH "NPM\-PING" "1" "May 2017" "" "" +.TH "NPM\-PING" "1" "June 2017" "" "" .SH "NAME" \fBnpm-ping\fR \- Ping npm registry .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-prefix.1 b/deps/npm/man/man1/npm-prefix.1 index 539cce1e6e8da3..46d06910454ac2 100644 --- a/deps/npm/man/man1/npm-prefix.1 +++ b/deps/npm/man/man1/npm-prefix.1 @@ -1,4 +1,4 @@ -.TH "NPM\-PREFIX" "1" "May 2017" "" "" +.TH "NPM\-PREFIX" "1" "June 2017" "" "" .SH "NAME" \fBnpm-prefix\fR \- Display prefix .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-prune.1 b/deps/npm/man/man1/npm-prune.1 index 21695ac1350b0c..c8051b36e8ed9d 100644 --- a/deps/npm/man/man1/npm-prune.1 +++ b/deps/npm/man/man1/npm-prune.1 @@ -1,4 +1,4 @@ -.TH "NPM\-PRUNE" "1" "May 2017" "" "" +.TH "NPM\-PRUNE" "1" "June 2017" "" "" .SH "NAME" \fBnpm-prune\fR \- Remove extraneous packages .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-publish.1 b/deps/npm/man/man1/npm-publish.1 index 603c79da7f499f..5095939be6ad8d 100644 --- a/deps/npm/man/man1/npm-publish.1 +++ b/deps/npm/man/man1/npm-publish.1 @@ -1,4 +1,4 @@ -.TH "NPM\-PUBLISH" "1" "May 2017" "" "" +.TH "NPM\-PUBLISH" "1" "June 2017" "" "" .SH "NAME" \fBnpm-publish\fR \- Publish a package .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-rebuild.1 b/deps/npm/man/man1/npm-rebuild.1 index 3eac6d27a9913e..7cb888b260d7c0 100644 --- a/deps/npm/man/man1/npm-rebuild.1 +++ b/deps/npm/man/man1/npm-rebuild.1 @@ -1,4 +1,4 @@ -.TH "NPM\-REBUILD" "1" "May 2017" "" "" +.TH "NPM\-REBUILD" "1" "June 2017" "" "" .SH "NAME" \fBnpm-rebuild\fR \- Rebuild a package .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-repo.1 b/deps/npm/man/man1/npm-repo.1 index 18f2a3f69f2cfe..cf2c9f7f5797a9 100644 --- a/deps/npm/man/man1/npm-repo.1 +++ b/deps/npm/man/man1/npm-repo.1 @@ -1,4 +1,4 @@ -.TH "NPM\-REPO" "1" "May 2017" "" "" +.TH "NPM\-REPO" "1" "June 2017" "" "" .SH "NAME" \fBnpm-repo\fR \- Open package repository page in the browser .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-restart.1 b/deps/npm/man/man1/npm-restart.1 index 95f402d09d4d3a..7a0c40d0502ddb 100644 --- a/deps/npm/man/man1/npm-restart.1 +++ b/deps/npm/man/man1/npm-restart.1 @@ -1,4 +1,4 @@ -.TH "NPM\-RESTART" "1" "May 2017" "" "" +.TH "NPM\-RESTART" "1" "June 2017" "" "" .SH "NAME" \fBnpm-restart\fR \- Restart a package .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-root.1 b/deps/npm/man/man1/npm-root.1 index 8a158479e4e923..fd30fb7cac442a 100644 --- a/deps/npm/man/man1/npm-root.1 +++ b/deps/npm/man/man1/npm-root.1 @@ -1,4 +1,4 @@ -.TH "NPM\-ROOT" "1" "May 2017" "" "" +.TH "NPM\-ROOT" "1" "June 2017" "" "" .SH "NAME" \fBnpm-root\fR \- Display npm root .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-run-script.1 b/deps/npm/man/man1/npm-run-script.1 index 7c75d8680d74fa..eaffbefc0ff5fa 100644 --- a/deps/npm/man/man1/npm-run-script.1 +++ b/deps/npm/man/man1/npm-run-script.1 @@ -1,4 +1,4 @@ -.TH "NPM\-RUN\-SCRIPT" "1" "May 2017" "" "" +.TH "NPM\-RUN\-SCRIPT" "1" "June 2017" "" "" .SH "NAME" \fBnpm-run-script\fR \- Run arbitrary package scripts .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-search.1 b/deps/npm/man/man1/npm-search.1 index caeab7142f5748..89cb716d847a1a 100644 --- a/deps/npm/man/man1/npm-search.1 +++ b/deps/npm/man/man1/npm-search.1 @@ -1,4 +1,4 @@ -.TH "NPM\-SEARCH" "1" "May 2017" "" "" +.TH "NPM\-SEARCH" "1" "June 2017" "" "" .SH "NAME" \fBnpm-search\fR \- Search for packages .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-shrinkwrap.1 b/deps/npm/man/man1/npm-shrinkwrap.1 index 08ce497d2066d5..d6d12bf1676774 100644 --- a/deps/npm/man/man1/npm-shrinkwrap.1 +++ b/deps/npm/man/man1/npm-shrinkwrap.1 @@ -1,4 +1,4 @@ -.TH "NPM\-SHRINKWRAP" "1" "May 2017" "" "" +.TH "NPM\-SHRINKWRAP" "1" "June 2017" "" "" .SH "NAME" \fBnpm-shrinkwrap\fR \- Lock down dependency versions for publication .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-star.1 b/deps/npm/man/man1/npm-star.1 index ed9afb395f1c0c..a04ce7363e2d7f 100644 --- a/deps/npm/man/man1/npm-star.1 +++ b/deps/npm/man/man1/npm-star.1 @@ -1,4 +1,4 @@ -.TH "NPM\-STAR" "1" "May 2017" "" "" +.TH "NPM\-STAR" "1" "June 2017" "" "" .SH "NAME" \fBnpm-star\fR \- Mark your favorite packages .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-stars.1 b/deps/npm/man/man1/npm-stars.1 index ca709693776bff..face66764b542e 100644 --- a/deps/npm/man/man1/npm-stars.1 +++ b/deps/npm/man/man1/npm-stars.1 @@ -1,4 +1,4 @@ -.TH "NPM\-STARS" "1" "May 2017" "" "" +.TH "NPM\-STARS" "1" "June 2017" "" "" .SH "NAME" \fBnpm-stars\fR \- View packages marked as favorites .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-start.1 b/deps/npm/man/man1/npm-start.1 index 9886f0d9a99e2c..0916970e0d247d 100644 --- a/deps/npm/man/man1/npm-start.1 +++ b/deps/npm/man/man1/npm-start.1 @@ -1,4 +1,4 @@ -.TH "NPM\-START" "1" "May 2017" "" "" +.TH "NPM\-START" "1" "June 2017" "" "" .SH "NAME" \fBnpm-start\fR \- Start a package .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-stop.1 b/deps/npm/man/man1/npm-stop.1 index 10fb4a4d0b9744..430f3c117f5c66 100644 --- a/deps/npm/man/man1/npm-stop.1 +++ b/deps/npm/man/man1/npm-stop.1 @@ -1,4 +1,4 @@ -.TH "NPM\-STOP" "1" "May 2017" "" "" +.TH "NPM\-STOP" "1" "June 2017" "" "" .SH "NAME" \fBnpm-stop\fR \- Stop a package .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-team.1 b/deps/npm/man/man1/npm-team.1 index 2a73f126df6c95..b38561f7114732 100644 --- a/deps/npm/man/man1/npm-team.1 +++ b/deps/npm/man/man1/npm-team.1 @@ -1,4 +1,4 @@ -.TH "NPM\-TEAM" "1" "May 2017" "" "" +.TH "NPM\-TEAM" "1" "June 2017" "" "" .SH "NAME" \fBnpm-team\fR \- Manage organization teams and team memberships .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-test.1 b/deps/npm/man/man1/npm-test.1 index e32f30670ae6a1..ad9fc14d558fab 100644 --- a/deps/npm/man/man1/npm-test.1 +++ b/deps/npm/man/man1/npm-test.1 @@ -1,4 +1,4 @@ -.TH "NPM\-TEST" "1" "May 2017" "" "" +.TH "NPM\-TEST" "1" "June 2017" "" "" .SH "NAME" \fBnpm-test\fR \- Test a package .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-uninstall.1 b/deps/npm/man/man1/npm-uninstall.1 index aa86ac30ba74bb..29df8f50f4f242 100644 --- a/deps/npm/man/man1/npm-uninstall.1 +++ b/deps/npm/man/man1/npm-uninstall.1 @@ -1,4 +1,4 @@ -.TH "NPM\-UNINSTALL" "1" "May 2017" "" "" +.TH "NPM\-UNINSTALL" "1" "June 2017" "" "" .SH "NAME" \fBnpm-uninstall\fR \- Remove a package .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-unpublish.1 b/deps/npm/man/man1/npm-unpublish.1 index ab85d670a914e1..c3883a59498f0a 100644 --- a/deps/npm/man/man1/npm-unpublish.1 +++ b/deps/npm/man/man1/npm-unpublish.1 @@ -1,4 +1,4 @@ -.TH "NPM\-UNPUBLISH" "1" "May 2017" "" "" +.TH "NPM\-UNPUBLISH" "1" "June 2017" "" "" .SH "NAME" \fBnpm-unpublish\fR \- Remove a package from the registry .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-update.1 b/deps/npm/man/man1/npm-update.1 index 0ebcd400eb6ea7..14bad07f5fedd4 100644 --- a/deps/npm/man/man1/npm-update.1 +++ b/deps/npm/man/man1/npm-update.1 @@ -1,4 +1,4 @@ -.TH "NPM\-UPDATE" "1" "May 2017" "" "" +.TH "NPM\-UPDATE" "1" "June 2017" "" "" .SH "NAME" \fBnpm-update\fR \- Update a package .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-version.1 b/deps/npm/man/man1/npm-version.1 index 069e9e45ea2404..ae2678a8db610a 100644 --- a/deps/npm/man/man1/npm-version.1 +++ b/deps/npm/man/man1/npm-version.1 @@ -1,4 +1,4 @@ -.TH "NPM\-VERSION" "1" "May 2017" "" "" +.TH "NPM\-VERSION" "1" "June 2017" "" "" .SH "NAME" \fBnpm-version\fR \- Bump a package version .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-view.1 b/deps/npm/man/man1/npm-view.1 index 0341f9001d26c7..0bfedd6b8b9c36 100644 --- a/deps/npm/man/man1/npm-view.1 +++ b/deps/npm/man/man1/npm-view.1 @@ -1,4 +1,4 @@ -.TH "NPM\-VIEW" "1" "May 2017" "" "" +.TH "NPM\-VIEW" "1" "June 2017" "" "" .SH "NAME" \fBnpm-view\fR \- View registry info .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm-whoami.1 b/deps/npm/man/man1/npm-whoami.1 index 66d53afa33d461..8fdf66c2fc5b93 100644 --- a/deps/npm/man/man1/npm-whoami.1 +++ b/deps/npm/man/man1/npm-whoami.1 @@ -1,4 +1,4 @@ -.TH "NPM\-WHOAMI" "1" "May 2017" "" "" +.TH "NPM\-WHOAMI" "1" "June 2017" "" "" .SH "NAME" \fBnpm-whoami\fR \- Display npm username .SH SYNOPSIS diff --git a/deps/npm/man/man1/npm.1 b/deps/npm/man/man1/npm.1 index 8ce03075f12ace..e3771ad9facb2f 100644 --- a/deps/npm/man/man1/npm.1 +++ b/deps/npm/man/man1/npm.1 @@ -1,4 +1,4 @@ -.TH "NPM" "1" "May 2017" "" "" +.TH "NPM" "1" "June 2017" "" "" .SH "NAME" \fBnpm\fR \- javascript package manager .SH SYNOPSIS @@ -10,7 +10,7 @@ npm [args] .RE .SH VERSION .P -5.0.0 +5.0.3 .SH DESCRIPTION .P npm is the package manager for the Node JavaScript platform\. It puts diff --git a/deps/npm/man/man5/npm-folders.5 b/deps/npm/man/man5/npm-folders.5 index d3757535db3f4d..194e6bcc02d474 100644 --- a/deps/npm/man/man5/npm-folders.5 +++ b/deps/npm/man/man5/npm-folders.5 @@ -1,4 +1,4 @@ -.TH "NPM\-FOLDERS" "5" "May 2017" "" "" +.TH "NPM\-FOLDERS" "5" "June 2017" "" "" .SH "NAME" \fBnpm-folders\fR \- Folder Structures Used by npm .SH DESCRIPTION diff --git a/deps/npm/man/man5/npm-global.5 b/deps/npm/man/man5/npm-global.5 index d3757535db3f4d..194e6bcc02d474 100644 --- a/deps/npm/man/man5/npm-global.5 +++ b/deps/npm/man/man5/npm-global.5 @@ -1,4 +1,4 @@ -.TH "NPM\-FOLDERS" "5" "May 2017" "" "" +.TH "NPM\-FOLDERS" "5" "June 2017" "" "" .SH "NAME" \fBnpm-folders\fR \- Folder Structures Used by npm .SH DESCRIPTION diff --git a/deps/npm/man/man5/npm-json.5 b/deps/npm/man/man5/npm-json.5 index a8c4be85a0b5a2..89eefefcf68123 100644 --- a/deps/npm/man/man5/npm-json.5 +++ b/deps/npm/man/man5/npm-json.5 @@ -1,4 +1,4 @@ -.TH "PACKAGE\.JSON" "5" "May 2017" "" "" +.TH "PACKAGE\.JSON" "5" "June 2017" "" "" .SH "NAME" \fBpackage.json\fR \- Specifics of npm's package\.json handling .SH DESCRIPTION @@ -265,6 +265,8 @@ Conversely, some files are always ignored: \fBconfig\.gypi\fP .IP \(bu 2 \fB*\.orig\fP +.IP \(bu 2 +\fBpackage\-lock\.json\fP (use shrinkwrap instead) .RE .SH main diff --git a/deps/npm/man/man5/npm-package-locks.5 b/deps/npm/man/man5/npm-package-locks.5 index d751dc55661570..4d6a28519294af 100644 --- a/deps/npm/man/man5/npm-package-locks.5 +++ b/deps/npm/man/man5/npm-package-locks.5 @@ -1,4 +1,4 @@ -.TH "NPM\-PACKAGE\-LOCKS" "5" "May 2017" "" "" +.TH "NPM\-PACKAGE\-LOCKS" "5" "June 2017" "" "" .SH "NAME" \fBnpm-package-locks\fR \- An explanation of npm lockfiles .SH DESCRIPTION diff --git a/deps/npm/man/man5/npm-shrinkwrap.json.5 b/deps/npm/man/man5/npm-shrinkwrap.json.5 index deb06a7244cd31..400e23b20adb5e 100644 --- a/deps/npm/man/man5/npm-shrinkwrap.json.5 +++ b/deps/npm/man/man5/npm-shrinkwrap.json.5 @@ -1,4 +1,4 @@ -.TH "NPM\-SHRINKWRAP\.JSON" "5" "May 2017" "" "" +.TH "NPM\-SHRINKWRAP\.JSON" "5" "June 2017" "" "" .SH "NAME" \fBnpm-shrinkwrap.json\fR \- A publishable lockfile .SH DESCRIPTION diff --git a/deps/npm/man/man5/npmrc.5 b/deps/npm/man/man5/npmrc.5 index 70b824a7d9cc47..a80fdca666fe9b 100644 --- a/deps/npm/man/man5/npmrc.5 +++ b/deps/npm/man/man5/npmrc.5 @@ -1,4 +1,4 @@ -.TH "NPMRC" "5" "May 2017" "" "" +.TH "NPMRC" "5" "June 2017" "" "" .SH "NAME" \fBnpmrc\fR \- The npm config files .SH DESCRIPTION diff --git a/deps/npm/man/man5/package-lock.json.5 b/deps/npm/man/man5/package-lock.json.5 index fb86d4d0c56e62..09dc0d760040ed 100644 --- a/deps/npm/man/man5/package-lock.json.5 +++ b/deps/npm/man/man5/package-lock.json.5 @@ -1,4 +1,4 @@ -.TH "PACKAGE\-LOCK\.JSON" "5" "May 2017" "" "" +.TH "PACKAGE\-LOCK\.JSON" "5" "June 2017" "" "" .SH "NAME" \fBpackage-lock.json\fR \- A manifestation of the manifest .SH DESCRIPTION @@ -47,7 +47,7 @@ whose semantics were used when generating this \fBpackage\-lock\.json\fP\|\. .P This is a subresource integrity \fIhttps://w3c\.github\.io/webappsec/specs/subresourceintegrity/\fR value -created from the \fBpacakge\.json\fP\|\. No preprocessing of the \fBpackage\.json\fP should +created from the \fBpackage\.json\fP\|\. No preprocessing of the \fBpackage\.json\fP should be done\. Subresource integrity strings can be produced by modules like \fBssri\fP \fIhttps://www\.npmjs\.com/package/ssri\fR\|\. .SS preserveSymlinks diff --git a/deps/npm/man/man5/package.json.5 b/deps/npm/man/man5/package.json.5 index a8c4be85a0b5a2..89eefefcf68123 100644 --- a/deps/npm/man/man5/package.json.5 +++ b/deps/npm/man/man5/package.json.5 @@ -1,4 +1,4 @@ -.TH "PACKAGE\.JSON" "5" "May 2017" "" "" +.TH "PACKAGE\.JSON" "5" "June 2017" "" "" .SH "NAME" \fBpackage.json\fR \- Specifics of npm's package\.json handling .SH DESCRIPTION @@ -265,6 +265,8 @@ Conversely, some files are always ignored: \fBconfig\.gypi\fP .IP \(bu 2 \fB*\.orig\fP +.IP \(bu 2 +\fBpackage\-lock\.json\fP (use shrinkwrap instead) .RE .SH main diff --git a/deps/npm/man/man7/npm-coding-style.7 b/deps/npm/man/man7/npm-coding-style.7 index 3ab6f30cbec6b1..6a788d870c223f 100644 --- a/deps/npm/man/man7/npm-coding-style.7 +++ b/deps/npm/man/man7/npm-coding-style.7 @@ -1,4 +1,4 @@ -.TH "NPM\-CODING\-STYLE" "7" "May 2017" "" "" +.TH "NPM\-CODING\-STYLE" "7" "June 2017" "" "" .SH "NAME" \fBnpm-coding-style\fR \- npm's "funny" coding style .SH DESCRIPTION diff --git a/deps/npm/man/man7/npm-config.7 b/deps/npm/man/man7/npm-config.7 index 67e8880659a055..7af1f90f7cb86a 100644 --- a/deps/npm/man/man7/npm-config.7 +++ b/deps/npm/man/man7/npm-config.7 @@ -1,4 +1,4 @@ -.TH "NPM\-CONFIG" "7" "May 2017" "" "" +.TH "NPM\-CONFIG" "7" "June 2017" "" "" .SH "NAME" \fBnpm-config\fR \- More than you probably want to know about npm configuration .SH DESCRIPTION diff --git a/deps/npm/man/man7/npm-developers.7 b/deps/npm/man/man7/npm-developers.7 index 52bf3c9144b7a1..da88a0df013cd7 100644 --- a/deps/npm/man/man7/npm-developers.7 +++ b/deps/npm/man/man7/npm-developers.7 @@ -1,4 +1,4 @@ -.TH "NPM\-DEVELOPERS" "7" "May 2017" "" "" +.TH "NPM\-DEVELOPERS" "7" "June 2017" "" "" .SH "NAME" \fBnpm-developers\fR \- Developer Guide .SH DESCRIPTION diff --git a/deps/npm/man/man7/npm-disputes.7 b/deps/npm/man/man7/npm-disputes.7 index 7c4f2462f9b677..8de6d02da89ac3 100644 --- a/deps/npm/man/man7/npm-disputes.7 +++ b/deps/npm/man/man7/npm-disputes.7 @@ -1,4 +1,4 @@ -.TH "NPM\-DISPUTES" "7" "May 2017" "" "" +.TH "NPM\-DISPUTES" "7" "June 2017" "" "" .SH "NAME" \fBnpm-disputes\fR \- Handling Module Name Disputes .P diff --git a/deps/npm/man/man7/npm-index.7 b/deps/npm/man/man7/npm-index.7 index 8ec9c159769861..689e6b91ad96c0 100644 --- a/deps/npm/man/man7/npm-index.7 +++ b/deps/npm/man/man7/npm-index.7 @@ -1,4 +1,4 @@ -.TH "NPM\-INDEX" "7" "May 2017" "" "" +.TH "NPM\-INDEX" "7" "June 2017" "" "" .SH "NAME" \fBnpm-index\fR \- Index of all npm documentation .SS npm help README diff --git a/deps/npm/man/man7/npm-orgs.7 b/deps/npm/man/man7/npm-orgs.7 index c8873a0122fcef..4c37567e15793a 100644 --- a/deps/npm/man/man7/npm-orgs.7 +++ b/deps/npm/man/man7/npm-orgs.7 @@ -1,4 +1,4 @@ -.TH "NPM\-ORGS" "7" "May 2017" "" "" +.TH "NPM\-ORGS" "7" "June 2017" "" "" .SH "NAME" \fBnpm-orgs\fR \- Working with Teams & Orgs .SH DESCRIPTION diff --git a/deps/npm/man/man7/npm-registry.7 b/deps/npm/man/man7/npm-registry.7 index 26806666babf10..483f36010c03ad 100644 --- a/deps/npm/man/man7/npm-registry.7 +++ b/deps/npm/man/man7/npm-registry.7 @@ -1,4 +1,4 @@ -.TH "NPM\-REGISTRY" "7" "May 2017" "" "" +.TH "NPM\-REGISTRY" "7" "June 2017" "" "" .SH "NAME" \fBnpm-registry\fR \- The JavaScript Package Registry .SH DESCRIPTION diff --git a/deps/npm/man/man7/npm-scope.7 b/deps/npm/man/man7/npm-scope.7 index 14243684d99999..5331efae492130 100644 --- a/deps/npm/man/man7/npm-scope.7 +++ b/deps/npm/man/man7/npm-scope.7 @@ -1,4 +1,4 @@ -.TH "NPM\-SCOPE" "7" "May 2017" "" "" +.TH "NPM\-SCOPE" "7" "June 2017" "" "" .SH "NAME" \fBnpm-scope\fR \- Scoped packages .SH DESCRIPTION diff --git a/deps/npm/man/man7/npm-scripts.7 b/deps/npm/man/man7/npm-scripts.7 index f57a4c221fef30..c58a1ef9544989 100644 --- a/deps/npm/man/man7/npm-scripts.7 +++ b/deps/npm/man/man7/npm-scripts.7 @@ -1,4 +1,4 @@ -.TH "NPM\-SCRIPTS" "7" "May 2017" "" "" +.TH "NPM\-SCRIPTS" "7" "June 2017" "" "" .SH "NAME" \fBnpm-scripts\fR \- How npm handles the "scripts" field .SH DESCRIPTION diff --git a/deps/npm/man/man7/removing-npm.7 b/deps/npm/man/man7/removing-npm.7 index 789a9e3516a49f..f2bd986225fa09 100644 --- a/deps/npm/man/man7/removing-npm.7 +++ b/deps/npm/man/man7/removing-npm.7 @@ -1,4 +1,4 @@ -.TH "NPM\-REMOVAL" "1" "May 2017" "" "" +.TH "NPM\-REMOVAL" "1" "June 2017" "" "" .SH "NAME" \fBnpm-removal\fR \- Cleaning the Slate .SH SYNOPSIS diff --git a/deps/npm/man/man7/semver.7 b/deps/npm/man/man7/semver.7 index d534638e02a793..88ed4a079912de 100644 --- a/deps/npm/man/man7/semver.7 +++ b/deps/npm/man/man7/semver.7 @@ -1,4 +1,4 @@ -.TH "SEMVER" "7" "May 2017" "" "" +.TH "SEMVER" "7" "June 2017" "" "" .SH "NAME" \fBsemver\fR \- The semantic versioner for npm .SH Usage diff --git a/deps/npm/node_modules/aproba/README.md b/deps/npm/node_modules/aproba/README.md index a9d38222a7debc..79e865924d78cf 100644 --- a/deps/npm/node_modules/aproba/README.md +++ b/deps/npm/node_modules/aproba/README.md @@ -20,17 +20,17 @@ myfunc('test', 23, function () {}, true) // too many args error Valid types are: -type | description ----- | ----------- -* | matches any type -A | Array.isArray OR an arguments object -S | typeof == string -N | typeof == number -F | typeof == function -O | typeof == object and not type A and not type E -B | typeof == boolean -E | instanceof Error OR null **(special: see below)** -Z | == null +| type | description +| :--: | :---------- +| * | matches any type +| A | `Array.isArray` OR an `arguments` object +| S | typeof == string +| N | typeof == number +| F | typeof == function +| O | typeof == object and not type A and not type E +| B | typeof == boolean +| E | `instanceof Error` OR `null` **(special: see below)** +| Z | == `null` Validation failures throw one of three exception types, distinguished by a `code` property of `EMISSINGARG`, `EINVALIDTYPE` or `ETOOMANYARGS`. diff --git a/deps/npm/node_modules/aproba/index.js b/deps/npm/node_modules/aproba/index.js index bc6ed1f17bfe41..4f8c1fc7d8534b 100644 --- a/deps/npm/node_modules/aproba/index.js +++ b/deps/npm/node_modules/aproba/index.js @@ -16,6 +16,11 @@ var types = { Z: {label: 'null', check: function (thingy) { return thingy == null }} } +function addSchema (schema, arity) { + var group = arity[schema.length] = arity[schema.length] || [] + if (group.indexOf(schema) === -1) group.push(schema) +} + var validate = module.exports = function (rawSchemas, args) { if (arguments.length !== 2) throw wrongNumberOfArgs(['SA'], arguments.length) if (!rawSchemas) throw missingRequiredArg(0, 'rawSchemas') @@ -24,21 +29,18 @@ var validate = module.exports = function (rawSchemas, args) { if (!types.A.check(args)) throw invalidType(1, ['array'], args) var schemas = rawSchemas.split('|') var arity = {} - function addSchema (schema) { - var group = arity[schema.length] = arity[schema.length] || [] - if (group.indexOf(schema) === -1) group.push(schema) - } + schemas.forEach(function (schema) { for (var ii = 0; ii < schema.length; ++ii) { var type = schema[ii] if (!types[type]) throw unknownType(ii, type) } if (/E.*E/.test(schema)) throw moreThanOneError(schema) - addSchema(schema) + addSchema(schema, arity) if (/E/.test(schema)) { - addSchema(schema.replace(/E.*$/, 'E')) - addSchema(schema.replace(/E/, 'Z')) - if (schema.length === 1) addSchema('') + addSchema(schema.replace(/E.*$/, 'E'), arity) + addSchema(schema.replace(/E/, 'Z'), arity) + if (schema.length === 1) addSchema('', arity) } }) var matching = arity[args.length] diff --git a/deps/npm/node_modules/aproba/package.json b/deps/npm/node_modules/aproba/package.json index ba6cb1385de0a0..e3a85f406627f3 100644 --- a/deps/npm/node_modules/aproba/package.json +++ b/deps/npm/node_modules/aproba/package.json @@ -1,36 +1,36 @@ { - "_from": "aproba@~1.1.1", - "_id": "aproba@1.1.1", - "_integrity": "sha1-ldNgDwdxCqDpKYxyatXs8urLq6s=", + "_from": "aproba@1.1.2", + "_id": "aproba@1.1.2", + "_inBundle": false, + "_integrity": "sha512-ZpYajIfO0j2cOFTO955KUMIKNmj6zhX8kVztMAxFsDaMwz+9Z9SV0uou2pC9HJqcfpffOsjnbrDMvkNy+9RXPw==", "_location": "/aproba", "_phantomChildren": {}, "_requested": { - "type": "range", + "type": "version", "registry": true, - "raw": "aproba@~1.1.1", + "raw": "aproba@1.1.2", "name": "aproba", "escapedName": "aproba", - "rawSpec": "~1.1.1", + "rawSpec": "1.1.2", "saveSpec": null, - "fetchSpec": "~1.1.1" + "fetchSpec": "1.1.2" }, "_requiredBy": [ + "#USER", "/", "/move-concurrently", "/move-concurrently/copy-concurrently", "/move-concurrently/run-queue", "/npmlog/gauge" ], - "_resolved": "https://registry.npmjs.org/aproba/-/aproba-1.1.1.tgz", - "_shasum": "95d3600f07710aa0e9298c726ad5ecf2eacbabab", - "_shrinkwrap": null, - "_spec": "aproba@~1.1.1", - "_where": "/Users/zkat/Documents/code/npm", + "_resolved": "https://registry.npmjs.org/aproba/-/aproba-1.1.2.tgz", + "_shasum": "45c6629094de4e96f693ef7eab74ae079c240fc1", + "_spec": "aproba@1.1.2", + "_where": "/Users/rebecca/code/npm", "author": { "name": "Rebecca Turner", "email": "me@re-becca.org" }, - "bin": null, "bugs": { "url": "https://github.com/iarna/aproba/issues" }, @@ -56,8 +56,6 @@ "license": "ISC", "main": "index.js", "name": "aproba", - "optionalDependencies": {}, - "peerDependencies": {}, "repository": { "type": "git", "url": "git+https://github.com/iarna/aproba.git" @@ -65,5 +63,5 @@ "scripts": { "test": "standard && tap -j3 test/*.js" }, - "version": "1.1.1" + "version": "1.1.2" } diff --git a/deps/npm/node_modules/cacache/CHANGELOG.md b/deps/npm/node_modules/cacache/CHANGELOG.md index 8235212ade495f..802257622eab58 100644 --- a/deps/npm/node_modules/cacache/CHANGELOG.md +++ b/deps/npm/node_modules/cacache/CHANGELOG.md @@ -2,6 +2,36 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. + +## [9.2.8](https://github.com/zkat/cacache/compare/v9.2.7...v9.2.8) (2017-06-05) + + +### Bug Fixes + +* **ssri:** bump ssri for bugfix ([c3232ea](https://github.com/zkat/cacache/commit/c3232ea)) + + + + +## [9.2.7](https://github.com/zkat/cacache/compare/v9.2.6...v9.2.7) (2017-06-05) + + +### Bug Fixes + +* **content:** make verified content completely read-only (#96) ([4131196](https://github.com/zkat/cacache/commit/4131196)) + + + + +## [9.2.6](https://github.com/zkat/cacache/compare/v9.2.5...v9.2.6) (2017-05-31) + + +### Bug Fixes + +* **node:** update ssri to prevent old node 4 crash ([5209ffe](https://github.com/zkat/cacache/commit/5209ffe)) + + + ## [9.2.5](https://github.com/zkat/cacache/compare/v9.2.4...v9.2.5) (2017-05-25) diff --git a/deps/npm/node_modules/cacache/lib/util/move-file.js b/deps/npm/node_modules/cacache/lib/util/move-file.js index 422c8294e3405a..e12e98188c42c0 100644 --- a/deps/npm/node_modules/cacache/lib/util/move-file.js +++ b/deps/npm/node_modules/cacache/lib/util/move-file.js @@ -2,6 +2,8 @@ const fs = require('graceful-fs') const BB = require('bluebird') +const chmod = BB.promisify(fs.chmod) +const unlink = BB.promisify(fs.unlink) let move let pinflight @@ -27,8 +29,11 @@ function moveFile (src, dest) { return cb(err) } } - return fs.unlink(src, cb) + return cb() }) + }).then(() => { + // content should never change for any reason, so make it read-only + return BB.join(unlink(src), process.platform !== 'win32' && chmod(dest, '0444')) }).catch(err => { if (process.platform !== 'win32') { throw err diff --git a/deps/npm/node_modules/cacache/package.json b/deps/npm/node_modules/cacache/package.json index 26b8e826f216ba..b55c3ba6897b82 100644 --- a/deps/npm/node_modules/cacache/package.json +++ b/deps/npm/node_modules/cacache/package.json @@ -1,19 +1,19 @@ { - "_from": "cacache@9.2.5", - "_id": "cacache@9.2.5", + "_from": "cacache@9.2.8", + "_id": "cacache@9.2.8", "_inBundle": false, - "_integrity": "sha512-mURsTvkjbCSFRTdkuPhHUp9sbEHn3AVrvM4mveg/bhlKKYolfRm23TsFUVAssC9p622lwmh7pgpb+H5mSVpYcA==", + "_integrity": "sha512-nA3gmaDPEsFWqI5eYAe35IfvW54yGJ3ns2wDopWf4iDA3fkhBNsdvnYp4NrL+L7ysMt0/isM84Mwi+b4l8/pMQ==", "_location": "/cacache", "_phantomChildren": {}, "_requested": { "type": "version", "registry": true, - "raw": "cacache@9.2.5", + "raw": "cacache@9.2.8", "name": "cacache", "escapedName": "cacache", - "rawSpec": "9.2.5", + "rawSpec": "9.2.8", "saveSpec": null, - "fetchSpec": "9.2.5" + "fetchSpec": "9.2.8" }, "_requiredBy": [ "#USER", @@ -21,10 +21,10 @@ "/pacote", "/pacote/make-fetch-happen" ], - "_resolved": "https://registry.npmjs.org/cacache/-/cacache-9.2.5.tgz", - "_shasum": "cb401d0e59858532062de1f104097cb40c71c3bf", - "_spec": "cacache@9.2.5", - "_where": "/Users/rebecca/code/npm", + "_resolved": "https://registry.npmjs.org/cacache/-/cacache-9.2.8.tgz", + "_shasum": "2e38b51161a3904e3b9fb35c0869b751f7d0bcf4", + "_spec": "cacache@9.2.8", + "_where": "/Users/zkat/Documents/code/npm", "author": { "name": "Kat Marchán", "email": "kzm@sykosomatic.org" @@ -66,7 +66,7 @@ "move-concurrently": "^1.0.1", "promise-inflight": "^1.0.1", "rimraf": "^2.6.1", - "ssri": "^4.1.3", + "ssri": "^4.1.5", "unique-filename": "^1.1.0", "y18n": "^3.2.1" }, @@ -76,13 +76,13 @@ "benchmark": "^2.1.4", "chalk": "^1.1.3", "cross-env": "^5.0.0", - "nyc": "^10.3.2", + "nyc": "^11.0.2", "require-inject": "^1.4.0", - "safe-buffer": "^5.0.1", + "safe-buffer": "^5.1.0", "standard": "^10.0.2", "standard-version": "^4.0.0", "tacks": "^1.2.2", - "tap": "^10.3.2", + "tap": "^10.3.3", "weallbehave": "^1.2.0", "weallcontribute": "^1.0.8" }, @@ -125,5 +125,5 @@ "update-coc": "weallbehave -o . && git add CODE_OF_CONDUCT.md && git commit -m 'docs(coc): updated CODE_OF_CONDUCT.md'", "update-contrib": "weallcontribute -o . && git add CONTRIBUTING.md && git commit -m 'docs(contributing): updated CONTRIBUTING.md'" }, - "version": "9.2.5" + "version": "9.2.8" } diff --git a/deps/npm/node_modules/node-gyp/CHANGELOG.md b/deps/npm/node_modules/node-gyp/CHANGELOG.md index e727128350b481..70aca6bc9e2ce5 100644 --- a/deps/npm/node_modules/node-gyp/CHANGELOG.md +++ b/deps/npm/node_modules/node-gyp/CHANGELOG.md @@ -1,3 +1,13 @@ +v3.6.2 2017-06-01 +================= + +* [[`72afdd62cd`](https://github.com/nodejs/node-gyp/commit/72afdd62cd)] - **build**: rename copyNodeLib() to doBuild() (Liu Chao) [#1206](https://github.com/nodejs/node-gyp/pull/1206) +* [[`bad903ac70`](https://github.com/nodejs/node-gyp/commit/bad903ac70)] - **win**: more robust parsing of SDK version (Refael Ackermann) [#1198](https://github.com/nodejs/node-gyp/pull/1198) +* [[`241752f381`](https://github.com/nodejs/node-gyp/commit/241752f381)] - Log dist-url. (Ben Noordhuis) [#1170](https://github.com/nodejs/node-gyp/pull/1170) +* [[`386746c7d1`](https://github.com/nodejs/node-gyp/commit/386746c7d1)] - **configure**: use full path in node_lib_file GYP var (Pavel Medvedev) [#964](https://github.com/nodejs/node-gyp/pull/964) +* [[`0913b2dd99`](https://github.com/nodejs/node-gyp/commit/0913b2dd99)] - **build, win**: use target_arch to link with node.lib (Pavel Medvedev) [#964](https://github.com/nodejs/node-gyp/pull/964) +* [[`c307b302f7`](https://github.com/nodejs/node-gyp/commit/c307b302f7)] - **doc**: blorb about setting `npm_config_OPTION_NAME` (Refael Ackermann) [#1185](https://github.com/nodejs/node-gyp/pull/1185) + v3.6.1 2017-04-30 ================= diff --git a/deps/npm/node_modules/node-gyp/README.md b/deps/npm/node_modules/node-gyp/README.md index d5443080dd0c34..a5c1325c712242 100644 --- a/deps/npm/node_modules/node-gyp/README.md +++ b/deps/npm/node_modules/node-gyp/README.md @@ -192,6 +192,23 @@ Command Options | `--solution=$solution` | Set Visual Studio Solution version (win) +Configuration +-------- + +__`node-gyp` responds to environment variables or `npm` configuration__ +1. Environment variables take the form `npm_config_OPTION_NAME` for any of the + options listed above (dashes in option names should be replaced by underscores). + These work also when `node-gyp` is invoked directly: + `$ export npm_config_devdir=/tmp/.gyp` + or on Windows + `> set npm_config_devdir=c:\temp\.gyp` +2. As `npm` configuration, variables take the form `OPTION_NAME`. + This way only works when `node-gyp` is executed by `npm`: + `$ npm config set [--global] devdir /tmp/.gyp` + `$ npm i buffertools` + + + License ------- diff --git a/deps/npm/node_modules/node-gyp/addon.gypi b/deps/npm/node_modules/node-gyp/addon.gypi index 1422900390221f..f2f6a7925e4ed0 100644 --- a/deps/npm/node_modules/node-gyp/addon.gypi +++ b/deps/npm/node_modules/node-gyp/addon.gypi @@ -109,7 +109,7 @@ '-luuid.lib', '-lodbc32.lib', '-lDelayImp.lib', - '-l"<(node_root_dir)/$(ConfigurationName)/<(node_lib_file)"' + '-l"<(node_lib_file)"' ], 'msvs_disabled_warnings': [ # warning C4251: 'node::ObjectWrap::handle_' : class 'v8::Persistent' diff --git a/deps/npm/node_modules/node-gyp/lib/Find-VS2017.cs b/deps/npm/node_modules/node-gyp/lib/Find-VS2017.cs index a41a354f61c454..87e0a9c9bbab80 100644 --- a/deps/npm/node_modules/node-gyp/lib/Find-VS2017.cs +++ b/deps/npm/node_modules/node-gyp/lib/Find-VS2017.cs @@ -228,9 +228,12 @@ private static bool CheckInstance(ISetupInstance2 setupInstance2, ref StringBuil hasMSBuild = true; else if (id == "Microsoft.VisualStudio.Component.VC.Tools.x86.x64") hasVCTools = true; - else if (id.StartsWith(Win10SDKPrefix)) - Win10SDKVer = Math.Max(Win10SDKVer, UInt32.Parse(id.Substring(Win10SDKPrefix.Length))); - else if (id == "Microsoft.VisualStudio.Component.Windows81SDK") + else if (id.StartsWith(Win10SDKPrefix)) { + string[] parts = id.Substring(Win10SDKPrefix.Length).Split('.'); + if (parts.Length > 1 && parts[1] != "Desktop") + continue; + Win10SDKVer = Math.Max(Win10SDKVer, UInt32.Parse(parts[0])); + } else if (id == "Microsoft.VisualStudio.Component.Windows81SDK") hasWin8SDK = true; else continue; diff --git a/deps/npm/node_modules/node-gyp/lib/build.js b/deps/npm/node_modules/node-gyp/lib/build.js index 5253109857bda7..0445fb6452ca44 100644 --- a/deps/npm/node_modules/node-gyp/lib/build.js +++ b/deps/npm/node_modules/node-gyp/lib/build.js @@ -11,7 +11,6 @@ var fs = require('graceful-fs') , glob = require('glob') , log = require('npmlog') , which = require('which') - , mkdirp = require('mkdirp') , exec = require('child_process').exec , processRelease = require('./process-release') , win = process.platform === 'win32' @@ -36,7 +35,6 @@ function build (gyp, argv, callback) { , config , arch , nodeDir - , copyDevLib loadConfigGypi() @@ -60,7 +58,6 @@ function build (gyp, argv, callback) { buildType = config.target_defaults.default_configuration arch = config.variables.target_arch nodeDir = config.variables.nodedir - copyDevLib = config.variables.copy_dev_lib == 'true' if ('debug' in gyp.opts) { buildType = gyp.opts.debug ? 'Debug' : 'Release' @@ -115,7 +112,7 @@ function build (gyp, argv, callback) { return } log.verbose('`which` succeeded for `' + command + '`', execPath) - copyNodeLib() + doBuild() }) } @@ -127,7 +124,7 @@ function build (gyp, argv, callback) { if (config.variables.msbuild_path) { command = config.variables.msbuild_path log.verbose('using MSBuild:', command) - copyNodeLib() + doBuild() return } @@ -180,36 +177,12 @@ function build (gyp, argv, callback) { return } command = msbuildPath - copyNodeLib() + doBuild() }) })() }) } - /** - * Copies the node.lib file for the current target architecture into the - * current proper dev dir location. - */ - - function copyNodeLib () { - if (!win || !copyDevLib) return doBuild() - - var buildDir = path.resolve(nodeDir, buildType) - , archNodeLibPath = path.resolve(nodeDir, arch, release.name + '.lib') - , buildNodeLibPath = path.resolve(buildDir, release.name + '.lib') - - mkdirp(buildDir, function (err, isNew) { - if (err) return callback(err) - log.verbose('"' + buildType + '" dir needed to be created?', isNew) - var rs = fs.createReadStream(archNodeLibPath) - , ws = fs.createWriteStream(buildNodeLibPath) - log.verbose('copying "' + release.name + '.lib" for ' + arch, buildNodeLibPath) - rs.pipe(ws) - rs.on('error', callback) - ws.on('error', callback) - rs.on('end', doBuild) - }) - } /** * Actually spawn the process and compile the module. diff --git a/deps/npm/node_modules/node-gyp/lib/configure.js b/deps/npm/node_modules/node-gyp/lib/configure.js index 4bad1bffd11cc6..1351576d12e8c8 100644 --- a/deps/npm/node_modules/node-gyp/lib/configure.js +++ b/deps/npm/node_modules/node-gyp/lib/configure.js @@ -144,9 +144,6 @@ function configure (gyp, argv, callback) { // set the node development directory variables.nodedir = nodeDir - // don't copy dev libraries with nodedir option - variables.copy_dev_lib = !gyp.opts.nodedir - // disable -T "thin" static archives by default variables.standalone_static_library = gyp.opts.thin ? 0 : 1 @@ -286,6 +283,9 @@ function configure (gyp, argv, callback) { output_dir = buildDir } var nodeGypDir = path.resolve(__dirname, '..') + var nodeLibFile = path.join(nodeDir, + !gyp.opts.nodedir ? '<(target_arch)' : '$(Configuration)', + release.name + '.lib') argv.push('-I', addon_gypi) argv.push('-I', common_gypi) @@ -296,7 +296,7 @@ function configure (gyp, argv, callback) { argv.push('-Dnode_exp_file=' + node_exp_file) } argv.push('-Dnode_gyp_dir=' + nodeGypDir) - argv.push('-Dnode_lib_file=' + release.name + '.lib') + argv.push('-Dnode_lib_file=' + nodeLibFile) argv.push('-Dmodule_root_dir=' + process.cwd()) argv.push('-Dnode_engine=' + (gyp.opts.node_engine || process.jsEngine || 'v8')) diff --git a/deps/npm/node_modules/node-gyp/lib/process-release.js b/deps/npm/node_modules/node-gyp/lib/process-release.js index 89eaf9be361290..0d177f1c93e4d3 100644 --- a/deps/npm/node_modules/node-gyp/lib/process-release.js +++ b/deps/npm/node_modules/node-gyp/lib/process-release.js @@ -74,6 +74,8 @@ function processRelease (argv, gyp, defaultVersion, defaultRelease) { } } + if (overrideDistUrl) + log.verbose('download', 'using dist-url', overrideDistUrl) if (overrideDistUrl) distBaseUrl = overrideDistUrl.replace(/\/+$/, '') diff --git a/deps/npm/node_modules/node-gyp/package.json b/deps/npm/node_modules/node-gyp/package.json index 9a3664d910c4ea..ce58e31b95ffbf 100644 --- a/deps/npm/node_modules/node-gyp/package.json +++ b/deps/npm/node_modules/node-gyp/package.json @@ -1,29 +1,29 @@ { - "_from": "node-gyp@latest", - "_id": "node-gyp@3.6.1", + "_from": "node-gyp@3.6.2", + "_id": "node-gyp@3.6.2", "_inBundle": false, - "_integrity": "sha1-GVYQZ/8YVGSt7UeCEmgfR/1XjLw=", + "_integrity": "sha1-m/vlRWIoYoSDjnUOrAUpWFP6HGA=", "_location": "/node-gyp", "_phantomChildren": { "abbrev": "1.1.0" }, "_requested": { - "type": "tag", + "type": "version", "registry": true, - "raw": "node-gyp@latest", + "raw": "node-gyp@3.6.2", "name": "node-gyp", "escapedName": "node-gyp", - "rawSpec": "latest", + "rawSpec": "3.6.2", "saveSpec": null, - "fetchSpec": "latest" + "fetchSpec": "3.6.2" }, "_requiredBy": [ "#USER", "/" ], - "_resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.6.1.tgz", - "_shasum": "19561067ff185464aded478212681f47fd578cbc", - "_spec": "node-gyp@latest", + "_resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.6.2.tgz", + "_shasum": "9bfbe54562286284838e750eac05295853fa1c60", + "_spec": "node-gyp@3.6.2", "_where": "/Users/zkat/Documents/code/npm", "author": { "name": "Nathan Rajlich", @@ -85,5 +85,5 @@ "scripts": { "test": "tape test/test-*" }, - "version": "3.6.1" + "version": "3.6.2" } diff --git a/deps/npm/node_modules/npm-package-arg/CHANGELOG.md b/deps/npm/node_modules/npm-package-arg/CHANGELOG.md deleted file mode 100644 index 339ef8793a93e5..00000000000000 --- a/deps/npm/node_modules/npm-package-arg/CHANGELOG.md +++ /dev/null @@ -1,23 +0,0 @@ -## new - -* New properties: - * `from` indicates how we parsed this specifier, values are: - localArgument, local, hosted, url and registry. - - _localArgument_ differs from _local_ in that it means the argument - parsing rules were used instead of the dependency parsing rules. That is, the - rules for `npm install /foo` instead of those for `"dependencies": - {"foo": "file:/foo"}`. - -* Changed properties: - * `type` indicates what sort of specifier this is, values are: file, directory, git, remote, version, range, tag. - -* Local specifiers: - * Trailing spaces on local specifiers are no longer trimmed. - * The `spec` field for local specifiers is now a fully resolved path. - * The type is now _file_ or _directory, never _local_. -* Git specifiers: - * The leading `git+` is no longer stripped. This makes the behavior match - `hosted-git-info`. -* Hosted git specifiers: - * The `type` is now _git_. You can check if something is hosted by looking at the `hosted` property or checking to see if `from` is _hosted_. diff --git a/deps/npm/node_modules/npm-package-arg/npa.js b/deps/npm/node_modules/npm-package-arg/npa.js index a94c54abbd7ff2..e359958a38187d 100644 --- a/deps/npm/node_modules/npm-package-arg/npa.js +++ b/deps/npm/node_modules/npm-package-arg/npa.js @@ -192,6 +192,22 @@ function unsupportedURLType (protocol, spec) { return err } +function matchGitScp (spec) { + // git ssh specifiers are overloaded to also use scp-style git + // specifiers, so we have to parse those out and treat them special. + // They are NOT true URIs, so we can't hand them to `url.parse`. + // + // This regex looks for things that look like: + // git+ssh://git@my.custom.git.com:username/project.git#deadbeef + // + // ...and various combinations. The username in the beginning is *required*. + const matched = spec.match(/^git\+ssh:\/\/([^:]+:[^#]+(?:\.git)?)(?:#(.*))$/i) + return matched && !matched[1].match(/:[0-9]+\/?.*$/i) && { + fetchSpec: matched[1], + gitCommittish: matched[2] + } +} + function fromURL (res) { if (!url) url = require('url') const urlparse = url.parse(res.rawSpec) @@ -203,15 +219,20 @@ function fromURL (res) { case 'git+https:': case 'git+rsync:': case 'git+ftp:': - case 'git+ssh:': case 'git+file:': + case 'git+ssh:': res.type = 'git' - setGitCommittish(res, urlparse.hash != null ? urlparse.hash.slice(1) : '') - urlparse.protocol = urlparse.protocol.replace(/^git[+]/, '') - delete urlparse.hash - res.fetchSpec = url.format(urlparse) + const match = urlparse.protocol === 'git+ssh:' && matchGitScp(res.rawSpec) + if (match) { + res.fetchSpec = match.fetchSpec + res.gitCommittish = match.gitCommittish + } else { + setGitCommittish(res, urlparse.hash != null ? urlparse.hash.slice(1) : '') + urlparse.protocol = urlparse.protocol.replace(/^git[+]/, '') + delete urlparse.hash + res.fetchSpec = url.format(urlparse) + } break - case 'http:': case 'https:': res.type = 'remote' diff --git a/deps/npm/node_modules/npm-package-arg/package.json b/deps/npm/node_modules/npm-package-arg/package.json index d8ef6979cbd501..b8afefc5772057 100644 --- a/deps/npm/node_modules/npm-package-arg/package.json +++ b/deps/npm/node_modules/npm-package-arg/package.json @@ -1,37 +1,37 @@ { - "_from": "npm-package-arg@~5.0.1", - "_id": "npm-package-arg@5.0.1", - "_integrity": "sha1-CagW4/RaVJ492vM+m65eezEHeHI=", + "_from": "npm-package-arg@latest", + "_id": "npm-package-arg@5.1.1", + "_inBundle": false, + "_integrity": "sha512-67wPa1moaLvn9YAVLLECpGe+v3jL82pBDTE2jMxLOQHd0kWBLnmtCqbxrFagp5pVNFukqmtYRruK3wfoeVTZ2g==", "_location": "/npm-package-arg", "_phantomChildren": {}, "_requested": { - "type": "range", + "type": "tag", "registry": true, - "raw": "npm-package-arg@~5.0.1", + "raw": "npm-package-arg@latest", "name": "npm-package-arg", "escapedName": "npm-package-arg", - "rawSpec": "~5.0.1", + "rawSpec": "latest", "saveSpec": null, - "fetchSpec": "~5.0.1" + "fetchSpec": "latest" }, "_requiredBy": [ + "#USER", "/", "/init-package-json", "/npm-registry-client", "/pacote", "/pacote/npm-pick-manifest" ], - "_resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-5.0.1.tgz", - "_shasum": "09a816e3f45a549e3ddaf33e9bae5e7b31077872", - "_shrinkwrap": null, - "_spec": "npm-package-arg@~5.0.1", + "_resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-5.1.1.tgz", + "_shasum": "a3d09053f2d8a0bfa562624507baa597737fc3bf", + "_spec": "npm-package-arg@latest", "_where": "/Users/zkat/Documents/code/npm", "author": { "name": "Isaac Z. Schlueter", "email": "i@izs.me", "url": "http://blog.izs.me/" }, - "bin": null, "bugs": { "url": "https://github.com/npm/npm-package-arg/issues" }, @@ -58,8 +58,6 @@ "license": "ISC", "main": "npa.js", "name": "npm-package-arg", - "optionalDependencies": {}, - "peerDependencies": {}, "repository": { "type": "git", "url": "git+https://github.com/npm/npm-package-arg.git" @@ -67,5 +65,5 @@ "scripts": { "test": "standard && tap -J --coverage test/*.js" }, - "version": "5.0.1" + "version": "5.1.1" } diff --git a/deps/npm/node_modules/npm-user-validate/.npmignore b/deps/npm/node_modules/npm-user-validate/.npmignore deleted file mode 100644 index 39747c08b4dc95..00000000000000 --- a/deps/npm/node_modules/npm-user-validate/.npmignore +++ /dev/null @@ -1,13 +0,0 @@ -*.swp -.*.swp - -.DS_Store -*~ -.project -.settings -npm-debug.log -coverage.html -.idea -lib-cov - -node_modules \ No newline at end of file diff --git a/deps/npm/node_modules/npm-user-validate/.travis.yml b/deps/npm/node_modules/npm-user-validate/.travis.yml deleted file mode 100644 index 6ff074b74880dd..00000000000000 --- a/deps/npm/node_modules/npm-user-validate/.travis.yml +++ /dev/null @@ -1,7 +0,0 @@ -language: node_js -before_install: -- npm install -g npm@latest -sudo: false -node_js: - - "0.8" - - "0.10" diff --git a/deps/npm/node_modules/npm-user-validate/npm-user-validate.js b/deps/npm/node_modules/npm-user-validate/npm-user-validate.js index 3a645ec9329acd..9250ce33a4abe0 100644 --- a/deps/npm/node_modules/npm-user-validate/npm-user-validate.js +++ b/deps/npm/node_modules/npm-user-validate/npm-user-validate.js @@ -1,19 +1,23 @@ exports.email = email exports.pw = pw exports.username = username - var requirements = exports.requirements = { username: { length: 'Name length must be less than or equal to 214 characters long', lowerCase: 'Name must be lowercase', urlSafe: 'Name may not contain non-url-safe chars', - dot: 'Name may not start with "."' + dot: 'Name may not start with "."', + illegal: 'Name may not contain illegal character' }, password: {}, email: { valid: 'Email must be an email address' } -}; +} + +var illegalCharacterRe = new RegExp('([' + [ + "'" +].join() + '])') function username (un) { if (un !== un.toLowerCase()) { @@ -32,6 +36,11 @@ function username (un) { return new Error(requirements.username.length) } + var illegal = un.match(illegalCharacterRe) + if (illegal) { + return new Error(requirements.username.illegal + ' "' + illegal[0] + '"') + } + return null } diff --git a/deps/npm/node_modules/npm-user-validate/package.json b/deps/npm/node_modules/npm-user-validate/package.json index d6e30bd54551c8..df646cd0559acf 100644 --- a/deps/npm/node_modules/npm-user-validate/package.json +++ b/deps/npm/node_modules/npm-user-validate/package.json @@ -1,42 +1,46 @@ { - "_from": "npm-user-validate@~0.1.5", - "_id": "npm-user-validate@0.1.5", - "_integrity": "sha1-UkZdUMLSApSlcSW5lrrtv1bFAEs=", + "_from": "npm-user-validate@latest", + "_id": "npm-user-validate@1.0.0", + "_inBundle": false, + "_integrity": "sha1-jOyg9c6gTU6TUZ73LQVXp1Ei6VE=", "_location": "/npm-user-validate", "_phantomChildren": {}, "_requested": { - "type": "range", + "type": "tag", "registry": true, - "raw": "npm-user-validate@~0.1.5", + "raw": "npm-user-validate@latest", "name": "npm-user-validate", "escapedName": "npm-user-validate", - "rawSpec": "~0.1.5", + "rawSpec": "latest", "saveSpec": null, - "fetchSpec": "~0.1.5" + "fetchSpec": "latest" }, "_requiredBy": [ + "#USER", "/" ], - "_resolved": "https://registry.npmjs.org/npm-user-validate/-/npm-user-validate-0.1.5.tgz", - "_shasum": "52465d50c2d20294a57125b996baedbf56c5004b", - "_shrinkwrap": null, - "_spec": "npm-user-validate@~0.1.5", + "_resolved": "https://registry.npmjs.org/npm-user-validate/-/npm-user-validate-1.0.0.tgz", + "_shasum": "8ceca0f5cea04d4e93519ef72d0557a75122e951", + "_spec": "npm-user-validate@latest", "_where": "/Users/zkat/Documents/code/npm", "author": { "name": "Robert Kowalski", "email": "rok@kowalski.gd" }, - "bin": null, "bugs": { "url": "https://github.com/npm/npm-user-validate/issues" }, "bundleDependencies": false, - "dependencies": {}, "deprecated": false, "description": "User validations for npm", "devDependencies": { - "tap": "^1.2.0" + "standard": "^8.4.0", + "standard-version": "^3.0.0", + "tap": "^7.1.2" }, + "files": [ + "npm-user-validate.js" + ], "homepage": "https://github.com/npm/npm-user-validate#readme", "keywords": [ "npm", @@ -46,14 +50,13 @@ "license": "BSD-2-Clause", "main": "npm-user-validate.js", "name": "npm-user-validate", - "optionalDependencies": {}, - "peerDependencies": {}, "repository": { "type": "git", "url": "git://github.com/npm/npm-user-validate.git" }, "scripts": { - "test": "tap test/*.js" + "pretest": "standard", + "test": "tap --100 test/*.js" }, - "version": "0.1.5" + "version": "1.0.0" } diff --git a/deps/npm/node_modules/npm-user-validate/test/email.test.js b/deps/npm/node_modules/npm-user-validate/test/email.test.js deleted file mode 100644 index 1060a9354d6ccd..00000000000000 --- a/deps/npm/node_modules/npm-user-validate/test/email.test.js +++ /dev/null @@ -1,26 +0,0 @@ -var test = require('tap').test -var v = require('../npm-user-validate.js').email - -test('email misses an @', function (t) { - err = v('namedomain') - t.type(err, 'object') - t.end() -}) - -test('email misses a dot', function (t) { - err = v('name@domain') - t.type(err, 'object') - t.end() -}) - -test('email misses a string before the @', function (t) { - err = v('@domain') - t.type(err, 'object') - t.end() -}) - -test('email is ok', function (t) { - err = v('name@domain.com') - t.type(err, 'null') - t.end() -}) \ No newline at end of file diff --git a/deps/npm/node_modules/npm-user-validate/test/pw.test.js b/deps/npm/node_modules/npm-user-validate/test/pw.test.js deleted file mode 100644 index d57401da0b5d2f..00000000000000 --- a/deps/npm/node_modules/npm-user-validate/test/pw.test.js +++ /dev/null @@ -1,32 +0,0 @@ -var test = require('tap').test -var v = require('../npm-user-validate.js').pw - -test('pw contains a \'', function (t) { - err = v('\'') - t.type(err, 'null') - t.end() -}) - -test('pw contains a :', function (t) { - err = v(':') - t.type(err, 'null') - t.end() -}) - -test('pw contains a @', function (t) { - err = v('@') - t.notOk(err, 'null') - t.end() -}) - -test('pw contains a "', function (t) { - err = v('"') - t.type(err, 'null') - t.end() -}) - -test('pw is ok', function (t) { - err = v('duck') - t.type(err, 'null') - t.end() -}) diff --git a/deps/npm/node_modules/npm-user-validate/test/username.test.js b/deps/npm/node_modules/npm-user-validate/test/username.test.js deleted file mode 100644 index aa0e6b33def686..00000000000000 --- a/deps/npm/node_modules/npm-user-validate/test/username.test.js +++ /dev/null @@ -1,42 +0,0 @@ -var test = require('tap').test -var v = require('../npm-user-validate.js').username - -test('username must be lowercase', function (t) { - var err = v('ERRR') - t.type(err, 'object') - t.match(err.message, /lowercase/) - t.end() -}) - -test('username may not contain non-url-safe chars', function (t) { - var err = v('f ') - t.type(err, 'object') - t.match(err.message, /url-safe/) - t.end() -}) - -test('username may not start with "."', function (t) { - var err = v('.username') - t.type(err, 'object') - t.match(err.message, /start with.*\./) - t.end() -}) - -test('username may not be longer than 214 characters', function (t) { - var err = v('bacon-ipsum-dolor-amet-tongue-short-loin-landjaeger-tenderloin-ball-tip-pork-loin-porchetta-pig-pork-chop-beef-ribs-pork-belly--shankle-t-bone-turducken-tongue-landjaeger-pork-loin-beef-chicken-short-loin-and-pickle') - t.type(err, 'object') - t.match(err.message, /less than or equal to 214/) - t.end() -}); - -test('username may be as long as 214 characters', function (t) { - var err = v('bacon-ipsum-dolor-amet-tongue-short-loin-landjaeger-tenderloin-ball-tip-pork-loin-porchetta-pig-pork-chop-beef-ribs-pork-belly--shankle-t-bone-turducken-tongue-landjaeger-pork-loin-beef-chicken-short-loin-porchetta') - t.type(err, 'null') - t.end() -}); - -test('username is ok', function (t) { - var err = v('ente') - t.type(err, 'null') - t.end() -}) diff --git a/deps/npm/node_modules/pacote/CHANGELOG.md b/deps/npm/node_modules/pacote/CHANGELOG.md index 55c0cda6861a5c..7f7eac282da100 100644 --- a/deps/npm/node_modules/pacote/CHANGELOG.md +++ b/deps/npm/node_modules/pacote/CHANGELOG.md @@ -2,6 +2,100 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. + +## [2.7.30](https://github.com/zkat/pacote/compare/v2.7.29...v2.7.30) (2017-06-05) + + +### Bug Fixes + +* **ssri:** bump ssri for bugfix ([70a859c](https://github.com/zkat/pacote/commit/70a859c)) + + + + +## [2.7.29](https://github.com/zkat/pacote/compare/v2.7.28...v2.7.29) (2017-06-05) + + +### Bug Fixes + +* **registry:** use cert instead of certfile opt ([a45880d](https://github.com/zkat/pacote/commit/a45880d)) + + + + +## [2.7.28](https://github.com/zkat/pacote/compare/v2.7.27...v2.7.28) (2017-06-05) + + +### Bug Fixes + +* **git:** limit ls-remote output to heads/tags (#97) ([c1e3dcd](https://github.com/zkat/pacote/commit/c1e3dcd)) +* **proxy:** send certificate authority, key and other options (#95) ([c4b6128](https://github.com/zkat/pacote/commit/c4b6128)) +* **registry:** add support for global auth and _auth token (#96) ([7919fb7](https://github.com/zkat/pacote/commit/7919fb7)) +* **registry:** emit npm-session header (#98) ([9816b18](https://github.com/zkat/pacote/commit/9816b18)) + + + + +## [2.7.27](https://github.com/zkat/pacote/compare/v2.7.26...v2.7.27) (2017-06-01) + + +### Bug Fixes + +* **git:** fix semver range detection. oops ([76d9233](https://github.com/zkat/pacote/commit/76d9233)) + + + + +## [2.7.26](https://github.com/zkat/pacote/compare/v2.7.25...v2.7.26) (2017-06-01) + + +### Bug Fixes + +* **git:** hash was not being replaced/appended correctly ([6fcbed5](https://github.com/zkat/pacote/commit/6fcbed5)) + + + + +## [2.7.25](https://github.com/zkat/pacote/compare/v2.7.24...v2.7.25) (2017-05-31) + + +### Bug Fixes + +* **git:** git deps were getting _resolved without shasums ([96f0675](https://github.com/zkat/pacote/commit/96f0675)) + + + + +## [2.7.24](https://github.com/zkat/pacote/compare/v2.7.23...v2.7.24) (2017-05-31) + + +### Bug Fixes + +* **deps:** update dep versions with new patches ([dc2e4ff](https://github.com/zkat/pacote/commit/dc2e4ff)) + + + + +## [2.7.23](https://github.com/zkat/pacote/compare/v2.7.22...v2.7.23) (2017-05-31) + + +### Bug Fixes + +* **git:** fix ls-remote command and throw away ^{} junk ([62ba84d](https://github.com/zkat/pacote/commit/62ba84d)) +* **git:** use the parsed git committish from npa ([77a676a](https://github.com/zkat/pacote/commit/77a676a)) + + + + +## [2.7.22](https://github.com/zkat/pacote/compare/v2.7.21...v2.7.22) (2017-05-31) + + +### Bug Fixes + +* **git:** accept shortened git hashes (#91) ([4466388](https://github.com/zkat/pacote/commit/4466388)) + + + ## [2.7.21](https://github.com/zkat/pacote/compare/v2.7.20...v2.7.21) (2017-05-25) diff --git a/deps/npm/node_modules/pacote/lib/fetchers/git.js b/deps/npm/node_modules/pacote/lib/fetchers/git.js index d8af7693642c30..9da6a6438a4256 100644 --- a/deps/npm/node_modules/pacote/lib/fetchers/git.js +++ b/deps/npm/node_modules/pacote/lib/fetchers/git.js @@ -15,7 +15,6 @@ const PassThrough = require('stream').PassThrough const path = require('path') const pipe = BB.promisify(require('mississippi').pipe) const rimraf = BB.promisify(require('rimraf')) -const semver = require('semver') const uniqueFilename = require('unique-filename') // `git` dependencies are fetched from git repositories and packed up. @@ -50,7 +49,7 @@ Fetcher.impl(fetchGit, { opts = optCheck(opts) let streamError const stream = new PassThrough().on('error', e => { streamError = e }) - const cacheName = manifest._resolved || spec.saveSpec || spec.fetchSpec + const cacheName = manifest._uniqueResolved || manifest._resolved || '' const cacheStream = ( opts.cache && cacache.get.stream( @@ -69,11 +68,9 @@ Fetcher.impl(fetchGit, { manifest._repo, manifest._ref, manifest._rawRef, tmp, opts ).then(HEAD => { if (streamError) { throw streamError } - if (!manifest._resolved) { - manifest._resolved = spec.saveSpec.replace(/#.*/, `#${HEAD}`) - manifest._uniqueResolved = manifest._resolved - } - return packDir(manifest, cacheName, tmp, stream, opts) + manifest._resolved = spec.saveSpec.replace(/(:?#.*)?$/, `#${HEAD}`) + manifest._uniqueResolved = manifest._resolved + return packDir(manifest, manifest._uniqueResolved, tmp, stream, opts) }) }).catch(err => stream.emit('error', err)) } @@ -102,9 +99,9 @@ function hostedManifest (spec, opts) { } function plainManifest (repo, spec, opts) { - const rawRef = spec.gitCommittish + const rawRef = spec.gitCommittish || spec.gitRange return resolve( - repo, rawRef, spec.name, opts + repo, spec, spec.name, opts ).then(ref => { if (ref) { const resolved = spec.saveSpec.replace(/(?:#.*)?$/, `#${ref.sha}`) @@ -113,7 +110,7 @@ function plainManifest (repo, spec, opts) { _resolved: resolved, _spec: spec, _ref: ref, - _rawRef: rawRef, + _rawRef: spec.gitCommittish || spec.gitRange, _uniqueResolved: resolved } } else { @@ -132,19 +129,18 @@ function plainManifest (repo, spec, opts) { }) } -function resolve (url, rawRef, name, opts) { - const semverMatch = rawRef.match(/^semver:v?(.*)/) - const isSemver = semverMatch && semver.validRange(semverMatch[1]) +function resolve (url, spec, name, opts) { + const isSemver = !!spec.gitRange return git.revs(url, opts).then(remoteRefs => { return isSemver ? pickManifest({ versions: remoteRefs.versions, 'dist-tags': remoteRefs['dist-tags'], name: name - }, semverMatch[1], opts) + }, spec.gitRange, opts) : remoteRefs ? BB.resolve( - remoteRefs.refs[rawRef] || remoteRefs.refs[remoteRefs.shas[rawRef]] + remoteRefs.refs[spec.gitCommittish] || remoteRefs.refs[remoteRefs.shas[spec.gitCommittish]] ) : null }) diff --git a/deps/npm/node_modules/pacote/lib/fetchers/registry/fetch.js b/deps/npm/node_modules/pacote/lib/fetchers/registry/fetch.js index 46a926a1a15b93..1c6c8e8d6e2ca9 100644 --- a/deps/npm/node_modules/pacote/lib/fetchers/registry/fetch.js +++ b/deps/npm/node_modules/pacote/lib/fetchers/registry/fetch.js @@ -16,14 +16,19 @@ function regFetch (uri, registry, opts) { algorithms: opts.algorithms, cache: getCacheMode(opts), cacheManager: opts.cache, + ca: opts.ca, + cert: opts.cert, headers: getHeaders(uri, registry, opts), integrity: opts.integrity, + key: opts.key, + localAddress: opts.localAddress, memoize: opts.memoize, noProxy: opts.noProxy, Promise: BB, proxy: opts.proxy, referer: opts.refer, retry: opts.retry, + strictSSL: !!opts.strictSSL, timeout: opts.timeout, uid: opts.uid, gid: opts.gid @@ -74,13 +79,15 @@ function getHeaders (uri, registry, opts) { const headers = Object.assign({ 'npm-in-ci': opts.isFromCI, 'npm-scope': opts.projectScope, + 'npm-session': opts.npmSession, 'user-agent': opts.userAgent, 'referer': opts.refer }, opts.headers) - const auth = ( + // check for auth settings specific to this registry + let auth = ( opts.auth && opts.auth[registryKey(registry)] - ) + ) || opts.auth // If a tarball is hosted on a different place than the manifest, only send // credentials on `alwaysAuth` const shouldAuth = auth && ( @@ -94,6 +101,8 @@ function getHeaders (uri, registry, opts) { `${auth.username}:${auth.password}`, 'utf8' ).toString('base64') headers.authorization = `Basic ${encoded}` + } else if (shouldAuth && auth._auth) { + headers.authorization = `Basic ${auth._auth}` } return headers } diff --git a/deps/npm/node_modules/pacote/lib/util/git.js b/deps/npm/node_modules/pacote/lib/util/git.js index dc189b54189a5d..fc3d158fa7c737 100644 --- a/deps/npm/node_modules/pacote/lib/util/git.js +++ b/deps/npm/node_modules/pacote/lib/util/git.js @@ -105,7 +105,7 @@ function revs (repo, opts) { return BB.resolve(cached) } return pinflight(`ls-remote:${repo}`, () => { - return spawnGit(['ls-remote', repo, '-t', '-h', '*'], { + return spawnGit(['ls-remote', '-h', '-t', repo], { env: gitEnv() }, opts).then(child => { let stdout = '' @@ -117,6 +117,7 @@ function revs (repo, opts) { const sha = split[0].trim() const ref = split[1].trim().match(/(?:refs\/[^/]+\/)?(.*)/)[1] if (!ref) { return revs } // ??? + if (ref.match(/\^\{\}$/)) { return revs } // refs/tags/x^{} crap const type = refType(line) const doc = {sha, ref, type} diff --git a/deps/npm/node_modules/pacote/lib/util/opt-check.js b/deps/npm/node_modules/pacote/lib/util/opt-check.js index dd8aa518dc5258..a2692836a3ad7c 100644 --- a/deps/npm/node_modules/pacote/lib/util/opt-check.js +++ b/deps/npm/node_modules/pacote/lib/util/opt-check.js @@ -12,7 +12,11 @@ function PacoteOptions (opts) { this.scopeTargets = opts.scopeTargets || {} this.defaultTag = opts.defaultTag || 'latest' this.cache = opts.cache + this.ca = opts.ca + this.cert = opts.cert this.integrity = opts.integrity + this.key = opts.key + this.localAddress = opts.localAddress this.log = opts.log || silentlog this.memoize = opts.memoize this.maxSockets = opts.maxSockets || 10 @@ -26,6 +30,7 @@ function PacoteOptions (opts) { this.userAgent = opts.userAgent || `${pkg.name}@${pkg.version}/node@${process.version}+${process.arch} (${process.platform})` this.where = opts.where this.preferOnline = opts.preferOnline + this.strictSSL = !!opts.strictSSL this.isFromCI = !!( opts.isFromCI || process.env['CI'] === 'true' || @@ -33,6 +38,7 @@ function PacoteOptions (opts) { process.env['JENKINS_URL'] || process.env['bamboo.buildKey'] ) + this.npmSession = opts.npmSession this.refer = opts.referer || opts.refer this.projectScope = opts.projectScope this.fullMetadata = opts.fullMetadata diff --git a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/CHANGELOG.md b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/CHANGELOG.md index 854388027b0634..54d88f339186a6 100644 --- a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/CHANGELOG.md +++ b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/CHANGELOG.md @@ -2,6 +2,27 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. + +## [2.4.11](https://github.com/zkat/make-fetch-happen/compare/v2.4.10...v2.4.11) (2017-06-05) + + +### Bug Fixes + +* **deps:** bump deps with ssri fix ([bef1994](https://github.com/zkat/make-fetch-happen/commit/bef1994)) + + + + +## [2.4.10](https://github.com/zkat/make-fetch-happen/compare/v2.4.9...v2.4.10) (2017-05-31) + + +### Bug Fixes + +* **deps:** bump dep versions with bugfixes ([0af4003](https://github.com/zkat/make-fetch-happen/commit/0af4003)) +* **proxy:** use auth parameter for proxy authentication (#30) ([c687306](https://github.com/zkat/make-fetch-happen/commit/c687306)) + + + ## [2.4.9](https://github.com/zkat/make-fetch-happen/compare/v2.4.8...v2.4.9) (2017-05-25) diff --git a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/agent.js b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/agent.js index 0100498947e21f..a3c910eb9340cc 100644 --- a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/agent.js +++ b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/agent.js @@ -126,6 +126,7 @@ function getProxy (proxyUrl, opts, isHttps) { port: proxyUrl.port, protocol: proxyUrl.protocol, path: proxyUrl.path, + auth: proxyUrl.auth, ca: opts.ca, cert: opts.cert, key: opts.key, diff --git a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/http-proxy-agent/node_modules/agent-base/.travis.yml b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/http-proxy-agent/node_modules/agent-base/.travis.yml index 85a50123c63edb..20b794051c9aaa 100644 --- a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/http-proxy-agent/node_modules/agent-base/.travis.yml +++ b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/http-proxy-agent/node_modules/agent-base/.travis.yml @@ -1,8 +1,29 @@ +sudo: false + language: node_js + node_js: - "0.8" - "0.10" - "0.12" -before_install: - - '[ "${TRAVIS_NODE_VERSION}" != "0.8" ] || npm install -g npm@1.4.28' - - npm install -g npm@latest + - "1" + - "2" + - "3" + - "4" + - "5" + - "6" + - "7" + +install: + - PATH="`npm bin`:`npm bin -g`:$PATH" + # Node 0.8 comes with a too obsolete npm + - if [[ "`node --version`" =~ ^v0\.8\. ]]; then npm install -g npm@1.4.28 ; fi + # Install dependencies and build + - npm install + +script: + # Output useful info for debugging + - node --version + - npm --version + # Run tests + - npm test diff --git a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/http-proxy-agent/node_modules/agent-base/History.md b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/http-proxy-agent/node_modules/agent-base/History.md index 0ceef6c13f70bf..2191a9e8014753 100644 --- a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/http-proxy-agent/node_modules/agent-base/History.md +++ b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/http-proxy-agent/node_modules/agent-base/History.md @@ -1,4 +1,22 @@ +2.1.1 / 2017-05-30 +================== + + * Revert [fe2162e0ba18123f5b301cba4de1e9dd74e437cd](https://github.com/TooTallNate/node-agent-base/commit/fe2162e0ba18123f5b301cba4de1e9dd74e437cd) and [270bdc92eb8e3bd0444d1e5266e8e9390aeb3095](https://github.com/TooTallNate/node-agent-base/commit/270bdc92eb8e3bd0444d1e5266e8e9390aeb3095) (fixes #7) + +2.1.0 / 2017-05-26 +================== + + * unref is not supported for node < 0.9.1 (@pi0) + * add tests to dangling socket (@pi0) + * check unref() is supported (@pi0) + * fix dangling sockets problem (@pi0) + * add basic "ws" module tests + * make `Agent` be subclassable + * turn `addRequest()` into a named function + * test: Node.js v4 likes to call `cork` on the stream (#3, @tomhughes) + * travis: test node v4, v5, v6 and v7 + 2.0.1 / 2015-09-10 ================== diff --git a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/http-proxy-agent/node_modules/agent-base/agent.js b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/http-proxy-agent/node_modules/agent-base/agent.js index 4005ebc0efb98e..7ea91f886cba24 100644 --- a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/http-proxy-agent/node_modules/agent-base/agent.js +++ b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/http-proxy-agent/node_modules/agent-base/agent.js @@ -24,12 +24,17 @@ module.exports = Agent; function Agent (callback) { if (!(this instanceof Agent)) return new Agent(callback); - if ('function' != typeof callback) throw new Error('Must pass a "callback function"'); EventEmitter.call(this); - this.callback = callback; + if ('function' === typeof callback) { + this.callback = callback; + } } inherits(Agent, EventEmitter); +Agent.prototype.callback = function callback (req, opts, fn) { + fn(new Error('"agent-base" has no default implementation, you must subclass and override `callback()`')); +}; + /** * Called by node-core's "_http_client.js" module when creating * a new HTTP request with this Agent instance. @@ -37,7 +42,7 @@ inherits(Agent, EventEmitter); * @api public */ -Agent.prototype.addRequest = function (req, host, port, localAddress) { +Agent.prototype.addRequest = function addRequest (req, host, port, localAddress) { var opts; if ('object' == typeof host) { // >= v0.11.x API diff --git a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/http-proxy-agent/node_modules/agent-base/package.json b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/http-proxy-agent/node_modules/agent-base/package.json index 0e296ced06eb1c..f74df4fcb787a4 100644 --- a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/http-proxy-agent/node_modules/agent-base/package.json +++ b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/http-proxy-agent/node_modules/agent-base/package.json @@ -1,7 +1,8 @@ { "_from": "agent-base@2", - "_id": "agent-base@2.0.1", - "_integrity": "sha1-vY+ehqjrIh//oHvRS+/VXfFCgV4=", + "_id": "agent-base@2.1.1", + "_inBundle": false, + "_integrity": "sha1-1t4Q1a9hMtW9aSQn1G/FOFOQlMc=", "_location": "/pacote/make-fetch-happen/http-proxy-agent/agent-base", "_phantomChildren": {}, "_requested": { @@ -17,9 +18,8 @@ "_requiredBy": [ "/pacote/make-fetch-happen/http-proxy-agent" ], - "_resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.0.1.tgz", - "_shasum": "bd8f9e86a8eb221fffa07bd14befd55df142815e", - "_shrinkwrap": null, + "_resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.1.1.tgz", + "_shasum": "d6de10d5af6132d5bd692427d46fc538539094c7", "_spec": "agent-base@2", "_where": "/Users/zkat/Documents/code/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/http-proxy-agent", "author": { @@ -27,7 +27,6 @@ "email": "nathan@tootallnate.net", "url": "http://n8.io/" }, - "bin": null, "bugs": { "url": "https://github.com/TooTallNate/node-agent-base/issues" }, @@ -39,7 +38,8 @@ "deprecated": false, "description": "Turn a function into an `http.Agent` instance", "devDependencies": { - "mocha": "2" + "mocha": "2", + "ws": "0.8.0" }, "homepage": "https://github.com/TooTallNate/node-agent-base#readme", "keywords": [ @@ -52,8 +52,6 @@ "license": "MIT", "main": "agent.js", "name": "agent-base", - "optionalDependencies": {}, - "peerDependencies": {}, "repository": { "type": "git", "url": "git://github.com/TooTallNate/node-agent-base.git" @@ -61,5 +59,5 @@ "scripts": { "test": "mocha --reporter spec" }, - "version": "2.0.1" + "version": "2.1.1" } diff --git a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/http-proxy-agent/node_modules/agent-base/test/test.js b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/http-proxy-agent/node_modules/agent-base/test/test.js index f87d308f8e65a2..7d8dee66ce902b 100644 --- a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/http-proxy-agent/node_modules/agent-base/test/test.js +++ b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/http-proxy-agent/node_modules/agent-base/test/test.js @@ -9,13 +9,45 @@ var net = require('net'); var tls = require('tls'); var http = require('http'); var https = require('https'); +var WebSocket = require('ws'); var assert = require('assert'); var events = require('events'); +var inherits = require('util').inherits; +var semver = require('semver'); var Agent = require('../'); describe('Agent', function () { + describe('subclass', function () { + it('should be subclassable', function (done) { + function MyAgent () { + Agent.call(this); + } + inherits(MyAgent, Agent); + + MyAgent.prototype.callback = function (req, opts, fn) { + assert.equal(req.path, '/foo'); + assert.equal(req.getHeader('host'), '127.0.0.1:1234'); + assert.equal(opts.secureEndpoint, true); + done(); + }; + + var info = url.parse('https://127.0.0.1:1234/foo'); + info.agent = new MyAgent; + https.get(info); + }); + }); describe('"error" event', function () { - it('should be invoked on `http.ClientRequest` instance if passed to callback function on the first tick', function (done) { + it('should be invoked on `http.ClientRequest` instance if `callback()` has not been defined', function (done) { + var agent = new Agent(); + var info = url.parse('http://127.0.0.1/foo'); + info.agent = agent; + var req = http.get(info); + req.on('error', function (err) { + assert.equal('"agent-base" has no default implementation, you must subclass and override `callback()`', err.message); + done(); + }); + }); + it('should be invoked on `http.ClientRequest` instance if Error passed to callback function on the first tick', function (done) { var agent = new Agent(function (req, opts, fn) { fn(new Error('is this caught?')); }); @@ -27,7 +59,7 @@ describe('Agent', function () { done(); }); }); - it('should be invoked on `http.ClientRequest` instance if passed to callback function after the first tick', function (done) { + it('should be invoked on `http.ClientRequest` instance if Error passed to callback function after the first tick', function (done) { var agent = new Agent(function (req, opts, fn) { setTimeout(function () { fn(new Error('is this caught?')); @@ -54,6 +86,10 @@ describe('Agent', function () { done(); }; + // needed for `http` module in Node.js 4 + stream.cork = function () { + }; + var opts = { method: 'GET', host: '127.0.0.1', @@ -298,3 +334,118 @@ describe('"https" module', function () { }); }); }); + +describe('"ws" server', function () { + var wss; + var server; + var port; + + // setup test HTTP server + before(function (done) { + server = http.createServer() + wss = new WebSocket.Server({ server: server }); + server.listen(0, function () { + port = server.address().port; + done(); + }); + }); + + // shut down test HTTP server + after(function (done) { + server.once('close', function () { + done(); + }); + server.close(); + }); + + it('should work for basic WebSocket connections', function (done) { + function onconnection(ws) { + ws.on('message', function (data) { + assert.equal('ping', data); + ws.send('pong'); + }); + } + wss.on('connection', onconnection); + + var agent = new Agent(function (req, opts, fn) { + var socket = net.connect(opts); + fn(null, socket); + }); + + var client = new WebSocket('ws://127.0.0.1:' + port + '/', { + agent: agent + }); + + client.on('open', function () { + client.send('ping'); + }); + + client.on('message', function (data) { + assert.equal('pong', data); + client.close(); + wss.removeListener('connection', onconnection); + done(); + }); + }); + +}); + +describe('"wss" server', function () { + var wss; + var server; + var port; + + // setup test HTTP server + before(function (done) { + var options = { + key: fs.readFileSync(__dirname + '/ssl-cert-snakeoil.key'), + cert: fs.readFileSync(__dirname + '/ssl-cert-snakeoil.pem') + }; + server = https.createServer(options); + wss = new WebSocket.Server({ server: server }); + server.listen(0, function () { + port = server.address().port; + done(); + }); + }); + + // shut down test HTTP server + after(function (done) { + server.once('close', function () { + done(); + }); + server.close(); + }); + + it('should work for secure WebSocket connections', function (done) { + function onconnection(ws) { + ws.on('message', function (data) { + assert.equal('ping', data); + ws.send('pong'); + }); + } + wss.on('connection', onconnection); + + var agent = new Agent(function (req, opts, fn) { + var socket = tls.connect(opts); + fn(null, socket); + }); + + var client = new WebSocket('wss://127.0.0.1:' + port + '/', { + agent: agent, + rejectUnauthorized: false + }); + + client.on('open', function () { + client.send('ping'); + }); + + client.on('message', function (data) { + assert.equal('pong', data); + client.close(); + wss.removeListener('connection', onconnection); + done(); + }); + }); + +}); diff --git a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/https-proxy-agent/node_modules/agent-base/.travis.yml b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/https-proxy-agent/node_modules/agent-base/.travis.yml index 85a50123c63edb..20b794051c9aaa 100644 --- a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/https-proxy-agent/node_modules/agent-base/.travis.yml +++ b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/https-proxy-agent/node_modules/agent-base/.travis.yml @@ -1,8 +1,29 @@ +sudo: false + language: node_js + node_js: - "0.8" - "0.10" - "0.12" -before_install: - - '[ "${TRAVIS_NODE_VERSION}" != "0.8" ] || npm install -g npm@1.4.28' - - npm install -g npm@latest + - "1" + - "2" + - "3" + - "4" + - "5" + - "6" + - "7" + +install: + - PATH="`npm bin`:`npm bin -g`:$PATH" + # Node 0.8 comes with a too obsolete npm + - if [[ "`node --version`" =~ ^v0\.8\. ]]; then npm install -g npm@1.4.28 ; fi + # Install dependencies and build + - npm install + +script: + # Output useful info for debugging + - node --version + - npm --version + # Run tests + - npm test diff --git a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/https-proxy-agent/node_modules/agent-base/History.md b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/https-proxy-agent/node_modules/agent-base/History.md index 0ceef6c13f70bf..2191a9e8014753 100644 --- a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/https-proxy-agent/node_modules/agent-base/History.md +++ b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/https-proxy-agent/node_modules/agent-base/History.md @@ -1,4 +1,22 @@ +2.1.1 / 2017-05-30 +================== + + * Revert [fe2162e0ba18123f5b301cba4de1e9dd74e437cd](https://github.com/TooTallNate/node-agent-base/commit/fe2162e0ba18123f5b301cba4de1e9dd74e437cd) and [270bdc92eb8e3bd0444d1e5266e8e9390aeb3095](https://github.com/TooTallNate/node-agent-base/commit/270bdc92eb8e3bd0444d1e5266e8e9390aeb3095) (fixes #7) + +2.1.0 / 2017-05-26 +================== + + * unref is not supported for node < 0.9.1 (@pi0) + * add tests to dangling socket (@pi0) + * check unref() is supported (@pi0) + * fix dangling sockets problem (@pi0) + * add basic "ws" module tests + * make `Agent` be subclassable + * turn `addRequest()` into a named function + * test: Node.js v4 likes to call `cork` on the stream (#3, @tomhughes) + * travis: test node v4, v5, v6 and v7 + 2.0.1 / 2015-09-10 ================== diff --git a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/https-proxy-agent/node_modules/agent-base/agent.js b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/https-proxy-agent/node_modules/agent-base/agent.js index 4005ebc0efb98e..7ea91f886cba24 100644 --- a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/https-proxy-agent/node_modules/agent-base/agent.js +++ b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/https-proxy-agent/node_modules/agent-base/agent.js @@ -24,12 +24,17 @@ module.exports = Agent; function Agent (callback) { if (!(this instanceof Agent)) return new Agent(callback); - if ('function' != typeof callback) throw new Error('Must pass a "callback function"'); EventEmitter.call(this); - this.callback = callback; + if ('function' === typeof callback) { + this.callback = callback; + } } inherits(Agent, EventEmitter); +Agent.prototype.callback = function callback (req, opts, fn) { + fn(new Error('"agent-base" has no default implementation, you must subclass and override `callback()`')); +}; + /** * Called by node-core's "_http_client.js" module when creating * a new HTTP request with this Agent instance. @@ -37,7 +42,7 @@ inherits(Agent, EventEmitter); * @api public */ -Agent.prototype.addRequest = function (req, host, port, localAddress) { +Agent.prototype.addRequest = function addRequest (req, host, port, localAddress) { var opts; if ('object' == typeof host) { // >= v0.11.x API diff --git a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/https-proxy-agent/node_modules/agent-base/package.json b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/https-proxy-agent/node_modules/agent-base/package.json index b57e81b1b464f6..9dedd7231d81e8 100644 --- a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/https-proxy-agent/node_modules/agent-base/package.json +++ b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/https-proxy-agent/node_modules/agent-base/package.json @@ -1,7 +1,8 @@ { "_from": "agent-base@2", - "_id": "agent-base@2.0.1", - "_integrity": "sha1-vY+ehqjrIh//oHvRS+/VXfFCgV4=", + "_id": "agent-base@2.1.1", + "_inBundle": false, + "_integrity": "sha1-1t4Q1a9hMtW9aSQn1G/FOFOQlMc=", "_location": "/pacote/make-fetch-happen/https-proxy-agent/agent-base", "_phantomChildren": {}, "_requested": { @@ -17,9 +18,8 @@ "_requiredBy": [ "/pacote/make-fetch-happen/https-proxy-agent" ], - "_resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.0.1.tgz", - "_shasum": "bd8f9e86a8eb221fffa07bd14befd55df142815e", - "_shrinkwrap": null, + "_resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.1.1.tgz", + "_shasum": "d6de10d5af6132d5bd692427d46fc538539094c7", "_spec": "agent-base@2", "_where": "/Users/zkat/Documents/code/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/https-proxy-agent", "author": { @@ -27,7 +27,6 @@ "email": "nathan@tootallnate.net", "url": "http://n8.io/" }, - "bin": null, "bugs": { "url": "https://github.com/TooTallNate/node-agent-base/issues" }, @@ -39,7 +38,8 @@ "deprecated": false, "description": "Turn a function into an `http.Agent` instance", "devDependencies": { - "mocha": "2" + "mocha": "2", + "ws": "0.8.0" }, "homepage": "https://github.com/TooTallNate/node-agent-base#readme", "keywords": [ @@ -52,8 +52,6 @@ "license": "MIT", "main": "agent.js", "name": "agent-base", - "optionalDependencies": {}, - "peerDependencies": {}, "repository": { "type": "git", "url": "git://github.com/TooTallNate/node-agent-base.git" @@ -61,5 +59,5 @@ "scripts": { "test": "mocha --reporter spec" }, - "version": "2.0.1" + "version": "2.1.1" } diff --git a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/https-proxy-agent/node_modules/agent-base/test/test.js b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/https-proxy-agent/node_modules/agent-base/test/test.js index f87d308f8e65a2..7d8dee66ce902b 100644 --- a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/https-proxy-agent/node_modules/agent-base/test/test.js +++ b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/https-proxy-agent/node_modules/agent-base/test/test.js @@ -9,13 +9,45 @@ var net = require('net'); var tls = require('tls'); var http = require('http'); var https = require('https'); +var WebSocket = require('ws'); var assert = require('assert'); var events = require('events'); +var inherits = require('util').inherits; +var semver = require('semver'); var Agent = require('../'); describe('Agent', function () { + describe('subclass', function () { + it('should be subclassable', function (done) { + function MyAgent () { + Agent.call(this); + } + inherits(MyAgent, Agent); + + MyAgent.prototype.callback = function (req, opts, fn) { + assert.equal(req.path, '/foo'); + assert.equal(req.getHeader('host'), '127.0.0.1:1234'); + assert.equal(opts.secureEndpoint, true); + done(); + }; + + var info = url.parse('https://127.0.0.1:1234/foo'); + info.agent = new MyAgent; + https.get(info); + }); + }); describe('"error" event', function () { - it('should be invoked on `http.ClientRequest` instance if passed to callback function on the first tick', function (done) { + it('should be invoked on `http.ClientRequest` instance if `callback()` has not been defined', function (done) { + var agent = new Agent(); + var info = url.parse('http://127.0.0.1/foo'); + info.agent = agent; + var req = http.get(info); + req.on('error', function (err) { + assert.equal('"agent-base" has no default implementation, you must subclass and override `callback()`', err.message); + done(); + }); + }); + it('should be invoked on `http.ClientRequest` instance if Error passed to callback function on the first tick', function (done) { var agent = new Agent(function (req, opts, fn) { fn(new Error('is this caught?')); }); @@ -27,7 +59,7 @@ describe('Agent', function () { done(); }); }); - it('should be invoked on `http.ClientRequest` instance if passed to callback function after the first tick', function (done) { + it('should be invoked on `http.ClientRequest` instance if Error passed to callback function after the first tick', function (done) { var agent = new Agent(function (req, opts, fn) { setTimeout(function () { fn(new Error('is this caught?')); @@ -54,6 +86,10 @@ describe('Agent', function () { done(); }; + // needed for `http` module in Node.js 4 + stream.cork = function () { + }; + var opts = { method: 'GET', host: '127.0.0.1', @@ -298,3 +334,118 @@ describe('"https" module', function () { }); }); }); + +describe('"ws" server', function () { + var wss; + var server; + var port; + + // setup test HTTP server + before(function (done) { + server = http.createServer() + wss = new WebSocket.Server({ server: server }); + server.listen(0, function () { + port = server.address().port; + done(); + }); + }); + + // shut down test HTTP server + after(function (done) { + server.once('close', function () { + done(); + }); + server.close(); + }); + + it('should work for basic WebSocket connections', function (done) { + function onconnection(ws) { + ws.on('message', function (data) { + assert.equal('ping', data); + ws.send('pong'); + }); + } + wss.on('connection', onconnection); + + var agent = new Agent(function (req, opts, fn) { + var socket = net.connect(opts); + fn(null, socket); + }); + + var client = new WebSocket('ws://127.0.0.1:' + port + '/', { + agent: agent + }); + + client.on('open', function () { + client.send('ping'); + }); + + client.on('message', function (data) { + assert.equal('pong', data); + client.close(); + wss.removeListener('connection', onconnection); + done(); + }); + }); + +}); + +describe('"wss" server', function () { + var wss; + var server; + var port; + + // setup test HTTP server + before(function (done) { + var options = { + key: fs.readFileSync(__dirname + '/ssl-cert-snakeoil.key'), + cert: fs.readFileSync(__dirname + '/ssl-cert-snakeoil.pem') + }; + server = https.createServer(options); + wss = new WebSocket.Server({ server: server }); + server.listen(0, function () { + port = server.address().port; + done(); + }); + }); + + // shut down test HTTP server + after(function (done) { + server.once('close', function () { + done(); + }); + server.close(); + }); + + it('should work for secure WebSocket connections', function (done) { + function onconnection(ws) { + ws.on('message', function (data) { + assert.equal('ping', data); + ws.send('pong'); + }); + } + wss.on('connection', onconnection); + + var agent = new Agent(function (req, opts, fn) { + var socket = tls.connect(opts); + fn(null, socket); + }); + + var client = new WebSocket('wss://127.0.0.1:' + port + '/', { + agent: agent, + rejectUnauthorized: false + }); + + client.on('open', function () { + client.send('ping'); + }); + + client.on('message', function (data) { + assert.equal('pong', data); + client.close(); + wss.removeListener('connection', onconnection); + done(); + }); + }); + +}); diff --git a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/socks-proxy-agent/node_modules/agent-base/.travis.yml b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/socks-proxy-agent/node_modules/agent-base/.travis.yml index 85a50123c63edb..20b794051c9aaa 100644 --- a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/socks-proxy-agent/node_modules/agent-base/.travis.yml +++ b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/socks-proxy-agent/node_modules/agent-base/.travis.yml @@ -1,8 +1,29 @@ +sudo: false + language: node_js + node_js: - "0.8" - "0.10" - "0.12" -before_install: - - '[ "${TRAVIS_NODE_VERSION}" != "0.8" ] || npm install -g npm@1.4.28' - - npm install -g npm@latest + - "1" + - "2" + - "3" + - "4" + - "5" + - "6" + - "7" + +install: + - PATH="`npm bin`:`npm bin -g`:$PATH" + # Node 0.8 comes with a too obsolete npm + - if [[ "`node --version`" =~ ^v0\.8\. ]]; then npm install -g npm@1.4.28 ; fi + # Install dependencies and build + - npm install + +script: + # Output useful info for debugging + - node --version + - npm --version + # Run tests + - npm test diff --git a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/socks-proxy-agent/node_modules/agent-base/History.md b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/socks-proxy-agent/node_modules/agent-base/History.md index 0ceef6c13f70bf..2191a9e8014753 100644 --- a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/socks-proxy-agent/node_modules/agent-base/History.md +++ b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/socks-proxy-agent/node_modules/agent-base/History.md @@ -1,4 +1,22 @@ +2.1.1 / 2017-05-30 +================== + + * Revert [fe2162e0ba18123f5b301cba4de1e9dd74e437cd](https://github.com/TooTallNate/node-agent-base/commit/fe2162e0ba18123f5b301cba4de1e9dd74e437cd) and [270bdc92eb8e3bd0444d1e5266e8e9390aeb3095](https://github.com/TooTallNate/node-agent-base/commit/270bdc92eb8e3bd0444d1e5266e8e9390aeb3095) (fixes #7) + +2.1.0 / 2017-05-26 +================== + + * unref is not supported for node < 0.9.1 (@pi0) + * add tests to dangling socket (@pi0) + * check unref() is supported (@pi0) + * fix dangling sockets problem (@pi0) + * add basic "ws" module tests + * make `Agent` be subclassable + * turn `addRequest()` into a named function + * test: Node.js v4 likes to call `cork` on the stream (#3, @tomhughes) + * travis: test node v4, v5, v6 and v7 + 2.0.1 / 2015-09-10 ================== diff --git a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/socks-proxy-agent/node_modules/agent-base/agent.js b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/socks-proxy-agent/node_modules/agent-base/agent.js index 4005ebc0efb98e..7ea91f886cba24 100644 --- a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/socks-proxy-agent/node_modules/agent-base/agent.js +++ b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/socks-proxy-agent/node_modules/agent-base/agent.js @@ -24,12 +24,17 @@ module.exports = Agent; function Agent (callback) { if (!(this instanceof Agent)) return new Agent(callback); - if ('function' != typeof callback) throw new Error('Must pass a "callback function"'); EventEmitter.call(this); - this.callback = callback; + if ('function' === typeof callback) { + this.callback = callback; + } } inherits(Agent, EventEmitter); +Agent.prototype.callback = function callback (req, opts, fn) { + fn(new Error('"agent-base" has no default implementation, you must subclass and override `callback()`')); +}; + /** * Called by node-core's "_http_client.js" module when creating * a new HTTP request with this Agent instance. @@ -37,7 +42,7 @@ inherits(Agent, EventEmitter); * @api public */ -Agent.prototype.addRequest = function (req, host, port, localAddress) { +Agent.prototype.addRequest = function addRequest (req, host, port, localAddress) { var opts; if ('object' == typeof host) { // >= v0.11.x API diff --git a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/socks-proxy-agent/node_modules/agent-base/package.json b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/socks-proxy-agent/node_modules/agent-base/package.json index 81950940bbdd6a..e2041315371230 100644 --- a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/socks-proxy-agent/node_modules/agent-base/package.json +++ b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/socks-proxy-agent/node_modules/agent-base/package.json @@ -1,7 +1,8 @@ { "_from": "agent-base@2", - "_id": "agent-base@2.0.1", - "_integrity": "sha1-vY+ehqjrIh//oHvRS+/VXfFCgV4=", + "_id": "agent-base@2.1.1", + "_inBundle": false, + "_integrity": "sha1-1t4Q1a9hMtW9aSQn1G/FOFOQlMc=", "_location": "/pacote/make-fetch-happen/socks-proxy-agent/agent-base", "_phantomChildren": {}, "_requested": { @@ -17,9 +18,8 @@ "_requiredBy": [ "/pacote/make-fetch-happen/socks-proxy-agent" ], - "_resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.0.1.tgz", - "_shasum": "bd8f9e86a8eb221fffa07bd14befd55df142815e", - "_shrinkwrap": null, + "_resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.1.1.tgz", + "_shasum": "d6de10d5af6132d5bd692427d46fc538539094c7", "_spec": "agent-base@2", "_where": "/Users/zkat/Documents/code/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/socks-proxy-agent", "author": { @@ -27,7 +27,6 @@ "email": "nathan@tootallnate.net", "url": "http://n8.io/" }, - "bin": null, "bugs": { "url": "https://github.com/TooTallNate/node-agent-base/issues" }, @@ -39,7 +38,8 @@ "deprecated": false, "description": "Turn a function into an `http.Agent` instance", "devDependencies": { - "mocha": "2" + "mocha": "2", + "ws": "0.8.0" }, "homepage": "https://github.com/TooTallNate/node-agent-base#readme", "keywords": [ @@ -52,8 +52,6 @@ "license": "MIT", "main": "agent.js", "name": "agent-base", - "optionalDependencies": {}, - "peerDependencies": {}, "repository": { "type": "git", "url": "git://github.com/TooTallNate/node-agent-base.git" @@ -61,5 +59,5 @@ "scripts": { "test": "mocha --reporter spec" }, - "version": "2.0.1" + "version": "2.1.1" } diff --git a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/socks-proxy-agent/node_modules/agent-base/test/test.js b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/socks-proxy-agent/node_modules/agent-base/test/test.js index f87d308f8e65a2..7d8dee66ce902b 100644 --- a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/socks-proxy-agent/node_modules/agent-base/test/test.js +++ b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/node_modules/socks-proxy-agent/node_modules/agent-base/test/test.js @@ -9,13 +9,45 @@ var net = require('net'); var tls = require('tls'); var http = require('http'); var https = require('https'); +var WebSocket = require('ws'); var assert = require('assert'); var events = require('events'); +var inherits = require('util').inherits; +var semver = require('semver'); var Agent = require('../'); describe('Agent', function () { + describe('subclass', function () { + it('should be subclassable', function (done) { + function MyAgent () { + Agent.call(this); + } + inherits(MyAgent, Agent); + + MyAgent.prototype.callback = function (req, opts, fn) { + assert.equal(req.path, '/foo'); + assert.equal(req.getHeader('host'), '127.0.0.1:1234'); + assert.equal(opts.secureEndpoint, true); + done(); + }; + + var info = url.parse('https://127.0.0.1:1234/foo'); + info.agent = new MyAgent; + https.get(info); + }); + }); describe('"error" event', function () { - it('should be invoked on `http.ClientRequest` instance if passed to callback function on the first tick', function (done) { + it('should be invoked on `http.ClientRequest` instance if `callback()` has not been defined', function (done) { + var agent = new Agent(); + var info = url.parse('http://127.0.0.1/foo'); + info.agent = agent; + var req = http.get(info); + req.on('error', function (err) { + assert.equal('"agent-base" has no default implementation, you must subclass and override `callback()`', err.message); + done(); + }); + }); + it('should be invoked on `http.ClientRequest` instance if Error passed to callback function on the first tick', function (done) { var agent = new Agent(function (req, opts, fn) { fn(new Error('is this caught?')); }); @@ -27,7 +59,7 @@ describe('Agent', function () { done(); }); }); - it('should be invoked on `http.ClientRequest` instance if passed to callback function after the first tick', function (done) { + it('should be invoked on `http.ClientRequest` instance if Error passed to callback function after the first tick', function (done) { var agent = new Agent(function (req, opts, fn) { setTimeout(function () { fn(new Error('is this caught?')); @@ -54,6 +86,10 @@ describe('Agent', function () { done(); }; + // needed for `http` module in Node.js 4 + stream.cork = function () { + }; + var opts = { method: 'GET', host: '127.0.0.1', @@ -298,3 +334,118 @@ describe('"https" module', function () { }); }); }); + +describe('"ws" server', function () { + var wss; + var server; + var port; + + // setup test HTTP server + before(function (done) { + server = http.createServer() + wss = new WebSocket.Server({ server: server }); + server.listen(0, function () { + port = server.address().port; + done(); + }); + }); + + // shut down test HTTP server + after(function (done) { + server.once('close', function () { + done(); + }); + server.close(); + }); + + it('should work for basic WebSocket connections', function (done) { + function onconnection(ws) { + ws.on('message', function (data) { + assert.equal('ping', data); + ws.send('pong'); + }); + } + wss.on('connection', onconnection); + + var agent = new Agent(function (req, opts, fn) { + var socket = net.connect(opts); + fn(null, socket); + }); + + var client = new WebSocket('ws://127.0.0.1:' + port + '/', { + agent: agent + }); + + client.on('open', function () { + client.send('ping'); + }); + + client.on('message', function (data) { + assert.equal('pong', data); + client.close(); + wss.removeListener('connection', onconnection); + done(); + }); + }); + +}); + +describe('"wss" server', function () { + var wss; + var server; + var port; + + // setup test HTTP server + before(function (done) { + var options = { + key: fs.readFileSync(__dirname + '/ssl-cert-snakeoil.key'), + cert: fs.readFileSync(__dirname + '/ssl-cert-snakeoil.pem') + }; + server = https.createServer(options); + wss = new WebSocket.Server({ server: server }); + server.listen(0, function () { + port = server.address().port; + done(); + }); + }); + + // shut down test HTTP server + after(function (done) { + server.once('close', function () { + done(); + }); + server.close(); + }); + + it('should work for secure WebSocket connections', function (done) { + function onconnection(ws) { + ws.on('message', function (data) { + assert.equal('ping', data); + ws.send('pong'); + }); + } + wss.on('connection', onconnection); + + var agent = new Agent(function (req, opts, fn) { + var socket = tls.connect(opts); + fn(null, socket); + }); + + var client = new WebSocket('wss://127.0.0.1:' + port + '/', { + agent: agent, + rejectUnauthorized: false + }); + + client.on('open', function () { + client.send('ping'); + }); + + client.on('message', function (data) { + assert.equal('pong', data); + client.close(); + wss.removeListener('connection', onconnection); + done(); + }); + }); + +}); diff --git a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/package.json b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/package.json index 8b8e2cd878d5ec..37607223547a3a 100644 --- a/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/package.json +++ b/deps/npm/node_modules/pacote/node_modules/make-fetch-happen/package.json @@ -1,28 +1,28 @@ { - "_from": "make-fetch-happen@^2.4.9", - "_id": "make-fetch-happen@2.4.9", + "_from": "make-fetch-happen@^2.4.11", + "_id": "make-fetch-happen@2.4.11", "_inBundle": false, - "_integrity": "sha512-/qh6T1E2gBD31bhutxeFehcHDwbBJJ7F+7w8bNAzPbacqfTwEpeo7W5SVQqciCSfNex51SjnEyw1XuK4zDn+Fw==", + "_integrity": "sha512-3dbl9CVS9Y0hqVzcD5HBYnaNUGw3XWpmeTqGT6ACRrmKS7WKwSDfv5+Gd1K0X/Mt52hsvZwtOH8hrNIulYkhag==", "_location": "/pacote/make-fetch-happen", "_phantomChildren": { - "safe-buffer": "5.0.1" + "safe-buffer": "5.1.0" }, "_requested": { "type": "range", "registry": true, - "raw": "make-fetch-happen@^2.4.9", + "raw": "make-fetch-happen@^2.4.11", "name": "make-fetch-happen", "escapedName": "make-fetch-happen", - "rawSpec": "^2.4.9", + "rawSpec": "^2.4.11", "saveSpec": null, - "fetchSpec": "^2.4.9" + "fetchSpec": "^2.4.11" }, "_requiredBy": [ "/pacote" ], - "_resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-2.4.9.tgz", - "_shasum": "245b799e35da3ec05a45e6ef31f9c34df7d1e0c1", - "_spec": "make-fetch-happen@^2.4.9", + "_resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-2.4.11.tgz", + "_shasum": "0b29967da2dc995e88f778dd0c673855ec7613e3", + "_spec": "make-fetch-happen@^2.4.11", "_where": "/Users/zkat/Documents/code/npm/node_modules/pacote", "author": { "name": "Kat Marchán", @@ -34,7 +34,7 @@ "bundleDependencies": false, "dependencies": { "agentkeepalive": "^3.1.0", - "cacache": "^9.2.4", + "cacache": "^9.2.7", "http-cache-semantics": "^3.7.3", "http-proxy-agent": "^1.0.0", "https-proxy-agent": "^1.0.0", @@ -42,8 +42,8 @@ "mississippi": "^1.2.0", "node-fetch-npm": "^2.0.1", "promise-retry": "^1.1.1", - "socks-proxy-agent": "^2.0.0", - "ssri": "^4.1.3" + "socks-proxy-agent": "^2.1.0", + "ssri": "^4.1.5" }, "deprecated": false, "description": "Opinionated, caching, retrying fetch client", @@ -52,13 +52,13 @@ "mkdirp": "^0.5.1", "nock": "^9.0.6", "npmlog": "^4.1.0", - "nyc": "^10.3.2", + "nyc": "^11.0.2", "rimraf": "^2.5.4", - "safe-buffer": "^5.0.1", + "safe-buffer": "^5.1.0", "standard": "^10.0.1", "standard-version": "^4.0.0", "tacks": "^1.2.6", - "tap": "^10.2.0", + "tap": "^10.3.3", "weallbehave": "^1.0.0", "weallcontribute": "^1.0.7" }, @@ -92,5 +92,5 @@ "update-coc": "weallbehave -o . && git add CODE_OF_CONDUCT.md && git commit -m 'docs(coc): updated CODE_OF_CONDUCT.md'", "update-contrib": "weallcontribute -o . && git add CONTRIBUTING.md && git commit -m 'docs(contributing): updated CONTRIBUTING.md'" }, - "version": "2.4.9" + "version": "2.4.11" } diff --git a/deps/npm/node_modules/pacote/package.json b/deps/npm/node_modules/pacote/package.json index c27683d0d20778..44e5b7eca0ab1e 100644 --- a/deps/npm/node_modules/pacote/package.json +++ b/deps/npm/node_modules/pacote/package.json @@ -1,40 +1,40 @@ { - "_from": "pacote@2.7.21", - "_id": "pacote@2.7.21", + "_from": "pacote@2.7.30", + "_id": "pacote@2.7.30", "_inBundle": false, - "_integrity": "sha512-ksTHJiAkJxLmcOGxO6iGMk1cVMTTtIC051ZUqvWbckICIhzScOSBgGRBc4CHRhd62NuqAL082RuOOmb1Mi6o6Q==", + "_integrity": "sha512-xFxozbxytemyfNPZmkL2seTD15mozK8ghov9npjBO4YTs3SnA8I55aiN94eZJ+XhLKzbN8yXqQMr9ti4c3WIDw==", "_location": "/pacote", "_phantomChildren": { - "cacache": "9.2.5", + "cacache": "9.2.8", "chownr": "1.0.1", "lru-cache": "4.0.2", "mississippi": "1.3.0", "mkdirp": "0.5.1", - "npm-package-arg": "5.0.1", + "npm-package-arg": "5.1.1", "once": "1.4.0", - "readable-stream": "2.2.9", + "readable-stream": "2.2.10", "retry": "0.10.1", - "safe-buffer": "5.0.1", + "safe-buffer": "5.1.0", "semver": "5.3.0", - "ssri": "4.1.3" + "ssri": "4.1.5" }, "_requested": { "type": "version", "registry": true, - "raw": "pacote@2.7.21", + "raw": "pacote@2.7.30", "name": "pacote", "escapedName": "pacote", - "rawSpec": "2.7.21", + "rawSpec": "2.7.30", "saveSpec": null, - "fetchSpec": "2.7.21" + "fetchSpec": "2.7.30" }, "_requiredBy": [ "#USER", "/" ], - "_resolved": "https://registry.npmjs.org/pacote/-/pacote-2.7.21.tgz", - "_shasum": "e909e8a0559940053300e1127297e92a1302d244", - "_spec": "pacote@2.7.21", + "_resolved": "https://registry.npmjs.org/pacote/-/pacote-2.7.30.tgz", + "_shasum": "f31678e0a40161b592498688c1e2c8d7918eac7e", + "_spec": "pacote@2.7.30", "_where": "/Users/zkat/Documents/code/npm", "author": { "name": "Kat Marchán", @@ -56,22 +56,22 @@ ], "dependencies": { "bluebird": "^3.5.0", - "cacache": "^9.2.5", + "cacache": "^9.2.8", "glob": "^7.1.2", "lru-cache": "^4.0.2", - "make-fetch-happen": "^2.4.9", + "make-fetch-happen": "^2.4.11", "minimatch": "^3.0.4", "mississippi": "^1.2.0", "normalize-package-data": "^2.3.6", - "npm-package-arg": "^5.0.0", + "npm-package-arg": "^5.1.1", "npm-pick-manifest": "^1.0.3", "osenv": "^0.1.4", "promise-inflight": "^1.0.1", "promise-retry": "^1.1.1", "protoduck": "^4.0.0", - "safe-buffer": "^5.0.1", + "safe-buffer": "^5.1.0", "semver": "^5.3.0", - "ssri": "^4.1.3", + "ssri": "^4.1.5", "tar-fs": "^1.15.1", "tar-stream": "^1.5.4", "unique-filename": "^1.1.0", @@ -83,13 +83,13 @@ "mkdirp": "^0.5.1", "nock": "^9.0.13", "npmlog": "^4.1.0", - "nyc": "^10.3.2", + "nyc": "^11.0.2", "require-inject": "^1.4.0", "rimraf": "^2.5.4", "standard": "^10.0.1", "standard-version": "^4.0.0", "tacks": "^1.2.6", - "tap": "^10.2.0", + "tap": "^10.3.3", "weallbehave": "^1.2.0", "weallcontribute": "^1.0.7" }, @@ -120,5 +120,5 @@ "update-coc": "weallbehave -o . && git add CODE_OF_CONDUCT.md && git commit -m 'docs(coc): updated CODE_OF_CONDUCT.md'", "update-contrib": "weallcontribute -o . && git add CONTRIBUTING.md && git commit -m 'docs(contributing): updated CONTRIBUTING.md'" }, - "version": "2.7.21" + "version": "2.7.30" } diff --git a/deps/npm/node_modules/read-package-tree/README.md b/deps/npm/node_modules/read-package-tree/README.md index b3cda81f7fdcf4..d2248f82b55a9e 100644 --- a/deps/npm/node_modules/read-package-tree/README.md +++ b/deps/npm/node_modules/read-package-tree/README.md @@ -35,7 +35,7 @@ mutate package.json data objects (beyond what doesn't limit its search to include/exclude `devDependencies`, or anything else. -Just follows the links in the `node_modules` heirarchy and reads the +Just follows the links in the `node_modules` hierarchy and reads the package.json files it finds therein. ## Symbolic Links diff --git a/deps/npm/node_modules/read-package-tree/package.json b/deps/npm/node_modules/read-package-tree/package.json index f9fa36224131bf..55513a93947088 100644 --- a/deps/npm/node_modules/read-package-tree/package.json +++ b/deps/npm/node_modules/read-package-tree/package.json @@ -1,33 +1,33 @@ { - "_from": "read-package-tree@~5.1.5", - "_id": "read-package-tree@5.1.5", - "_integrity": "sha1-rOfmOBx2hPlwqqmPx8XStmat2rY=", + "_from": "read-package-tree@5.1.6", + "_id": "read-package-tree@5.1.6", + "_inBundle": false, + "_integrity": "sha512-FCX1aT3GWyY658wzDICef4p+n0dB+ENRct8E/Qyvppj6xVpOYerBHfUu7OP5Rt1/393Tdglguf5ju5DEX4wZNg==", "_location": "/read-package-tree", "_phantomChildren": {}, "_requested": { - "type": "range", + "type": "version", "registry": true, - "raw": "read-package-tree@~5.1.5", + "raw": "read-package-tree@5.1.6", "name": "read-package-tree", "escapedName": "read-package-tree", - "rawSpec": "~5.1.5", + "rawSpec": "5.1.6", "saveSpec": null, - "fetchSpec": "~5.1.5" + "fetchSpec": "5.1.6" }, "_requiredBy": [ + "#USER", "/" ], - "_resolved": "https://registry.npmjs.org/read-package-tree/-/read-package-tree-5.1.5.tgz", - "_shasum": "ace7e6381c7684f970aaa98fc7c5d2b666addab6", - "_shrinkwrap": null, - "_spec": "read-package-tree@~5.1.5", - "_where": "/Users/zkat/Documents/code/npm", + "_resolved": "https://registry.npmjs.org/read-package-tree/-/read-package-tree-5.1.6.tgz", + "_shasum": "4f03e83d0486856fb60d97c94882841c2a7b1b7a", + "_spec": "read-package-tree@5.1.6", + "_where": "/Users/rebecca/code/npm", "author": { "name": "Isaac Z. Schlueter", "email": "i@izs.me", "url": "http://blog.izs.me/" }, - "bin": null, "bugs": { "url": "https://github.com/npm/read-package-tree/issues" }, @@ -42,9 +42,10 @@ "deprecated": false, "description": "Read the contents of node_modules.", "devDependencies": { - "archy": "0", + "archy": "^1.0.0", + "mkdirp": "^0.5.1", "tacks": "^1.2.1", - "tap": "^1.2.0" + "tap": "^6.3.0" }, "directories": { "test": "test" @@ -56,8 +57,6 @@ "license": "ISC", "main": "rpt.js", "name": "read-package-tree", - "optionalDependencies": {}, - "peerDependencies": {}, "repository": { "type": "git", "url": "git+https://github.com/npm/read-package-tree.git" @@ -65,5 +64,5 @@ "scripts": { "test": "tap test/*.js" }, - "version": "5.1.5" + "version": "5.1.6" } diff --git a/deps/npm/node_modules/read-package-tree/rpt.js b/deps/npm/node_modules/read-package-tree/rpt.js index 8a6a89b085a9ba..96f152012090e5 100644 --- a/deps/npm/node_modules/read-package-tree/rpt.js +++ b/deps/npm/node_modules/read-package-tree/rpt.js @@ -37,25 +37,27 @@ rpt.Node = Node rpt.Link = Link var ID = 0 -function Node (pkg, logical, physical, er, cache) { - if (cache[physical]) return cache[physical] - +function Node (pkg, logical, physical, er, cache, fromLink) { if (!(this instanceof Node)) { return new Node(pkg, logical, physical, er, cache) } - cache[physical] = this + var node = cache[physical] || this + if (fromLink && cache[physical]) return cache[physical] - debug(this.constructor.name, dpath(physical), pkg && pkg._id) + debug(node.constructor.name, dpath(physical), pkg && pkg._id) - this.id = ID++ - this.package = pkg || {} - this.path = logical - this.realpath = physical - this.parent = null - this.isLink = false - this.children = [] - this.error = er + node.path = logical + node.realpath = physical + node.error = er + if (!cache[physical]) { + node.id = ID++ + node.package = pkg || {} + node.parent = null + node.isLink = false + node.children = [] + } + return cache[physical] = node } Node.prototype.package = null @@ -80,7 +82,7 @@ function Link (pkg, logical, physical, realpath, er, cache) { this.realpath = realpath this.package = pkg || {} this.parent = null - this.target = new Node(this.package, logical, realpath, er, cache) + this.target = new Node(this.package, logical, realpath, er, cache, true) this.isLink = true this.children = this.target.children this.error = er diff --git a/deps/npm/node_modules/readable-stream/.travis.yml b/deps/npm/node_modules/readable-stream/.travis.yml index 76b4b0cfcb0765..0c5d2bc262d399 100644 --- a/deps/npm/node_modules/readable-stream/.travis.yml +++ b/deps/npm/node_modules/readable-stream/.travis.yml @@ -2,26 +2,40 @@ sudo: false language: node_js before_install: - npm install -g npm@2 - - npm install -g npm + - test $NPM_LEGACY && npm install -g npm@latest-3 || npm install npm -g notifications: email: false matrix: fast_finish: true include: - node_js: '0.8' - env: TASK=test + env: + - TASK=test + - NPM_LEGACY=true - node_js: '0.10' - env: TASK=test + env: + - TASK=test + - NPM_LEGACY=true - node_js: '0.11' - env: TASK=test + env: + - TASK=test + - NPM_LEGACY=true - node_js: '0.12' - env: TASK=test + env: + - TASK=test + - NPM_LEGACY=true - node_js: 1 - env: TASK=test + env: + - TASK=test + - NPM_LEGACY=true - node_js: 2 - env: TASK=test + env: + - TASK=test + - NPM_LEGACY=true - node_js: 3 - env: TASK=test + env: + - TASK=test + - NPM_LEGACY=true - node_js: 4 env: TASK=test - node_js: 5 @@ -30,17 +44,19 @@ matrix: env: TASK=test - node_js: 7 env: TASK=test - - node_js: 5 + - node_js: 8 + env: TASK=test + - node_js: 6 env: TASK=browser BROWSER_NAME=ie BROWSER_VERSION="9..latest" - - node_js: 5 + - node_js: 6 env: TASK=browser BROWSER_NAME=opera BROWSER_VERSION="11..latest" - - node_js: 5 + - node_js: 6 env: TASK=browser BROWSER_NAME=chrome BROWSER_VERSION="-3..latest" - - node_js: 5 + - node_js: 6 env: TASK=browser BROWSER_NAME=firefox BROWSER_VERSION="-3..latest" - - node_js: 5 + - node_js: 6 env: TASK=browser BROWSER_NAME=safari BROWSER_VERSION="5..latest" - - node_js: 5 + - node_js: 6 env: TASK=browser BROWSER_NAME=microsoftedge BROWSER_VERSION=latest script: "npm run $TASK" env: diff --git a/deps/npm/node_modules/readable-stream/README.md b/deps/npm/node_modules/readable-stream/README.md index 8b6e5d39bd3944..3024d77c69567a 100644 --- a/deps/npm/node_modules/readable-stream/README.md +++ b/deps/npm/node_modules/readable-stream/README.md @@ -18,7 +18,7 @@ npm install --save readable-stream This package is a mirror of the Streams2 and Streams3 implementations in Node-core. -Full documentation may be found on the [Node.js website](https://nodejs.org/dist/v7.8.0/docs/api/). +Full documentation may be found on the [Node.js website](https://nodejs.org/dist/v7.10.0/docs/api/stream.html). If you want to guarantee a stable streams base, regardless of what version of Node you, or the users of your libraries are using, use **readable-stream** *only* and avoid the *"stream"* module in Node-core, for background see [this blogpost](http://r.va.gg/2014/06/why-i-dont-use-nodes-core-stream-module.html). diff --git a/deps/npm/node_modules/readable-stream/lib/_stream_readable.js b/deps/npm/node_modules/readable-stream/lib/_stream_readable.js index b19b2088b95776..a01012e3cfbb70 100644 --- a/deps/npm/node_modules/readable-stream/lib/_stream_readable.js +++ b/deps/npm/node_modules/readable-stream/lib/_stream_readable.js @@ -28,9 +28,8 @@ var EElistenerCount = function (emitter, type) { var Stream = require('./internal/streams/stream'); /**/ -var Buffer = require('buffer').Buffer; /**/ -var bufferShim = require('buffer-shims'); +var Buffer = require('safe-buffer').Buffer; /**/ /**/ @@ -163,7 +162,7 @@ Readable.prototype.push = function (chunk, encoding) { if (!state.objectMode && typeof chunk === 'string') { encoding = encoding || state.defaultEncoding; if (encoding !== state.encoding) { - chunk = bufferShim.from(chunk, encoding); + chunk = Buffer.from(chunk, encoding); encoding = ''; } } @@ -483,7 +482,7 @@ Readable.prototype.pipe = function (dest, pipeOpts) { var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr; - var endFn = doEnd ? onend : cleanup; + var endFn = doEnd ? onend : unpipe; if (state.endEmitted) processNextTick(endFn);else src.once('end', endFn); dest.on('unpipe', onunpipe); @@ -516,7 +515,7 @@ Readable.prototype.pipe = function (dest, pipeOpts) { dest.removeListener('error', onerror); dest.removeListener('unpipe', onunpipe); src.removeListener('end', onend); - src.removeListener('end', cleanup); + src.removeListener('end', unpipe); src.removeListener('data', ondata); cleanedUp = true; @@ -873,7 +872,7 @@ function copyFromBufferString(n, list) { // This function is designed to be inlinable, so please take care when making // changes to the function body. function copyFromBuffer(n, list) { - var ret = bufferShim.allocUnsafe(n); + var ret = Buffer.allocUnsafe(n); var p = list.head; var c = 1; p.data.copy(ret); diff --git a/deps/npm/node_modules/readable-stream/lib/_stream_writable.js b/deps/npm/node_modules/readable-stream/lib/_stream_writable.js index 15db0386836c84..e9701f500727cf 100644 --- a/deps/npm/node_modules/readable-stream/lib/_stream_writable.js +++ b/deps/npm/node_modules/readable-stream/lib/_stream_writable.js @@ -35,9 +35,8 @@ var internalUtil = { var Stream = require('./internal/streams/stream'); /**/ -var Buffer = require('buffer').Buffer; /**/ -var bufferShim = require('buffer-shims'); +var Buffer = require('safe-buffer').Buffer; /**/ util.inherits(Writable, Stream); @@ -293,7 +292,7 @@ Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) { function decodeChunk(state, chunk, encoding) { if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') { - chunk = bufferShim.from(chunk, encoding); + chunk = Buffer.from(chunk, encoding); } return chunk; } diff --git a/deps/npm/node_modules/readable-stream/lib/internal/streams/BufferList.js b/deps/npm/node_modules/readable-stream/lib/internal/streams/BufferList.js index e4bfcf02dc8bbf..82598c852179cb 100644 --- a/deps/npm/node_modules/readable-stream/lib/internal/streams/BufferList.js +++ b/deps/npm/node_modules/readable-stream/lib/internal/streams/BufferList.js @@ -1,8 +1,8 @@ 'use strict'; -var Buffer = require('buffer').Buffer; /**/ -var bufferShim = require('buffer-shims'); + +var Buffer = require('safe-buffer').Buffer; /**/ module.exports = BufferList; @@ -50,9 +50,9 @@ BufferList.prototype.join = function (s) { }; BufferList.prototype.concat = function (n) { - if (this.length === 0) return bufferShim.alloc(0); + if (this.length === 0) return Buffer.alloc(0); if (this.length === 1) return this.head.data; - var ret = bufferShim.allocUnsafe(n >>> 0); + var ret = Buffer.allocUnsafe(n >>> 0); var p = this.head; var i = 0; while (p) { diff --git a/deps/npm/node_modules/readable-stream/node_modules/buffer-shims/index.js b/deps/npm/node_modules/readable-stream/node_modules/buffer-shims/index.js deleted file mode 100644 index 1cab4c05e1ac2a..00000000000000 --- a/deps/npm/node_modules/readable-stream/node_modules/buffer-shims/index.js +++ /dev/null @@ -1,108 +0,0 @@ -'use strict'; - -var buffer = require('buffer'); -var Buffer = buffer.Buffer; -var SlowBuffer = buffer.SlowBuffer; -var MAX_LEN = buffer.kMaxLength || 2147483647; -exports.alloc = function alloc(size, fill, encoding) { - if (typeof Buffer.alloc === 'function') { - return Buffer.alloc(size, fill, encoding); - } - if (typeof encoding === 'number') { - throw new TypeError('encoding must not be number'); - } - if (typeof size !== 'number') { - throw new TypeError('size must be a number'); - } - if (size > MAX_LEN) { - throw new RangeError('size is too large'); - } - var enc = encoding; - var _fill = fill; - if (_fill === undefined) { - enc = undefined; - _fill = 0; - } - var buf = new Buffer(size); - if (typeof _fill === 'string') { - var fillBuf = new Buffer(_fill, enc); - var flen = fillBuf.length; - var i = -1; - while (++i < size) { - buf[i] = fillBuf[i % flen]; - } - } else { - buf.fill(_fill); - } - return buf; -} -exports.allocUnsafe = function allocUnsafe(size) { - if (typeof Buffer.allocUnsafe === 'function') { - return Buffer.allocUnsafe(size); - } - if (typeof size !== 'number') { - throw new TypeError('size must be a number'); - } - if (size > MAX_LEN) { - throw new RangeError('size is too large'); - } - return new Buffer(size); -} -exports.from = function from(value, encodingOrOffset, length) { - if (typeof Buffer.from === 'function' && (!global.Uint8Array || Uint8Array.from !== Buffer.from)) { - return Buffer.from(value, encodingOrOffset, length); - } - if (typeof value === 'number') { - throw new TypeError('"value" argument must not be a number'); - } - if (typeof value === 'string') { - return new Buffer(value, encodingOrOffset); - } - if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) { - var offset = encodingOrOffset; - if (arguments.length === 1) { - return new Buffer(value); - } - if (typeof offset === 'undefined') { - offset = 0; - } - var len = length; - if (typeof len === 'undefined') { - len = value.byteLength - offset; - } - if (offset >= value.byteLength) { - throw new RangeError('\'offset\' is out of bounds'); - } - if (len > value.byteLength - offset) { - throw new RangeError('\'length\' is out of bounds'); - } - return new Buffer(value.slice(offset, offset + len)); - } - if (Buffer.isBuffer(value)) { - var out = new Buffer(value.length); - value.copy(out, 0, 0, value.length); - return out; - } - if (value) { - if (Array.isArray(value) || (typeof ArrayBuffer !== 'undefined' && value.buffer instanceof ArrayBuffer) || 'length' in value) { - return new Buffer(value); - } - if (value.type === 'Buffer' && Array.isArray(value.data)) { - return new Buffer(value.data); - } - } - - throw new TypeError('First argument must be a string, Buffer, ' + 'ArrayBuffer, Array, or array-like object.'); -} -exports.allocUnsafeSlow = function allocUnsafeSlow(size) { - if (typeof Buffer.allocUnsafeSlow === 'function') { - return Buffer.allocUnsafeSlow(size); - } - if (typeof size !== 'number') { - throw new TypeError('size must be a number'); - } - if (size >= MAX_LEN) { - throw new RangeError('size is too large'); - } - return new SlowBuffer(size); -} diff --git a/deps/npm/node_modules/readable-stream/node_modules/buffer-shims/license.md b/deps/npm/node_modules/readable-stream/node_modules/buffer-shims/license.md deleted file mode 100644 index 01cfaefe2fcaff..00000000000000 --- a/deps/npm/node_modules/readable-stream/node_modules/buffer-shims/license.md +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (c) 2016 Calvin Metcalf - -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.** diff --git a/deps/npm/node_modules/readable-stream/node_modules/buffer-shims/package.json b/deps/npm/node_modules/readable-stream/node_modules/buffer-shims/package.json deleted file mode 100644 index 8e4af6603bb26b..00000000000000 --- a/deps/npm/node_modules/readable-stream/node_modules/buffer-shims/package.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "_from": "buffer-shims@~1.0.0", - "_id": "buffer-shims@1.0.0", - "_integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=", - "_location": "/readable-stream/buffer-shims", - "_phantomChildren": {}, - "_requested": { - "type": "range", - "registry": true, - "raw": "buffer-shims@~1.0.0", - "name": "buffer-shims", - "escapedName": "buffer-shims", - "rawSpec": "~1.0.0", - "saveSpec": null, - "fetchSpec": "~1.0.0" - }, - "_requiredBy": [ - "/readable-stream", - "/readable-stream/string_decoder" - ], - "_resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", - "_shasum": "9978ce317388c649ad8793028c3477ef044a8b51", - "_shrinkwrap": null, - "_spec": "buffer-shims@~1.0.0", - "_where": "/Users/zkat/Documents/code/npm/node_modules/readable-stream", - "bin": null, - "bugs": { - "url": "https://github.com/calvinmetcalf/buffer-shims/issues" - }, - "bundleDependencies": false, - "dependencies": {}, - "deprecated": false, - "description": "some shims for node buffers", - "devDependencies": { - "tape": "^4.5.1" - }, - "files": [ - "index.js" - ], - "homepage": "https://github.com/calvinmetcalf/buffer-shims#readme", - "license": "MIT", - "main": "index.js", - "name": "buffer-shims", - "optionalDependencies": {}, - "peerDependencies": {}, - "repository": { - "type": "git", - "url": "git+ssh://git@github.com/calvinmetcalf/buffer-shims.git" - }, - "scripts": { - "test": "tape test/*.js" - }, - "version": "1.0.0" -} diff --git a/deps/npm/node_modules/readable-stream/node_modules/buffer-shims/readme.md b/deps/npm/node_modules/readable-stream/node_modules/buffer-shims/readme.md deleted file mode 100644 index 7ea6475e284e8e..00000000000000 --- a/deps/npm/node_modules/readable-stream/node_modules/buffer-shims/readme.md +++ /dev/null @@ -1,21 +0,0 @@ -buffer-shims -=== - -functions to make sure the new buffer methods work in older browsers. - -```js -var bufferShim = require('buffer-shims'); -bufferShim.from('foo'); -bufferShim.alloc(9, 'cafeface', 'hex'); -bufferShim.allocUnsafe(15); -bufferShim.allocUnsafeSlow(21); -``` - -should just use the original in newer nodes and on older nodes uses fallbacks. - -Known Issues -=== -- this does not patch the buffer object, only the constructor stuff -- it's actually a polyfill - -![](https://i.imgur.com/zxII3jJ.gif) diff --git a/deps/npm/node_modules/readable-stream/node_modules/string_decoder/README.md b/deps/npm/node_modules/readable-stream/node_modules/string_decoder/README.md index 13d827d8947e43..dc3a2d2160b900 100644 --- a/deps/npm/node_modules/readable-stream/node_modules/string_decoder/README.md +++ b/deps/npm/node_modules/readable-stream/node_modules/string_decoder/README.md @@ -7,8 +7,6 @@ [![NPM](https://nodei.co/npm-dl/string_decoder.png?&months=6&height=3)](https://nodei.co/npm/string_decoder/) -[![Sauce Test Status](https://saucelabs.com/browser-matrix/string_decoder.svg)](https://saucelabs.com/u/string_decoder) - ```bash npm install --save string_decoder ``` diff --git a/deps/npm/node_modules/readable-stream/node_modules/string_decoder/lib/string_decoder.js b/deps/npm/node_modules/readable-stream/node_modules/string_decoder/lib/string_decoder.js index 696d7ab6136a60..26fb94c349ac4f 100644 --- a/deps/npm/node_modules/readable-stream/node_modules/string_decoder/lib/string_decoder.js +++ b/deps/npm/node_modules/readable-stream/node_modules/string_decoder/lib/string_decoder.js @@ -1,7 +1,6 @@ 'use strict'; -var Buffer = require('buffer').Buffer; -var bufferShim = require('buffer-shims'); +var Buffer = require('safe-buffer').Buffer; var isEncoding = Buffer.isEncoding || function (encoding) { encoding = '' + encoding; @@ -78,7 +77,7 @@ function StringDecoder(encoding) { } this.lastNeed = 0; this.lastTotal = 0; - this.lastChar = bufferShim.allocUnsafe(nb); + this.lastChar = Buffer.allocUnsafe(nb); } StringDecoder.prototype.write = function (buf) { diff --git a/deps/npm/node_modules/readable-stream/node_modules/string_decoder/package.json b/deps/npm/node_modules/readable-stream/node_modules/string_decoder/package.json index fb2958ba2cfcfa..cb5868ecedc40a 100644 --- a/deps/npm/node_modules/readable-stream/node_modules/string_decoder/package.json +++ b/deps/npm/node_modules/readable-stream/node_modules/string_decoder/package.json @@ -1,7 +1,8 @@ { "_from": "string_decoder@~1.0.0", - "_id": "string_decoder@1.0.0", - "_integrity": "sha1-8G9BFXtmTYYGn4S9vcmw2KsoFmc=", + "_id": "string_decoder@1.0.1", + "_inBundle": false, + "_integrity": "sha1-YuIA8DmVWmgQ2N8KM//A8BNmLZg=", "_location": "/readable-stream/string_decoder", "_phantomChildren": {}, "_requested": { @@ -17,18 +18,16 @@ "_requiredBy": [ "/readable-stream" ], - "_resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.0.tgz", - "_shasum": "f06f41157b664d86069f84bdbdc9b0d8ab281667", - "_shrinkwrap": null, + "_resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.1.tgz", + "_shasum": "62e200f039955a6810d8df0a33ffc0f013662d98", "_spec": "string_decoder@~1.0.0", "_where": "/Users/zkat/Documents/code/npm/node_modules/readable-stream", - "bin": null, "bugs": { "url": "https://github.com/rvagg/string_decoder/issues" }, "bundleDependencies": false, "dependencies": { - "buffer-shims": "~1.0.0" + "safe-buffer": "^5.0.1" }, "deprecated": false, "description": "The string_decoder module from Node core", @@ -46,8 +45,6 @@ "license": "MIT", "main": "lib/string_decoder.js", "name": "string_decoder", - "optionalDependencies": {}, - "peerDependencies": {}, "repository": { "type": "git", "url": "git://github.com/rvagg/string_decoder.git" @@ -55,5 +52,5 @@ "scripts": { "test": "tap test/parallel/*.js" }, - "version": "1.0.0" + "version": "1.0.1" } diff --git a/deps/npm/node_modules/readable-stream/package.json b/deps/npm/node_modules/readable-stream/package.json index d1bf299d055bb2..5308555f496301 100644 --- a/deps/npm/node_modules/readable-stream/package.json +++ b/deps/npm/node_modules/readable-stream/package.json @@ -1,20 +1,24 @@ { - "_from": "readable-stream@~2.2.9", - "_id": "readable-stream@2.2.9", - "_integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", + "_from": "readable-stream@2.2.10", + "_id": "readable-stream@2.2.10", + "_inBundle": false, + "_integrity": "sha512-HQEnnoV404e0EtwB9yNiuk2tJ+egeVC8Y9QBAxzDg8DBJt4BzRp+yQuIb/t3FIWkSTmIi+sgx7yVv/ZM0GNoqw==", "_location": "/readable-stream", - "_phantomChildren": {}, + "_phantomChildren": { + "safe-buffer": "5.0.1" + }, "_requested": { - "type": "range", + "type": "version", "registry": true, - "raw": "readable-stream@~2.2.9", + "raw": "readable-stream@2.2.10", "name": "readable-stream", "escapedName": "readable-stream", - "rawSpec": "~2.2.9", + "rawSpec": "2.2.10", "saveSpec": null, - "fetchSpec": "~2.2.9" + "fetchSpec": "2.2.10" }, "_requiredBy": [ + "#USER", "/", "/fs-write-stream-atomic", "/mississippi/concat-stream", @@ -34,12 +38,10 @@ "/tap/tap-mocha-reporter", "/tap/tap-parser" ], - "_resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", - "_shasum": "cf78ec6f4a6d1eb43d26488cac97f042e74b7fc8", - "_shrinkwrap": null, - "_spec": "readable-stream@~2.2.9", + "_resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.10.tgz", + "_shasum": "effe72bb7c884c0dd335e2379d526196d9d011ee", + "_spec": "readable-stream@2.2.10", "_where": "/Users/zkat/Documents/code/npm", - "bin": null, "browser": { "util": false, "./readable.js": "./readable-browser.js", @@ -52,11 +54,11 @@ }, "bundleDependencies": false, "dependencies": { - "buffer-shims": "~1.0.0", "core-util-is": "~1.0.0", "inherits": "~2.0.1", "isarray": "~1.0.0", "process-nextick-args": "~1.0.6", + "safe-buffer": "^5.0.1", "string_decoder": "~1.0.0", "util-deprecate": "~1.0.1" }, @@ -85,8 +87,6 @@ "lib/**.js" ] }, - "optionalDependencies": {}, - "peerDependencies": {}, "repository": { "type": "git", "url": "git://github.com/nodejs/readable-stream.git" @@ -99,5 +99,5 @@ "test": "tap test/parallel/*.js test/ours/*.js", "write-zuul": "printf \"ui: tape\nbrowsers:\n - name: $BROWSER_NAME\n version: $BROWSER_VERSION\n\">.zuul.yml" }, - "version": "2.2.9" + "version": "2.2.10" } diff --git a/deps/npm/node_modules/safe-buffer/README.md b/deps/npm/node_modules/safe-buffer/README.md index 96eb387aa08586..e9a81afd0406f0 100644 --- a/deps/npm/node_modules/safe-buffer/README.md +++ b/deps/npm/node_modules/safe-buffer/README.md @@ -1,17 +1,20 @@ -# safe-buffer [![travis][travis-image]][travis-url] [![npm][npm-image]][npm-url] [![downloads][downloads-image]][npm-url] +# safe-buffer [![travis][travis-image]][travis-url] [![npm][npm-image]][npm-url] [![downloads][downloads-image]][downloads-url] [![javascript style guide][standard-image]][standard-url] -#### Safer Node.js Buffer API - -**Use the new Node.js v6 Buffer APIs (`Buffer.from`, `Buffer.alloc`, -`Buffer.allocUnsafe`, `Buffer.allocUnsafeSlow`) in Node.js v0.10, v0.12, v4.x, and v5.x.** - -**Uses the built-in implementations when available.** - -[travis-image]: https://img.shields.io/travis/feross/safe-buffer.svg +[travis-image]: https://img.shields.io/travis/feross/safe-buffer/master.svg [travis-url]: https://travis-ci.org/feross/safe-buffer [npm-image]: https://img.shields.io/npm/v/safe-buffer.svg [npm-url]: https://npmjs.org/package/safe-buffer [downloads-image]: https://img.shields.io/npm/dm/safe-buffer.svg +[downloads-url]: https://npmjs.org/package/safe-buffer +[standard-image]: https://img.shields.io/badge/code_style-standard-brightgreen.svg +[standard-url]: https://standardjs.com + +#### Safer Node.js Buffer API + +**Use the new Node.js Buffer APIs (`Buffer.from`, `Buffer.alloc`, +`Buffer.allocUnsafe`, `Buffer.allocUnsafeSlow`) in all versions of Node.js.** + +**Uses the built-in implementation when available.** ## install diff --git a/deps/npm/node_modules/safe-buffer/browser.js b/deps/npm/node_modules/safe-buffer/browser.js deleted file mode 100644 index 0bd12027d30ff7..00000000000000 --- a/deps/npm/node_modules/safe-buffer/browser.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('buffer') diff --git a/deps/npm/node_modules/safe-buffer/index.js b/deps/npm/node_modules/safe-buffer/index.js index 74a7358ee82ac5..ea87b099d83dec 100644 --- a/deps/npm/node_modules/safe-buffer/index.js +++ b/deps/npm/node_modules/safe-buffer/index.js @@ -1,4 +1,6 @@ +/* eslint-disable node/no-deprecated-api */ var buffer = require('buffer') +var Buffer = buffer.Buffer if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) { module.exports = buffer diff --git a/deps/npm/node_modules/safe-buffer/package.json b/deps/npm/node_modules/safe-buffer/package.json index d866dd9580b6dc..8bce3da12596e7 100644 --- a/deps/npm/node_modules/safe-buffer/package.json +++ b/deps/npm/node_modules/safe-buffer/package.json @@ -1,34 +1,36 @@ { - "_from": "safe-buffer@~5.0.1", - "_id": "safe-buffer@5.0.1", + "_from": "safe-buffer@latest", + "_id": "safe-buffer@5.1.0", "_inBundle": false, - "_integrity": "sha1-0mPKVGls2KMGtcplUekt5XkY++c=", + "_integrity": "sha512-aSLEDudu6OoRr/2rU609gRmnYboRLxgDG1z9o2Q0os7236FwvcqIOO8r8U5JUEwivZOhDaKlFO4SbPTJYyBEyQ==", "_location": "/safe-buffer", "_phantomChildren": {}, "_requested": { - "type": "range", + "type": "tag", "registry": true, - "raw": "safe-buffer@~5.0.1", + "raw": "safe-buffer@latest", "name": "safe-buffer", "escapedName": "safe-buffer", - "rawSpec": "~5.0.1", + "rawSpec": "latest", "saveSpec": null, - "fetchSpec": "~5.0.1" + "fetchSpec": "latest" }, "_requiredBy": [ "#USER", - "/" + "/", + "/readable-stream", + "/readable-stream/string_decoder", + "/ssri" ], - "_resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.0.1.tgz", - "_shasum": "d263ca54696cd8a306b5ca6551e92de57918fbe7", - "_spec": "safe-buffer@~5.0.1", + "_resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.0.tgz", + "_shasum": "fe4c8460397f9eaaaa58e73be46273408a45e223", + "_spec": "safe-buffer@latest", "_where": "/Users/zkat/Documents/code/npm", "author": { "name": "Feross Aboukhadijeh", "email": "feross@feross.org", "url": "http://feross.org" }, - "browser": "./browser.js", "bugs": { "url": "https://github.com/feross/safe-buffer/issues" }, @@ -36,7 +38,7 @@ "deprecated": false, "description": "Safer Node.js Buffer API", "devDependencies": { - "standard": "^7.0.0", + "standard": "*", "tape": "^4.0.0", "zuul": "^3.0.0" }, @@ -60,5 +62,5 @@ "scripts": { "test": "standard && tape test.js" }, - "version": "5.0.1" + "version": "5.1.0" } diff --git a/deps/npm/node_modules/safe-buffer/test.js b/deps/npm/node_modules/safe-buffer/test.js index 7da8ad761ee720..4925059c5c592d 100644 --- a/deps/npm/node_modules/safe-buffer/test.js +++ b/deps/npm/node_modules/safe-buffer/test.js @@ -1,3 +1,5 @@ +/* eslint-disable node/no-deprecated-api */ + var test = require('tape') var SafeBuffer = require('./').Buffer diff --git a/deps/npm/node_modules/ssri/CHANGELOG.md b/deps/npm/node_modules/ssri/CHANGELOG.md index 46a0093e00c366..c03bb4174eff96 100644 --- a/deps/npm/node_modules/ssri/CHANGELOG.md +++ b/deps/npm/node_modules/ssri/CHANGELOG.md @@ -2,6 +2,26 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. + +## [4.1.5](https://github.com/zkat/ssri/compare/v4.1.4...v4.1.5) (2017-06-05) + + +### Bug Fixes + +* **integrityStream:** stop crashing if opts.algorithms and opts.integrity have an algo mismatch ([fb1293e](https://github.com/zkat/ssri/commit/fb1293e)) + + + + +## [4.1.4](https://github.com/zkat/ssri/compare/v4.1.3...v4.1.4) (2017-05-31) + + +### Bug Fixes + +* **node:** older versions of node[@4](https://github.com/4) do not support base64buffer string parsing ([513df4e](https://github.com/zkat/ssri/commit/513df4e)) + + + ## [4.1.3](https://github.com/zkat/ssri/compare/v4.1.2...v4.1.3) (2017-05-24) diff --git a/deps/npm/node_modules/ssri/index.js b/deps/npm/node_modules/ssri/index.js index f01986fa51b1bb..6ec0d73df6bab8 100644 --- a/deps/npm/node_modules/ssri/index.js +++ b/deps/npm/node_modules/ssri/index.js @@ -1,5 +1,7 @@ 'use strict' +const Buffer = require('safe-buffer').Buffer + const crypto = require('crypto') const Transform = require('stream').Transform @@ -31,7 +33,7 @@ class Hash { this.options = rawOpts ? rawOpts.slice(1).split('?') : [] } hexDigest () { - return this.digest && bufFrom(this.digest, 'base64').toString('hex') + return this.digest && Buffer.from(this.digest, 'base64').toString('hex') } toJSON () { return this.toString() @@ -154,7 +156,7 @@ function fromHex (hexDigest, algorithm, opts) { : '' return parse( `${algorithm}-${ - bufFrom(hexDigest, 'hex').toString('base64') + Buffer.from(hexDigest, 'hex').toString('base64') }${optString}`, opts ) } @@ -257,6 +259,7 @@ function integrityStream (opts) { const match = ( // Integrity verification mode opts.integrity && + newSri[algorithm] && digests && digests.find(hash => { return newSri[algorithm].find(newhash => { @@ -332,7 +335,3 @@ function getPrioritizedHash (algo1, algo2) { ? algo1 : algo2 } - -function bufFrom (data, enc) { - return Buffer.from ? Buffer.from(data, enc) : new Buffer(data, enc) -} diff --git a/deps/npm/node_modules/ssri/package.json b/deps/npm/node_modules/ssri/package.json index fae62d7c52961c..b004400f3801be 100644 --- a/deps/npm/node_modules/ssri/package.json +++ b/deps/npm/node_modules/ssri/package.json @@ -1,19 +1,19 @@ { - "_from": "ssri@4.1.3", - "_id": "ssri@4.1.3", + "_from": "ssri@4.1.5", + "_id": "ssri@4.1.5", "_inBundle": false, - "_integrity": "sha512-vDXK4C5lxEMlMXyUvsaNAqyYkoMaScW8r6jUTg3uwUOMnvbMmNRSw3Cal0iiWHtMsQxga7NG4GShS0CKt3Pt1w==", + "_integrity": "sha512-TaLitc/pZH1UF8LCgZWdbssPiOUcPjBmIJsYJa+YltP77mY2qQ0Y2b+VS4C9RbZRH1GPMt4zckqqBd7GE/61ew==", "_location": "/ssri", "_phantomChildren": {}, "_requested": { "type": "version", "registry": true, - "raw": "ssri@4.1.3", + "raw": "ssri@4.1.5", "name": "ssri", "escapedName": "ssri", - "rawSpec": "4.1.3", + "rawSpec": "4.1.5", "saveSpec": null, - "fetchSpec": "4.1.3" + "fetchSpec": "4.1.5" }, "_requiredBy": [ "#USER", @@ -23,9 +23,9 @@ "/pacote", "/pacote/make-fetch-happen" ], - "_resolved": "https://registry.npmjs.org/ssri/-/ssri-4.1.3.tgz", - "_shasum": "ec8b5585cbfc726a5f9aad829efce238de831935", - "_spec": "ssri@4.1.3", + "_resolved": "https://registry.npmjs.org/ssri/-/ssri-4.1.5.tgz", + "_shasum": "e3844770b5379ced69b512e70a28d86d86abd43a", + "_spec": "ssri@4.1.5", "_where": "/Users/zkat/Documents/code/npm", "author": { "name": "Kat Marchán", @@ -43,7 +43,9 @@ ] } }, - "dependencies": {}, + "dependencies": { + "safe-buffer": "^5.0.1" + }, "deprecated": false, "description": "Standard Subresource Integrity library -- parses, serializes, generates, and verifies integrity metadata according to the SRI spec.", "devDependencies": { @@ -88,5 +90,5 @@ "update-coc": "weallbehave -o . && git add CODE_OF_CONDUCT.md && git commit -m 'docs(coc): updated CODE_OF_CONDUCT.md'", "update-contrib": "weallcontribute -o . && git add CONTRIBUTING.md && git commit -m 'docs(contributing): updated CONTRIBUTING.md'" }, - "version": "4.1.3" + "version": "4.1.5" } diff --git a/deps/npm/package.json b/deps/npm/package.json index 3bb9001de010d1..ba61cdda81ef13 100644 --- a/deps/npm/package.json +++ b/deps/npm/package.json @@ -1,5 +1,5 @@ { - "version": "5.0.0", + "version": "5.0.3", "name": "npm", "description": "a package manager for JavaScript", "keywords": [ @@ -35,10 +35,10 @@ "ansi-regex": "~2.1.1", "ansicolors": "~0.3.2", "ansistyles": "~0.1.3", - "aproba": "~1.1.1", + "aproba": "~1.1.2", "archy": "~1.0.0", "bluebird": "~3.5.0", - "cacache": "~9.2.5", + "cacache": "~9.2.8", "call-limit": "~1.1.0", "chownr": "~1.0.1", "cmd-shim": "~2.0.2", @@ -71,37 +71,37 @@ "mississippi": "~1.3.0", "mkdirp": "~0.5.1", "move-concurrently": "~1.0.1", - "node-gyp": "~3.6.1", + "node-gyp": "~3.6.2", "nopt": "~4.0.1", "normalize-package-data": "~2.3.8", "npm-cache-filename": "~1.0.2", "npm-install-checks": "~3.0.0", - "npm-package-arg": "~5.0.1", + "npm-package-arg": "~5.1.1", "npm-registry-client": "~8.3.0", - "npm-user-validate": "~0.1.5", + "npm-user-validate": "~1.0.0", "npmlog": "~4.1.0", "once": "~1.4.0", "opener": "~1.4.3", "osenv": "~0.1.4", - "pacote": "~2.7.21", + "pacote": "~2.7.30", "path-is-inside": "~1.0.2", "promise-inflight": "~1.0.1", "read": "~1.0.7", "read-cmd-shim": "~1.0.1", "read-installed": "~4.0.3", "read-package-json": "~2.0.5", - "read-package-tree": "~5.1.5", - "readable-stream": "~2.2.9", + "read-package-tree": "~5.1.6", + "readable-stream": "~2.2.10", "request": "~2.81.0", "retry": "~0.10.1", "rimraf": "~2.6.1", - "safe-buffer": "~5.0.1", + "safe-buffer": "~5.1.0", "semver": "~5.3.0", "sha": "~2.0.1", "slide": "~1.1.6", "sorted-object": "~2.0.1", "sorted-union-stream": "~2.1.3", - "ssri": "~4.1.3", + "ssri": "~4.1.5", "strip-ansi": "~3.0.1", "tar": "~2.2.1", "text-table": "~0.2.0", diff --git a/deps/npm/test/tap/prepublish.js b/deps/npm/test/tap/prepublish.js index 18bfe5f22aa0ba..c71455a2480cca 100644 --- a/deps/npm/test/tap/prepublish.js +++ b/deps/npm/test/tap/prepublish.js @@ -94,7 +94,7 @@ test('prepublish deprecation warning on `npm install`', function (t) { t.equal(code, 0, 'pack finished successfully') t.ifErr(err, 'pack finished successfully') - t.match(stderr, /`prepublish` scripts will run only for `npm publish`/) + t.match(stderr, /`prepublish` scripts are deprecated/) var c = stdout.trim() var regex = new RegExp('' + '> npm-test-prepublish@1.2.5 prepublish [^\\r\\n]+\\r?\\n' + diff --git a/deps/npm/test/tap/publish-config.js b/deps/npm/test/tap/publish-config.js index 399fd0f93b42b0..fb430af2101820 100644 --- a/deps/npm/test/tap/publish-config.js +++ b/deps/npm/test/tap/publish-config.js @@ -1,36 +1,43 @@ -var common = require('../common-tap.js') -var test = require('tap').test -var fs = require('fs') -var osenv = require('osenv') -var pkg = process.env.npm_config_tmp || '/tmp' -pkg += '/npm-test-publish-config' +'use strict' + +const common = require('../common-tap.js') +const test = require('tap').test +const fs = require('fs') +const osenv = require('osenv') +const pkg = `${process.env.npm_config_tmp || '/tmp'}/npm-test-publish-config` require('mkdirp').sync(pkg) fs.writeFileSync(pkg + '/package.json', JSON.stringify({ name: 'npm-test-publish-config', version: '1.2.3', - publishConfig: { registry: common.registry } + publishConfig: { + registry: common.registry + } }), 'utf8') fs.writeFileSync(pkg + '/fixture_npmrc', '//localhost:1337/:email = fancy@feast.net\n' + '//localhost:1337/:username = fancy\n' + - '//localhost:1337/:_password = ' + new Buffer('feast').toString('base64') + '\n' + - 'registry = http://localhost:1337/') + '//localhost:1337/:_password = ' + new Buffer('feast').toString('base64')) test(function (t) { - var child - t.plan(4) + let child + t.plan(5) require('http').createServer(function (req, res) { t.pass('got request on the fakey fake registry') - this.close() - res.statusCode = 500 - res.end(JSON.stringify({ - error: 'sshhh. naptime nao. \\^O^/ <(YAWWWWN!)' - })) - child.kill('SIGINT') - }).listen(common.port, function () { + let body = '' + req.on('data', (d) => { body += d }) + req.on('end', () => { + this.close() + res.statusCode = 500 + res.end(JSON.stringify({ + error: 'sshhh. naptime nao. \\^O^/ <(YAWWWWN!)' + })) + t.match(body, /"beta"/, 'got expected tag') + child.kill('SIGINT') + }) + }).listen(common.port, () => { t.pass('server is listening') // don't much care about listening to the child's results @@ -40,7 +47,7 @@ test(function (t) { // itself functions normally. // // Make sure that we don't sit around waiting for lock files - child = common.npm(['publish', '--userconfig=' + pkg + '/fixture_npmrc'], { + child = common.npm(['publish', '--userconfig=' + pkg + '/fixture_npmrc', '--tag=beta'], { cwd: pkg, stdio: 'inherit', env: { diff --git a/deps/openssl/asm/arm-void-gas/aes/bsaes-armv7.S b/deps/openssl/asm/arm-void-gas/aes/bsaes-armv7.S index 449e7a442e87ce..b21ed7078b194a 100644 --- a/deps/openssl/asm/arm-void-gas/aes/bsaes-armv7.S +++ b/deps/openssl/asm/arm-void-gas/aes/bsaes-armv7.S @@ -1298,7 +1298,7 @@ bsaes_cbc_encrypt: vmov q4,q15 @ just in case ensure that IV vmov q5,q0 @ and input are preserved bl AES_decrypt - vld1.8 {q0}, [r9,:64] @ load result + vld1.8 {q0}, [r9] @ load result veor q0, q0, q4 @ ^= IV vmov q15, q5 @ q5 holds input vst1.8 {q0}, [r10] @ write output diff --git a/deps/openssl/asm/x64-elf-gas/aes/aesni-sha1-x86_64.s b/deps/openssl/asm/x64-elf-gas/aes/aesni-sha1-x86_64.s index 88042248685372..c7c53e8771e132 100644 --- a/deps/openssl/asm/x64-elf-gas/aes/aesni-sha1-x86_64.s +++ b/deps/openssl/asm/x64-elf-gas/aes/aesni-sha1-x86_64.s @@ -2692,6 +2692,7 @@ aesni_cbc_sha1_enc_shaext: movl 240(%rcx),%r11d subq %rdi,%rsi movups (%rcx),%xmm15 + movups (%r8),%xmm2 movups 16(%rcx),%xmm0 leaq 112(%rcx),%rcx diff --git a/deps/openssl/asm/x64-elf-gas/aes/aesni-sha256-x86_64.s b/deps/openssl/asm/x64-elf-gas/aes/aesni-sha256-x86_64.s index 139ebe3615c46c..70eed05b00c136 100644 --- a/deps/openssl/asm/x64-elf-gas/aes/aesni-sha256-x86_64.s +++ b/deps/openssl/asm/x64-elf-gas/aes/aesni-sha256-x86_64.s @@ -4012,6 +4012,7 @@ aesni_cbc_sha256_enc_shaext: movl 240(%rcx),%r11d subq %rdi,%rsi movups (%rcx),%xmm15 + movups (%r8),%xmm6 movups 16(%rcx),%xmm4 leaq 112(%rcx),%rcx diff --git a/deps/openssl/asm/x64-elf-gas/x86_64cpuid.s b/deps/openssl/asm/x64-elf-gas/x86_64cpuid.s index 0e81a290e3ec09..06d11dc9c8e95e 100644 --- a/deps/openssl/asm/x64-elf-gas/x86_64cpuid.s +++ b/deps/openssl/asm/x64-elf-gas/x86_64cpuid.s @@ -107,14 +107,6 @@ OPENSSL_ia32_cpuid: shrl $14,%r10d andl $0xfff,%r10d - cmpl $7,%r11d - jb .Lnocacheinfo - - movl $7,%eax - xorl %ecx,%ecx - cpuid - movl %ebx,8(%rdi) - .Lnocacheinfo: movl $1,%eax cpuid @@ -144,6 +136,15 @@ OPENSSL_ia32_cpuid: orl %ecx,%r9d movl %edx,%r10d + + cmpl $7,%r11d + jb .Lno_extended_info + movl $7,%eax + xorl %ecx,%ecx + cpuid + movl %ebx,8(%rdi) +.Lno_extended_info: + btl $27,%r9d jnc .Lclear_avx xorl %ecx,%ecx diff --git a/deps/openssl/asm/x64-macosx-gas/aes/aesni-sha1-x86_64.s b/deps/openssl/asm/x64-macosx-gas/aes/aesni-sha1-x86_64.s index c7606aec49a95b..cdce52cd0a2358 100644 --- a/deps/openssl/asm/x64-macosx-gas/aes/aesni-sha1-x86_64.s +++ b/deps/openssl/asm/x64-macosx-gas/aes/aesni-sha1-x86_64.s @@ -2692,6 +2692,7 @@ aesni_cbc_sha1_enc_shaext: movl 240(%rcx),%r11d subq %rdi,%rsi movups (%rcx),%xmm15 + movups (%r8),%xmm2 movups 16(%rcx),%xmm0 leaq 112(%rcx),%rcx diff --git a/deps/openssl/asm/x64-macosx-gas/aes/aesni-sha256-x86_64.s b/deps/openssl/asm/x64-macosx-gas/aes/aesni-sha256-x86_64.s index 89faf46249a9b9..40e75bfedb6d3a 100644 --- a/deps/openssl/asm/x64-macosx-gas/aes/aesni-sha256-x86_64.s +++ b/deps/openssl/asm/x64-macosx-gas/aes/aesni-sha256-x86_64.s @@ -4012,6 +4012,7 @@ aesni_cbc_sha256_enc_shaext: movl 240(%rcx),%r11d subq %rdi,%rsi movups (%rcx),%xmm15 + movups (%r8),%xmm6 movups 16(%rcx),%xmm4 leaq 112(%rcx),%rcx diff --git a/deps/openssl/asm/x64-macosx-gas/x86_64cpuid.s b/deps/openssl/asm/x64-macosx-gas/x86_64cpuid.s index ef623d5967716c..909270ecae312b 100644 --- a/deps/openssl/asm/x64-macosx-gas/x86_64cpuid.s +++ b/deps/openssl/asm/x64-macosx-gas/x86_64cpuid.s @@ -108,14 +108,6 @@ L$intel: shrl $14,%r10d andl $0xfff,%r10d - cmpl $7,%r11d - jb L$nocacheinfo - - movl $7,%eax - xorl %ecx,%ecx - cpuid - movl %ebx,8(%rdi) - L$nocacheinfo: movl $1,%eax cpuid @@ -145,6 +137,15 @@ L$generic: orl %ecx,%r9d movl %edx,%r10d + + cmpl $7,%r11d + jb L$no_extended_info + movl $7,%eax + xorl %ecx,%ecx + cpuid + movl %ebx,8(%rdi) +L$no_extended_info: + btl $27,%r9d jnc L$clear_avx xorl %ecx,%ecx diff --git a/deps/openssl/asm/x64-win32-masm/aes/aesni-sha1-x86_64.asm b/deps/openssl/asm/x64-win32-masm/aes/aesni-sha1-x86_64.asm index 7403dc3ee6bac1..5a2c8e0eb52b0b 100644 --- a/deps/openssl/asm/x64-win32-masm/aes/aesni-sha1-x86_64.asm +++ b/deps/openssl/asm/x64-win32-masm/aes/aesni-sha1-x86_64.asm @@ -2793,6 +2793,7 @@ $L$prologue_shaext:: mov r11d,DWORD PTR[240+rcx] sub rsi,rdi movups xmm15,XMMWORD PTR[rcx] + movups xmm2,XMMWORD PTR[r8] movups xmm0,XMMWORD PTR[16+rcx] lea rcx,QWORD PTR[112+rcx] diff --git a/deps/openssl/asm/x64-win32-masm/aes/aesni-sha256-x86_64.asm b/deps/openssl/asm/x64-win32-masm/aes/aesni-sha256-x86_64.asm index 4fe9772a0f5e26..d697869bb25b71 100644 --- a/deps/openssl/asm/x64-win32-masm/aes/aesni-sha256-x86_64.asm +++ b/deps/openssl/asm/x64-win32-masm/aes/aesni-sha256-x86_64.asm @@ -4146,6 +4146,7 @@ $L$prologue_shaext:: mov r11d,DWORD PTR[240+rcx] sub rsi,rdi movups xmm15,XMMWORD PTR[rcx] + movups xmm6,XMMWORD PTR[r8] movups xmm4,XMMWORD PTR[16+rcx] lea rcx,QWORD PTR[112+rcx] diff --git a/deps/openssl/asm/x64-win32-masm/x86_64cpuid.asm b/deps/openssl/asm/x64-win32-masm/x86_64cpuid.asm index c767b91f9a7cd1..6cb8077b9da0a5 100644 --- a/deps/openssl/asm/x64-win32-masm/x86_64cpuid.asm +++ b/deps/openssl/asm/x64-win32-masm/x86_64cpuid.asm @@ -118,14 +118,6 @@ $L$intel:: shr r10d,14 and r10d,0fffh - cmp r11d,7 - jb $L$nocacheinfo - - mov eax,7 - xor ecx,ecx - cpuid - mov DWORD PTR[8+rdi],ebx - $L$nocacheinfo:: mov eax,1 cpuid @@ -155,6 +147,15 @@ $L$generic:: or r9d,ecx mov r10d,edx + + cmp r11d,7 + jb $L$no_extended_info + mov eax,7 + xor ecx,ecx + cpuid + mov DWORD PTR[8+rdi],ebx +$L$no_extended_info:: + bt r9d,27 jnc $L$clear_avx xor ecx,ecx diff --git a/deps/openssl/asm/x86-elf-gas/x86cpuid.s b/deps/openssl/asm/x86-elf-gas/x86cpuid.s index 80a4d1a5183adf..08369b42391d75 100644 --- a/deps/openssl/asm/x86-elf-gas/x86cpuid.s +++ b/deps/openssl/asm/x86-elf-gas/x86cpuid.s @@ -20,10 +20,10 @@ OPENSSL_ia32_cpuid: popl %eax xorl %eax,%ecx xorl %eax,%eax - btl $21,%ecx - jnc .L000nocpuid movl 20(%esp),%esi movl %eax,8(%esi) + btl $21,%ecx + jnc .L000nocpuid .byte 0x0f,0xa2 movl %eax,%edi xorl %eax,%eax @@ -74,40 +74,32 @@ OPENSSL_ia32_cpuid: andl $4026531839,%edx jmp .L002generic .L001intel: - cmpl $7,%edi - jb .L003cacheinfo - movl 20(%esp),%esi - movl $7,%eax - xorl %ecx,%ecx - .byte 0x0f,0xa2 - movl %ebx,8(%esi) -.L003cacheinfo: cmpl $4,%edi - movl $-1,%edi - jb .L004nocacheinfo + movl $-1,%esi + jb .L003nocacheinfo movl $4,%eax movl $0,%ecx .byte 0x0f,0xa2 - movl %eax,%edi - shrl $14,%edi - andl $4095,%edi -.L004nocacheinfo: + movl %eax,%esi + shrl $14,%esi + andl $4095,%esi +.L003nocacheinfo: movl $1,%eax xorl %ecx,%ecx .byte 0x0f,0xa2 andl $3220176895,%edx cmpl $0,%ebp - jne .L005notintel + jne .L004notintel orl $1073741824,%edx andb $15,%ah cmpb $15,%ah - jne .L005notintel + jne .L004notintel orl $1048576,%edx -.L005notintel: +.L004notintel: btl $28,%edx jnc .L002generic andl $4026531839,%edx - cmpl $0,%edi + cmpl $0,%esi je .L002generic orl $268435456,%edx shrl $16,%ebx @@ -119,7 +111,15 @@ OPENSSL_ia32_cpuid: andl $4294965247,%ecx movl %edx,%esi orl %ecx,%ebp - btl $27,%ecx + cmpl $7,%edi + movl 20(%esp),%edi + jb .L005no_extended_info + movl $7,%eax + xorl %ecx,%ecx + .byte 0x0f,0xa2 + movl %ebx,8(%edi) +.L005no_extended_info: + btl $27,%ebp jnc .L006clear_avx xorl %ecx,%ecx .byte 15,1,208 @@ -133,7 +133,6 @@ OPENSSL_ia32_cpuid: andl $4278190079,%esi .L006clear_avx: andl $4026525695,%ebp - movl 20(%esp),%edi andl $4294967263,8(%edi) .L007done: movl %esi,%eax diff --git a/deps/openssl/asm/x86-macosx-gas/x86cpuid.s b/deps/openssl/asm/x86-macosx-gas/x86cpuid.s index 3db70b61139e72..c3e9fd6dbaf05b 100644 --- a/deps/openssl/asm/x86-macosx-gas/x86cpuid.s +++ b/deps/openssl/asm/x86-macosx-gas/x86cpuid.s @@ -19,10 +19,10 @@ L_OPENSSL_ia32_cpuid_begin: popl %eax xorl %eax,%ecx xorl %eax,%eax - btl $21,%ecx - jnc L000nocpuid movl 20(%esp),%esi movl %eax,8(%esi) + btl $21,%ecx + jnc L000nocpuid .byte 0x0f,0xa2 movl %eax,%edi xorl %eax,%eax @@ -73,40 +73,32 @@ L_OPENSSL_ia32_cpuid_begin: andl $4026531839,%edx jmp L002generic L001intel: - cmpl $7,%edi - jb L003cacheinfo - movl 20(%esp),%esi - movl $7,%eax - xorl %ecx,%ecx - .byte 0x0f,0xa2 - movl %ebx,8(%esi) -L003cacheinfo: cmpl $4,%edi - movl $-1,%edi - jb L004nocacheinfo + movl $-1,%esi + jb L003nocacheinfo movl $4,%eax movl $0,%ecx .byte 0x0f,0xa2 - movl %eax,%edi - shrl $14,%edi - andl $4095,%edi -L004nocacheinfo: + movl %eax,%esi + shrl $14,%esi + andl $4095,%esi +L003nocacheinfo: movl $1,%eax xorl %ecx,%ecx .byte 0x0f,0xa2 andl $3220176895,%edx cmpl $0,%ebp - jne L005notintel + jne L004notintel orl $1073741824,%edx andb $15,%ah cmpb $15,%ah - jne L005notintel + jne L004notintel orl $1048576,%edx -L005notintel: +L004notintel: btl $28,%edx jnc L002generic andl $4026531839,%edx - cmpl $0,%edi + cmpl $0,%esi je L002generic orl $268435456,%edx shrl $16,%ebx @@ -118,7 +110,15 @@ L002generic: andl $4294965247,%ecx movl %edx,%esi orl %ecx,%ebp - btl $27,%ecx + cmpl $7,%edi + movl 20(%esp),%edi + jb L005no_extended_info + movl $7,%eax + xorl %ecx,%ecx + .byte 0x0f,0xa2 + movl %ebx,8(%edi) +L005no_extended_info: + btl $27,%ebp jnc L006clear_avx xorl %ecx,%ecx .byte 15,1,208 @@ -132,7 +132,6 @@ L008clear_xmm: andl $4278190079,%esi L006clear_avx: andl $4026525695,%ebp - movl 20(%esp),%edi andl $4294967263,8(%edi) L007done: movl %esi,%eax diff --git a/deps/openssl/asm/x86-win32-masm/x86cpuid.asm b/deps/openssl/asm/x86-win32-masm/x86cpuid.asm index b4462fc2aa72bd..d53b6a44d895a3 100644 --- a/deps/openssl/asm/x86-win32-masm/x86cpuid.asm +++ b/deps/openssl/asm/x86-win32-masm/x86cpuid.asm @@ -35,10 +35,10 @@ $L_OPENSSL_ia32_cpuid_begin:: pop eax xor ecx,eax xor eax,eax - bt ecx,21 - jnc $L000nocpuid mov esi,DWORD PTR 20[esp] mov DWORD PTR 8[esi],eax + bt ecx,21 + jnc $L000nocpuid cpuid mov edi,eax xor eax,eax @@ -89,40 +89,32 @@ $L_OPENSSL_ia32_cpuid_begin:: and edx,4026531839 jmp $L002generic $L001intel: - cmp edi,7 - jb $L003cacheinfo - mov esi,DWORD PTR 20[esp] - mov eax,7 - xor ecx,ecx - cpuid - mov DWORD PTR 8[esi],ebx -$L003cacheinfo: cmp edi,4 - mov edi,-1 - jb $L004nocacheinfo + mov esi,-1 + jb $L003nocacheinfo mov eax,4 mov ecx,0 cpuid - mov edi,eax - shr edi,14 - and edi,4095 -$L004nocacheinfo: + mov esi,eax + shr esi,14 + and esi,4095 +$L003nocacheinfo: mov eax,1 xor ecx,ecx cpuid and edx,3220176895 cmp ebp,0 - jne $L005notintel + jne $L004notintel or edx,1073741824 and ah,15 cmp ah,15 - jne $L005notintel + jne $L004notintel or edx,1048576 -$L005notintel: +$L004notintel: bt edx,28 jnc $L002generic and edx,4026531839 - cmp edi,0 + cmp esi,0 je $L002generic or edx,268435456 shr ebx,16 @@ -134,7 +126,15 @@ $L002generic: and ecx,4294965247 mov esi,edx or ebp,ecx - bt ecx,27 + cmp edi,7 + mov edi,DWORD PTR 20[esp] + jb $L005no_extended_info + mov eax,7 + xor ecx,ecx + cpuid + mov DWORD PTR 8[edi],ebx +$L005no_extended_info: + bt ebp,27 jnc $L006clear_avx xor ecx,ecx DB 15,1,208 @@ -148,7 +148,6 @@ $L008clear_xmm: and esi,4278190079 $L006clear_avx: and ebp,4026525695 - mov edi,DWORD PTR 20[esp] and DWORD PTR 8[edi],4294967263 $L007done: mov eax,esi diff --git a/deps/openssl/asm_obsolete/arm-void-gas/aes/bsaes-armv7.S b/deps/openssl/asm_obsolete/arm-void-gas/aes/bsaes-armv7.S index 449e7a442e87ce..b21ed7078b194a 100644 --- a/deps/openssl/asm_obsolete/arm-void-gas/aes/bsaes-armv7.S +++ b/deps/openssl/asm_obsolete/arm-void-gas/aes/bsaes-armv7.S @@ -1298,7 +1298,7 @@ bsaes_cbc_encrypt: vmov q4,q15 @ just in case ensure that IV vmov q5,q0 @ and input are preserved bl AES_decrypt - vld1.8 {q0}, [r9,:64] @ load result + vld1.8 {q0}, [r9] @ load result veor q0, q0, q4 @ ^= IV vmov q15, q5 @ q5 holds input vst1.8 {q0}, [r10] @ write output diff --git a/deps/openssl/asm_obsolete/x64-elf-gas/aes/aesni-sha1-x86_64.s b/deps/openssl/asm_obsolete/x64-elf-gas/aes/aesni-sha1-x86_64.s index d4ed2047c6db9c..84c5dced020b22 100644 --- a/deps/openssl/asm_obsolete/x64-elf-gas/aes/aesni-sha1-x86_64.s +++ b/deps/openssl/asm_obsolete/x64-elf-gas/aes/aesni-sha1-x86_64.s @@ -1389,6 +1389,7 @@ aesni_cbc_sha1_enc_shaext: movl 240(%rcx),%r11d subq %rdi,%rsi movups (%rcx),%xmm15 + movups (%r8),%xmm2 movups 16(%rcx),%xmm0 leaq 112(%rcx),%rcx diff --git a/deps/openssl/asm_obsolete/x64-elf-gas/x86_64cpuid.s b/deps/openssl/asm_obsolete/x64-elf-gas/x86_64cpuid.s index 0e81a290e3ec09..06d11dc9c8e95e 100644 --- a/deps/openssl/asm_obsolete/x64-elf-gas/x86_64cpuid.s +++ b/deps/openssl/asm_obsolete/x64-elf-gas/x86_64cpuid.s @@ -107,14 +107,6 @@ OPENSSL_ia32_cpuid: shrl $14,%r10d andl $0xfff,%r10d - cmpl $7,%r11d - jb .Lnocacheinfo - - movl $7,%eax - xorl %ecx,%ecx - cpuid - movl %ebx,8(%rdi) - .Lnocacheinfo: movl $1,%eax cpuid @@ -144,6 +136,15 @@ OPENSSL_ia32_cpuid: orl %ecx,%r9d movl %edx,%r10d + + cmpl $7,%r11d + jb .Lno_extended_info + movl $7,%eax + xorl %ecx,%ecx + cpuid + movl %ebx,8(%rdi) +.Lno_extended_info: + btl $27,%r9d jnc .Lclear_avx xorl %ecx,%ecx diff --git a/deps/openssl/asm_obsolete/x64-macosx-gas/aes/aesni-sha1-x86_64.s b/deps/openssl/asm_obsolete/x64-macosx-gas/aes/aesni-sha1-x86_64.s index 015db5faa7facd..8cd95238b020d7 100644 --- a/deps/openssl/asm_obsolete/x64-macosx-gas/aes/aesni-sha1-x86_64.s +++ b/deps/openssl/asm_obsolete/x64-macosx-gas/aes/aesni-sha1-x86_64.s @@ -1389,6 +1389,7 @@ aesni_cbc_sha1_enc_shaext: movl 240(%rcx),%r11d subq %rdi,%rsi movups (%rcx),%xmm15 + movups (%r8),%xmm2 movups 16(%rcx),%xmm0 leaq 112(%rcx),%rcx diff --git a/deps/openssl/asm_obsolete/x64-macosx-gas/x86_64cpuid.s b/deps/openssl/asm_obsolete/x64-macosx-gas/x86_64cpuid.s index ef623d5967716c..909270ecae312b 100644 --- a/deps/openssl/asm_obsolete/x64-macosx-gas/x86_64cpuid.s +++ b/deps/openssl/asm_obsolete/x64-macosx-gas/x86_64cpuid.s @@ -108,14 +108,6 @@ L$intel: shrl $14,%r10d andl $0xfff,%r10d - cmpl $7,%r11d - jb L$nocacheinfo - - movl $7,%eax - xorl %ecx,%ecx - cpuid - movl %ebx,8(%rdi) - L$nocacheinfo: movl $1,%eax cpuid @@ -145,6 +137,15 @@ L$generic: orl %ecx,%r9d movl %edx,%r10d + + cmpl $7,%r11d + jb L$no_extended_info + movl $7,%eax + xorl %ecx,%ecx + cpuid + movl %ebx,8(%rdi) +L$no_extended_info: + btl $27,%r9d jnc L$clear_avx xorl %ecx,%ecx diff --git a/deps/openssl/asm_obsolete/x64-win32-masm/aes/aesni-sha1-x86_64.asm b/deps/openssl/asm_obsolete/x64-win32-masm/aes/aesni-sha1-x86_64.asm index bfc5fa17b4aa70..dbad8c5e233db6 100644 --- a/deps/openssl/asm_obsolete/x64-win32-masm/aes/aesni-sha1-x86_64.asm +++ b/deps/openssl/asm_obsolete/x64-win32-masm/aes/aesni-sha1-x86_64.asm @@ -1454,6 +1454,7 @@ $L$prologue_shaext:: mov r11d,DWORD PTR[240+rcx] sub rsi,rdi movups xmm15,XMMWORD PTR[rcx] + movups xmm2,XMMWORD PTR[r8] movups xmm0,XMMWORD PTR[16+rcx] lea rcx,QWORD PTR[112+rcx] diff --git a/deps/openssl/asm_obsolete/x64-win32-masm/x86_64cpuid.asm b/deps/openssl/asm_obsolete/x64-win32-masm/x86_64cpuid.asm index c767b91f9a7cd1..6cb8077b9da0a5 100644 --- a/deps/openssl/asm_obsolete/x64-win32-masm/x86_64cpuid.asm +++ b/deps/openssl/asm_obsolete/x64-win32-masm/x86_64cpuid.asm @@ -118,14 +118,6 @@ $L$intel:: shr r10d,14 and r10d,0fffh - cmp r11d,7 - jb $L$nocacheinfo - - mov eax,7 - xor ecx,ecx - cpuid - mov DWORD PTR[8+rdi],ebx - $L$nocacheinfo:: mov eax,1 cpuid @@ -155,6 +147,15 @@ $L$generic:: or r9d,ecx mov r10d,edx + + cmp r11d,7 + jb $L$no_extended_info + mov eax,7 + xor ecx,ecx + cpuid + mov DWORD PTR[8+rdi],ebx +$L$no_extended_info:: + bt r9d,27 jnc $L$clear_avx xor ecx,ecx diff --git a/deps/openssl/asm_obsolete/x86-elf-gas/x86cpuid.s b/deps/openssl/asm_obsolete/x86-elf-gas/x86cpuid.s index 80a4d1a5183adf..08369b42391d75 100644 --- a/deps/openssl/asm_obsolete/x86-elf-gas/x86cpuid.s +++ b/deps/openssl/asm_obsolete/x86-elf-gas/x86cpuid.s @@ -20,10 +20,10 @@ OPENSSL_ia32_cpuid: popl %eax xorl %eax,%ecx xorl %eax,%eax - btl $21,%ecx - jnc .L000nocpuid movl 20(%esp),%esi movl %eax,8(%esi) + btl $21,%ecx + jnc .L000nocpuid .byte 0x0f,0xa2 movl %eax,%edi xorl %eax,%eax @@ -74,40 +74,32 @@ OPENSSL_ia32_cpuid: andl $4026531839,%edx jmp .L002generic .L001intel: - cmpl $7,%edi - jb .L003cacheinfo - movl 20(%esp),%esi - movl $7,%eax - xorl %ecx,%ecx - .byte 0x0f,0xa2 - movl %ebx,8(%esi) -.L003cacheinfo: cmpl $4,%edi - movl $-1,%edi - jb .L004nocacheinfo + movl $-1,%esi + jb .L003nocacheinfo movl $4,%eax movl $0,%ecx .byte 0x0f,0xa2 - movl %eax,%edi - shrl $14,%edi - andl $4095,%edi -.L004nocacheinfo: + movl %eax,%esi + shrl $14,%esi + andl $4095,%esi +.L003nocacheinfo: movl $1,%eax xorl %ecx,%ecx .byte 0x0f,0xa2 andl $3220176895,%edx cmpl $0,%ebp - jne .L005notintel + jne .L004notintel orl $1073741824,%edx andb $15,%ah cmpb $15,%ah - jne .L005notintel + jne .L004notintel orl $1048576,%edx -.L005notintel: +.L004notintel: btl $28,%edx jnc .L002generic andl $4026531839,%edx - cmpl $0,%edi + cmpl $0,%esi je .L002generic orl $268435456,%edx shrl $16,%ebx @@ -119,7 +111,15 @@ OPENSSL_ia32_cpuid: andl $4294965247,%ecx movl %edx,%esi orl %ecx,%ebp - btl $27,%ecx + cmpl $7,%edi + movl 20(%esp),%edi + jb .L005no_extended_info + movl $7,%eax + xorl %ecx,%ecx + .byte 0x0f,0xa2 + movl %ebx,8(%edi) +.L005no_extended_info: + btl $27,%ebp jnc .L006clear_avx xorl %ecx,%ecx .byte 15,1,208 @@ -133,7 +133,6 @@ OPENSSL_ia32_cpuid: andl $4278190079,%esi .L006clear_avx: andl $4026525695,%ebp - movl 20(%esp),%edi andl $4294967263,8(%edi) .L007done: movl %esi,%eax diff --git a/deps/openssl/asm_obsolete/x86-macosx-gas/x86cpuid.s b/deps/openssl/asm_obsolete/x86-macosx-gas/x86cpuid.s index 3db70b61139e72..c3e9fd6dbaf05b 100644 --- a/deps/openssl/asm_obsolete/x86-macosx-gas/x86cpuid.s +++ b/deps/openssl/asm_obsolete/x86-macosx-gas/x86cpuid.s @@ -19,10 +19,10 @@ L_OPENSSL_ia32_cpuid_begin: popl %eax xorl %eax,%ecx xorl %eax,%eax - btl $21,%ecx - jnc L000nocpuid movl 20(%esp),%esi movl %eax,8(%esi) + btl $21,%ecx + jnc L000nocpuid .byte 0x0f,0xa2 movl %eax,%edi xorl %eax,%eax @@ -73,40 +73,32 @@ L_OPENSSL_ia32_cpuid_begin: andl $4026531839,%edx jmp L002generic L001intel: - cmpl $7,%edi - jb L003cacheinfo - movl 20(%esp),%esi - movl $7,%eax - xorl %ecx,%ecx - .byte 0x0f,0xa2 - movl %ebx,8(%esi) -L003cacheinfo: cmpl $4,%edi - movl $-1,%edi - jb L004nocacheinfo + movl $-1,%esi + jb L003nocacheinfo movl $4,%eax movl $0,%ecx .byte 0x0f,0xa2 - movl %eax,%edi - shrl $14,%edi - andl $4095,%edi -L004nocacheinfo: + movl %eax,%esi + shrl $14,%esi + andl $4095,%esi +L003nocacheinfo: movl $1,%eax xorl %ecx,%ecx .byte 0x0f,0xa2 andl $3220176895,%edx cmpl $0,%ebp - jne L005notintel + jne L004notintel orl $1073741824,%edx andb $15,%ah cmpb $15,%ah - jne L005notintel + jne L004notintel orl $1048576,%edx -L005notintel: +L004notintel: btl $28,%edx jnc L002generic andl $4026531839,%edx - cmpl $0,%edi + cmpl $0,%esi je L002generic orl $268435456,%edx shrl $16,%ebx @@ -118,7 +110,15 @@ L002generic: andl $4294965247,%ecx movl %edx,%esi orl %ecx,%ebp - btl $27,%ecx + cmpl $7,%edi + movl 20(%esp),%edi + jb L005no_extended_info + movl $7,%eax + xorl %ecx,%ecx + .byte 0x0f,0xa2 + movl %ebx,8(%edi) +L005no_extended_info: + btl $27,%ebp jnc L006clear_avx xorl %ecx,%ecx .byte 15,1,208 @@ -132,7 +132,6 @@ L008clear_xmm: andl $4278190079,%esi L006clear_avx: andl $4026525695,%ebp - movl 20(%esp),%edi andl $4294967263,8(%edi) L007done: movl %esi,%eax diff --git a/deps/openssl/asm_obsolete/x86-win32-masm/x86cpuid.asm b/deps/openssl/asm_obsolete/x86-win32-masm/x86cpuid.asm index b4462fc2aa72bd..d53b6a44d895a3 100644 --- a/deps/openssl/asm_obsolete/x86-win32-masm/x86cpuid.asm +++ b/deps/openssl/asm_obsolete/x86-win32-masm/x86cpuid.asm @@ -35,10 +35,10 @@ $L_OPENSSL_ia32_cpuid_begin:: pop eax xor ecx,eax xor eax,eax - bt ecx,21 - jnc $L000nocpuid mov esi,DWORD PTR 20[esp] mov DWORD PTR 8[esi],eax + bt ecx,21 + jnc $L000nocpuid cpuid mov edi,eax xor eax,eax @@ -89,40 +89,32 @@ $L_OPENSSL_ia32_cpuid_begin:: and edx,4026531839 jmp $L002generic $L001intel: - cmp edi,7 - jb $L003cacheinfo - mov esi,DWORD PTR 20[esp] - mov eax,7 - xor ecx,ecx - cpuid - mov DWORD PTR 8[esi],ebx -$L003cacheinfo: cmp edi,4 - mov edi,-1 - jb $L004nocacheinfo + mov esi,-1 + jb $L003nocacheinfo mov eax,4 mov ecx,0 cpuid - mov edi,eax - shr edi,14 - and edi,4095 -$L004nocacheinfo: + mov esi,eax + shr esi,14 + and esi,4095 +$L003nocacheinfo: mov eax,1 xor ecx,ecx cpuid and edx,3220176895 cmp ebp,0 - jne $L005notintel + jne $L004notintel or edx,1073741824 and ah,15 cmp ah,15 - jne $L005notintel + jne $L004notintel or edx,1048576 -$L005notintel: +$L004notintel: bt edx,28 jnc $L002generic and edx,4026531839 - cmp edi,0 + cmp esi,0 je $L002generic or edx,268435456 shr ebx,16 @@ -134,7 +126,15 @@ $L002generic: and ecx,4294965247 mov esi,edx or ebp,ecx - bt ecx,27 + cmp edi,7 + mov edi,DWORD PTR 20[esp] + jb $L005no_extended_info + mov eax,7 + xor ecx,ecx + cpuid + mov DWORD PTR 8[edi],ebx +$L005no_extended_info: + bt ebp,27 jnc $L006clear_avx xor ecx,ecx DB 15,1,208 @@ -148,7 +148,6 @@ $L008clear_xmm: and esi,4278190079 $L006clear_avx: and ebp,4026525695 - mov edi,DWORD PTR 20[esp] and DWORD PTR 8[edi],4294967263 $L007done: mov eax,esi diff --git a/deps/openssl/config/archs/aix-gcc/opensslconf.h b/deps/openssl/config/archs/aix-gcc/opensslconf.h index 0b5a4da2199b20..c647b9485aa624 100644 --- a/deps/openssl/config/archs/aix-gcc/opensslconf.h +++ b/deps/openssl/config/archs/aix-gcc/opensslconf.h @@ -235,7 +235,7 @@ extern "C" { even newer MIPS CPU's, but at the moment one size fits all for optimization options. Older Sparc's work better with only UNROLL, but there's no way to tell at compile time what it is you're running on */ - + #if defined( __sun ) || defined ( sun ) /* Newer Sparc's */ # define DES_PTR # define DES_RISC1 diff --git a/deps/openssl/config/archs/aix64-gcc/opensslconf.h b/deps/openssl/config/archs/aix64-gcc/opensslconf.h index 0cca4cae21dd10..b7632639d750eb 100644 --- a/deps/openssl/config/archs/aix64-gcc/opensslconf.h +++ b/deps/openssl/config/archs/aix64-gcc/opensslconf.h @@ -235,7 +235,7 @@ extern "C" { even newer MIPS CPU's, but at the moment one size fits all for optimization options. Older Sparc's work better with only UNROLL, but there's no way to tell at compile time what it is you're running on */ - + #if defined( __sun ) || defined ( sun ) /* Newer Sparc's */ # define DES_PTR # define DES_RISC1 diff --git a/deps/openssl/config/archs/linux-ppc/opensslconf.h b/deps/openssl/config/archs/linux-ppc/opensslconf.h index e0d62da24e142e..8d7bda716a4b97 100644 --- a/deps/openssl/config/archs/linux-ppc/opensslconf.h +++ b/deps/openssl/config/archs/linux-ppc/opensslconf.h @@ -232,7 +232,7 @@ extern "C" { even newer MIPS CPU's, but at the moment one size fits all for optimization options. Older Sparc's work better with only UNROLL, but there's no way to tell at compile time what it is you're running on */ - + #if defined( __sun ) || defined ( sun ) /* Newer Sparc's */ # define DES_PTR # define DES_RISC1 diff --git a/deps/openssl/config/archs/linux-ppc64/opensslconf.h b/deps/openssl/config/archs/linux-ppc64/opensslconf.h index 3f7202d25427e3..bec911036c26ae 100644 --- a/deps/openssl/config/archs/linux-ppc64/opensslconf.h +++ b/deps/openssl/config/archs/linux-ppc64/opensslconf.h @@ -232,7 +232,7 @@ extern "C" { even newer MIPS CPU's, but at the moment one size fits all for optimization options. Older Sparc's work better with only UNROLL, but there's no way to tell at compile time what it is you're running on */ - + #if defined( __sun ) || defined ( sun ) /* Newer Sparc's */ # define DES_PTR # define DES_RISC1 diff --git a/deps/openssl/config/archs/linux32-s390x/opensslconf.h b/deps/openssl/config/archs/linux32-s390x/opensslconf.h index e0d0f8fa613456..32759db4742fa1 100644 --- a/deps/openssl/config/archs/linux32-s390x/opensslconf.h +++ b/deps/openssl/config/archs/linux32-s390x/opensslconf.h @@ -232,7 +232,7 @@ extern "C" { even newer MIPS CPU's, but at the moment one size fits all for optimization options. Older Sparc's work better with only UNROLL, but there's no way to tell at compile time what it is you're running on */ - + #if defined( __sun ) || defined ( sun ) /* Newer Sparc's */ # define DES_PTR # define DES_RISC1 diff --git a/deps/openssl/config/archs/linux64-s390x/opensslconf.h b/deps/openssl/config/archs/linux64-s390x/opensslconf.h index dbb03486798275..c4865e0b623caa 100644 --- a/deps/openssl/config/archs/linux64-s390x/opensslconf.h +++ b/deps/openssl/config/archs/linux64-s390x/opensslconf.h @@ -232,7 +232,7 @@ extern "C" { even newer MIPS CPU's, but at the moment one size fits all for optimization options. Older Sparc's work better with only UNROLL, but there's no way to tell at compile time what it is you're running on */ - + #if defined( __sun ) || defined ( sun ) /* Newer Sparc's */ # define DES_PTR # define DES_RISC1 diff --git a/deps/openssl/doc/UPGRADING.md b/deps/openssl/doc/UPGRADING.md index 106701864c0eba..fc229f1975776b 100644 --- a/deps/openssl/doc/UPGRADING.md +++ b/deps/openssl/doc/UPGRADING.md @@ -346,6 +346,7 @@ ohtsu@ubuntu:~/github/node/deps/openssl/asm_obsolete$ make clean find . -iname '*.asm' -exec rm "{}" \; find . -iname '*.s' -exec rm "{}" \; find . -iname '*.S' -exec rm "{}" \; +ohtsu@ubuntu:~/github/node/deps/openssl/asm_obsolete$ make ohtsu@ubuntu:~/github/node/deps/openssl$ git status ohtsu@ubuntu:~/github/node/deps/openssl$ git commit asm asm_obsolete ```` @@ -353,6 +354,8 @@ The commit message can be >deps: update openssl asm and asm_obsolete files > ->Regenerate asm files with Makefile and CC=gcc and ASM=gcc where ->gcc-4.8.4. Also asm files in asm_obsolete dir to support old compiler ->and assembler are regenerated without CC and ASM envs. +>Regenerate asm files with Makefile and CC=gcc and ASM=nasm where gcc +>version was 5.4.0 and nasm version was 2.11.08. +> +>Also asm files in asm_obsolete dir to support old compiler and +>assembler are regenerated without CC and ASM envs. diff --git a/deps/openssl/openssl/CHANGES b/deps/openssl/openssl/CHANGES index 95aabc64d05475..307b2ed5e31287 100644 --- a/deps/openssl/openssl/CHANGES +++ b/deps/openssl/openssl/CHANGES @@ -2,6 +2,12 @@ OpenSSL CHANGES _______________ + Changes between 1.0.2k and 1.0.2l [25 May 2017] + + *) Have 'config' recognise 64-bit mingw and choose 'mingw64' as the target + platform rather than 'mingw'. + [Richard Levitte] + Changes between 1.0.2j and 1.0.2k [26 Jan 2017] *) Truncated packet could crash via OOB read diff --git a/deps/openssl/openssl/Configure b/deps/openssl/openssl/Configure index 5da7cadbf3326c..fd7988e2b3d93a 100755 --- a/deps/openssl/openssl/Configure +++ b/deps/openssl/openssl/Configure @@ -109,7 +109,7 @@ my $usage="Usage: Configure [no- ...] [enable- ...] [experimenta # Minimum warning options... any contributions to OpenSSL should at least get # past these. -my $gcc_devteam_warn = "-Wall -pedantic -DPEDANTIC -Wno-long-long -Wsign-compare -Wmissing-prototypes -Wshadow -Wformat -Werror -DCRYPTO_MDEBUG_ALL -DCRYPTO_MDEBUG_ABORT -DREF_CHECK -DOPENSSL_NO_DEPRECATED"; +my $gcc_devteam_warn = "-Wall -pedantic -DPEDANTIC -Wno-long-long -Wsign-compare -Wmissing-prototypes -Wshadow -Wformat -Wundef -Werror -DCRYPTO_MDEBUG_ALL -DCRYPTO_MDEBUG_ABORT -DREF_CHECK -DOPENSSL_NO_DEPRECATED"; # TODO(openssl-team): fix problems and investigate if (at least) the following # warnings can also be enabled: @@ -2041,12 +2041,13 @@ EOF close(OUT); } else { my $make_command = "$make PERL=\'$perl\'"; - my $make_targets = ""; - $make_targets .= " links" if $symlink; - $make_targets .= " depend" if $depflags ne $default_depflags && $make_depend; - $make_targets .= " gentests" if $symlink; - (system $make_command.$make_targets) == 0 or exit $? - if $make_targets ne ""; + my @make_targets = (); + push @make_targets, "links" if $symlink; + push @make_targets, "depend" if $depflags ne $default_depflags && $make_depend; + push @make_targets, "gentests" if $symlink; + foreach my $make_target (@make_targets) { + (system "$make_command $make_target") == 0 or exit $?; + } if ( $perl =~ m@^/@) { &dofile("tools/c_rehash",$perl,'^#!/', '#!%s','^my \$dir;$', 'my $dir = "' . $openssldir . '";', '^my \$prefix;$', 'my $prefix = "' . $prefix . '";'); &dofile("apps/CA.pl",$perl,'^#!/', '#!%s'); @@ -2056,8 +2057,8 @@ EOF &dofile("apps/CA.pl",'/usr/local/bin/perl','^#!/', '#!%s'); } if ($depflags ne $default_depflags && !$make_depend) { - $warn_make_depend++; - } + $warn_make_depend++; + } } # create the ms/version32.rc file if needed diff --git a/deps/openssl/openssl/LICENSE b/deps/openssl/openssl/LICENSE index fb03713dd11115..bdfd985a691b07 100644 --- a/deps/openssl/openssl/LICENSE +++ b/deps/openssl/openssl/LICENSE @@ -2,7 +2,7 @@ LICENSE ISSUES ============== - The OpenSSL toolkit stays under a dual license, i.e. both the conditions of + The OpenSSL toolkit stays under a double license, i.e. both the conditions of the OpenSSL License and the original SSLeay license apply to the toolkit. See below for the actual license texts. Actually both licenses are BSD-style Open Source licenses. In case of any license issues related to OpenSSL @@ -12,7 +12,7 @@ --------------- /* ==================================================================== - * Copyright (c) 1998-2016 The OpenSSL Project. All rights reserved. + * Copyright (c) 1998-2017 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/deps/openssl/openssl/Makefile b/deps/openssl/openssl/Makefile index 0b894ff47f300b..a3d30318f9178d 100644 --- a/deps/openssl/openssl/Makefile +++ b/deps/openssl/openssl/Makefile @@ -4,7 +4,7 @@ ## Makefile for OpenSSL ## -VERSION=1.0.2k +VERSION=1.0.2l MAJOR=1 MINOR=0.2 SHLIB_VERSION_NUMBER=1.0.0 @@ -426,6 +426,14 @@ clean: libclean rm -fr $$i/*; \ done +distclean: clean + -$(RM) `find . -name .git -prune -o -type l -print` + $(RM) apps/CA.pl + $(RM) test/evptests.txt test/newkey.pem test/testkey.pem test/testreq.pem + $(RM) tools/c_rehash + $(RM) crypto/opensslconf.h + $(RM) Makefile Makefile.bak + makefile.one: files $(PERL) util/mk1mf.pl >makefile.one; \ sh util/do_ms.sh diff --git a/deps/openssl/openssl/Makefile.bak b/deps/openssl/openssl/Makefile.bak index 402333e809e51a..ea0d92e4d7db50 100644 --- a/deps/openssl/openssl/Makefile.bak +++ b/deps/openssl/openssl/Makefile.bak @@ -4,7 +4,7 @@ ## Makefile for OpenSSL ## -VERSION=1.0.2k +VERSION=1.0.2l MAJOR=1 MINOR=0.2 SHLIB_VERSION_NUMBER=1.0.0 @@ -426,6 +426,14 @@ clean: libclean rm -fr $$i/*; \ done +distclean: clean + -$(RM) `find . -name .git -prune -o -type l -print` + $(RM) apps/CA.pl + $(RM) test/evptests.txt test/newkey.pem test/testkey.pem test/testreq.pem + $(RM) tools/c_rehash + $(RM) crypto/opensslconf.h + $(RM) Makefile Makefile.bak + makefile.one: files $(PERL) util/mk1mf.pl >makefile.one; \ sh util/do_ms.sh diff --git a/deps/openssl/openssl/Makefile.org b/deps/openssl/openssl/Makefile.org index 61a329b4f20f6e..f51f0a756c3e08 100644 --- a/deps/openssl/openssl/Makefile.org +++ b/deps/openssl/openssl/Makefile.org @@ -424,6 +424,14 @@ clean: libclean rm -fr $$i/*; \ done +distclean: clean + -$(RM) `find . -name .git -prune -o -type l -print` + $(RM) apps/CA.pl + $(RM) test/evptests.txt test/newkey.pem test/testkey.pem test/testreq.pem + $(RM) tools/c_rehash + $(RM) crypto/opensslconf.h + $(RM) Makefile Makefile.bak + makefile.one: files $(PERL) util/mk1mf.pl >makefile.one; \ sh util/do_ms.sh diff --git a/deps/openssl/openssl/NEWS b/deps/openssl/openssl/NEWS index be4a266bac13a4..fd49cedeba4c5c 100644 --- a/deps/openssl/openssl/NEWS +++ b/deps/openssl/openssl/NEWS @@ -5,6 +5,10 @@ This file gives a brief overview of the major changes between each OpenSSL release. For more details please read the CHANGES file. + Major changes between OpenSSL 1.0.2k and OpenSSL 1.0.2l [25 May 2017] + + o config now recognises 64-bit mingw and chooses mingw64 instead of mingw + Major changes between OpenSSL 1.0.2j and OpenSSL 1.0.2k [26 Jan 2017] o Truncated packet could crash via OOB read (CVE-2017-3731) diff --git a/deps/openssl/openssl/README b/deps/openssl/openssl/README index 615d0c6a5dc8f5..4c357d9a836d08 100644 --- a/deps/openssl/openssl/README +++ b/deps/openssl/openssl/README @@ -1,5 +1,5 @@ - OpenSSL 1.0.2k 26 Jan 2017 + OpenSSL 1.0.2l 25 May 2017 Copyright (c) 1998-2015 The OpenSSL Project Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson diff --git a/deps/openssl/openssl/apps/ca.c b/deps/openssl/openssl/apps/ca.c index 4cea3cb7b1cea8..f90f033baed375 100644 --- a/deps/openssl/openssl/apps/ca.c +++ b/deps/openssl/openssl/apps/ca.c @@ -2126,10 +2126,8 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, goto err; } - for (i = 0; i < DB_NUMBER; i++) { + for (i = 0; i < DB_NUMBER; i++) irow[i] = row[i]; - row[i] = NULL; - } irow[DB_NUMBER] = NULL; if (!TXT_DB_insert(db->db, irow)) { @@ -2137,11 +2135,14 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, BIO_printf(bio_err, "TXT_DB error number %ld\n", db->db->error); goto err; } + irow = NULL; ok = 1; err: - for (i = 0; i < DB_NUMBER; i++) - if (row[i] != NULL) + if (irow != NULL) { + for (i = 0; i < DB_NUMBER; i++) OPENSSL_free(row[i]); + OPENSSL_free(irow); + } if (CAname != NULL) X509_NAME_free(CAname); @@ -2396,18 +2397,20 @@ static int do_revoke(X509 *x509, CA_DB *db, int type, char *value) goto err; } - for (i = 0; i < DB_NUMBER; i++) { + for (i = 0; i < DB_NUMBER; i++) irow[i] = row[i]; - row[i] = NULL; - } irow[DB_NUMBER] = NULL; if (!TXT_DB_insert(db->db, irow)) { BIO_printf(bio_err, "failed to update database\n"); BIO_printf(bio_err, "TXT_DB error number %ld\n", db->db->error); + OPENSSL_free(irow); goto err; } + for (i = 0; i < DB_NUMBER; i++) + row[i] = NULL; + /* Revoke Certificate */ if (type == -1) ok = 1; diff --git a/deps/openssl/openssl/apps/dhparam.c b/deps/openssl/openssl/apps/dhparam.c index 1210adb104d9f3..bd91234abd664d 100644 --- a/deps/openssl/openssl/apps/dhparam.c +++ b/deps/openssl/openssl/apps/dhparam.c @@ -381,10 +381,19 @@ int MAIN(int argc, char **argv) } else # endif { - if (informat == FORMAT_ASN1) + if (informat == FORMAT_ASN1) { + /* + * We have no PEM header to determine what type of DH params it + * is. We'll just try both. + */ dh = d2i_DHparams_bio(in, NULL); - else /* informat == FORMAT_PEM */ + /* BIO_reset() returns 0 for success for file BIOs only!!! */ + if (dh == NULL && BIO_reset(in) == 0) + dh = d2i_DHxparams_bio(in, NULL); + } else { + /* informat == FORMAT_PEM */ dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL); + } if (dh == NULL) { BIO_printf(bio_err, "unable to load DH parameters\n"); @@ -484,10 +493,13 @@ int MAIN(int argc, char **argv) } if (!noout) { - if (outformat == FORMAT_ASN1) - i = i2d_DHparams_bio(out, dh); - else if (outformat == FORMAT_PEM) { - if (dh->q) + if (outformat == FORMAT_ASN1) { + if (dh->q != NULL) + i = i2d_DHxparams_bio(out, dh); + else + i = i2d_DHparams_bio(out, dh); + } else if (outformat == FORMAT_PEM) { + if (dh->q != NULL) i = PEM_write_bio_DHxparams(out, dh); else i = PEM_write_bio_DHparams(out, dh); diff --git a/deps/openssl/openssl/apps/enc.c b/deps/openssl/openssl/apps/enc.c index 8c8f1ef0f90b21..66145b3be770e7 100644 --- a/deps/openssl/openssl/apps/enc.c +++ b/deps/openssl/openssl/apps/enc.c @@ -81,20 +81,32 @@ int set_hex(char *in, unsigned char *out, int size); #define BSIZE (8*1024) #define PROG enc_main -static void show_ciphers(const OBJ_NAME *name, void *bio_) +struct doall_enc_ciphers { + BIO *bio; + int n; +}; + +static void show_ciphers(const OBJ_NAME *name, void *arg) { - BIO *bio = bio_; - static int n; + struct doall_enc_ciphers *dec = (struct doall_enc_ciphers *)arg; + const EVP_CIPHER *cipher; if (!islower((unsigned char)*name->name)) return; - BIO_printf(bio, "-%-25s", name->name); - if (++n == 3) { - BIO_printf(bio, "\n"); - n = 0; + /* Filter out ciphers that we cannot use */ + cipher = EVP_get_cipherbyname(name->name); + if (cipher == NULL || + (EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) != 0 || + EVP_CIPHER_mode(cipher) == EVP_CIPH_XTS_MODE) + return; + + BIO_printf(dec->bio, "-%-25s", name->name); + if (++dec->n == 3) { + BIO_printf(dec->bio, "\n"); + dec->n = 0; } else - BIO_printf(bio, " "); + BIO_printf(dec->bio, " "); } int MAIN(int, char **); @@ -130,6 +142,7 @@ int MAIN(int argc, char **argv) ENGINE *e = NULL; const EVP_MD *dgst = NULL; int non_fips_allow = 0; + struct doall_enc_ciphers dec; apps_startup(); @@ -311,8 +324,10 @@ int MAIN(int argc, char **argv) #endif BIO_printf(bio_err, "Cipher Types\n"); + dec.n = 0; + dec.bio = bio_err; OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, - show_ciphers, bio_err); + show_ciphers, &dec); BIO_printf(bio_err, "\n"); goto end; diff --git a/deps/openssl/openssl/apps/engine.c b/deps/openssl/openssl/apps/engine.c index f54631b50d819a..a8eed9af5c18cb 100644 --- a/deps/openssl/openssl/apps/engine.c +++ b/deps/openssl/openssl/apps/engine.c @@ -108,13 +108,16 @@ static int append_buf(char **buf, const char *s, int *size, int step) } if (strlen(*buf) + strlen(s) >= (unsigned int)*size) { + char *p = *buf; + *size += step; *buf = OPENSSL_realloc(*buf, *size); + if (*buf == NULL) { + OPENSSL_free(p); + return 0; + } } - if (*buf == NULL) - return 0; - if (**buf != '\0') BUF_strlcat(*buf, ", ", *size); BUF_strlcat(*buf, s, *size); diff --git a/deps/openssl/openssl/apps/pkeyutl.c b/deps/openssl/openssl/apps/pkeyutl.c index 7c62d1c8709bcf..19f2e5d9cf9fd1 100644 --- a/deps/openssl/openssl/apps/pkeyutl.c +++ b/deps/openssl/openssl/apps/pkeyutl.c @@ -322,8 +322,10 @@ int MAIN(int argc, char **argv) buf_in, (size_t)buf_inlen); if (rv == 0) BIO_puts(out, "Signature Verification Failure\n"); - else if (rv == 1) + else if (rv == 1) { BIO_puts(out, "Signature Verified Successfully\n"); + ret = 0; + } if (rv >= 0) goto end; } else { diff --git a/deps/openssl/openssl/apps/prime.c b/deps/openssl/openssl/apps/prime.c index 133167f2d4d1e5..d8f764a3d7f1f0 100644 --- a/deps/openssl/openssl/apps/prime.c +++ b/deps/openssl/openssl/apps/prime.c @@ -155,5 +155,8 @@ int MAIN(int argc, char **argv) BIO_printf(bio_err, "options are\n"); BIO_printf(bio_err, "%-14s hex\n", "-hex"); BIO_printf(bio_err, "%-14s number of checks\n", "-checks "); + BIO_printf(bio_err, "%-14s generate prime\n", "-generate"); + BIO_printf(bio_err, "%-14s number of bits\n", "-bits "); + BIO_printf(bio_err, "%-14s safe prime\n", "-safe"); return 1; } diff --git a/deps/openssl/openssl/apps/progs.h b/deps/openssl/openssl/apps/progs.h index fb498fd20c2746..d5c0039bd69d13 100644 --- a/deps/openssl/openssl/apps/progs.h +++ b/deps/openssl/openssl/apps/progs.h @@ -58,7 +58,7 @@ extern int srp_main(int argc, char *argv[]); typedef struct { int type; const char *name; - int (*func) (int argc, char *argv[]); + int (*func)(int argc, char *argv[]); } FUNCTION; DECLARE_LHASH_OF(FUNCTION); diff --git a/deps/openssl/openssl/apps/progs.pl b/deps/openssl/openssl/apps/progs.pl index fa6258cf5e1324..73498e3d6efad8 100644 --- a/deps/openssl/openssl/apps/progs.pl +++ b/deps/openssl/openssl/apps/progs.pl @@ -6,22 +6,22 @@ grep(s/^asn1pars$/asn1parse/,@ARGV); foreach (@ARGV) - { printf "extern int %s_main(int argc,char *argv[]);\n",$_; } + { printf "extern int %s_main(int argc, char *argv[]);\n",$_; } print <<'EOF'; -#define FUNC_TYPE_GENERAL 1 -#define FUNC_TYPE_MD 2 -#define FUNC_TYPE_CIPHER 3 -#define FUNC_TYPE_PKEY 4 -#define FUNC_TYPE_MD_ALG 5 -#define FUNC_TYPE_CIPHER_ALG 6 +#define FUNC_TYPE_GENERAL 1 +#define FUNC_TYPE_MD 2 +#define FUNC_TYPE_CIPHER 3 +#define FUNC_TYPE_PKEY 4 +#define FUNC_TYPE_MD_ALG 5 +#define FUNC_TYPE_CIPHER_ALG 6 typedef struct { - int type; - const char *name; - int (*func)(int argc,char *argv[]); - } FUNCTION; + int type; + const char *name; + int (*func)(int argc, char *argv[]); +} FUNCTION; DECLARE_LHASH_OF(FUNCTION); FUNCTION functions[] = { @@ -30,7 +30,7 @@ foreach (@ARGV) { push(@files,$_); - $str="\t{FUNC_TYPE_GENERAL,\"$_\",${_}_main},\n"; + $str=" {FUNC_TYPE_GENERAL, \"$_\", ${_}_main},\n"; if (($_ =~ /^s_/) || ($_ =~ /^ciphers$/)) { print "#if !defined(OPENSSL_NO_SOCK)\n${str}#endif\n"; } elsif ( ($_ =~ /^speed$/)) @@ -60,7 +60,7 @@ foreach ("md2","md4","md5","sha","sha1","mdc2","rmd160") { push(@files,$_); - printf "#ifndef OPENSSL_NO_".uc($_)."\n\t{FUNC_TYPE_MD,\"".$_."\",dgst_main},\n#endif\n"; + printf "#ifndef OPENSSL_NO_".uc($_)."\n {FUNC_TYPE_MD, \"".$_."\", dgst_main},\n#endif\n"; } foreach ( @@ -86,7 +86,7 @@ { push(@files,$_); - $t=sprintf("\t{FUNC_TYPE_CIPHER,\"%s\",enc_main},\n",$_); + $t=sprintf(" {FUNC_TYPE_CIPHER, \"%s\", enc_main},\n",$_); if ($_ =~ /des/) { $t="#ifndef OPENSSL_NO_DES\n${t}#endif\n"; } elsif ($_ =~ /aes/) { $t="#ifndef OPENSSL_NO_AES\n${t}#endif\n"; } elsif ($_ =~ /camellia/) { $t="#ifndef OPENSSL_NO_CAMELLIA\n${t}#endif\n"; } @@ -101,4 +101,4 @@ print $t; } -print "\t{0,NULL,NULL}\n\t};\n"; +print " {0, NULL, NULL}\n};\n"; diff --git a/deps/openssl/openssl/apps/req.c b/deps/openssl/openssl/apps/req.c index cdea1f61119472..ede1d32cae62cc 100644 --- a/deps/openssl/openssl/apps/req.c +++ b/deps/openssl/openssl/apps/req.c @@ -331,7 +331,6 @@ int MAIN(int argc, char **argv) else if (strcmp(*argv, "-text") == 0) text = 1; else if (strcmp(*argv, "-x509") == 0) { - newreq = 1; x509 = 1; } else if (strcmp(*argv, "-asn1-kludge") == 0) kludge = 1; @@ -447,6 +446,9 @@ int MAIN(int argc, char **argv) goto end; } + if (x509 && infile == NULL) + newreq = 1; + ERR_load_crypto_strings(); if (!app_passwd(bio_err, passargin, passargout, &passin, &passout)) { BIO_printf(bio_err, "Error getting passwords\n"); @@ -753,7 +755,7 @@ int MAIN(int argc, char **argv) } } - if (newreq) { + if (newreq || x509) { if (pkey == NULL) { BIO_printf(bio_err, "you need to specify a private key\n"); goto end; diff --git a/deps/openssl/openssl/apps/s_client.c b/deps/openssl/openssl/apps/s_client.c index cdea5ff8d857e2..ffb8ffc5af20c7 100644 --- a/deps/openssl/openssl/apps/s_client.c +++ b/deps/openssl/openssl/apps/s_client.c @@ -2147,6 +2147,7 @@ int MAIN(int argc, char **argv) BIO_free(bio_c_msg); bio_c_msg = NULL; } + SSL_COMP_free_compression_methods(); apps_shutdown(); OPENSSL_EXIT(ret); } diff --git a/deps/openssl/openssl/apps/s_server.c b/deps/openssl/openssl/apps/s_server.c index b561cf3a362bf9..d75871386928f5 100644 --- a/deps/openssl/openssl/apps/s_server.c +++ b/deps/openssl/openssl/apps/s_server.c @@ -2132,6 +2132,7 @@ int MAIN(int argc, char *argv[]) BIO_free(bio_s_msg); bio_s_msg = NULL; } + SSL_COMP_free_compression_methods(); apps_shutdown(); OPENSSL_EXIT(ret); } diff --git a/deps/openssl/openssl/apps/srp.c b/deps/openssl/openssl/apps/srp.c index 37341a5d20ed61..ce01a24f2a78c4 100644 --- a/deps/openssl/openssl/apps/srp.c +++ b/deps/openssl/openssl/apps/srp.c @@ -183,10 +183,8 @@ static int update_index(CA_DB *db, BIO *bio, char **row) return 0; } - for (i = 0; i < DB_NUMBER; i++) { + for (i = 0; i < DB_NUMBER; i++) irow[i] = row[i]; - row[i] = NULL; - } irow[DB_NUMBER] = NULL; if (!TXT_DB_insert(db->db, irow)) { diff --git a/deps/openssl/openssl/appveyor.yml b/deps/openssl/openssl/appveyor.yml index 8695359488d8dd..8c38feae6d954c 100644 --- a/deps/openssl/openssl/appveyor.yml +++ b/deps/openssl/openssl/appveyor.yml @@ -50,11 +50,3 @@ build_script: test_script: - nmake /f ms\%MAK% test - -notifications: - - provider: Email - to: - - openssl-commits@openssl.org - on_build_success: false - on_build_failure: true - on_build_status_changed: true diff --git a/deps/openssl/openssl/config b/deps/openssl/openssl/config index bba370c4f3f1cb..21534e00ba4a28 100755 --- a/deps/openssl/openssl/config +++ b/deps/openssl/openssl/config @@ -344,6 +344,15 @@ case "${SYSTEM}:${RELEASE}:${VERSION}:${MACHINE}" in echo "mips-sony-newsos4"; exit 0; ;; + # The following combinations are supported + # MINGW64* on x86_64 => mingw64 + # MINGW32* on x86_64 => mingw + # MINGW32* on i?86 => mingw + # + # MINGW64* on i?86 isn't expected to work... + MINGW64*:*:*:x86_64) + echo "${MACHINE}-whatever-mingw64"; exit 0; + ;; MINGW*) echo "${MACHINE}-whatever-mingw"; exit 0; ;; diff --git a/deps/openssl/openssl/crypto/aes/Makefile b/deps/openssl/openssl/crypto/aes/Makefile index e825c140194f60..05e4a0149ed86d 100644 --- a/deps/openssl/openssl/crypto/aes/Makefile +++ b/deps/openssl/openssl/crypto/aes/Makefile @@ -133,7 +133,7 @@ dclean: mv -f Makefile.new $(MAKEFILE) clean: - rm -f *.s *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff + rm -f *.s *.S *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff # DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/deps/openssl/openssl/crypto/aes/asm/aesni-sha1-x86_64.pl b/deps/openssl/openssl/crypto/aes/asm/aesni-sha1-x86_64.pl index 8c84260856e164..7a30e893fbe67b 100644 --- a/deps/openssl/openssl/crypto/aes/asm/aesni-sha1-x86_64.pl +++ b/deps/openssl/openssl/crypto/aes/asm/aesni-sha1-x86_64.pl @@ -1702,6 +1702,7 @@ () mov 240($key),$rounds sub $in0,$out movups ($key),$rndkey0 # $key[0] + movups ($ivp),$iv # load IV movups 16($key),$rndkey[0] # forward reference lea 112($key),$key # size optimization diff --git a/deps/openssl/openssl/crypto/aes/asm/aesni-sha256-x86_64.pl b/deps/openssl/openssl/crypto/aes/asm/aesni-sha256-x86_64.pl index 72f44ecf625345..588ade64ee52c4 100644 --- a/deps/openssl/openssl/crypto/aes/asm/aesni-sha256-x86_64.pl +++ b/deps/openssl/openssl/crypto/aes/asm/aesni-sha256-x86_64.pl @@ -1299,6 +1299,7 @@ () mov 240($key),$rounds sub $in0,$out movups ($key),$rndkey0 # $key[0] + movups ($ivp),$iv # load IV movups 16($key),$rndkey[0] # forward reference lea 112($key),$key # size optimization diff --git a/deps/openssl/openssl/crypto/aes/asm/bsaes-armv7.pl b/deps/openssl/openssl/crypto/aes/asm/bsaes-armv7.pl index 83343e2de1af7b..70b3f9656f4fa7 100644 --- a/deps/openssl/openssl/crypto/aes/asm/bsaes-armv7.pl +++ b/deps/openssl/openssl/crypto/aes/asm/bsaes-armv7.pl @@ -1333,7 +1333,7 @@ sub bitslice_key { vmov @XMM[4],@XMM[15] @ just in case ensure that IV vmov @XMM[5],@XMM[0] @ and input are preserved bl AES_decrypt - vld1.8 {@XMM[0]}, [$fp,:64] @ load result + vld1.8 {@XMM[0]}, [$fp] @ load result veor @XMM[0], @XMM[0], @XMM[4] @ ^= IV vmov @XMM[15], @XMM[5] @ @XMM[5] holds input vst1.8 {@XMM[0]}, [$rounds] @ write output diff --git a/deps/openssl/openssl/crypto/asn1/a_bitstr.c b/deps/openssl/openssl/crypto/asn1/a_bitstr.c index f906188b114b08..c429342e03d42a 100644 --- a/deps/openssl/openssl/crypto/asn1/a_bitstr.c +++ b/deps/openssl/openssl/crypto/asn1/a_bitstr.c @@ -114,10 +114,11 @@ int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp) *(p++) = (unsigned char)bits; d = a->data; - memcpy(p, d, len); - p += len; - if (len > 0) + if (len > 0) { + memcpy(p, d, len); + p += len; p[-1] &= (0xff << bits); + } *pp = p; return (ret); } diff --git a/deps/openssl/openssl/crypto/asn1/a_digest.c b/deps/openssl/openssl/crypto/asn1/a_digest.c index 7cbc4751cd8120..57a04f768ca024 100644 --- a/deps/openssl/openssl/crypto/asn1/a_digest.c +++ b/deps/openssl/openssl/crypto/asn1/a_digest.c @@ -86,8 +86,10 @@ int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data, p = str; i2d(data, &p); - if (!EVP_Digest(str, i, md, len, type, NULL)) + if (!EVP_Digest(str, i, md, len, type, NULL)) { + OPENSSL_free(str); return 0; + } OPENSSL_free(str); return (1); } @@ -104,8 +106,10 @@ int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *asn, if (!str) return (0); - if (!EVP_Digest(str, i, md, len, type, NULL)) + if (!EVP_Digest(str, i, md, len, type, NULL)) { + OPENSSL_free(str); return 0; + } OPENSSL_free(str); return (1); } diff --git a/deps/openssl/openssl/crypto/asn1/a_gentm.c b/deps/openssl/openssl/crypto/asn1/a_gentm.c index fa76dcac91f34b..85118137859f91 100644 --- a/deps/openssl/openssl/crypto/asn1/a_gentm.c +++ b/deps/openssl/openssl/crypto/asn1/a_gentm.c @@ -202,7 +202,7 @@ int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d) if (a[o] == 'Z') o++; else if ((a[o] == '+') || (a[o] == '-')) { - int offsign = a[o] == '-' ? -1 : 1, offset = 0; + int offsign = a[o] == '-' ? 1 : -1, offset = 0; o++; if (o + 4 > l) goto err; diff --git a/deps/openssl/openssl/crypto/asn1/a_strnid.c b/deps/openssl/openssl/crypto/asn1/a_strnid.c index 2d2303d8599e7a..99ffe737873569 100644 --- a/deps/openssl/openssl/crypto/asn1/a_strnid.c +++ b/deps/openssl/openssl/crypto/asn1/a_strnid.c @@ -192,7 +192,8 @@ static const ASN1_STRING_TABLE tbl_standard[] = { {NID_name, 1, ub_name, DIRSTRING_TYPE, 0}, {NID_dnQualifier, -1, -1, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK}, {NID_domainComponent, 1, -1, B_ASN1_IA5STRING, STABLE_NO_MASK}, - {NID_ms_csp_name, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK} + {NID_ms_csp_name, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK}, + {NID_jurisdictionCountryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK} }; static int sk_table_cmp(const ASN1_STRING_TABLE *const *a, diff --git a/deps/openssl/openssl/crypto/asn1/a_time.c b/deps/openssl/openssl/crypto/asn1/a_time.c index fcb2d565cdd0ac..0eeb79cd428ce0 100644 --- a/deps/openssl/openssl/crypto/asn1/a_time.c +++ b/deps/openssl/openssl/crypto/asn1/a_time.c @@ -137,7 +137,7 @@ int ASN1_TIME_check(ASN1_TIME *t) ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out) { - ASN1_GENERALIZEDTIME *ret; + ASN1_GENERALIZEDTIME *ret = NULL; char *str; int newlen; @@ -146,22 +146,21 @@ ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, if (!out || !*out) { if (!(ret = ASN1_GENERALIZEDTIME_new())) - return NULL; - if (out) - *out = ret; - } else + goto err; + } else { ret = *out; + } /* If already GeneralizedTime just copy across */ if (t->type == V_ASN1_GENERALIZEDTIME) { if (!ASN1_STRING_set(ret, t->data, t->length)) - return NULL; - return ret; + goto err; + goto done; } /* grow the string */ if (!ASN1_STRING_set(ret, NULL, t->length + 2)) - return NULL; + goto err; /* ASN1_STRING_set() allocated 'len + 1' bytes. */ newlen = t->length + 2 + 1; str = (char *)ret->data; @@ -173,9 +172,18 @@ ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, BUF_strlcat(str, (char *)t->data, newlen); - return ret; + done: + if (out != NULL && *out == NULL) + *out = ret; + return ret; + + err: + if (out == NULL || *out != ret) + ASN1_GENERALIZEDTIME_free(ret); + return NULL; } + int ASN1_TIME_set_string(ASN1_TIME *s, const char *str) { ASN1_TIME t; diff --git a/deps/openssl/openssl/crypto/asn1/a_utctm.c b/deps/openssl/openssl/crypto/asn1/a_utctm.c index 724a10be4ed6ab..0344482cc247f2 100644 --- a/deps/openssl/openssl/crypto/asn1/a_utctm.c +++ b/deps/openssl/openssl/crypto/asn1/a_utctm.c @@ -172,7 +172,7 @@ int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d) if (a[o] == 'Z') o++; else if ((a[o] == '+') || (a[o] == '-')) { - int offsign = a[o] == '-' ? -1 : 1, offset = 0; + int offsign = a[o] == '-' ? 1 : -1, offset = 0; o++; if (o + 4 > l) goto err; diff --git a/deps/openssl/openssl/crypto/asn1/f_enum.c b/deps/openssl/openssl/crypto/asn1/f_enum.c index 94cd54dbeedd3a..527f1d8f87b3f2 100644 --- a/deps/openssl/openssl/crypto/asn1/f_enum.c +++ b/deps/openssl/openssl/crypto/asn1/f_enum.c @@ -138,7 +138,7 @@ int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size) bufp = (unsigned char *)buf; if (first) { first = 0; - if ((bufp[0] == '0') && (buf[1] == '0')) { + if ((bufp[0] == '0') && (bufp[1] == '0')) { bufp += 2; i -= 2; } diff --git a/deps/openssl/openssl/crypto/asn1/f_int.c b/deps/openssl/openssl/crypto/asn1/f_int.c index 2bdc78d74491ce..e6ed7f1e770b99 100644 --- a/deps/openssl/openssl/crypto/asn1/f_int.c +++ b/deps/openssl/openssl/crypto/asn1/f_int.c @@ -152,7 +152,7 @@ int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size) bufp = (unsigned char *)buf; if (first) { first = 0; - if ((bufp[0] == '0') && (buf[1] == '0')) { + if ((bufp[0] == '0') && (bufp[1] == '0')) { bufp += 2; i -= 2; } diff --git a/deps/openssl/openssl/crypto/asn1/tasn_dec.c b/deps/openssl/openssl/crypto/asn1/tasn_dec.c index d25402730b8b9d..d49a5d5792a430 100644 --- a/deps/openssl/openssl/crypto/asn1/tasn_dec.c +++ b/deps/openssl/openssl/crypto/asn1/tasn_dec.c @@ -673,6 +673,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, } len -= p - q; if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val, skfield)) { + ASN1_item_ex_free(&skfield, ASN1_ITEM_ptr(tt->item)); ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_MALLOC_FAILURE); goto err; } diff --git a/deps/openssl/openssl/crypto/asn1/tasn_new.c b/deps/openssl/openssl/crypto/asn1/tasn_new.c index b0c73beeb57870..54f459d1ed9cbf 100644 --- a/deps/openssl/openssl/crypto/asn1/tasn_new.c +++ b/deps/openssl/openssl/crypto/asn1/tasn_new.c @@ -158,7 +158,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, } asn1_set_choice_selector(pval, -1, it); if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL)) - goto auxerr; + goto auxerr2; break; case ASN1_ITYPE_NDEF_SEQUENCE: @@ -186,10 +186,10 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) { pseqval = asn1_get_field_ptr(pval, tt); if (!ASN1_template_new(pseqval, tt)) - goto memerr; + goto memerr2; } if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL)) - goto auxerr; + goto auxerr2; break; } #ifdef CRYPTO_MDEBUG @@ -198,6 +198,8 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, #endif return 1; + memerr2: + ASN1_item_ex_free(pval, it); memerr: ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ERR_R_MALLOC_FAILURE); #ifdef CRYPTO_MDEBUG @@ -206,9 +208,10 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, #endif return 0; + auxerr2: + ASN1_item_ex_free(pval, it); auxerr: ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ASN1_R_AUX_ERROR); - ASN1_item_ex_free(pval, it); #ifdef CRYPTO_MDEBUG if (it->sname) CRYPTO_pop_info(); diff --git a/deps/openssl/openssl/crypto/asn1/x_long.c b/deps/openssl/openssl/crypto/asn1/x_long.c index 3aed44a3ddf753..aecb95069de723 100644 --- a/deps/openssl/openssl/crypto/asn1/x_long.c +++ b/deps/openssl/openssl/crypto/asn1/x_long.c @@ -126,7 +126,7 @@ static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, * set. */ if (ltmp < 0) - utmp = -ltmp - 1; + utmp = 0 - (unsigned long)ltmp - 1; else utmp = ltmp; clen = BN_num_bits_word(utmp); @@ -155,19 +155,41 @@ static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it) { - int neg, i; + int neg = -1, i; long ltmp; unsigned long utmp = 0; char *cp = (char *)pval; + + if (len) { + /* + * Check possible pad byte. Worst case, we're skipping past actual + * content, but since that's only with 0x00 and 0xff and we set neg + * accordingly, the result will be correct in the end anyway. + */ + switch (cont[0]) { + case 0xff: + cont++; + len--; + neg = 1; + break; + case 0: + cont++; + len--; + neg = 0; + break; + } + } if (len > (int)sizeof(long)) { ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG); return 0; } - /* Is it negative? */ - if (len && (cont[0] & 0x80)) - neg = 1; - else - neg = 0; + if (neg == -1) { + /* Is it negative? */ + if (len && (cont[0] & 0x80)) + neg = 1; + else + neg = 0; + } utmp = 0; for (i = 0; i < len; i++) { utmp <<= 8; @@ -178,8 +200,8 @@ static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, } ltmp = (long)utmp; if (neg) { - ltmp++; ltmp = -ltmp; + ltmp--; } if (ltmp == it->size) { ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG); diff --git a/deps/openssl/openssl/crypto/asn1/x_name.c b/deps/openssl/openssl/crypto/asn1/x_name.c index 26378fdb2a02e1..1fb7ad1cbf88af 100644 --- a/deps/openssl/openssl/crypto/asn1/x_name.c +++ b/deps/openssl/openssl/crypto/asn1/x_name.c @@ -178,6 +178,16 @@ static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) *pval = NULL; } +static void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne) +{ + sk_X509_NAME_ENTRY_free(ne); +} + +static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne) +{ + sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free); +} + static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_ITEM *it, int tag, int aclass, @@ -228,13 +238,14 @@ static int x509_name_ex_d2i(ASN1_VALUE **val, entry->set = i; if (!sk_X509_NAME_ENTRY_push(nm.x->entries, entry)) goto err; + sk_X509_NAME_ENTRY_set(entries, j, NULL); } - sk_X509_NAME_ENTRY_free(entries); } - sk_STACK_OF_X509_NAME_ENTRY_free(intname.s); ret = x509_name_canon(nm.x); if (!ret) goto err; + sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, + local_sk_X509_NAME_ENTRY_free); nm.x->modified = 0; *val = nm.a; *in = p; @@ -242,6 +253,8 @@ static int x509_name_ex_d2i(ASN1_VALUE **val, err: if (nm.x != NULL) X509_NAME_free(nm.x); + sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, + local_sk_X509_NAME_ENTRY_pop_free); ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR); return 0; } @@ -267,16 +280,6 @@ static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, return ret; } -static void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne) -{ - sk_X509_NAME_ENTRY_free(ne); -} - -static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne) -{ - sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free); -} - static int x509_name_encode(X509_NAME *a) { union { @@ -299,8 +302,10 @@ static int x509_name_encode(X509_NAME *a) entries = sk_X509_NAME_ENTRY_new_null(); if (!entries) goto memerr; - if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s, entries)) + if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s, entries)) { + sk_X509_NAME_ENTRY_free(entries); goto memerr; + } set = entry->set; } if (!sk_X509_NAME_ENTRY_push(entries, entry)) @@ -370,8 +375,10 @@ static int x509_name_canon(X509_NAME *a) entries = sk_X509_NAME_ENTRY_new_null(); if (!entries) goto err; - if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries)) + if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries)) { + sk_X509_NAME_ENTRY_free(entries); goto err; + } set = entry->set; } tmpentry = X509_NAME_ENTRY_new(); diff --git a/deps/openssl/openssl/crypto/bio/b_print.c b/deps/openssl/openssl/crypto/bio/b_print.c index 987fe068c6de10..eb3ab759349cde 100644 --- a/deps/openssl/openssl/crypto/bio/b_print.c +++ b/deps/openssl/openssl/crypto/bio/b_print.c @@ -502,7 +502,7 @@ fmtint(char **sbuffer, if (!(flags & DP_F_UNSIGNED)) { if (value < 0) { signvalue = '-'; - uvalue = -value; + uvalue = -(unsigned LLONG)value; } else if (flags & DP_F_PLUS) signvalue = '+'; else if (flags & DP_F_SPACE) diff --git a/deps/openssl/openssl/crypto/bio/bio_cb.c b/deps/openssl/openssl/crypto/bio/bio_cb.c index d3e860686c3c58..f96294bb430475 100644 --- a/deps/openssl/openssl/crypto/bio/bio_cb.c +++ b/deps/openssl/openssl/crypto/bio/bio_cb.c @@ -78,6 +78,9 @@ long MS_CALLBACK BIO_debug_callback(BIO *bio, int cmd, const char *argp, len = BIO_snprintf(buf,sizeof buf,"BIO[%p]: ",(void *)bio); + /* Ignore errors and continue printing the other information. */ + if (len < 0) + len = 0; p = buf + len; p_maxlen = sizeof(buf) - len; diff --git a/deps/openssl/openssl/crypto/bio/bss_file.c b/deps/openssl/openssl/crypto/bio/bss_file.c index a6e3b3ac0130aa..0cf67e5b770b0c 100644 --- a/deps/openssl/openssl/crypto/bio/bss_file.c +++ b/deps/openssl/openssl/crypto/bio/bss_file.c @@ -251,7 +251,7 @@ static int MS_CALLBACK file_read(BIO *b, char *out, int outl) ret = fread(out, 1, (int)outl, (FILE *)b->ptr); if (ret == 0 && (b->flags & BIO_FLAGS_UPLINK) ? UP_ferror((FILE *)b->ptr) : - ferror((FILE *)b->ptr)) { + ferror((FILE *)b->ptr)) { SYSerr(SYS_F_FREAD, get_last_sys_error()); BIOerr(BIO_F_FILE_READ, ERR_R_SYS_LIB); ret = -1; @@ -287,6 +287,7 @@ static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr) FILE *fp = (FILE *)b->ptr; FILE **fpp; char p[4]; + int st; switch (cmd) { case BIO_C_FILE_SEEK: @@ -318,8 +319,11 @@ static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr) # if defined(__MINGW32__) && defined(__MSVCRT__) && !defined(_IOB_ENTRIES) # define _IOB_ENTRIES 20 # endif -# if defined(_IOB_ENTRIES) /* Safety net to catch purely internal BIO_set_fp calls */ +# if defined(_MSC_VER) && _MSC_VER>=1900 + if (ptr == stdin || ptr == stdout || ptr == stderr) + BIO_clear_flags(b, BIO_FLAGS_UPLINK); +# elif defined(_IOB_ENTRIES) if ((size_t)ptr >= (size_t)stdin && (size_t)ptr < (size_t)(stdin + _IOB_ENTRIES)) BIO_clear_flags(b, BIO_FLAGS_UPLINK); @@ -424,10 +428,14 @@ static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr) b->shutdown = (int)num; break; case BIO_CTRL_FLUSH: - if (b->flags & BIO_FLAGS_UPLINK) - UP_fflush(b->ptr); - else - fflush((FILE *)b->ptr); + st = b->flags & BIO_FLAGS_UPLINK + ? UP_fflush(b->ptr) : fflush((FILE *)b->ptr); + if (st == EOF) { + SYSerr(SYS_F_FFLUSH, get_last_sys_error()); + ERR_add_error_data(1, "fflush()"); + BIOerr(BIO_F_FILE_CTRL, ERR_R_SYS_LIB); + ret = 0; + } break; case BIO_CTRL_DUP: ret = 1; diff --git a/deps/openssl/openssl/crypto/bn/Makefile b/deps/openssl/openssl/crypto/bn/Makefile index c4c6409517596f..20e8ef0a28d7e9 100644 --- a/deps/openssl/openssl/crypto/bn/Makefile +++ b/deps/openssl/openssl/crypto/bn/Makefile @@ -187,7 +187,7 @@ dclean: mv -f Makefile.new $(MAKEFILE) clean: - rm -f *.s *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff + rm -f *.s *.S *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff # DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/deps/openssl/openssl/crypto/bn/asm/sparcv9-mont.pl b/deps/openssl/openssl/crypto/bn/asm/sparcv9-mont.pl index b8fb1e8a25dc0b..d8662878006eac 100644 --- a/deps/openssl/openssl/crypto/bn/asm/sparcv9-mont.pl +++ b/deps/openssl/openssl/crypto/bn/asm/sparcv9-mont.pl @@ -290,7 +290,7 @@ ######## .Lbn_sqr_mont gives up to 20% *overall* improvement over ######## code without following dedicated squaring procedure. ######## -$sbit="%i2"; # re-use $bp! +$sbit="%o5"; $code.=<<___; .align 32 @@ -403,7 +403,7 @@ mulx $apj,$mul0,$acc0 mulx $npj,$mul1,$acc1 add $acc0,$car0,$car0 - add $tpj,$car1,$car1 + add $tpj,$sbit,$sbit ld [$ap+$j],$apj ! ap[j] and $car0,$mask,$acc0 ld [$np+$j],$npj ! np[j] @@ -412,7 +412,7 @@ ld [$tp+8],$tpj ! tp[j] add $acc0,$acc0,$acc0 add $j,4,$j ! j++ - or $sbit,$acc0,$acc0 + add $sbit,$acc0,$acc0 srlx $acc0,32,$sbit and $acc0,$mask,$acc0 cmp $j,$num @@ -426,12 +426,12 @@ mulx $apj,$mul0,$acc0 mulx $npj,$mul1,$acc1 add $acc0,$car0,$car0 - add $tpj,$car1,$car1 + add $tpj,$sbit,$sbit and $car0,$mask,$acc0 srlx $car0,32,$car0 add $acc1,$car1,$car1 add $acc0,$acc0,$acc0 - or $sbit,$acc0,$acc0 + add $sbit,$acc0,$acc0 srlx $acc0,32,$sbit and $acc0,$mask,$acc0 add $acc0,$car1,$car1 @@ -439,7 +439,7 @@ srlx $car1,32,$car1 add $car0,$car0,$car0 - or $sbit,$car0,$car0 + add $sbit,$car0,$car0 add $car0,$car1,$car1 add $car2,$car1,$car1 st $car1,[$tp+4] @@ -499,7 +499,7 @@ .Lsqr_inner2: mulx $apj,$mul0,$acc0 mulx $npj,$mul1,$acc1 - add $tpj,$car1,$car1 + add $tpj,$sbit,$sbit add $acc0,$car0,$car0 ld [$ap+$j],$apj ! ap[j] and $car0,$mask,$acc0 @@ -507,7 +507,7 @@ srlx $car0,32,$car0 add $acc0,$acc0,$acc0 ld [$tp+8],$tpj ! tp[j] - or $sbit,$acc0,$acc0 + add $sbit,$acc0,$acc0 add $j,4,$j ! j++ srlx $acc0,32,$sbit and $acc0,$mask,$acc0 @@ -522,12 +522,12 @@ .Lsqr_no_inner2: mulx $apj,$mul0,$acc0 mulx $npj,$mul1,$acc1 - add $tpj,$car1,$car1 + add $tpj,$sbit,$sbit add $acc0,$car0,$car0 and $car0,$mask,$acc0 srlx $car0,32,$car0 add $acc0,$acc0,$acc0 - or $sbit,$acc0,$acc0 + add $sbit,$acc0,$acc0 srlx $acc0,32,$sbit and $acc0,$mask,$acc0 add $acc0,$car1,$car1 @@ -536,7 +536,7 @@ srlx $car1,32,$car1 add $car0,$car0,$car0 - or $sbit,$car0,$car0 + add $sbit,$car0,$car0 add $car0,$car1,$car1 add $car2,$car1,$car1 st $car1,[$tp+4] @@ -581,14 +581,17 @@ !.Lsqr_last mulx $npj,$mul1,$acc1 - add $tpj,$car1,$car1 + add $tpj,$acc0,$acc0 + srlx $acc0,32,$tmp0 + and $acc0,$mask,$acc0 + add $tmp0,$sbit,$sbit add $acc0,$car1,$car1 add $acc1,$car1,$car1 st $car1,[$tp] srlx $car1,32,$car1 add $car0,$car0,$car0 ! recover $car0 - or $sbit,$car0,$car0 + add $sbit,$car0,$car0 add $car0,$car1,$car1 add $car2,$car1,$car1 st $car1,[$tp+4] diff --git a/deps/openssl/openssl/crypto/bn/bn_prime.c b/deps/openssl/openssl/crypto/bn/bn_prime.c index 8177fd294772f2..e911e157859aae 100644 --- a/deps/openssl/openssl/crypto/bn/bn_prime.c +++ b/deps/openssl/openssl/crypto/bn/bn_prime.c @@ -252,7 +252,6 @@ int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, BN_CTX *ctx = NULL; BIGNUM *A1, *A1_odd, *check; /* taken from ctx */ BN_MONT_CTX *mont = NULL; - const BIGNUM *A = NULL; if (BN_cmp(a, BN_value_one()) <= 0) return 0; @@ -278,25 +277,14 @@ int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, goto err; BN_CTX_start(ctx); - /* A := abs(a) */ - if (a->neg) { - BIGNUM *t; - if ((t = BN_CTX_get(ctx)) == NULL) - goto err; - if (BN_copy(t, a) == NULL) - goto err; - t->neg = 0; - A = t; - } else - A = a; A1 = BN_CTX_get(ctx); A1_odd = BN_CTX_get(ctx); check = BN_CTX_get(ctx); if (check == NULL) goto err; - /* compute A1 := A - 1 */ - if (!BN_copy(A1, A)) + /* compute A1 := a - 1 */ + if (!BN_copy(A1, a)) goto err; if (!BN_sub_word(A1, 1)) goto err; @@ -312,11 +300,11 @@ int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, if (!BN_rshift(A1_odd, A1, k)) goto err; - /* Montgomery setup for computations mod A */ + /* Montgomery setup for computations mod a */ mont = BN_MONT_CTX_new(); if (mont == NULL) goto err; - if (!BN_MONT_CTX_set(mont, A, ctx)) + if (!BN_MONT_CTX_set(mont, a, ctx)) goto err; for (i = 0; i < checks; i++) { @@ -324,9 +312,9 @@ int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, goto err; if (!BN_add_word(check, 1)) goto err; - /* now 1 <= check < A */ + /* now 1 <= check < a */ - j = witness(check, A, A1, A1_odd, k, ctx, mont); + j = witness(check, a, A1, A1_odd, k, ctx, mont); if (j == -1) goto err; if (j) { diff --git a/deps/openssl/openssl/crypto/bn/bn_prime.h b/deps/openssl/openssl/crypto/bn/bn_prime.h index 5cf0de169e0497..489af8b424ca56 100644 --- a/deps/openssl/openssl/crypto/bn/bn_prime.h +++ b/deps/openssl/openssl/crypto/bn/bn_prime.h @@ -64,263 +64,263 @@ typedef unsigned short prime_t; typedef unsigned char prime_t; #endif static const prime_t primes[NUMPRIMES] = { - 2, 3, 5, 7, 11, 13, 17, 19, - 23, 29, 31, 37, 41, 43, 47, 53, - 59, 61, 67, 71, 73, 79, 83, 89, - 97, 101, 103, 107, 109, 113, 127, 131, - 137, 139, 149, 151, 157, 163, 167, 173, - 179, 181, 191, 193, 197, 199, 211, 223, - 227, 229, 233, 239, 241, 251, + 2, 3, 5, 7, 11, 13, 17, 19, + 23, 29, 31, 37, 41, 43, 47, 53, + 59, 61, 67, 71, 73, 79, 83, 89, + 97, 101, 103, 107, 109, 113, 127, 131, + 137, 139, 149, 151, 157, 163, 167, 173, + 179, 181, 191, 193, 197, 199, 211, 223, + 227, 229, 233, 239, 241, 251, #ifndef EIGHT_BIT - 257, 263, - 269, 271, 277, 281, 283, 293, 307, 311, - 313, 317, 331, 337, 347, 349, 353, 359, - 367, 373, 379, 383, 389, 397, 401, 409, - 419, 421, 431, 433, 439, 443, 449, 457, - 461, 463, 467, 479, 487, 491, 499, 503, - 509, 521, 523, 541, 547, 557, 563, 569, - 571, 577, 587, 593, 599, 601, 607, 613, - 617, 619, 631, 641, 643, 647, 653, 659, - 661, 673, 677, 683, 691, 701, 709, 719, - 727, 733, 739, 743, 751, 757, 761, 769, - 773, 787, 797, 809, 811, 821, 823, 827, - 829, 839, 853, 857, 859, 863, 877, 881, - 883, 887, 907, 911, 919, 929, 937, 941, - 947, 953, 967, 971, 977, 983, 991, 997, - 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, - 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, - 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, - 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, - 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, - 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, - 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, - 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, - 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, - 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, - 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, - 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, - 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, - 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, - 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, - 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, - 1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003, - 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, - 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, - 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, - 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, - 2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311, - 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, - 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, - 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, - 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, - 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, - 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, - 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, - 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, - 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, - 2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939, - 2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011, - 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, - 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, - 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221, - 3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301, - 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, - 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, - 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, - 3499, 3511, 3517, 3527, 3529, 3533, 3539, 3541, - 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, - 3613, 3617, 3623, 3631, 3637, 3643, 3659, 3671, - 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, - 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, - 3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863, - 3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923, - 3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003, - 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, - 4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, - 4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211, - 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, - 4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337, - 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, - 4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481, - 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547, - 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, - 4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673, - 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751, - 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, - 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909, - 4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967, - 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011, - 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, - 5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167, - 5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233, - 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309, - 5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399, - 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, - 5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, - 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573, - 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653, - 5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711, - 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, - 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, - 5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897, - 5903, 5923, 5927, 5939, 5953, 5981, 5987, 6007, - 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, - 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133, - 6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, - 6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271, - 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, - 6337, 6343, 6353, 6359, 6361, 6367, 6373, 6379, - 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, - 6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, - 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637, - 6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701, - 6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779, - 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, - 6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, - 6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971, - 6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027, - 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121, - 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, - 7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253, - 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349, - 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457, - 7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517, - 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, - 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, - 7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691, - 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757, - 7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853, - 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919, - 7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009, - 8011, 8017, 8039, 8053, 8059, 8069, 8081, 8087, - 8089, 8093, 8101, 8111, 8117, 8123, 8147, 8161, - 8167, 8171, 8179, 8191, 8209, 8219, 8221, 8231, - 8233, 8237, 8243, 8263, 8269, 8273, 8287, 8291, - 8293, 8297, 8311, 8317, 8329, 8353, 8363, 8369, - 8377, 8387, 8389, 8419, 8423, 8429, 8431, 8443, - 8447, 8461, 8467, 8501, 8513, 8521, 8527, 8537, - 8539, 8543, 8563, 8573, 8581, 8597, 8599, 8609, - 8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677, - 8681, 8689, 8693, 8699, 8707, 8713, 8719, 8731, - 8737, 8741, 8747, 8753, 8761, 8779, 8783, 8803, - 8807, 8819, 8821, 8831, 8837, 8839, 8849, 8861, - 8863, 8867, 8887, 8893, 8923, 8929, 8933, 8941, - 8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011, - 9013, 9029, 9041, 9043, 9049, 9059, 9067, 9091, - 9103, 9109, 9127, 9133, 9137, 9151, 9157, 9161, - 9173, 9181, 9187, 9199, 9203, 9209, 9221, 9227, - 9239, 9241, 9257, 9277, 9281, 9283, 9293, 9311, - 9319, 9323, 9337, 9341, 9343, 9349, 9371, 9377, - 9391, 9397, 9403, 9413, 9419, 9421, 9431, 9433, - 9437, 9439, 9461, 9463, 9467, 9473, 9479, 9491, - 9497, 9511, 9521, 9533, 9539, 9547, 9551, 9587, - 9601, 9613, 9619, 9623, 9629, 9631, 9643, 9649, - 9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733, - 9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791, - 9803, 9811, 9817, 9829, 9833, 9839, 9851, 9857, - 9859, 9871, 9883, 9887, 9901, 9907, 9923, 9929, - 9931, 9941, 9949, 9967, 9973, 10007, 10009, 10037, - 10039, 10061, 10067, 10069, 10079, 10091, 10093, 10099, - 10103, 10111, 10133, 10139, 10141, 10151, 10159, 10163, - 10169, 10177, 10181, 10193, 10211, 10223, 10243, 10247, - 10253, 10259, 10267, 10271, 10273, 10289, 10301, 10303, - 10313, 10321, 10331, 10333, 10337, 10343, 10357, 10369, - 10391, 10399, 10427, 10429, 10433, 10453, 10457, 10459, - 10463, 10477, 10487, 10499, 10501, 10513, 10529, 10531, - 10559, 10567, 10589, 10597, 10601, 10607, 10613, 10627, - 10631, 10639, 10651, 10657, 10663, 10667, 10687, 10691, - 10709, 10711, 10723, 10729, 10733, 10739, 10753, 10771, - 10781, 10789, 10799, 10831, 10837, 10847, 10853, 10859, - 10861, 10867, 10883, 10889, 10891, 10903, 10909, 10937, - 10939, 10949, 10957, 10973, 10979, 10987, 10993, 11003, - 11027, 11047, 11057, 11059, 11069, 11071, 11083, 11087, - 11093, 11113, 11117, 11119, 11131, 11149, 11159, 11161, - 11171, 11173, 11177, 11197, 11213, 11239, 11243, 11251, - 11257, 11261, 11273, 11279, 11287, 11299, 11311, 11317, - 11321, 11329, 11351, 11353, 11369, 11383, 11393, 11399, - 11411, 11423, 11437, 11443, 11447, 11467, 11471, 11483, - 11489, 11491, 11497, 11503, 11519, 11527, 11549, 11551, - 11579, 11587, 11593, 11597, 11617, 11621, 11633, 11657, - 11677, 11681, 11689, 11699, 11701, 11717, 11719, 11731, - 11743, 11777, 11779, 11783, 11789, 11801, 11807, 11813, - 11821, 11827, 11831, 11833, 11839, 11863, 11867, 11887, - 11897, 11903, 11909, 11923, 11927, 11933, 11939, 11941, - 11953, 11959, 11969, 11971, 11981, 11987, 12007, 12011, - 12037, 12041, 12043, 12049, 12071, 12073, 12097, 12101, - 12107, 12109, 12113, 12119, 12143, 12149, 12157, 12161, - 12163, 12197, 12203, 12211, 12227, 12239, 12241, 12251, - 12253, 12263, 12269, 12277, 12281, 12289, 12301, 12323, - 12329, 12343, 12347, 12373, 12377, 12379, 12391, 12401, - 12409, 12413, 12421, 12433, 12437, 12451, 12457, 12473, - 12479, 12487, 12491, 12497, 12503, 12511, 12517, 12527, - 12539, 12541, 12547, 12553, 12569, 12577, 12583, 12589, - 12601, 12611, 12613, 12619, 12637, 12641, 12647, 12653, - 12659, 12671, 12689, 12697, 12703, 12713, 12721, 12739, - 12743, 12757, 12763, 12781, 12791, 12799, 12809, 12821, - 12823, 12829, 12841, 12853, 12889, 12893, 12899, 12907, - 12911, 12917, 12919, 12923, 12941, 12953, 12959, 12967, - 12973, 12979, 12983, 13001, 13003, 13007, 13009, 13033, - 13037, 13043, 13049, 13063, 13093, 13099, 13103, 13109, - 13121, 13127, 13147, 13151, 13159, 13163, 13171, 13177, - 13183, 13187, 13217, 13219, 13229, 13241, 13249, 13259, - 13267, 13291, 13297, 13309, 13313, 13327, 13331, 13337, - 13339, 13367, 13381, 13397, 13399, 13411, 13417, 13421, - 13441, 13451, 13457, 13463, 13469, 13477, 13487, 13499, - 13513, 13523, 13537, 13553, 13567, 13577, 13591, 13597, - 13613, 13619, 13627, 13633, 13649, 13669, 13679, 13681, - 13687, 13691, 13693, 13697, 13709, 13711, 13721, 13723, - 13729, 13751, 13757, 13759, 13763, 13781, 13789, 13799, - 13807, 13829, 13831, 13841, 13859, 13873, 13877, 13879, - 13883, 13901, 13903, 13907, 13913, 13921, 13931, 13933, - 13963, 13967, 13997, 13999, 14009, 14011, 14029, 14033, - 14051, 14057, 14071, 14081, 14083, 14087, 14107, 14143, - 14149, 14153, 14159, 14173, 14177, 14197, 14207, 14221, - 14243, 14249, 14251, 14281, 14293, 14303, 14321, 14323, - 14327, 14341, 14347, 14369, 14387, 14389, 14401, 14407, - 14411, 14419, 14423, 14431, 14437, 14447, 14449, 14461, - 14479, 14489, 14503, 14519, 14533, 14537, 14543, 14549, - 14551, 14557, 14561, 14563, 14591, 14593, 14621, 14627, - 14629, 14633, 14639, 14653, 14657, 14669, 14683, 14699, - 14713, 14717, 14723, 14731, 14737, 14741, 14747, 14753, - 14759, 14767, 14771, 14779, 14783, 14797, 14813, 14821, - 14827, 14831, 14843, 14851, 14867, 14869, 14879, 14887, - 14891, 14897, 14923, 14929, 14939, 14947, 14951, 14957, - 14969, 14983, 15013, 15017, 15031, 15053, 15061, 15073, - 15077, 15083, 15091, 15101, 15107, 15121, 15131, 15137, - 15139, 15149, 15161, 15173, 15187, 15193, 15199, 15217, - 15227, 15233, 15241, 15259, 15263, 15269, 15271, 15277, - 15287, 15289, 15299, 15307, 15313, 15319, 15329, 15331, - 15349, 15359, 15361, 15373, 15377, 15383, 15391, 15401, - 15413, 15427, 15439, 15443, 15451, 15461, 15467, 15473, - 15493, 15497, 15511, 15527, 15541, 15551, 15559, 15569, - 15581, 15583, 15601, 15607, 15619, 15629, 15641, 15643, - 15647, 15649, 15661, 15667, 15671, 15679, 15683, 15727, - 15731, 15733, 15737, 15739, 15749, 15761, 15767, 15773, - 15787, 15791, 15797, 15803, 15809, 15817, 15823, 15859, - 15877, 15881, 15887, 15889, 15901, 15907, 15913, 15919, - 15923, 15937, 15959, 15971, 15973, 15991, 16001, 16007, - 16033, 16057, 16061, 16063, 16067, 16069, 16073, 16087, - 16091, 16097, 16103, 16111, 16127, 16139, 16141, 16183, - 16187, 16189, 16193, 16217, 16223, 16229, 16231, 16249, - 16253, 16267, 16273, 16301, 16319, 16333, 16339, 16349, - 16361, 16363, 16369, 16381, 16411, 16417, 16421, 16427, - 16433, 16447, 16451, 16453, 16477, 16481, 16487, 16493, - 16519, 16529, 16547, 16553, 16561, 16567, 16573, 16603, - 16607, 16619, 16631, 16633, 16649, 16651, 16657, 16661, - 16673, 16691, 16693, 16699, 16703, 16729, 16741, 16747, - 16759, 16763, 16787, 16811, 16823, 16829, 16831, 16843, - 16871, 16879, 16883, 16889, 16901, 16903, 16921, 16927, - 16931, 16937, 16943, 16963, 16979, 16981, 16987, 16993, - 17011, 17021, 17027, 17029, 17033, 17041, 17047, 17053, - 17077, 17093, 17099, 17107, 17117, 17123, 17137, 17159, - 17167, 17183, 17189, 17191, 17203, 17207, 17209, 17231, - 17239, 17257, 17291, 17293, 17299, 17317, 17321, 17327, - 17333, 17341, 17351, 17359, 17377, 17383, 17387, 17389, - 17393, 17401, 17417, 17419, 17431, 17443, 17449, 17467, - 17471, 17477, 17483, 17489, 17491, 17497, 17509, 17519, - 17539, 17551, 17569, 17573, 17579, 17581, 17597, 17599, - 17609, 17623, 17627, 17657, 17659, 17669, 17681, 17683, - 17707, 17713, 17729, 17737, 17747, 17749, 17761, 17783, - 17789, 17791, 17807, 17827, 17837, 17839, 17851, 17863, + 257, 263, + 269, 271, 277, 281, 283, 293, 307, 311, + 313, 317, 331, 337, 347, 349, 353, 359, + 367, 373, 379, 383, 389, 397, 401, 409, + 419, 421, 431, 433, 439, 443, 449, 457, + 461, 463, 467, 479, 487, 491, 499, 503, + 509, 521, 523, 541, 547, 557, 563, 569, + 571, 577, 587, 593, 599, 601, 607, 613, + 617, 619, 631, 641, 643, 647, 653, 659, + 661, 673, 677, 683, 691, 701, 709, 719, + 727, 733, 739, 743, 751, 757, 761, 769, + 773, 787, 797, 809, 811, 821, 823, 827, + 829, 839, 853, 857, 859, 863, 877, 881, + 883, 887, 907, 911, 919, 929, 937, 941, + 947, 953, 967, 971, 977, 983, 991, 997, + 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, + 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, + 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, + 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, + 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, + 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, + 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, + 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, + 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, + 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, + 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, + 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, + 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, + 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, + 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, + 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, + 1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003, + 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, + 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, + 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, + 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, + 2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311, + 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, + 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, + 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, + 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, + 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, + 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, + 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, + 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, + 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, + 2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939, + 2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011, + 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, + 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, + 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221, + 3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301, + 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, + 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, + 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, + 3499, 3511, 3517, 3527, 3529, 3533, 3539, 3541, + 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, + 3613, 3617, 3623, 3631, 3637, 3643, 3659, 3671, + 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, + 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, + 3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863, + 3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923, + 3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003, + 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, + 4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, + 4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211, + 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, + 4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337, + 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, + 4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481, + 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547, + 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, + 4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673, + 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751, + 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, + 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909, + 4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967, + 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011, + 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, + 5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167, + 5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233, + 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309, + 5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399, + 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, + 5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, + 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573, + 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653, + 5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711, + 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, + 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, + 5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897, + 5903, 5923, 5927, 5939, 5953, 5981, 5987, 6007, + 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, + 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133, + 6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, + 6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271, + 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, + 6337, 6343, 6353, 6359, 6361, 6367, 6373, 6379, + 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, + 6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, + 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637, + 6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701, + 6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779, + 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, + 6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, + 6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971, + 6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027, + 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121, + 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, + 7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253, + 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349, + 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457, + 7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517, + 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, + 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, + 7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691, + 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757, + 7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853, + 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919, + 7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009, + 8011, 8017, 8039, 8053, 8059, 8069, 8081, 8087, + 8089, 8093, 8101, 8111, 8117, 8123, 8147, 8161, + 8167, 8171, 8179, 8191, 8209, 8219, 8221, 8231, + 8233, 8237, 8243, 8263, 8269, 8273, 8287, 8291, + 8293, 8297, 8311, 8317, 8329, 8353, 8363, 8369, + 8377, 8387, 8389, 8419, 8423, 8429, 8431, 8443, + 8447, 8461, 8467, 8501, 8513, 8521, 8527, 8537, + 8539, 8543, 8563, 8573, 8581, 8597, 8599, 8609, + 8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677, + 8681, 8689, 8693, 8699, 8707, 8713, 8719, 8731, + 8737, 8741, 8747, 8753, 8761, 8779, 8783, 8803, + 8807, 8819, 8821, 8831, 8837, 8839, 8849, 8861, + 8863, 8867, 8887, 8893, 8923, 8929, 8933, 8941, + 8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011, + 9013, 9029, 9041, 9043, 9049, 9059, 9067, 9091, + 9103, 9109, 9127, 9133, 9137, 9151, 9157, 9161, + 9173, 9181, 9187, 9199, 9203, 9209, 9221, 9227, + 9239, 9241, 9257, 9277, 9281, 9283, 9293, 9311, + 9319, 9323, 9337, 9341, 9343, 9349, 9371, 9377, + 9391, 9397, 9403, 9413, 9419, 9421, 9431, 9433, + 9437, 9439, 9461, 9463, 9467, 9473, 9479, 9491, + 9497, 9511, 9521, 9533, 9539, 9547, 9551, 9587, + 9601, 9613, 9619, 9623, 9629, 9631, 9643, 9649, + 9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733, + 9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791, + 9803, 9811, 9817, 9829, 9833, 9839, 9851, 9857, + 9859, 9871, 9883, 9887, 9901, 9907, 9923, 9929, + 9931, 9941, 9949, 9967, 9973, 10007, 10009, 10037, + 10039, 10061, 10067, 10069, 10079, 10091, 10093, 10099, + 10103, 10111, 10133, 10139, 10141, 10151, 10159, 10163, + 10169, 10177, 10181, 10193, 10211, 10223, 10243, 10247, + 10253, 10259, 10267, 10271, 10273, 10289, 10301, 10303, + 10313, 10321, 10331, 10333, 10337, 10343, 10357, 10369, + 10391, 10399, 10427, 10429, 10433, 10453, 10457, 10459, + 10463, 10477, 10487, 10499, 10501, 10513, 10529, 10531, + 10559, 10567, 10589, 10597, 10601, 10607, 10613, 10627, + 10631, 10639, 10651, 10657, 10663, 10667, 10687, 10691, + 10709, 10711, 10723, 10729, 10733, 10739, 10753, 10771, + 10781, 10789, 10799, 10831, 10837, 10847, 10853, 10859, + 10861, 10867, 10883, 10889, 10891, 10903, 10909, 10937, + 10939, 10949, 10957, 10973, 10979, 10987, 10993, 11003, + 11027, 11047, 11057, 11059, 11069, 11071, 11083, 11087, + 11093, 11113, 11117, 11119, 11131, 11149, 11159, 11161, + 11171, 11173, 11177, 11197, 11213, 11239, 11243, 11251, + 11257, 11261, 11273, 11279, 11287, 11299, 11311, 11317, + 11321, 11329, 11351, 11353, 11369, 11383, 11393, 11399, + 11411, 11423, 11437, 11443, 11447, 11467, 11471, 11483, + 11489, 11491, 11497, 11503, 11519, 11527, 11549, 11551, + 11579, 11587, 11593, 11597, 11617, 11621, 11633, 11657, + 11677, 11681, 11689, 11699, 11701, 11717, 11719, 11731, + 11743, 11777, 11779, 11783, 11789, 11801, 11807, 11813, + 11821, 11827, 11831, 11833, 11839, 11863, 11867, 11887, + 11897, 11903, 11909, 11923, 11927, 11933, 11939, 11941, + 11953, 11959, 11969, 11971, 11981, 11987, 12007, 12011, + 12037, 12041, 12043, 12049, 12071, 12073, 12097, 12101, + 12107, 12109, 12113, 12119, 12143, 12149, 12157, 12161, + 12163, 12197, 12203, 12211, 12227, 12239, 12241, 12251, + 12253, 12263, 12269, 12277, 12281, 12289, 12301, 12323, + 12329, 12343, 12347, 12373, 12377, 12379, 12391, 12401, + 12409, 12413, 12421, 12433, 12437, 12451, 12457, 12473, + 12479, 12487, 12491, 12497, 12503, 12511, 12517, 12527, + 12539, 12541, 12547, 12553, 12569, 12577, 12583, 12589, + 12601, 12611, 12613, 12619, 12637, 12641, 12647, 12653, + 12659, 12671, 12689, 12697, 12703, 12713, 12721, 12739, + 12743, 12757, 12763, 12781, 12791, 12799, 12809, 12821, + 12823, 12829, 12841, 12853, 12889, 12893, 12899, 12907, + 12911, 12917, 12919, 12923, 12941, 12953, 12959, 12967, + 12973, 12979, 12983, 13001, 13003, 13007, 13009, 13033, + 13037, 13043, 13049, 13063, 13093, 13099, 13103, 13109, + 13121, 13127, 13147, 13151, 13159, 13163, 13171, 13177, + 13183, 13187, 13217, 13219, 13229, 13241, 13249, 13259, + 13267, 13291, 13297, 13309, 13313, 13327, 13331, 13337, + 13339, 13367, 13381, 13397, 13399, 13411, 13417, 13421, + 13441, 13451, 13457, 13463, 13469, 13477, 13487, 13499, + 13513, 13523, 13537, 13553, 13567, 13577, 13591, 13597, + 13613, 13619, 13627, 13633, 13649, 13669, 13679, 13681, + 13687, 13691, 13693, 13697, 13709, 13711, 13721, 13723, + 13729, 13751, 13757, 13759, 13763, 13781, 13789, 13799, + 13807, 13829, 13831, 13841, 13859, 13873, 13877, 13879, + 13883, 13901, 13903, 13907, 13913, 13921, 13931, 13933, + 13963, 13967, 13997, 13999, 14009, 14011, 14029, 14033, + 14051, 14057, 14071, 14081, 14083, 14087, 14107, 14143, + 14149, 14153, 14159, 14173, 14177, 14197, 14207, 14221, + 14243, 14249, 14251, 14281, 14293, 14303, 14321, 14323, + 14327, 14341, 14347, 14369, 14387, 14389, 14401, 14407, + 14411, 14419, 14423, 14431, 14437, 14447, 14449, 14461, + 14479, 14489, 14503, 14519, 14533, 14537, 14543, 14549, + 14551, 14557, 14561, 14563, 14591, 14593, 14621, 14627, + 14629, 14633, 14639, 14653, 14657, 14669, 14683, 14699, + 14713, 14717, 14723, 14731, 14737, 14741, 14747, 14753, + 14759, 14767, 14771, 14779, 14783, 14797, 14813, 14821, + 14827, 14831, 14843, 14851, 14867, 14869, 14879, 14887, + 14891, 14897, 14923, 14929, 14939, 14947, 14951, 14957, + 14969, 14983, 15013, 15017, 15031, 15053, 15061, 15073, + 15077, 15083, 15091, 15101, 15107, 15121, 15131, 15137, + 15139, 15149, 15161, 15173, 15187, 15193, 15199, 15217, + 15227, 15233, 15241, 15259, 15263, 15269, 15271, 15277, + 15287, 15289, 15299, 15307, 15313, 15319, 15329, 15331, + 15349, 15359, 15361, 15373, 15377, 15383, 15391, 15401, + 15413, 15427, 15439, 15443, 15451, 15461, 15467, 15473, + 15493, 15497, 15511, 15527, 15541, 15551, 15559, 15569, + 15581, 15583, 15601, 15607, 15619, 15629, 15641, 15643, + 15647, 15649, 15661, 15667, 15671, 15679, 15683, 15727, + 15731, 15733, 15737, 15739, 15749, 15761, 15767, 15773, + 15787, 15791, 15797, 15803, 15809, 15817, 15823, 15859, + 15877, 15881, 15887, 15889, 15901, 15907, 15913, 15919, + 15923, 15937, 15959, 15971, 15973, 15991, 16001, 16007, + 16033, 16057, 16061, 16063, 16067, 16069, 16073, 16087, + 16091, 16097, 16103, 16111, 16127, 16139, 16141, 16183, + 16187, 16189, 16193, 16217, 16223, 16229, 16231, 16249, + 16253, 16267, 16273, 16301, 16319, 16333, 16339, 16349, + 16361, 16363, 16369, 16381, 16411, 16417, 16421, 16427, + 16433, 16447, 16451, 16453, 16477, 16481, 16487, 16493, + 16519, 16529, 16547, 16553, 16561, 16567, 16573, 16603, + 16607, 16619, 16631, 16633, 16649, 16651, 16657, 16661, + 16673, 16691, 16693, 16699, 16703, 16729, 16741, 16747, + 16759, 16763, 16787, 16811, 16823, 16829, 16831, 16843, + 16871, 16879, 16883, 16889, 16901, 16903, 16921, 16927, + 16931, 16937, 16943, 16963, 16979, 16981, 16987, 16993, + 17011, 17021, 17027, 17029, 17033, 17041, 17047, 17053, + 17077, 17093, 17099, 17107, 17117, 17123, 17137, 17159, + 17167, 17183, 17189, 17191, 17203, 17207, 17209, 17231, + 17239, 17257, 17291, 17293, 17299, 17317, 17321, 17327, + 17333, 17341, 17351, 17359, 17377, 17383, 17387, 17389, + 17393, 17401, 17417, 17419, 17431, 17443, 17449, 17467, + 17471, 17477, 17483, 17489, 17491, 17497, 17509, 17519, + 17539, 17551, 17569, 17573, 17579, 17581, 17597, 17599, + 17609, 17623, 17627, 17657, 17659, 17669, 17681, 17683, + 17707, 17713, 17729, 17737, 17747, 17749, 17761, 17783, + 17789, 17791, 17807, 17827, 17837, 17839, 17851, 17863, #endif }; diff --git a/deps/openssl/openssl/crypto/bn/bn_prime.pl b/deps/openssl/openssl/crypto/bn/bn_prime.pl index 3fafb6f3e90aa8..6bede65e1dd45f 100644 --- a/deps/openssl/openssl/crypto/bn/bn_prime.pl +++ b/deps/openssl/openssl/crypto/bn/bn_prime.pl @@ -26,7 +26,7 @@ # * the code are not to be removed. # * See the COPYRIGHT file in the SSLeay distribution for more details. # */ -# +# # EOF print <<\EOF; @@ -37,21 +37,21 @@ * This package is an SSL implementation written * by Eric Young (eay@cryptsoft.com). * The implementation was written so as to conform with Netscapes SSL. - * + * * This library is free for commercial and non-commercial use as long as * the following conditions are aheared to. The following conditions * apply to all code found in this distribution, be it the RC4, RSA, * lhash, DES, etc., code; not just the SSL code. The SSL documentation * included with this distribution is covered by the same copyright terms * except that the holder is Tim Hudson (tjh@cryptsoft.com). - * + * * Copyright remains Eric Young's, and as such any Copyright notices in * the code are not to be removed. * If this package is used in a product, Eric Young should be given attribution * as the author of the parts of the library used. * This can be in the form of a textual message at program startup or * in documentation (online or textual) provided with the package. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -66,10 +66,10 @@ * Eric Young (eay@cryptsoft.com)" * The word 'cryptographic' can be left out if the rouines from the library * being used are not cryptographic related :-). - * 4. If you include any Windows specific code (or a derivative thereof) from + * 4. If you include any Windows specific code (or a derivative thereof) from * the apps directory (application code) you must include an acknowledgement: * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" - * + * * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -81,7 +81,7 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * + * * The licence and distribution terms for any publically available version or * derivative of this code cannot be changed. i.e. this code cannot simply be * copied and put under another distribution licence @@ -100,20 +100,20 @@ } printf "#ifndef EIGHT_BIT\n"; -printf "#define NUMPRIMES %d\n",$num; +printf "# define NUMPRIMES %d\n",$num; printf "typedef unsigned short prime_t;\n"; printf "#else\n"; -printf "#define NUMPRIMES %d\n",$eight; +printf "# define NUMPRIMES %d\n",$eight; printf "typedef unsigned char prime_t;\n"; printf "#endif\n"; -print "static const prime_t primes[NUMPRIMES]=\n\t{\n\t"; +print "static const prime_t primes[NUMPRIMES] = {"; $init=0; for ($i=0; $i <= $#primes; $i++) { - printf "\n#ifndef EIGHT_BIT\n\t" if ($primes[$i] > 256) && !($init++); - printf("\n\t") if (($i%8) == 0) && ($i != 0); - printf("%4d,",$primes[$i]); + printf "\n#ifndef EIGHT_BIT\n " if ($primes[$i] > 256) && !($init++); + printf("\n ") if ($i%8) == 0; + printf(" %5d,",$primes[$i]); } -print "\n#endif\n\t};\n"; +print "\n#endif\n};\n"; diff --git a/deps/openssl/openssl/crypto/bn/bn_print.c b/deps/openssl/openssl/crypto/bn/bn_print.c index f121fb6e9a08d8..f85a6550a54ee5 100644 --- a/deps/openssl/openssl/crypto/bn/bn_print.c +++ b/deps/openssl/openssl/crypto/bn/bn_print.c @@ -82,8 +82,6 @@ char *BN_bn2hex(const BIGNUM *a) p = buf; if (a->neg) *(p++) = '-'; - if (BN_is_zero(a)) - *(p++) = '0'; for (i = a->top - 1; i >= 0; i--) { for (j = BN_BITS2 - 8; j >= 0; j -= 8) { /* strip leading zeros */ diff --git a/deps/openssl/openssl/crypto/comp/c_rle.c b/deps/openssl/openssl/crypto/comp/c_rle.c index e9aabbd166a2ec..41919613eec5a3 100644 --- a/deps/openssl/openssl/crypto/comp/c_rle.c +++ b/deps/openssl/openssl/crypto/comp/c_rle.c @@ -31,12 +31,11 @@ static int rle_compress_block(COMP_CTX *ctx, unsigned char *out, unsigned int olen, unsigned char *in, unsigned int ilen) { - /* int i; */ + if (ilen == 0) + return 0; - if (ilen == 0 || olen < (ilen - 1)) { - /* ZZZZZZZZZZZZZZZZZZZZZZ */ - return (-1); - } + if (olen <= ilen) + return -1; *(out++) = 0; memcpy(out, in, ilen); @@ -49,14 +48,16 @@ static int rle_expand_block(COMP_CTX *ctx, unsigned char *out, { int i; - if (olen < (ilen - 1)) { - /* ZZZZZZZZZZZZZZZZZZZZZZ */ - return (-1); - } + if (ilen == 0) + return 0; + + if (olen < (ilen - 1)) + return -1; i = *(in++); - if (i == 0) { - memcpy(out, in, ilen - 1); - } + if (i != 0) + return -1; + + memcpy(out, in, ilen - 1); return (ilen - 1); } diff --git a/deps/openssl/openssl/crypto/conf/conf.h b/deps/openssl/openssl/crypto/conf/conf.h index 8d926d5d8268f5..fe49113080b700 100644 --- a/deps/openssl/openssl/crypto/conf/conf.h +++ b/deps/openssl/openssl/crypto/conf/conf.h @@ -259,6 +259,7 @@ void ERR_load_CONF_strings(void); # define CONF_R_NO_VALUE 108 # define CONF_R_UNABLE_TO_CREATE_NEW_SECTION 103 # define CONF_R_UNKNOWN_MODULE_NAME 113 +# define CONF_R_VARIABLE_EXPANSION_TOO_LONG 116 # define CONF_R_VARIABLE_HAS_NO_VALUE 104 #ifdef __cplusplus diff --git a/deps/openssl/openssl/crypto/conf/conf_def.c b/deps/openssl/openssl/crypto/conf/conf_def.c index 68c77cec7d8b46..75e309aaca8184 100644 --- a/deps/openssl/openssl/crypto/conf/conf_def.c +++ b/deps/openssl/openssl/crypto/conf/conf_def.c @@ -69,6 +69,12 @@ #include #include +/* + * The maximum length we can grow a value to after variable expansion. 64k + * should be more than enough for all reasonable uses. + */ +#define MAX_CONF_VALUE_LENGTH 65536 + static char *eat_ws(CONF *conf, char *p); static char *eat_alpha_numeric(CONF *conf, char *p); static void clear_comments(CONF *conf, char *p); @@ -530,6 +536,8 @@ static int str_copy(CONF *conf, char *section, char **pto, char *from) } else if (IS_EOF(conf, *from)) break; else if (*from == '$') { + size_t newsize; + /* try to expand it */ rrp = NULL; s = &(from[1]); @@ -584,8 +592,12 @@ static int str_copy(CONF *conf, char *section, char **pto, char *from) CONFerr(CONF_F_STR_COPY, CONF_R_VARIABLE_HAS_NO_VALUE); goto err; } - if (!BUF_MEM_grow_clean(buf, - (strlen(p) + buf->length - (e - from)))) { + newsize = strlen(p) + buf->length - (e - from); + if (newsize > MAX_CONF_VALUE_LENGTH) { + CONFerr(CONF_F_STR_COPY, CONF_R_VARIABLE_EXPANSION_TOO_LONG); + goto err; + } + if (!BUF_MEM_grow_clean(buf, newsize)) { CONFerr(CONF_F_STR_COPY, ERR_R_MALLOC_FAILURE); goto err; } diff --git a/deps/openssl/openssl/crypto/conf/conf_err.c b/deps/openssl/openssl/crypto/conf/conf_err.c index bb5e2fe25215b8..b0b6896f837ee8 100644 --- a/deps/openssl/openssl/crypto/conf/conf_err.c +++ b/deps/openssl/openssl/crypto/conf/conf_err.c @@ -115,6 +115,8 @@ static ERR_STRING_DATA CONF_str_reasons[] = { {ERR_REASON(CONF_R_UNABLE_TO_CREATE_NEW_SECTION), "unable to create new section"}, {ERR_REASON(CONF_R_UNKNOWN_MODULE_NAME), "unknown module name"}, + {ERR_REASON(CONF_R_VARIABLE_EXPANSION_TOO_LONG), + "variable expansion too long"}, {ERR_REASON(CONF_R_VARIABLE_HAS_NO_VALUE), "variable has no value"}, {0, NULL} }; diff --git a/deps/openssl/openssl/crypto/des/Makefile b/deps/openssl/openssl/crypto/des/Makefile index 8b5166ca9ff5fa..89156ba5ce2dcc 100644 --- a/deps/openssl/openssl/crypto/des/Makefile +++ b/deps/openssl/openssl/crypto/des/Makefile @@ -107,7 +107,7 @@ dclean: mv -f Makefile.new $(MAKEFILE) clean: - rm -f *.s *.o *.obj des lib tags core .pure .nfs* *.old *.bak fluff + rm -f *.s *.S *.o *.obj des lib tags core .pure .nfs* *.old *.bak fluff # DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/deps/openssl/openssl/crypto/des/set_key.c b/deps/openssl/openssl/crypto/des/set_key.c index 8fd8fe14bb6316..d9c5e7fcb3bbfb 100644 --- a/deps/openssl/openssl/crypto/des/set_key.c +++ b/deps/openssl/openssl/crypto/des/set_key.c @@ -120,7 +120,7 @@ int DES_check_key_parity(const_DES_cblock *key) } /*- - * Weak and semi week keys as take from + * Weak and semi weak keys as taken from * %A D.W. Davies * %A W.L. Price * %T Security for Computer Networks diff --git a/deps/openssl/openssl/crypto/dh/dh.h b/deps/openssl/openssl/crypto/dh/dh.h index a5bd9016aae85a..a228c7a7a4c3a1 100644 --- a/deps/openssl/openssl/crypto/dh/dh.h +++ b/deps/openssl/openssl/crypto/dh/dh.h @@ -182,12 +182,29 @@ struct dh_st { */ # define DH_CHECK_P_NOT_STRONG_PRIME DH_CHECK_P_NOT_SAFE_PRIME -# define d2i_DHparams_fp(fp,x) (DH *)ASN1_d2i_fp((char *(*)())DH_new, \ - (char *(*)())d2i_DHparams,(fp),(unsigned char **)(x)) -# define i2d_DHparams_fp(fp,x) ASN1_i2d_fp(i2d_DHparams,(fp), \ - (unsigned char *)(x)) -# define d2i_DHparams_bio(bp,x) ASN1_d2i_bio_of(DH,DH_new,d2i_DHparams,bp,x) -# define i2d_DHparams_bio(bp,x) ASN1_i2d_bio_of_const(DH,i2d_DHparams,bp,x) +# define d2i_DHparams_fp(fp,x) \ + (DH *)ASN1_d2i_fp((char *(*)())DH_new, \ + (char *(*)())d2i_DHparams, \ + (fp), \ + (unsigned char **)(x)) +# define i2d_DHparams_fp(fp,x) \ + ASN1_i2d_fp(i2d_DHparams,(fp), (unsigned char *)(x)) +# define d2i_DHparams_bio(bp,x) \ + ASN1_d2i_bio_of(DH, DH_new, d2i_DHparams, bp, x) +# define i2d_DHparams_bio(bp,x) \ + ASN1_i2d_bio_of_const(DH,i2d_DHparams,bp,x) + +# define d2i_DHxparams_fp(fp,x) \ + (DH *)ASN1_d2i_fp((char *(*)())DH_new, \ + (char *(*)())d2i_DHxparams, \ + (fp), \ + (unsigned char **)(x)) +# define i2d_DHxparams_fp(fp,x) \ + ASN1_i2d_fp(i2d_DHxparams,(fp), (unsigned char *)(x)) +# define d2i_DHxparams_bio(bp,x) \ + ASN1_d2i_bio_of(DH, DH_new, d2i_DHxparams, bp, x) +# define i2d_DHxparams_bio(bp,x) \ + ASN1_i2d_bio_of_const(DH, i2d_DHxparams, bp, x) DH *DHparams_dup(DH *); diff --git a/deps/openssl/openssl/crypto/ec/ec_ameth.c b/deps/openssl/openssl/crypto/ec/ec_ameth.c index d089af7a28300b..2c41c6e7a9f181 100644 --- a/deps/openssl/openssl/crypto/ec/ec_ameth.c +++ b/deps/openssl/openssl/crypto/ec/ec_ameth.c @@ -342,8 +342,10 @@ static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) } if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0, - ptype, pval, ep, eplen)) + ptype, pval, ep, eplen)) { + OPENSSL_free(ep); return 0; + } return 1; } diff --git a/deps/openssl/openssl/crypto/ec/ec_asn1.c b/deps/openssl/openssl/crypto/ec/ec_asn1.c index 33abf61f44417c..b0cd3e1788dcae 100644 --- a/deps/openssl/openssl/crypto/ec/ec_asn1.c +++ b/deps/openssl/openssl/crypto/ec/ec_asn1.c @@ -62,17 +62,22 @@ #include #include +#define OSSL_NELEM(x) (sizeof(x)/sizeof(x[0])) + int EC_GROUP_get_basis_type(const EC_GROUP *group) { - int i = 0; + int i; if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != NID_X9_62_characteristic_two_field) /* everything else is currently not supported */ return 0; - while (group->poly[i] != 0) - i++; + /* Find the last non-zero element of group->poly[] */ + for (i = 0; + i < (int)OSSL_NELEM(group->poly) && group->poly[i] != 0; + i++) + continue; if (i == 4) return NID_X9_62_ppBasis; diff --git a/deps/openssl/openssl/crypto/ec/ec_mult.c b/deps/openssl/openssl/crypto/ec/ec_mult.c index 23b8c3089b2fa8..24ca67a6ef1e71 100644 --- a/deps/openssl/openssl/crypto/ec/ec_mult.c +++ b/deps/openssl/openssl/crypto/ec/ec_mult.c @@ -68,10 +68,14 @@ #include "ec_lcl.h" /* - * This file implements the wNAF-based interleaving multi-exponentation method - * (); - * for multiplication with precomputation, we use wNAF splitting - * (). + * This file implements the wNAF-based interleaving multi-exponentiation method + * Formerly at: + * http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#multiexp + * You might now find it here: + * http://link.springer.com/chapter/10.1007%2F3-540-45537-X_13 + * http://www.bmoeller.de/pdf/TI-01-08.multiexp.pdf + * For multiplication with precomputation, we use wNAF splitting, formerly at: + * http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#fastexp */ /* structure for precomputed multiples of the generator */ diff --git a/deps/openssl/openssl/crypto/ec/eck_prn.c b/deps/openssl/openssl/crypto/ec/eck_prn.c index df9b37a750d625..176ec1f17308bd 100644 --- a/deps/openssl/openssl/crypto/ec/eck_prn.c +++ b/deps/openssl/openssl/crypto/ec/eck_prn.c @@ -342,7 +342,7 @@ static int print_bin(BIO *fp, const char *name, const unsigned char *buf, size_t len, int off) { size_t i; - char str[128]; + char str[128 + 1 + 4]; if (buf == NULL) return 1; diff --git a/deps/openssl/openssl/crypto/engine/eng_cryptodev.c b/deps/openssl/openssl/crypto/engine/eng_cryptodev.c index 2a2b95ce837e24..af59471c4771cf 100644 --- a/deps/openssl/openssl/crypto/engine/eng_cryptodev.c +++ b/deps/openssl/openssl/crypto/engine/eng_cryptodev.c @@ -810,14 +810,15 @@ static int cryptodev_digest_update(EVP_MD_CTX *ctx, const void *data, if (!(ctx->flags & EVP_MD_CTX_FLAG_ONESHOT)) { /* if application doesn't support one buffer */ - state->mac_data = + char *mac_data = OPENSSL_realloc(state->mac_data, state->mac_len + count); - if (!state->mac_data) { + if (mac_data == NULL) { printf("cryptodev_digest_update: realloc failed\n"); return (0); } + state->mac_data = mac_data; memcpy(state->mac_data + state->mac_len, data, count); state->mac_len += count; diff --git a/deps/openssl/openssl/crypto/err/err.c b/deps/openssl/openssl/crypto/err/err.c index 52dc9a5ddd873c..0b1fcfc1f1a5de 100644 --- a/deps/openssl/openssl/crypto/err/err.c +++ b/deps/openssl/openssl/crypto/err/err.c @@ -172,6 +172,7 @@ static ERR_STRING_DATA ERR_str_functs[] = { # endif {ERR_PACK(0, SYS_F_OPENDIR, 0), "opendir"}, {ERR_PACK(0, SYS_F_FREAD, 0), "fread"}, + {ERR_PACK(0, SYS_F_FFLUSH, 0), "fflush"}, {0, NULL}, }; diff --git a/deps/openssl/openssl/crypto/err/err.h b/deps/openssl/openssl/crypto/err/err.h index 585aa8ba3df935..f42365620db0c0 100644 --- a/deps/openssl/openssl/crypto/err/err.h +++ b/deps/openssl/openssl/crypto/err/err.h @@ -258,6 +258,7 @@ typedef struct err_state_st { # define SYS_F_WSASTARTUP 9/* Winsock stuff */ # define SYS_F_OPENDIR 10 # define SYS_F_FREAD 11 +# define SYS_F_FFLUSH 18 /* reasons */ # define ERR_R_SYS_LIB ERR_LIB_SYS/* 2 */ diff --git a/deps/openssl/openssl/crypto/evp/e_aes.c b/deps/openssl/openssl/crypto/evp/e_aes.c index 7c62d327a1f613..b45b364466acb8 100644 --- a/deps/openssl/openssl/crypto/evp/e_aes.c +++ b/deps/openssl/openssl/crypto/evp/e_aes.c @@ -1120,6 +1120,8 @@ BLOCK_CIPHER_generic_pack(NID_aes, 128, EVP_CIPH_FLAG_FIPS) static int aes_gcm_cleanup(EVP_CIPHER_CTX *c) { EVP_AES_GCM_CTX *gctx = c->cipher_data; + if (gctx == NULL) + return 0; OPENSSL_cleanse(&gctx->gcm, sizeof(gctx->gcm)); if (gctx->iv != c->iv) OPENSSL_free(gctx->iv); @@ -1235,10 +1237,15 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) { unsigned int len = c->buf[arg - 2] << 8 | c->buf[arg - 1]; /* Correct length for explicit IV */ + if (len < EVP_GCM_TLS_EXPLICIT_IV_LEN) + return 0; len -= EVP_GCM_TLS_EXPLICIT_IV_LEN; /* If decrypting correct for tag too */ - if (!c->encrypt) + if (!c->encrypt) { + if (len < EVP_GCM_TLS_TAG_LEN) + return 0; len -= EVP_GCM_TLS_TAG_LEN; + } c->buf[arg - 2] = len >> 8; c->buf[arg - 1] = len & 0xff; } diff --git a/deps/openssl/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c b/deps/openssl/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c index 6dfd590a4a2c8e..d114710e98ec4e 100644 --- a/deps/openssl/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c +++ b/deps/openssl/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c @@ -859,6 +859,8 @@ static int aesni_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, key->payload_length = len; if ((key->aux.tls_ver = p[arg - 4] << 8 | p[arg - 3]) >= TLS1_1_VERSION) { + if (len < AES_BLOCK_SIZE) + return 0; len -= AES_BLOCK_SIZE; p[arg - 2] = len >> 8; p[arg - 1] = len; diff --git a/deps/openssl/openssl/crypto/evp/e_aes_cbc_hmac_sha256.c b/deps/openssl/openssl/crypto/evp/e_aes_cbc_hmac_sha256.c index 46c9d033895b87..917ae0751dee3f 100644 --- a/deps/openssl/openssl/crypto/evp/e_aes_cbc_hmac_sha256.c +++ b/deps/openssl/openssl/crypto/evp/e_aes_cbc_hmac_sha256.c @@ -825,15 +825,19 @@ static int aesni_cbc_hmac_sha256_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, case EVP_CTRL_AEAD_TLS1_AAD: { unsigned char *p = ptr; - unsigned int len = p[arg - 2] << 8 | p[arg - 1]; + unsigned int len; if (arg != EVP_AEAD_TLS1_AAD_LEN) return -1; + len = p[arg - 2] << 8 | p[arg - 1]; + if (ctx->encrypt) { key->payload_length = len; if ((key->aux.tls_ver = p[arg - 4] << 8 | p[arg - 3]) >= TLS1_1_VERSION) { + if (len < AES_BLOCK_SIZE) + return 0; len -= AES_BLOCK_SIZE; p[arg - 2] = len >> 8; p[arg - 1] = len; diff --git a/deps/openssl/openssl/crypto/evp/e_des3.c b/deps/openssl/openssl/crypto/evp/e_des3.c index 0e910d6d8085b9..ab8126e5c9cf68 100644 --- a/deps/openssl/openssl/crypto/evp/e_des3.c +++ b/deps/openssl/openssl/crypto/evp/e_des3.c @@ -212,6 +212,8 @@ static int des_ede3_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, size_t n; unsigned char c[1], d[1]; + if (!EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS)) + inl *= 8; for (n = 0; n < inl; ++n) { c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0; DES_ede3_cfb_encrypt(c, d, 1, 1, diff --git a/deps/openssl/openssl/crypto/evp/evp_enc.c b/deps/openssl/openssl/crypto/evp/evp_enc.c index 0e40f09f2f91f4..be577bac767fe9 100644 --- a/deps/openssl/openssl/crypto/evp/evp_enc.c +++ b/deps/openssl/openssl/crypto/evp/evp_enc.c @@ -182,6 +182,7 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, if (ctx->cipher->ctx_size) { ctx->cipher_data = OPENSSL_malloc(ctx->cipher->ctx_size); if (!ctx->cipher_data) { + ctx->cipher = NULL; EVPerr(EVP_F_EVP_CIPHERINIT_EX, ERR_R_MALLOC_FAILURE); return 0; } @@ -193,6 +194,7 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, ctx->flags &= EVP_CIPHER_CTX_FLAG_WRAP_ALLOW; if (ctx->cipher->flags & EVP_CIPH_CTRL_INIT) { if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL)) { + ctx->cipher = NULL; EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR); return 0; } @@ -654,6 +656,7 @@ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) if (in->cipher_data && in->cipher->ctx_size) { out->cipher_data = OPENSSL_malloc(in->cipher->ctx_size); if (!out->cipher_data) { + out->cipher = NULL; EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, ERR_R_MALLOC_FAILURE); return 0; } @@ -661,6 +664,10 @@ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) } if (in->cipher->flags & EVP_CIPH_CUSTOM_COPY) - return in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out); + if (!in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out)) { + out->cipher = NULL; + EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, EVP_R_INITIALIZATION_ERROR); + return 0; + } return 1; } diff --git a/deps/openssl/openssl/crypto/evp/pmeth_lib.c b/deps/openssl/openssl/crypto/evp/pmeth_lib.c index d06686290459c7..b7b7bdcd0290e6 100644 --- a/deps/openssl/openssl/crypto/evp/pmeth_lib.c +++ b/deps/openssl/openssl/crypto/evp/pmeth_lib.c @@ -188,6 +188,7 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) if (pmeth->init) { if (pmeth->init(ret) <= 0) { + ret->pmeth = NULL; EVP_PKEY_CTX_free(ret); return NULL; } @@ -315,6 +316,7 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx) if (pctx->pmeth->copy(rctx, pctx) > 0) return rctx; + rctx->pmeth = NULL; EVP_PKEY_CTX_free(rctx); return NULL; diff --git a/deps/openssl/openssl/crypto/ex_data.c b/deps/openssl/openssl/crypto/ex_data.c index f96a51781ab065..108a1959eacfc2 100644 --- a/deps/openssl/openssl/crypto/ex_data.c +++ b/deps/openssl/openssl/crypto/ex_data.c @@ -331,7 +331,11 @@ static EX_CLASS_ITEM *def_get_class(int class_index) * from the insert will be NULL */ (void)lh_EX_CLASS_ITEM_insert(ex_data, gen); - p = gen; + p = lh_EX_CLASS_ITEM_retrieve(ex_data, &d); + if (p != gen) { + sk_CRYPTO_EX_DATA_FUNCS_free(gen->meth); + OPENSSL_free(gen); + } } } } @@ -455,7 +459,7 @@ static int int_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from) { int mx, j, i; - char *ptr; + void *ptr; CRYPTO_EX_DATA_FUNCS **storage = NULL; EX_CLASS_ITEM *item; if (!from->sk) @@ -469,6 +473,8 @@ static int int_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, if (j < mx) mx = j; if (mx > 0) { + if (!CRYPTO_set_ex_data(to, mx - 1, NULL)) + goto skip; storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS *)); if (!storage) goto skip; @@ -499,11 +505,12 @@ static void int_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) int mx, i; EX_CLASS_ITEM *item; void *ptr; + CRYPTO_EX_DATA_FUNCS *f; CRYPTO_EX_DATA_FUNCS **storage = NULL; if (ex_data == NULL) - return; + goto err; if ((item = def_get_class(class_index)) == NULL) - return; + goto err; CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA); mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth); if (mx > 0) { @@ -515,23 +522,23 @@ static void int_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) } skip: CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA); - if ((mx > 0) && !storage) { - CRYPTOerr(CRYPTO_F_INT_FREE_EX_DATA, ERR_R_MALLOC_FAILURE); - return; - } for (i = 0; i < mx; i++) { - if (storage[i] && storage[i]->free_func) { + if (storage != NULL) + f = storage[i]; + else { + CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA); + f = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth, i); + CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA); + } + if (f != NULL && f->free_func != NULL) { ptr = CRYPTO_get_ex_data(ad, i); - storage[i]->free_func(obj, ptr, ad, i, - storage[i]->argl, storage[i]->argp); + f->free_func(obj, ptr, ad, i, f->argl, f->argp); } } - if (storage) - OPENSSL_free(storage); - if (ad->sk) { - sk_void_free(ad->sk); - ad->sk = NULL; - } + OPENSSL_free(storage); + err: + sk_void_free(ad->sk); + ad->sk = NULL; } /********************************************************************/ diff --git a/deps/openssl/openssl/crypto/hmac/hm_pmeth.c b/deps/openssl/openssl/crypto/hmac/hm_pmeth.c index 0ffff79cc4503b..0a59a01cf0e81f 100644 --- a/deps/openssl/openssl/crypto/hmac/hm_pmeth.c +++ b/deps/openssl/openssl/crypto/hmac/hm_pmeth.c @@ -99,15 +99,18 @@ static int pkey_hmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) sctx = src->data; dctx = dst->data; dctx->md = sctx->md; - HMAC_CTX_init(&dctx->ctx); if (!HMAC_CTX_copy(&dctx->ctx, &sctx->ctx)) - return 0; - if (sctx->ktmp.data) { + goto err; + if (sctx->ktmp.data != NULL) { if (!ASN1_OCTET_STRING_set(&dctx->ktmp, sctx->ktmp.data, sctx->ktmp.length)) - return 0; + goto err; } return 1; + err: + HMAC_CTX_cleanup(&dctx->ctx); + OPENSSL_free(dctx); + return 0; } static void pkey_hmac_cleanup(EVP_PKEY_CTX *ctx) diff --git a/deps/openssl/openssl/crypto/include/internal/bn_conf.h b/deps/openssl/openssl/crypto/include/internal/bn_conf.h new file mode 100644 index 00000000000000..34bd8b78b4f90f --- /dev/null +++ b/deps/openssl/openssl/crypto/include/internal/bn_conf.h @@ -0,0 +1,28 @@ +/* WARNING: do not edit! */ +/* Generated by Makefile from crypto/include/internal/bn_conf.h.in */ +/* + * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_BN_CONF_H +# define HEADER_BN_CONF_H + +/* + * The contents of this file are not used in the UEFI build, as + * both 32-bit and 64-bit builds are supported from a single run + * of the Configure script. + */ + +/* Should we define BN_DIV2W here? */ + +/* Only one for the following should be defined */ +#define SIXTY_FOUR_BIT_LONG +#undef SIXTY_FOUR_BIT +#undef THIRTY_TWO_BIT + +#endif diff --git a/deps/openssl/openssl/crypto/include/internal/dso_conf.h b/deps/openssl/openssl/crypto/include/internal/dso_conf.h new file mode 100644 index 00000000000000..7a52dd1f1a1159 --- /dev/null +++ b/deps/openssl/openssl/crypto/include/internal/dso_conf.h @@ -0,0 +1,16 @@ +/* WARNING: do not edit! */ +/* Generated by Makefile from crypto/include/internal/dso_conf.h.in */ +/* + * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_DSO_CONF_H +# define HEADER_DSO_CONF_H + +# define DSO_EXTENSION ".so" +#endif diff --git a/deps/openssl/openssl/crypto/md5/Makefile b/deps/openssl/openssl/crypto/md5/Makefile index f5240da74cd791..9942cb4e37a692 100644 --- a/deps/openssl/openssl/crypto/md5/Makefile +++ b/deps/openssl/openssl/crypto/md5/Makefile @@ -90,7 +90,7 @@ dclean: mv -f Makefile.new $(MAKEFILE) clean: - rm -f *.s *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff + rm -f *.s *.S *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff # DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/deps/openssl/openssl/crypto/mem.c b/deps/openssl/openssl/crypto/mem.c index 06c3960cc6c05b..dd4c9ce9e0b86b 100644 --- a/deps/openssl/openssl/crypto/mem.c +++ b/deps/openssl/openssl/crypto/mem.c @@ -150,12 +150,12 @@ static long (*get_debug_options_func) (void) = NULL; int CRYPTO_set_mem_functions(void *(*m) (size_t), void *(*r) (void *, size_t), void (*f) (void *)) { - /* Dummy call just to ensure OPENSSL_init() gets linked in */ - OPENSSL_init(); if (!allow_customize) return 0; if ((m == 0) || (r == 0) || (f == 0)) return 0; + /* Dummy call just to ensure OPENSSL_init() gets linked in */ + OPENSSL_init(); malloc_func = m; malloc_ex_func = default_malloc_ex; realloc_func = r; diff --git a/deps/openssl/openssl/crypto/modes/Makefile b/deps/openssl/openssl/crypto/modes/Makefile index a7863d98be2f5c..2528f4a1b9cad4 100644 --- a/deps/openssl/openssl/crypto/modes/Makefile +++ b/deps/openssl/openssl/crypto/modes/Makefile @@ -106,7 +106,7 @@ dclean: mv -f Makefile.new $(MAKEFILE) clean: - rm -f *.s *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff + rm -f *.s *.S *.o */*.o *.obj lib tags core .pure .nfs* *.old *.bak fluff # DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/deps/openssl/openssl/crypto/o_dir.c b/deps/openssl/openssl/crypto/o_dir.c index f9dbed87112793..fb3b2fd8e4370f 100644 --- a/deps/openssl/openssl/crypto/o_dir.c +++ b/deps/openssl/openssl/crypto/o_dir.c @@ -73,7 +73,8 @@ #include "o_dir.h" #define LPDIR_H -#if defined OPENSSL_SYS_UNIX || defined DJGPP +#if defined OPENSSL_SYS_UNIX || defined DJGPP \ + || (defined __VMS_VER && __VMS_VER >= 70000000) # include "LPdir_unix.c" #elif defined OPENSSL_SYS_VMS # include "LPdir_vms.c" diff --git a/deps/openssl/openssl/crypto/o_time.c b/deps/openssl/openssl/crypto/o_time.c index b99e5990b4e4e9..04d805d9a96d04 100755 --- a/deps/openssl/openssl/crypto/o_time.c +++ b/deps/openssl/openssl/crypto/o_time.c @@ -106,11 +106,8 @@ struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result) struct tm *ts = NULL; #if defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_SYS_OS2) && (!defined(OPENSSL_SYS_VMS) || defined(gmtime_r)) && !defined(OPENSSL_SYS_MACOSX) && !defined(OPENSSL_SYS_SUNOS) - /* - * should return &data, but doesn't on some systems, so we don't even - * look at the return value - */ - gmtime_r(timer, result); + if (gmtime_r(timer, result) == NULL) + return NULL; ts = result; #elif !defined(OPENSSL_SYS_VMS) || defined(VMS_GMTIME_OK) ts = gmtime(timer); diff --git a/deps/openssl/openssl/crypto/opensslv.h b/deps/openssl/openssl/crypto/opensslv.h index 645dd0793f32e0..825a330abc8825 100644 --- a/deps/openssl/openssl/crypto/opensslv.h +++ b/deps/openssl/openssl/crypto/opensslv.h @@ -30,11 +30,11 @@ extern "C" { * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for * major minor fix final patch/beta) */ -# define OPENSSL_VERSION_NUMBER 0x100020bfL +# define OPENSSL_VERSION_NUMBER 0x100020cfL # ifdef OPENSSL_FIPS -# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2k-fips 26 Jan 2017" +# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2l-fips 25 May 2017" # else -# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2k 26 Jan 2017" +# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2l 25 May 2017" # endif # define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT diff --git a/deps/openssl/openssl/crypto/perlasm/x86_64-xlate.pl b/deps/openssl/openssl/crypto/perlasm/x86_64-xlate.pl index 79cd2d4f65b1e1..d19195ea06a87d 100755 --- a/deps/openssl/openssl/crypto/perlasm/x86_64-xlate.pl +++ b/deps/openssl/openssl/crypto/perlasm/x86_64-xlate.pl @@ -415,7 +415,7 @@ } } } -{ package expr; # pick up expressioins +{ package expr; # pick up expressions sub re { my $self = shift; # single instance is enough... local *line = shift; @@ -978,7 +978,7 @@ sub rxb { # the area above user stack pointer in true asynchronous manner... # # All the above means that if assembler programmer adheres to Unix -# register and stack layout, but disregards the "red zone" existense, +# register and stack layout, but disregards the "red zone" existence, # it's possible to use following prologue and epilogue to "gear" from # Unix to Win64 ABI in leaf functions with not more than 6 arguments. # diff --git a/deps/openssl/openssl/crypto/pkcs12/p12_mutl.c b/deps/openssl/openssl/crypto/pkcs12/p12_mutl.c index cbf34da05adadb..b1f7381a6fb5e4 100644 --- a/deps/openssl/openssl/crypto/pkcs12/p12_mutl.c +++ b/deps/openssl/openssl/crypto/pkcs12/p12_mutl.c @@ -159,7 +159,10 @@ int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen, int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen, const EVP_MD *md_type) { - if (!(p12->mac = PKCS12_MAC_DATA_new())) + PKCS12_MAC_DATA_free(p12->mac); + p12->mac = NULL; + + if ((p12->mac = PKCS12_MAC_DATA_new()) == NULL) return PKCS12_ERROR; if (iter > 1) { if (!(p12->mac->iter = M_ASN1_INTEGER_new())) { diff --git a/deps/openssl/openssl/crypto/ppccap.c b/deps/openssl/openssl/crypto/ppccap.c index 74af4732b5fa8d..60566b1a5f52fb 100644 --- a/deps/openssl/openssl/crypto/ppccap.c +++ b/deps/openssl/openssl/crypto/ppccap.c @@ -7,6 +7,10 @@ #if defined(__linux) || defined(_AIX) # include #endif +#if defined(__APPLE__) && defined(__MACH__) +# include +# include +#endif #include #include @@ -123,6 +127,26 @@ void OPENSSL_cpuid_setup(void) } #endif +#if defined(__APPLE__) && defined(__MACH__) + { + int val; + size_t len = sizeof(val); + + if (sysctlbyname("hw.optional.64bitops", &val, &len, NULL, 0) == 0) { + if (val) + OPENSSL_ppccap_P |= PPC_FPU64; + } + + len = sizeof(val); + if (sysctlbyname("hw.optional.altivec", &val, &len, NULL, 0) == 0) { + if (val) + OPENSSL_ppccap_P |= PPC_ALTIVEC; + } + + return; + } +#endif + memset(&ill_act, 0, sizeof(ill_act)); ill_act.sa_handler = ill_handler; ill_act.sa_mask = all_masked; diff --git a/deps/openssl/openssl/crypto/rand/md_rand.c b/deps/openssl/openssl/crypto/rand/md_rand.c index bd76e23e3deb33..29e465b07524b1 100644 --- a/deps/openssl/openssl/crypto/rand/md_rand.c +++ b/deps/openssl/openssl/crypto/rand/md_rand.c @@ -266,17 +266,21 @@ static void ssleay_rand_add(const void *buf, int num, double add) j = (num - i); j = (j > MD_DIGEST_LENGTH) ? MD_DIGEST_LENGTH : j; - MD_Init(&m); - MD_Update(&m, local_md, MD_DIGEST_LENGTH); + if (!MD_Init(&m) || + !MD_Update(&m, local_md, MD_DIGEST_LENGTH)) + goto err; k = (st_idx + j) - STATE_SIZE; if (k > 0) { - MD_Update(&m, &(state[st_idx]), j - k); - MD_Update(&m, &(state[0]), k); + if (!MD_Update(&m, &(state[st_idx]), j - k) || + !MD_Update(&m, &(state[0]), k)) + goto err; } else - MD_Update(&m, &(state[st_idx]), j); + if (!MD_Update(&m, &(state[st_idx]), j)) + goto err; /* DO NOT REMOVE THE FOLLOWING CALL TO MD_Update()! */ - MD_Update(&m, buf, j); + if (!MD_Update(&m, buf, j)) + goto err; /* * We know that line may cause programs such as purify and valgrind * to complain about use of uninitialized data. The problem is not, @@ -285,8 +289,9 @@ static void ssleay_rand_add(const void *buf, int num, double add) * insecure keys. */ - MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c)); - MD_Final(&m, local_md); + if (!MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c)) || + !MD_Final(&m, local_md)) + goto err; md_c[1]++; buf = (const char *)buf + j; @@ -305,7 +310,6 @@ static void ssleay_rand_add(const void *buf, int num, double add) st_idx = 0; } } - EVP_MD_CTX_cleanup(&m); if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND); @@ -326,6 +330,9 @@ static void ssleay_rand_add(const void *buf, int num, double add) #if !defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) assert(md_c[1] == md_count[1]); #endif + + err: + EVP_MD_CTX_cleanup(&m); } static void ssleay_rand_seed(const void *buf, int num) @@ -469,15 +476,18 @@ int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock) /* num_ceil -= MD_DIGEST_LENGTH/2 */ j = (num >= MD_DIGEST_LENGTH / 2) ? MD_DIGEST_LENGTH / 2 : num; num -= j; - MD_Init(&m); + if (!MD_Init(&m)) + goto err; #ifndef GETPID_IS_MEANINGLESS if (curr_pid) { /* just in the first iteration to save time */ - MD_Update(&m, (unsigned char *)&curr_pid, sizeof curr_pid); + if (!MD_Update(&m, (unsigned char *)&curr_pid, sizeof curr_pid)) + goto err; curr_pid = 0; } #endif - MD_Update(&m, local_md, MD_DIGEST_LENGTH); - MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c)); + if (!MD_Update(&m, local_md, MD_DIGEST_LENGTH) || + !MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c))) + goto err; #ifndef PURIFY /* purify complains */ /* @@ -487,16 +497,21 @@ int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock) * builds it is not used: the removal of such a small source of * entropy has negligible impact on security. */ - MD_Update(&m, buf, j); + if (!MD_Update(&m, buf, j)) + goto err; #endif k = (st_idx + MD_DIGEST_LENGTH / 2) - st_num; if (k > 0) { - MD_Update(&m, &(state[st_idx]), MD_DIGEST_LENGTH / 2 - k); - MD_Update(&m, &(state[0]), k); - } else - MD_Update(&m, &(state[st_idx]), MD_DIGEST_LENGTH / 2); - MD_Final(&m, local_md); + if (!MD_Update(&m, &(state[st_idx]), MD_DIGEST_LENGTH / 2 - k) || + !MD_Update(&m, &(state[0]), k)) + goto err; + } else { + if (!MD_Update(&m, &(state[st_idx]), MD_DIGEST_LENGTH / 2)) + goto err; + } + if (!MD_Final(&m, local_md)) + goto err; for (i = 0; i < MD_DIGEST_LENGTH / 2; i++) { /* may compete with other threads */ @@ -508,13 +523,18 @@ int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock) } } - MD_Init(&m); - MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c)); - MD_Update(&m, local_md, MD_DIGEST_LENGTH); + if (!MD_Init(&m) || + !MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c)) || + !MD_Update(&m, local_md, MD_DIGEST_LENGTH)) + goto err; if (lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND); - MD_Update(&m, md, MD_DIGEST_LENGTH); - MD_Final(&m, md); + if (!MD_Update(&m, md, MD_DIGEST_LENGTH) || + !MD_Final(&m, md)) { + if (lock) + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + goto err; + } if (lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND); @@ -529,6 +549,10 @@ int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock) "http://www.openssl.org/support/faq.html"); return (0); } + + err: + EVP_MD_CTX_cleanup(&m); + return (0); } static int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num) diff --git a/deps/openssl/openssl/crypto/rc4/Makefile b/deps/openssl/openssl/crypto/rc4/Makefile index 7434ff737e6613..a495324cc6b5ae 100644 --- a/deps/openssl/openssl/crypto/rc4/Makefile +++ b/deps/openssl/openssl/crypto/rc4/Makefile @@ -100,7 +100,7 @@ dclean: mv -f Makefile.new $(MAKEFILE) clean: - rm -f *.s *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff + rm -f *.s *.S *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff # DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/deps/openssl/openssl/crypto/rsa/rsa_pmeth.c b/deps/openssl/openssl/crypto/rsa/rsa_pmeth.c index ac583bf60b0181..8896e2e977149b 100644 --- a/deps/openssl/openssl/crypto/rsa/rsa_pmeth.c +++ b/deps/openssl/openssl/crypto/rsa/rsa_pmeth.c @@ -446,19 +446,14 @@ static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, int ret; RSA_PKEY_CTX *rctx = ctx->data; if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) { - int i; if (!setup_tbuf(rctx, ctx)) return -1; ret = RSA_private_decrypt(inlen, in, rctx->tbuf, ctx->pkey->pkey.rsa, RSA_NO_PADDING); if (ret <= 0) return ret; - for (i = 0; i < ret; i++) { - if (rctx->tbuf[i]) - break; - } - ret = RSA_padding_check_PKCS1_OAEP_mgf1(out, ret, rctx->tbuf + i, - ret - i, ret, + ret = RSA_padding_check_PKCS1_OAEP_mgf1(out, ret, rctx->tbuf, + ret, ret, rctx->oaep_label, rctx->oaep_labellen, rctx->md, rctx->mgf1md); diff --git a/deps/openssl/openssl/crypto/rsa/rsa_pss.c b/deps/openssl/openssl/crypto/rsa/rsa_pss.c index 41bc0844e48ed9..2c3fd73b0996a9 100644 --- a/deps/openssl/openssl/crypto/rsa/rsa_pss.c +++ b/deps/openssl/openssl/crypto/rsa/rsa_pss.c @@ -122,7 +122,11 @@ int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash, EM++; emLen--; } - if (emLen < (hLen + sLen + 2)) { /* sLen can be small negative */ + if (emLen < hLen + 2) { + RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE); + goto err; + } + if (sLen > emLen - hLen - 2) { /* sLen can be small negative */ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE); goto err; } @@ -222,9 +226,14 @@ int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM, *EM++ = 0; emLen--; } + if (emLen < hLen + 2) { + RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, + RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + goto err; + } if (sLen == -2) { sLen = emLen - hLen - 2; - } else if (emLen < (hLen + sLen + 2)) { + } else if (sLen > emLen - hLen - 2) { RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); goto err; diff --git a/deps/openssl/openssl/crypto/sha/Makefile b/deps/openssl/openssl/crypto/sha/Makefile index de6cdde58a9ca1..8b8f8b285f1c68 100644 --- a/deps/openssl/openssl/crypto/sha/Makefile +++ b/deps/openssl/openssl/crypto/sha/Makefile @@ -135,7 +135,7 @@ dclean: mv -f Makefile.new $(MAKEFILE) clean: - rm -f *.s *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff + rm -f *.s *.S *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff # DO NOT DELETE THIS LINE -- make depend depends on it. diff --git a/deps/openssl/openssl/crypto/srp/srp_vfy.c b/deps/openssl/openssl/crypto/srp/srp_vfy.c index a8ec52a4dadc24..c8bc7a94b26c4b 100644 --- a/deps/openssl/openssl/crypto/srp/srp_vfy.c +++ b/deps/openssl/openssl/crypto/srp/srp_vfy.c @@ -86,10 +86,13 @@ static int t_fromb64(unsigned char *a, size_t alen, const char *src) int i, j; int size; + if (alen == 0 || alen > INT_MAX) + return -1; + while (*src && (*src == ' ' || *src == '\t' || *src == '\n')) ++src; size = strlen(src); - if (alen > INT_MAX || size > (int)alen) + if (size < 0 || size >= (int)alen) return -1; i = 0; @@ -127,7 +130,7 @@ static int t_fromb64(unsigned char *a, size_t alen, const char *src) if (--i < 0) break; } - while (a[j] == 0 && j <= size) + while (j <= size && a[j] == 0) ++j; i = 0; while (j <= size) diff --git a/deps/openssl/openssl/crypto/txt_db/txt_db.c b/deps/openssl/openssl/crypto/txt_db/txt_db.c index f9b42ac6e5880c..ed02efc261834c 100644 --- a/deps/openssl/openssl/crypto/txt_db/txt_db.c +++ b/deps/openssl/openssl/crypto/txt_db/txt_db.c @@ -162,6 +162,7 @@ TXT_DB *TXT_DB_read(BIO *in, int num) "wrong number of fields on line %ld (looking for field %d, got %d, '%s' left)\n", ln, num, n, f); #endif + OPENSSL_free(pp); er = 2; goto err; } @@ -171,6 +172,7 @@ TXT_DB *TXT_DB_read(BIO *in, int num) * fix :-( */ fprintf(stderr, "failure in sk_push\n"); #endif + OPENSSL_free(pp); er = 2; goto err; } @@ -222,7 +224,7 @@ int TXT_DB_create_index(TXT_DB *db, int field, int (*qual) (OPENSSL_STRING *), LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp) { LHASH_OF(OPENSSL_STRING) *idx; - OPENSSL_STRING *r; + OPENSSL_STRING *r, *k; int i, n; if (field >= db->num_fields) { @@ -239,13 +241,18 @@ int TXT_DB_create_index(TXT_DB *db, int field, int (*qual) (OPENSSL_STRING *), r = sk_OPENSSL_PSTRING_value(db->data, i); if ((qual != NULL) && (qual(r) == 0)) continue; - if ((r = lh_OPENSSL_STRING_insert(idx, r)) != NULL) { + if ((k = lh_OPENSSL_STRING_insert(idx, r)) != NULL) { db->error = DB_ERROR_INDEX_CLASH; - db->arg1 = sk_OPENSSL_PSTRING_find(db->data, r); + db->arg1 = sk_OPENSSL_PSTRING_find(db->data, k); db->arg2 = i; lh_OPENSSL_STRING_free(idx); return (0); } + if (lh_OPENSSL_STRING_retrieve(idx, r) == NULL) { + db->error = DB_ERROR_MALLOC; + lh_OPENSSL_STRING_free(idx); + return (0); + } } if (db->index[field] != NULL) lh_OPENSSL_STRING_free(db->index[field]); @@ -320,20 +327,29 @@ int TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *row) } } } - /* We have passed the index checks, now just append and insert */ - if (!sk_OPENSSL_PSTRING_push(db->data, row)) { - db->error = DB_ERROR_MALLOC; - goto err; - } for (i = 0; i < db->num_fields; i++) { if (db->index[i] != NULL) { if ((db->qual[i] != NULL) && (db->qual[i] (row) == 0)) continue; (void)lh_OPENSSL_STRING_insert(db->index[i], row); + if (lh_OPENSSL_STRING_retrieve(db->index[i], row) == NULL) + goto err1; } } + if (!sk_OPENSSL_PSTRING_push(db->data, row)) + goto err1; return (1); + + err1: + db->error = DB_ERROR_MALLOC; + while (i-- > 0) { + if (db->index[i] != NULL) { + if ((db->qual[i] != NULL) && (db->qual[i] (row) == 0)) + continue; + (void)lh_OPENSSL_STRING_delete(db->index[i], row); + } + } err: return (0); } diff --git a/deps/openssl/openssl/crypto/ui/ui_lib.c b/deps/openssl/openssl/crypto/ui/ui_lib.c index 3cc067c3b7ee80..643ae593439aeb 100644 --- a/deps/openssl/openssl/crypto/ui/ui_lib.c +++ b/deps/openssl/openssl/crypto/ui/ui_lib.c @@ -747,7 +747,6 @@ const char *UI_get0_action_string(UI_STRING *uis) if (!uis) return NULL; switch (uis->type) { - case UIT_PROMPT: case UIT_BOOLEAN: return uis->_.boolean_data.action_desc; default: diff --git a/deps/openssl/openssl/crypto/x509/x509_lu.c b/deps/openssl/openssl/crypto/x509/x509_lu.c index 50120a4d70c645..b7424809fdbb2e 100644 --- a/deps/openssl/openssl/crypto/x509/x509_lu.c +++ b/deps/openssl/openssl/crypto/x509/x509_lu.c @@ -185,14 +185,16 @@ X509_STORE *X509_STORE_new(void) if ((ret = (X509_STORE *)OPENSSL_malloc(sizeof(X509_STORE))) == NULL) return NULL; - ret->objs = sk_X509_OBJECT_new(x509_object_cmp); + if ((ret->objs = sk_X509_OBJECT_new(x509_object_cmp)) == NULL) + goto err0; ret->cache = 1; - ret->get_cert_methods = sk_X509_LOOKUP_new_null(); + if ((ret->get_cert_methods = sk_X509_LOOKUP_new_null()) == NULL) + goto err1; ret->verify = 0; ret->verify_cb = 0; if ((ret->param = X509_VERIFY_PARAM_new()) == NULL) - return NULL; + goto err2; ret->get_issuer = 0; ret->check_issued = 0; @@ -204,14 +206,21 @@ X509_STORE *X509_STORE_new(void) ret->lookup_crls = 0; ret->cleanup = 0; - if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data)) { - sk_X509_OBJECT_free(ret->objs); - OPENSSL_free(ret); - return NULL; - } + if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data)) + goto err3; ret->references = 1; return ret; + + err3: + X509_VERIFY_PARAM_free(ret->param); + err2: + sk_X509_LOOKUP_free(ret->get_cert_methods); + err1: + sk_X509_OBJECT_free(ret->objs); + err0: + OPENSSL_free(ret); + return NULL; } static void cleanup(X509_OBJECT *a) @@ -360,8 +369,12 @@ int X509_STORE_add_cert(X509_STORE *ctx, X509 *x) X509err(X509_F_X509_STORE_ADD_CERT, X509_R_CERT_ALREADY_IN_HASH_TABLE); ret = 0; - } else - sk_X509_OBJECT_push(ctx->objs, obj); + } else if (!sk_X509_OBJECT_push(ctx->objs, obj)) { + X509_OBJECT_free_contents(obj); + OPENSSL_free(obj); + X509err(X509_F_X509_STORE_ADD_CERT, ERR_R_MALLOC_FAILURE); + ret = 0; + } CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); @@ -392,8 +405,12 @@ int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x) OPENSSL_free(obj); X509err(X509_F_X509_STORE_ADD_CRL, X509_R_CERT_ALREADY_IN_HASH_TABLE); ret = 0; - } else - sk_X509_OBJECT_push(ctx->objs, obj); + } else if (!sk_X509_OBJECT_push(ctx->objs, obj)) { + X509_OBJECT_free_contents(obj); + OPENSSL_free(obj); + X509err(X509_F_X509_STORE_ADD_CRL, ERR_R_MALLOC_FAILURE); + ret = 0; + } CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); diff --git a/deps/openssl/openssl/crypto/x509v3/v3_alt.c b/deps/openssl/openssl/crypto/x509v3/v3_alt.c index 7f1e71dd1a4292..a0351faf11192f 100644 --- a/deps/openssl/openssl/crypto/x509v3/v3_alt.c +++ b/deps/openssl/openssl/crypto/x509v3/v3_alt.c @@ -119,32 +119,39 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, int i; switch (gen->type) { case GEN_OTHERNAME: - X509V3_add_value("othername", "", &ret); + if (!X509V3_add_value("othername", "", &ret)) + return NULL; break; case GEN_X400: - X509V3_add_value("X400Name", "", &ret); + if (!X509V3_add_value("X400Name", "", &ret)) + return NULL; break; case GEN_EDIPARTY: - X509V3_add_value("EdiPartyName", "", &ret); + if (!X509V3_add_value("EdiPartyName", "", &ret)) + return NULL; break; case GEN_EMAIL: - X509V3_add_value_uchar("email", gen->d.ia5->data, &ret); + if (!X509V3_add_value_uchar("email", gen->d.ia5->data, &ret)) + return NULL; break; case GEN_DNS: - X509V3_add_value_uchar("DNS", gen->d.ia5->data, &ret); + if (!X509V3_add_value_uchar("DNS", gen->d.ia5->data, &ret)) + return NULL; break; case GEN_URI: - X509V3_add_value_uchar("URI", gen->d.ia5->data, &ret); + if (!X509V3_add_value_uchar("URI", gen->d.ia5->data, &ret)) + return NULL; break; case GEN_DIRNAME: - X509_NAME_oneline(gen->d.dirn, oline, 256); - X509V3_add_value("DirName", oline, &ret); + if (X509_NAME_oneline(gen->d.dirn, oline, 256) == NULL + || !X509V3_add_value("DirName", oline, &ret)) + return NULL; break; case GEN_IPADD: @@ -162,15 +169,18 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, strcat(oline, ":"); } } else { - X509V3_add_value("IP Address", "", &ret); + if (!X509V3_add_value("IP Address", "", &ret)) + return NULL; break; } - X509V3_add_value("IP Address", oline, &ret); + if (!X509V3_add_value("IP Address", oline, &ret)) + return NULL; break; case GEN_RID: i2t_ASN1_OBJECT(oline, 256, gen->d.rid); - X509V3_add_value("Registered ID", oline, &ret); + if (!X509V3_add_value("Registered ID", oline, &ret)) + return NULL; break; } return ret; diff --git a/deps/openssl/openssl/crypto/x509v3/v3_cpols.c b/deps/openssl/openssl/crypto/x509v3/v3_cpols.c index d97f6226b9ee01..b99269e7f839a5 100644 --- a/deps/openssl/openssl/crypto/x509v3/v3_cpols.c +++ b/deps/openssl/openssl/crypto/x509v3/v3_cpols.c @@ -390,10 +390,10 @@ static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos) return 1; merr: + ASN1_INTEGER_free(aint); X509V3err(X509V3_F_NREF_NOS, ERR_R_MALLOC_FAILURE); err: - sk_ASN1_INTEGER_pop_free(nnums, ASN1_STRING_free); return 0; } @@ -458,9 +458,15 @@ static void print_notice(BIO *out, USERNOTICE *notice, int indent) num = sk_ASN1_INTEGER_value(ref->noticenos, i); if (i) BIO_puts(out, ", "); - tmp = i2s_ASN1_INTEGER(NULL, num); - BIO_puts(out, tmp); - OPENSSL_free(tmp); + if (num == NULL) + BIO_puts(out, "(null)"); + else { + tmp = i2s_ASN1_INTEGER(NULL, num); + if (tmp == NULL) + return; + BIO_puts(out, tmp); + OPENSSL_free(tmp); + } } BIO_puts(out, "\n"); } diff --git a/deps/openssl/openssl/crypto/x509v3/v3_info.c b/deps/openssl/openssl/crypto/x509v3/v3_info.c index e052a34b940a30..7064c725d98dba 100644 --- a/deps/openssl/openssl/crypto/x509v3/v3_info.c +++ b/deps/openssl/openssl/crypto/x509v3/v3_info.c @@ -107,29 +107,30 @@ ASN1_ITEM_TEMPLATE_END(AUTHORITY_INFO_ACCESS) IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS) -static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD - *method, AUTHORITY_INFO_ACCESS - *ainfo, STACK_OF(CONF_VALUE) - *ret) +static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS( + X509V3_EXT_METHOD *method, AUTHORITY_INFO_ACCESS *ainfo, + STACK_OF(CONF_VALUE) *ret) { ACCESS_DESCRIPTION *desc; int i, nlen; char objtmp[80], *ntmp; CONF_VALUE *vtmp; + STACK_OF(CONF_VALUE) *tret = ret; + for (i = 0; i < sk_ACCESS_DESCRIPTION_num(ainfo); i++) { + STACK_OF(CONF_VALUE) *tmp; + desc = sk_ACCESS_DESCRIPTION_value(ainfo, i); - ret = i2v_GENERAL_NAME(method, desc->location, ret); - if (!ret) - break; - vtmp = sk_CONF_VALUE_value(ret, i); + tmp = i2v_GENERAL_NAME(method, desc->location, tret); + if (tmp == NULL) + goto err; + tret = tmp; + vtmp = sk_CONF_VALUE_value(tret, i); i2t_ASN1_OBJECT(objtmp, sizeof objtmp, desc->method); nlen = strlen(objtmp) + strlen(vtmp->name) + 5; ntmp = OPENSSL_malloc(nlen); - if (!ntmp) { - X509V3err(X509V3_F_I2V_AUTHORITY_INFO_ACCESS, - ERR_R_MALLOC_FAILURE); - return NULL; - } + if (ntmp == NULL) + goto err; BUF_strlcpy(ntmp, objtmp, nlen); BUF_strlcat(ntmp, " - ", nlen); BUF_strlcat(ntmp, vtmp->name, nlen); @@ -137,9 +138,15 @@ static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD vtmp->name = ntmp; } - if (!ret) + if (ret == NULL && tret == NULL) return sk_CONF_VALUE_new_null(); - return ret; + + return tret; + err: + X509V3err(X509V3_F_I2V_AUTHORITY_INFO_ACCESS, ERR_R_MALLOC_FAILURE); + if (ret == NULL && tret != NULL) + sk_CONF_VALUE_pop_free(tret, X509V3_conf_free); + return NULL; } static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD diff --git a/deps/openssl/openssl/crypto/x509v3/v3_purp.c b/deps/openssl/openssl/crypto/x509v3/v3_purp.c index 845be673b79998..96e629a9301f62 100644 --- a/deps/openssl/openssl/crypto/x509v3/v3_purp.c +++ b/deps/openssl/openssl/crypto/x509v3/v3_purp.c @@ -321,6 +321,7 @@ int X509_supported_extension(X509_EXTENSION *ex) NID_subject_alt_name, /* 85 */ NID_basic_constraints, /* 87 */ NID_certificate_policies, /* 89 */ + NID_crl_distribution_points, /* 103 */ NID_ext_key_usage, /* 126 */ #ifndef OPENSSL_NO_RFC3779 NID_sbgp_ipAddrBlock, /* 290 */ diff --git a/deps/openssl/openssl/crypto/x86_64cpuid.pl b/deps/openssl/openssl/crypto/x86_64cpuid.pl index d208d02392e9d2..a3d6f438f91e7b 100644 --- a/deps/openssl/openssl/crypto/x86_64cpuid.pl +++ b/deps/openssl/openssl/crypto/x86_64cpuid.pl @@ -59,7 +59,7 @@ mov %rbx,%r8 # save %rbx xor %eax,%eax - mov %eax,8(%rdi) # clear 3rd word + mov %eax,8(%rdi) # clear extended feature flags cpuid mov %eax,%r11d # max value for standard query level @@ -127,14 +127,6 @@ shr \$14,%r10d and \$0xfff,%r10d # number of cores -1 per L1D - cmp \$7,%r11d - jb .Lnocacheinfo - - mov \$7,%eax - xor %ecx,%ecx - cpuid - mov %ebx,8(%rdi) - .Lnocacheinfo: mov \$1,%eax cpuid @@ -164,6 +156,15 @@ or %ecx,%r9d # merge AMD XOP flag mov %edx,%r10d # %r9d:%r10d is copy of %ecx:%edx + + cmp \$7,%r11d + jb .Lno_extended_info + mov \$7,%eax + xor %ecx,%ecx + cpuid + mov %ebx,8(%rdi) # save extended feature flags +.Lno_extended_info: + bt \$27,%r9d # check OSXSAVE bit jnc .Lclear_avx xor %ecx,%ecx # XCR0 diff --git a/deps/openssl/openssl/crypto/x86cpuid.pl b/deps/openssl/openssl/crypto/x86cpuid.pl index e95f6274f5e063..90ed196c09cd15 100644 --- a/deps/openssl/openssl/crypto/x86cpuid.pl +++ b/deps/openssl/openssl/crypto/x86cpuid.pl @@ -20,10 +20,10 @@ &pop ("eax"); &xor ("ecx","eax"); &xor ("eax","eax"); + &mov ("esi",&wparam(0)); + &mov (&DWP(8,"esi"),"eax"); # clear extended feature flags &bt ("ecx",21); &jnc (&label("nocpuid")); - &mov ("esi",&wparam(0)); - &mov (&DWP(8,"esi"),"eax"); # clear 3rd word &cpuid (); &mov ("edi","eax"); # max value for standard query level @@ -81,26 +81,16 @@ &jmp (&label("generic")); &set_label("intel"); - &cmp ("edi",7); - &jb (&label("cacheinfo")); - - &mov ("esi",&wparam(0)); - &mov ("eax",7); - &xor ("ecx","ecx"); - &cpuid (); - &mov (&DWP(8,"esi"),"ebx"); - -&set_label("cacheinfo"); &cmp ("edi",4); - &mov ("edi",-1); + &mov ("esi",-1); &jb (&label("nocacheinfo")); &mov ("eax",4); &mov ("ecx",0); # query L1D &cpuid (); - &mov ("edi","eax"); - &shr ("edi",14); - &and ("edi",0xfff); # number of cores -1 per L1D + &mov ("esi","eax"); + &shr ("esi",14); + &and ("esi",0xfff); # number of cores -1 per L1D &set_label("nocacheinfo"); &mov ("eax",1); @@ -118,7 +108,7 @@ &bt ("edx",28); # test hyper-threading bit &jnc (&label("generic")); &and ("edx",0xefffffff); - &cmp ("edi",0); + &cmp ("esi",0); &je (&label("generic")); &or ("edx",0x10000000); @@ -130,10 +120,19 @@ &set_label("generic"); &and ("ebp",1<<11); # isolate AMD XOP flag &and ("ecx",0xfffff7ff); # force 11th bit to 0 - &mov ("esi","edx"); + &mov ("esi","edx"); # %ebp:%esi is copy of %ecx:%edx &or ("ebp","ecx"); # merge AMD XOP flag - &bt ("ecx",27); # check OSXSAVE bit + &cmp ("edi",7); + &mov ("edi",&wparam(0)); + &jb (&label("no_extended_info")); + &mov ("eax",7); + &xor ("ecx","ecx"); + &cpuid (); + &mov (&DWP(8,"edi"),"ebx"); # save extended feature flag +&set_label("no_extended_info"); + + &bt ("ebp",27); # check OSXSAVE bit &jnc (&label("clear_avx")); &xor ("ecx","ecx"); &data_byte(0x0f,0x01,0xd0); # xgetbv @@ -147,7 +146,6 @@ &and ("esi",0xfeffffff); # clear FXSR &set_label("clear_avx"); &and ("ebp",0xefffe7ff); # clear AVX, FMA and AMD XOP bits - &mov ("edi",&wparam(0)); &and (&DWP(8,"edi"),0xffffffdf); # clear AVX2 &set_label("done"); &mov ("eax","esi"); diff --git a/deps/openssl/openssl/doc-nits b/deps/openssl/openssl/doc-nits new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/deps/openssl/openssl/doc/apps/ciphers.pod b/deps/openssl/openssl/doc/apps/ciphers.pod index 9224557255ed67..35d40bbf27aeff 100644 --- a/deps/openssl/openssl/doc/apps/ciphers.pod +++ b/deps/openssl/openssl/doc/apps/ciphers.pod @@ -179,7 +179,8 @@ When in doubt, include B in your cipherlist. =item B, B -cipher suites using RSA key exchange. +cipher suites using RSA key exchange or authentication. B is an alias for +B. =item B, B, B diff --git a/deps/openssl/openssl/doc/apps/config.pod b/deps/openssl/openssl/doc/apps/config.pod index e12591528c0cd8..3f607d3b5fc84f 100644 --- a/deps/openssl/openssl/doc/apps/config.pod +++ b/deps/openssl/openssl/doc/apps/config.pod @@ -47,7 +47,8 @@ or B<${section::name}>. By using the form B<$ENV::name> environment variables can be substituted. It is also possible to assign values to environment variables by using the name B, this will work if the program looks up environment variables using the B library -instead of calling B directly. +instead of calling B directly. The value string must not exceed 64k in +length after variable expansion. Otherwise an error will occur. It is possible to escape certain characters by using any kind of quote or the B<\> character. By making the last character of a line a B<\> diff --git a/deps/openssl/openssl/doc/apps/genrsa.pod b/deps/openssl/openssl/doc/apps/genrsa.pod index 3dc9870f34b96a..f4ed9593ae2695 100644 --- a/deps/openssl/openssl/doc/apps/genrsa.pod +++ b/deps/openssl/openssl/doc/apps/genrsa.pod @@ -7,11 +7,15 @@ genrsa - generate an RSA private key =head1 SYNOPSIS B B +[B<-help>] [B<-out filename>] [B<-passout arg>] [B<-aes128>] [B<-aes192>] [B<-aes256>] +[B<-aria128>] +[B<-aria192>] +[B<-aria256>] [B<-camellia128>] [B<-camellia192>] [B<-camellia256>] @@ -32,17 +36,21 @@ The B command generates an RSA private key. =over 4 +=item B<-help> + +Print out a usage message. + =item B<-out filename> -the output filename. If this argument is not specified then standard output is -used. +Output the key to the specified file. If this argument is not specified then +standard output is used. =item B<-passout arg> the output file password source. For more information about the format of B -see the B section in L. +see the B section in L. -=item B<-aes128|-aes192|-aes256|-camellia128|-camellia192|-camellia256|-des|-des3|-idea> +=item B<-aes128|-aes192|-aes256|-aria128|-aria192|-aria256|-camellia128|-camellia192|-camellia256|-des|-des3|-idea> These options encrypt the private key with specified cipher before outputting it. If none of these options is @@ -56,8 +64,8 @@ the public exponent to use, either 65537 or 3. The default is 65537. =item B<-rand file(s)> a file or files containing random data used to seed the random number -generator, or an EGD socket (see L). -Multiple files can be specified separated by a OS-dependent character. +generator, or an EGD socket (see L). +Multiple files can be specified separated by an OS-dependent character. The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for all others. @@ -71,7 +79,7 @@ for all available algorithms. =item B the size of the private key to generate in bits. This must be the last option -specified. The default is 512. +specified. The default is 2048. =back @@ -96,7 +104,15 @@ be much larger (typically 1024 bits). =head1 SEE ALSO -L +L -=cut +=head1 COPYRIGHT +Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the OpenSSL license (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/deps/openssl/openssl/doc/apps/req.pod b/deps/openssl/openssl/doc/apps/req.pod index 30653e50935777..1682ba5143dd02 100644 --- a/deps/openssl/openssl/doc/apps/req.pod +++ b/deps/openssl/openssl/doc/apps/req.pod @@ -237,6 +237,9 @@ a self signed root CA. The extensions added to the certificate using the B option, a large random number will be used for the serial number. +If existing request is specified with the B<-in> option, it is converted +to the self signed certificate otherwise new request is created. + =item B<-days n> when the B<-x509> option is being used this specifies the number of diff --git a/deps/openssl/openssl/doc/apps/s_client.pod b/deps/openssl/openssl/doc/apps/s_client.pod index 29675dd213f451..b45acbc5e3e42f 100644 --- a/deps/openssl/openssl/doc/apps/s_client.pod +++ b/deps/openssl/openssl/doc/apps/s_client.pod @@ -42,6 +42,8 @@ B B [B<-no_tls1_2>] [B<-fallback_scsv>] [B<-bugs>] +[B<-sigalgs sigalglist>] +[B<-curves curvelist>] [B<-cipher cipherlist>] [B<-serverpref>] [B<-starttls protocol>] @@ -217,6 +219,19 @@ Send TLS_FALLBACK_SCSV in the ClientHello. there are several known bug in SSL and TLS implementations. Adding this option enables various workarounds. +=item B<-sigalgs sigalglist> + +Specifies the list of signature algorithms that are sent by the client. +The server selects one entry in the list based on its preferences. +For example strings, see L + +=item B<-curves curvelist> + +Specifies the list of supported curves to be sent by the client. The curve is +is ultimately selected by the server. For a list of all curves, use: + + $ openssl ecparam -list_curves + =item B<-cipher cipherlist> this allows the cipher list sent by the client to be modified. Although diff --git a/deps/openssl/openssl/doc/apps/s_server.pod b/deps/openssl/openssl/doc/apps/s_server.pod index fa17488d917359..1fe93ddfbebb0b 100644 --- a/deps/openssl/openssl/doc/apps/s_server.pod +++ b/deps/openssl/openssl/doc/apps/s_server.pod @@ -35,6 +35,8 @@ B B [B<-CAfile filename>] [B<-no_alt_chains>] [B<-nocert>] +[B<-client_sigalgs sigalglist>] +[B<-named_curve curve>] [B<-cipher cipherlist>] [B<-serverpref>] [B<-quiet>] @@ -234,6 +236,18 @@ option enables various workarounds. this option enables a further workaround for some some early Netscape SSL code (?). +=item B<-client_sigalgs sigalglist> + +Signature algorithms to support for client certificate authentication +(colon-separated list) + +=item B<-named_curve curve> + +Specifies the elliptic curve to use. NOTE: this is single curve, not a list. +For a list of all possible curves, use: + + $ openssl ecparam -list_curves + =item B<-cipher cipherlist> this allows the cipher list used by the server to be modified. When diff --git a/deps/openssl/openssl/doc/crypto/EVP_EncryptInit.pod b/deps/openssl/openssl/doc/crypto/EVP_EncryptInit.pod index d9513338d8aacb..0c0a30c1ffa048 100644 --- a/deps/openssl/openssl/doc/crypto/EVP_EncryptInit.pod +++ b/deps/openssl/openssl/doc/crypto/EVP_EncryptInit.pod @@ -19,14 +19,17 @@ EVP_CIPHER_CTX_mode, EVP_CIPHER_param_to_asn1, EVP_CIPHER_asn1_to_param, EVP_CIPHER_CTX_set_padding, EVP_enc_null, EVP_des_cbc, EVP_des_ecb, EVP_des_cfb, EVP_des_ofb, EVP_des_ede_cbc, EVP_des_ede, EVP_des_ede_ofb, EVP_des_ede_cfb, EVP_des_ede3_cbc, EVP_des_ede3, EVP_des_ede3_ofb, -EVP_des_ede3_cfb, EVP_desx_cbc, EVP_rc4, EVP_rc4_40, EVP_idea_cbc, -EVP_idea_ecb, EVP_idea_cfb, EVP_idea_ofb, EVP_idea_cbc, EVP_rc2_cbc, +EVP_des_ede3_cfb, EVP_desx_cbc, EVP_rc4, EVP_rc4_40, EVP_rc4_hmac_md5, +EVP_idea_cbc, EVP_idea_ecb, EVP_idea_cfb, EVP_idea_ofb, EVP_rc2_cbc, EVP_rc2_ecb, EVP_rc2_cfb, EVP_rc2_ofb, EVP_rc2_40_cbc, EVP_rc2_64_cbc, EVP_bf_cbc, EVP_bf_ecb, EVP_bf_cfb, EVP_bf_ofb, EVP_cast5_cbc, EVP_cast5_ecb, EVP_cast5_cfb, EVP_cast5_ofb, EVP_rc5_32_12_16_cbc, EVP_rc5_32_12_16_ecb, EVP_rc5_32_12_16_cfb, EVP_rc5_32_12_16_ofb, EVP_aes_128_gcm, EVP_aes_192_gcm, EVP_aes_256_gcm, EVP_aes_128_ccm, -EVP_aes_192_ccm, EVP_aes_256_ccm - EVP cipher routines +EVP_aes_192_ccm, EVP_aes_256_ccm, +EVP_aes_128_cbc_hmac_sha1, EVP_aes_256_cbc_hmac_sha1, +EVP_aes_128_cbc_hmac_sha256, EVP_aes_256_cbc_hmac_sha256 +- EVP cipher routines =head1 SYNOPSIS @@ -395,8 +398,6 @@ Sets the expected tag to B bytes from B. This call is only legal when decrypting data and must be made B any data is processed (e.g. before any EVP_DecryptUpdate() call). -See L below for an example of the use of GCM mode. - =head1 CCM Mode The behaviour of CCM mode ciphers is similar to CCM mode but with a few diff --git a/deps/openssl/openssl/doc/crypto/RSA_private_encrypt.pod b/deps/openssl/openssl/doc/crypto/RSA_private_encrypt.pod index 746a80c79ea0c8..3e1f895c5ad8c1 100644 --- a/deps/openssl/openssl/doc/crypto/RSA_private_encrypt.pod +++ b/deps/openssl/openssl/doc/crypto/RSA_private_encrypt.pod @@ -8,10 +8,10 @@ RSA_private_encrypt, RSA_public_decrypt - low level signature operations #include - int RSA_private_encrypt(int flen, unsigned char *from, + int RSA_private_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); - int RSA_public_decrypt(int flen, unsigned char *from, + int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); =head1 DESCRIPTION diff --git a/deps/openssl/openssl/doc/crypto/RSA_public_encrypt.pod b/deps/openssl/openssl/doc/crypto/RSA_public_encrypt.pod index ab0fe3b2cd1c77..0541f348b3e20c 100644 --- a/deps/openssl/openssl/doc/crypto/RSA_public_encrypt.pod +++ b/deps/openssl/openssl/doc/crypto/RSA_public_encrypt.pod @@ -8,10 +8,10 @@ RSA_public_encrypt, RSA_private_decrypt - RSA public key cryptography #include - int RSA_public_encrypt(int flen, unsigned char *from, + int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); - int RSA_private_decrypt(int flen, unsigned char *from, + int RSA_private_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding); =head1 DESCRIPTION diff --git a/deps/openssl/openssl/doc/crypto/X509_STORE_CTX_new.pod b/deps/openssl/openssl/doc/crypto/X509_STORE_CTX_new.pod index eb38b0a1090512..1aee1172686385 100644 --- a/deps/openssl/openssl/doc/crypto/X509_STORE_CTX_new.pod +++ b/deps/openssl/openssl/doc/crypto/X509_STORE_CTX_new.pod @@ -41,7 +41,7 @@ is no longer valid. X509_STORE_CTX_init() sets up B for a subsequent verification operation. It must be called before each call to X509_verify_cert(), i.e. a B is only good for one call to X509_verify_cert(); if you want to verify a second -certificate with the same B then you must call X509_XTORE_CTX_cleanup() +certificate with the same B then you must call X509_STORE_CTX_cleanup() and then X509_STORE_CTX_init() again before the second call to X509_verify_cert(). The trusted certificate store is set to B, the end entity certificate to be verified is set to B and a set of additional diff --git a/deps/openssl/openssl/doc/crypto/des.pod b/deps/openssl/openssl/doc/crypto/des.pod index e1add56b5e8139..339617aab02431 100644 --- a/deps/openssl/openssl/doc/crypto/des.pod +++ b/deps/openssl/openssl/doc/crypto/des.pod @@ -123,7 +123,7 @@ architecture dependent I via the DES_set_key_checked() or DES_set_key_unchecked() function. DES_set_key_checked() will check that the key passed is of odd parity -and is not a week or semi-weak key. If the parity is wrong, then -1 +and is not a weak or semi-weak key. If the parity is wrong, then -1 is returned. If the key is a weak key, then -2 is returned. If an error is returned, the key schedule is not generated. diff --git a/deps/openssl/openssl/doc/man3/SSL_CTX_set_tlsext_servername_callback.pod b/deps/openssl/openssl/doc/man3/SSL_CTX_set_tlsext_servername_callback.pod new file mode 100644 index 00000000000000..3b0a50956d9bc9 --- /dev/null +++ b/deps/openssl/openssl/doc/man3/SSL_CTX_set_tlsext_servername_callback.pod @@ -0,0 +1,62 @@ +=pod + +=head1 NAME + +SSL_CTX_set_tlsext_servername_callback, SSL_CTX_set_tlsext_servername_arg, +SSL_get_servername_type, SSL_get_servername - handle server name indication +(SNI) + +=head1 SYNOPSIS + + #include + + long SSL_CTX_set_tlsext_servername_callback(SSL_CTX *ctx, + int (*cb)(SSL *, int *, void *)); + long SSL_CTX_set_tlsext_servername_arg(SSL_CTX *ctx, void *arg); + + const char *SSL_get_servername(const SSL *s, const int type); + int SSL_get_servername_type(const SSL *s); + +=head1 DESCRIPTION + +SSL_CTX_set_tlsext_servername_callback() sets the application callback B +used by a server to perform any actions or configuration required based on +the servername extension received in the incoming connection. When B +is NULL, SNI is not used. The B value is a pointer which is passed to +the application callback. + +SSL_CTX_set_tlsext_servername_arg() sets a context-specific argument to be +passed into the callback for this B. + +SSL_get_servername() returns a servername extension value of the specified +type if provided in the Client Hello or NULL. + +SSL_get_servername_type() returns the servername type or -1 if no servername +is present. Currently the only supported type (defined in RFC3546) is +B. + +=head1 NOTES + +The ALPN and SNI callbacks are both executed during Client Hello processing. +The servername callback is executed first, followed by the ALPN callback. + +=head1 RETURN VALUES + +SSL_CTX_set_tlsext_servername_callback() and +SSL_CTX_set_tlsext_servername_arg() both always return 1 indicating success. + +=head1 SEE ALSO + +L, L, +L + +=head1 COPYRIGHT + +Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the OpenSSL license (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/deps/openssl/openssl/include/openssl/conf.h b/deps/openssl/openssl/include/openssl/conf.h index 8d926d5d8268f5..fe49113080b700 100644 --- a/deps/openssl/openssl/include/openssl/conf.h +++ b/deps/openssl/openssl/include/openssl/conf.h @@ -259,6 +259,7 @@ void ERR_load_CONF_strings(void); # define CONF_R_NO_VALUE 108 # define CONF_R_UNABLE_TO_CREATE_NEW_SECTION 103 # define CONF_R_UNKNOWN_MODULE_NAME 113 +# define CONF_R_VARIABLE_EXPANSION_TOO_LONG 116 # define CONF_R_VARIABLE_HAS_NO_VALUE 104 #ifdef __cplusplus diff --git a/deps/openssl/openssl/include/openssl/dh.h b/deps/openssl/openssl/include/openssl/dh.h index a5bd9016aae85a..a228c7a7a4c3a1 100644 --- a/deps/openssl/openssl/include/openssl/dh.h +++ b/deps/openssl/openssl/include/openssl/dh.h @@ -182,12 +182,29 @@ struct dh_st { */ # define DH_CHECK_P_NOT_STRONG_PRIME DH_CHECK_P_NOT_SAFE_PRIME -# define d2i_DHparams_fp(fp,x) (DH *)ASN1_d2i_fp((char *(*)())DH_new, \ - (char *(*)())d2i_DHparams,(fp),(unsigned char **)(x)) -# define i2d_DHparams_fp(fp,x) ASN1_i2d_fp(i2d_DHparams,(fp), \ - (unsigned char *)(x)) -# define d2i_DHparams_bio(bp,x) ASN1_d2i_bio_of(DH,DH_new,d2i_DHparams,bp,x) -# define i2d_DHparams_bio(bp,x) ASN1_i2d_bio_of_const(DH,i2d_DHparams,bp,x) +# define d2i_DHparams_fp(fp,x) \ + (DH *)ASN1_d2i_fp((char *(*)())DH_new, \ + (char *(*)())d2i_DHparams, \ + (fp), \ + (unsigned char **)(x)) +# define i2d_DHparams_fp(fp,x) \ + ASN1_i2d_fp(i2d_DHparams,(fp), (unsigned char *)(x)) +# define d2i_DHparams_bio(bp,x) \ + ASN1_d2i_bio_of(DH, DH_new, d2i_DHparams, bp, x) +# define i2d_DHparams_bio(bp,x) \ + ASN1_i2d_bio_of_const(DH,i2d_DHparams,bp,x) + +# define d2i_DHxparams_fp(fp,x) \ + (DH *)ASN1_d2i_fp((char *(*)())DH_new, \ + (char *(*)())d2i_DHxparams, \ + (fp), \ + (unsigned char **)(x)) +# define i2d_DHxparams_fp(fp,x) \ + ASN1_i2d_fp(i2d_DHxparams,(fp), (unsigned char *)(x)) +# define d2i_DHxparams_bio(bp,x) \ + ASN1_d2i_bio_of(DH, DH_new, d2i_DHxparams, bp, x) +# define i2d_DHxparams_bio(bp,x) \ + ASN1_i2d_bio_of_const(DH, i2d_DHxparams, bp, x) DH *DHparams_dup(DH *); diff --git a/deps/openssl/openssl/include/openssl/err.h b/deps/openssl/openssl/include/openssl/err.h index 585aa8ba3df935..f42365620db0c0 100644 --- a/deps/openssl/openssl/include/openssl/err.h +++ b/deps/openssl/openssl/include/openssl/err.h @@ -258,6 +258,7 @@ typedef struct err_state_st { # define SYS_F_WSASTARTUP 9/* Winsock stuff */ # define SYS_F_OPENDIR 10 # define SYS_F_FREAD 11 +# define SYS_F_FFLUSH 18 /* reasons */ # define ERR_R_SYS_LIB ERR_LIB_SYS/* 2 */ diff --git a/deps/openssl/openssl/include/openssl/opensslv.h b/deps/openssl/openssl/include/openssl/opensslv.h index 645dd0793f32e0..825a330abc8825 100644 --- a/deps/openssl/openssl/include/openssl/opensslv.h +++ b/deps/openssl/openssl/include/openssl/opensslv.h @@ -30,11 +30,11 @@ extern "C" { * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for * major minor fix final patch/beta) */ -# define OPENSSL_VERSION_NUMBER 0x100020bfL +# define OPENSSL_VERSION_NUMBER 0x100020cfL # ifdef OPENSSL_FIPS -# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2k-fips 26 Jan 2017" +# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2l-fips 25 May 2017" # else -# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2k 26 Jan 2017" +# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2l 25 May 2017" # endif # define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT diff --git a/deps/openssl/openssl/openssl.spec b/deps/openssl/openssl/openssl.spec index 7bbcdf69a4310f..add18a4b37c260 100644 --- a/deps/openssl/openssl/openssl.spec +++ b/deps/openssl/openssl/openssl.spec @@ -7,7 +7,7 @@ Release: 1 Summary: Secure Sockets Layer and cryptography libraries and tools Name: openssl -Version: 1.0.2k +Version: 1.0.2l Source0: ftp://ftp.openssl.org/source/%{name}-%{version}.tar.gz License: OpenSSL Group: System Environment/Libraries diff --git a/deps/openssl/openssl/ssl/d1_both.c b/deps/openssl/openssl/ssl/d1_both.c index 9bc61536101b5c..e6bc761e8bf236 100644 --- a/deps/openssl/openssl/ssl/d1_both.c +++ b/deps/openssl/openssl/ssl/d1_both.c @@ -517,6 +517,17 @@ long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) return i; } + /* + * Don't change the *message* read sequence number while listening. For + * the *record* write sequence we reflect the ClientHello sequence number + * when listening. + */ + if (s->d1->listen) + memcpy(s->s3->write_sequence, s->s3->read_sequence, + sizeof(s->s3->write_sequence)); + else + s->d1->handshake_read_seq++; + if (mt >= 0 && s->s3->tmp.message_type != mt) { al = SSL_AD_UNEXPECTED_MESSAGE; SSLerr(SSL_F_DTLS1_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); @@ -544,10 +555,6 @@ long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); - /* Don't change sequence numbers while listening */ - if (!s->d1->listen) - s->d1->handshake_read_seq++; - s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; return s->init_num; @@ -1068,7 +1075,9 @@ int dtls1_send_change_cipher_spec(SSL *s, int a, int b) int dtls1_read_failed(SSL *s, int code) { if (code > 0) { +#ifdef TLS_DEBUG fprintf(stderr, "invalid state reached %s:%d", __FILE__, __LINE__); +#endif return 1; } @@ -1140,7 +1149,9 @@ int dtls1_retransmit_buffered_messages(SSL *s) (frag->msg_header.seq, frag->msg_header.is_ccs), 0, &found) <= 0 && found) { +#ifdef TLS_DEBUG fprintf(stderr, "dtls1_retransmit_message() failed\n"); +#endif return -1; } } @@ -1240,7 +1251,9 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off, item = pqueue_find(s->d1->sent_messages, seq64be); if (item == NULL) { +#ifdef TLS_DEBUG fprintf(stderr, "retransmit: message %d non-existant\n", seq); +#endif *found = 0; return 0; } diff --git a/deps/openssl/openssl/ssl/d1_clnt.c b/deps/openssl/openssl/ssl/d1_clnt.c index 7e2f5c2830b512..76451a346d86b4 100644 --- a/deps/openssl/openssl/ssl/d1_clnt.c +++ b/deps/openssl/openssl/ssl/d1_clnt.c @@ -320,8 +320,13 @@ int dtls1_connect(SSL *s) s->shutdown = 0; /* every DTLS ClientHello resets Finished MAC */ - ssl3_init_finished_mac(s); + if (!ssl3_init_finished_mac(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + /* fall thru */ case SSL3_ST_CW_CLNT_HELLO_B: dtls1_start_timer(s); ret = ssl3_client_hello(s); diff --git a/deps/openssl/openssl/ssl/d1_pkt.c b/deps/openssl/openssl/ssl/d1_pkt.c index 7a02459f2b7876..10586fee5408ea 100644 --- a/deps/openssl/openssl/ssl/d1_pkt.c +++ b/deps/openssl/openssl/ssl/d1_pkt.c @@ -1323,9 +1323,9 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) /* XDTLS: check that epoch is consistent */ if ((rr->length != ccs_hdr_len) || (rr->off != 0) || (rr->data[0] != SSL3_MT_CCS)) { - i = SSL_AD_ILLEGAL_PARAMETER; + al = SSL_AD_ILLEGAL_PARAMETER; SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_BAD_CHANGE_CIPHER_SPEC); - goto err; + goto f_err; } rr->length = 0; diff --git a/deps/openssl/openssl/ssl/d1_srvr.c b/deps/openssl/openssl/ssl/d1_srvr.c index bc875b53c9a0d9..8502b242e51cd3 100644 --- a/deps/openssl/openssl/ssl/d1_srvr.c +++ b/deps/openssl/openssl/ssl/d1_srvr.c @@ -282,7 +282,12 @@ int dtls1_accept(SSL *s) goto end; } - ssl3_init_finished_mac(s); + if (!ssl3_init_finished_mac(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + s->state = SSL3_ST_SR_CLNT_HELLO_A; s->ctx->stats.sess_accept++; } else if (!s->s3->send_connection_binding && @@ -322,7 +327,11 @@ int dtls1_accept(SSL *s) s->state = SSL3_ST_SW_FLUSH; s->init_num = 0; - ssl3_init_finished_mac(s); + if (!ssl3_init_finished_mac(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } break; case SSL3_ST_SW_HELLO_REQ_C: @@ -346,15 +355,6 @@ int dtls1_accept(SSL *s) s->init_num = 0; - /* - * Reflect ClientHello sequence to remain stateless while - * listening - */ - if (listen) { - memcpy(s->s3->write_sequence, s->s3->read_sequence, - sizeof(s->s3->write_sequence)); - } - /* If we're just listening, stop here */ if (listen && s->state == SSL3_ST_SW_SRVR_HELLO_A) { ret = 2; @@ -381,7 +381,11 @@ int dtls1_accept(SSL *s) /* HelloVerifyRequest resets Finished MAC */ if (s->version != DTLS1_BAD_VER) - ssl3_init_finished_mac(s); + if (!ssl3_init_finished_mac(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } break; #ifndef OPENSSL_NO_SCTP diff --git a/deps/openssl/openssl/ssl/s23_clnt.c b/deps/openssl/openssl/ssl/s23_clnt.c index 6850dc0c670444..b80d1fd8ce6e9d 100644 --- a/deps/openssl/openssl/ssl/s23_clnt.c +++ b/deps/openssl/openssl/ssl/s23_clnt.c @@ -204,7 +204,10 @@ int ssl23_connect(SSL *s) goto end; } - ssl3_init_finished_mac(s); + if (!ssl3_init_finished_mac(s)) { + ret = -1; + goto end; + } s->state = SSL23_ST_CW_CLNT_HELLO_A; s->ctx->stats.sess_connect++; diff --git a/deps/openssl/openssl/ssl/s23_srvr.c b/deps/openssl/openssl/ssl/s23_srvr.c index 470bd3d94f29a4..d3f6db15cceee7 100644 --- a/deps/openssl/openssl/ssl/s23_srvr.c +++ b/deps/openssl/openssl/ssl/s23_srvr.c @@ -195,7 +195,10 @@ int ssl23_accept(SSL *s) s->init_buf = buf; } - ssl3_init_finished_mac(s); + if (!ssl3_init_finished_mac(s)) { + ret = -1; + goto end; + } s->state = SSL23_ST_SR_CLNT_HELLO_A; s->ctx->stats.sess_accept++; diff --git a/deps/openssl/openssl/ssl/s3_clnt.c b/deps/openssl/openssl/ssl/s3_clnt.c index 32f2f1aeed2b19..5b8b2da59f544f 100644 --- a/deps/openssl/openssl/ssl/s3_clnt.c +++ b/deps/openssl/openssl/ssl/s3_clnt.c @@ -263,6 +263,7 @@ int ssl3_connect(SSL *s) if (!ssl3_setup_buffers(s)) { ret = -1; + s->state = SSL_ST_ERR; goto end; } @@ -275,7 +276,11 @@ int ssl3_connect(SSL *s) /* don't push the buffering BIO quite yet */ - ssl3_init_finished_mac(s); + if (!ssl3_init_finished_mac(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } s->state = SSL3_ST_CW_CLNT_HELLO_A; s->ctx->stats.sess_connect++; @@ -1864,6 +1869,7 @@ int ssl3_get_key_exchange(SSL *s) goto err; } if (EC_KEY_set_group(ecdh, ngroup) == 0) { + EC_GROUP_free(ngroup); SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_EC_LIB); goto err; } diff --git a/deps/openssl/openssl/ssl/s3_enc.c b/deps/openssl/openssl/ssl/s3_enc.c index fbc954d43c70c7..1eee9d9b21cf5c 100644 --- a/deps/openssl/openssl/ssl/s3_enc.c +++ b/deps/openssl/openssl/ssl/s3_enc.c @@ -177,32 +177,34 @@ static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num) EVP_MD_CTX_init(&s1); for (i = 0; (int)i < num; i += MD5_DIGEST_LENGTH) { k++; - if (k > sizeof buf) { + if (k > sizeof(buf)) /* bug: 'buf' is too small for this ciphersuite */ - SSLerr(SSL_F_SSL3_GENERATE_KEY_BLOCK, ERR_R_INTERNAL_ERROR); - return 0; - } + goto err; for (j = 0; j < k; j++) buf[j] = c; c++; - EVP_DigestInit_ex(&s1, EVP_sha1(), NULL); - EVP_DigestUpdate(&s1, buf, k); - EVP_DigestUpdate(&s1, s->session->master_key, - s->session->master_key_length); - EVP_DigestUpdate(&s1, s->s3->server_random, SSL3_RANDOM_SIZE); - EVP_DigestUpdate(&s1, s->s3->client_random, SSL3_RANDOM_SIZE); - EVP_DigestFinal_ex(&s1, smd, NULL); - - EVP_DigestInit_ex(&m5, EVP_md5(), NULL); - EVP_DigestUpdate(&m5, s->session->master_key, - s->session->master_key_length); - EVP_DigestUpdate(&m5, smd, SHA_DIGEST_LENGTH); + if (!EVP_DigestInit_ex(&s1, EVP_sha1(), NULL) || + !EVP_DigestUpdate(&s1, buf, k) || + !EVP_DigestUpdate(&s1, s->session->master_key, + s->session->master_key_length) || + !EVP_DigestUpdate(&s1, s->s3->server_random, SSL3_RANDOM_SIZE) || + !EVP_DigestUpdate(&s1, s->s3->client_random, SSL3_RANDOM_SIZE) || + !EVP_DigestFinal_ex(&s1, smd, NULL)) + goto err2; + + if (!EVP_DigestInit_ex(&m5, EVP_md5(), NULL) || + !EVP_DigestUpdate(&m5, s->session->master_key, + s->session->master_key_length) || + !EVP_DigestUpdate(&m5, smd, SHA_DIGEST_LENGTH)) + goto err2; if ((int)(i + MD5_DIGEST_LENGTH) > num) { - EVP_DigestFinal_ex(&m5, smd, NULL); + if (!EVP_DigestFinal_ex(&m5, smd, NULL)) + goto err2; memcpy(km, smd, (num - i)); } else - EVP_DigestFinal_ex(&m5, km, NULL); + if (!EVP_DigestFinal_ex(&m5, km, NULL)) + goto err2; km += MD5_DIGEST_LENGTH; } @@ -210,6 +212,12 @@ static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num) EVP_MD_CTX_cleanup(&m5); EVP_MD_CTX_cleanup(&s1); return 1; + err: + SSLerr(SSL_F_SSL3_GENERATE_KEY_BLOCK, ERR_R_INTERNAL_ERROR); + err2: + EVP_MD_CTX_cleanup(&m5); + EVP_MD_CTX_cleanup(&s1); + return 0; } int ssl3_change_cipher_state(SSL *s, int which) @@ -360,25 +368,33 @@ int ssl3_change_cipher_state(SSL *s, int which) * In here I set both the read and write key/iv to the same value * since only the correct one will be used :-). */ - EVP_DigestInit_ex(&md, EVP_md5(), NULL); - EVP_DigestUpdate(&md, key, j); - EVP_DigestUpdate(&md, er1, SSL3_RANDOM_SIZE); - EVP_DigestUpdate(&md, er2, SSL3_RANDOM_SIZE); - EVP_DigestFinal_ex(&md, &(exp_key[0]), NULL); + if (!EVP_DigestInit_ex(&md, EVP_md5(), NULL) || + !EVP_DigestUpdate(&md, key, j) || + !EVP_DigestUpdate(&md, er1, SSL3_RANDOM_SIZE) || + !EVP_DigestUpdate(&md, er2, SSL3_RANDOM_SIZE) || + !EVP_DigestFinal_ex(&md, &(exp_key[0]), NULL)) { + EVP_MD_CTX_cleanup(&md); + goto err2; + } key = &(exp_key[0]); if (k > 0) { - EVP_DigestInit_ex(&md, EVP_md5(), NULL); - EVP_DigestUpdate(&md, er1, SSL3_RANDOM_SIZE); - EVP_DigestUpdate(&md, er2, SSL3_RANDOM_SIZE); - EVP_DigestFinal_ex(&md, &(exp_iv[0]), NULL); + if (!EVP_DigestInit_ex(&md, EVP_md5(), NULL) || + !EVP_DigestUpdate(&md, er1, SSL3_RANDOM_SIZE) || + !EVP_DigestUpdate(&md, er2, SSL3_RANDOM_SIZE) || + !EVP_DigestFinal_ex(&md, &(exp_iv[0]), NULL)) { + EVP_MD_CTX_cleanup(&md); + goto err2; + } iv = &(exp_iv[0]); } } + EVP_MD_CTX_cleanup(&md); s->session->key_arg_length = 0; - EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE)); + if (!EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE))) + goto err2; #ifdef OPENSSL_SSL_TRACE_CRYPTO if (s->msg_callback) { @@ -399,7 +415,6 @@ int ssl3_change_cipher_state(SSL *s, int which) OPENSSL_cleanse(&(exp_key[0]), sizeof(exp_key)); OPENSSL_cleanse(&(exp_iv[0]), sizeof(exp_iv)); - EVP_MD_CTX_cleanup(&md); return (1); err: SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE); @@ -555,17 +570,20 @@ int ssl3_enc(SSL *s, int send) if ((bs != 1) && !send) return ssl3_cbc_remove_padding(s, rec, bs, mac_size); } - return (1); + return 1; } -void ssl3_init_finished_mac(SSL *s) +int ssl3_init_finished_mac(SSL *s) { if (s->s3->handshake_buffer) BIO_free(s->s3->handshake_buffer); if (s->s3->handshake_dgst) ssl3_free_digest_list(s); s->s3->handshake_buffer = BIO_new(BIO_s_mem()); + if (s->s3->handshake_buffer == NULL) + return 0; (void)BIO_set_close(s->s3->handshake_buffer, BIO_CLOSE); + return 1; } void ssl3_free_digest_list(SSL *s) @@ -622,6 +640,10 @@ int ssl3_digest_cached_records(SSL *s) for (i = 0; ssl_get_handshake_digest(i, &mask, &md); i++) { if ((mask & ssl_get_algorithm2(s)) && md) { s->s3->handshake_dgst[i] = EVP_MD_CTX_create(); + if (s->s3->handshake_dgst[i] == NULL) { + SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, ERR_R_MALLOC_FAILURE); + return 0; + } #ifdef OPENSSL_FIPS if (EVP_MD_nid(md) == NID_md5) { EVP_MD_CTX_set_flags(s->s3->handshake_dgst[i], @@ -903,7 +925,7 @@ int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, s, s->msg_callback_arg); } #endif - OPENSSL_cleanse(buf, sizeof buf); + OPENSSL_cleanse(buf, sizeof(buf)); return (ret); } diff --git a/deps/openssl/openssl/ssl/s3_lib.c b/deps/openssl/openssl/ssl/s3_lib.c index 0385e039c8d46c..1014a3fce16f75 100644 --- a/deps/openssl/openssl/ssl/s3_lib.c +++ b/deps/openssl/openssl/ssl/s3_lib.c @@ -4237,7 +4237,7 @@ int ssl3_get_req_cert_type(SSL *s, unsigned char *p) return (int)s->cert->ctype_num; } /* get configured sigalgs */ - siglen = tls12_get_psigalgs(s, &sig); + siglen = tls12_get_psigalgs(s, 1, &sig); if (s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT) nostrict = 0; for (i = 0; i < siglen; i += 2, sig += 2) { diff --git a/deps/openssl/openssl/ssl/s3_pkt.c b/deps/openssl/openssl/ssl/s3_pkt.c index 6ece87d0628c4f..0290c991d8101d 100644 --- a/deps/openssl/openssl/ssl/s3_pkt.c +++ b/deps/openssl/openssl/ssl/s3_pkt.c @@ -670,7 +670,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) * promptly send beyond the end of the users buffer ... so we trap and * report the error in a way the user will notice */ - if (len < tot) { + if ((len < tot) || ((wb->left != 0) && (len < (tot + s->s3->wpend_tot)))) { SSLerr(SSL_F_SSL3_WRITE_BYTES, SSL_R_BAD_LENGTH); return (-1); } @@ -699,6 +699,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) len >= 4 * (int)(max_send_fragment = s->max_send_fragment) && s->compress == NULL && s->msg_callback == NULL && SSL_USE_EXPLICIT_IV(s) && + s->enc_write_ctx != NULL && EVP_CIPHER_flags(s->enc_write_ctx->cipher) & EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK) { unsigned char aad[13]; diff --git a/deps/openssl/openssl/ssl/s3_srvr.c b/deps/openssl/openssl/ssl/s3_srvr.c index ea56f9ca81509b..ba17f1b562812c 100644 --- a/deps/openssl/openssl/ssl/s3_srvr.c +++ b/deps/openssl/openssl/ssl/s3_srvr.c @@ -311,7 +311,12 @@ int ssl3_accept(SSL *s) goto end; } - ssl3_init_finished_mac(s); + if (!ssl3_init_finished_mac(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + s->state = SSL3_ST_SR_CLNT_HELLO_A; s->ctx->stats.sess_accept++; } else if (!s->s3->send_connection_binding && @@ -348,7 +353,11 @@ int ssl3_accept(SSL *s) s->state = SSL3_ST_SW_FLUSH; s->init_num = 0; - ssl3_init_finished_mac(s); + if (!ssl3_init_finished_mac(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } break; case SSL3_ST_SW_HELLO_REQ_C: @@ -1704,6 +1713,12 @@ int ssl3_send_server_key_exchange(SSL *s) if (type & SSL_kEECDH) { const EC_GROUP *group; + if (s->s3->tmp.ecdh != NULL) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + ecdhp = cert->ecdh_tmp; if (s->cert->ecdh_tmp_auto) { /* Get NID of appropriate shared curve */ @@ -1724,17 +1739,7 @@ int ssl3_send_server_key_exchange(SSL *s) goto f_err; } - if (s->s3->tmp.ecdh != NULL) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, - ERR_R_INTERNAL_ERROR); - goto err; - } - /* Duplicate the ECDH structure. */ - if (ecdhp == NULL) { - SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB); - goto err; - } if (s->cert->ecdh_tmp_auto) ecdh = ecdhp; else if ((ecdh = EC_KEY_dup(ecdhp)) == NULL) { @@ -2084,7 +2089,7 @@ int ssl3_send_certificate_request(SSL *s) if (SSL_USE_SIGALGS(s)) { const unsigned char *psigs; - nl = tls12_get_psigalgs(s, &psigs); + nl = tls12_get_psigalgs(s, 1, &psigs); s2n(nl, p); memcpy(p, psigs, nl); p += nl; @@ -3018,6 +3023,11 @@ int ssl3_get_cert_verify(SSL *s) peer = s->session->peer; pkey = X509_get_pubkey(peer); + if (pkey == NULL) { + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + type = X509_certificate_type(peer, pkey); if (!(type & EVP_PKT_SIGN)) { @@ -3154,7 +3164,9 @@ int ssl3_get_cert_verify(SSL *s) goto f_err; } if (i != 64) { +#ifdef SSL_DEBUG fprintf(stderr, "GOST signature length is %d", i); +#endif } for (idx = 0; idx < 64; idx++) { signature[63 - idx] = p[idx]; @@ -3463,8 +3475,22 @@ int ssl3_send_newsession_ticket(SSL *s) * all the work otherwise use generated values from parent ctx. */ if (tctx->tlsext_ticket_key_cb) { - if (tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx, - &hctx, 1) < 0) + /* if 0 is returned, write en empty ticket */ + int ret = tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx, + &hctx, 1); + + if (ret == 0) { + l2n(0, p); /* timeout */ + s2n(0, p); /* length */ + ssl_set_handshake_header(s, SSL3_MT_NEWSESSION_TICKET, + p - ssl_handshake_start(s)); + s->state = SSL3_ST_SW_SESSION_TICKET_B; + OPENSSL_free(senc); + EVP_CIPHER_CTX_cleanup(&ctx); + HMAC_CTX_cleanup(&hctx); + return ssl_do_write(s); + } + if (ret < 0) goto err; } else { if (RAND_bytes(iv, 16) <= 0) diff --git a/deps/openssl/openssl/ssl/ssl_cert.c b/deps/openssl/openssl/ssl/ssl_cert.c index 1be6fb0032e200..155728d03772b1 100644 --- a/deps/openssl/openssl/ssl/ssl_cert.c +++ b/deps/openssl/openssl/ssl/ssl_cert.c @@ -412,6 +412,7 @@ CERT *ssl_cert_dup(CERT *cert) #endif ssl_cert_clear_certs(ret); + OPENSSL_free(ret); return NULL; } diff --git a/deps/openssl/openssl/ssl/ssl_ciph.c b/deps/openssl/openssl/ssl/ssl_ciph.c index 2ad8f4392236e6..40021329a93617 100644 --- a/deps/openssl/openssl/ssl/ssl_ciph.c +++ b/deps/openssl/openssl/ssl/ssl_ciph.c @@ -2001,7 +2001,7 @@ int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm) if (id < 193 || id > 255) { SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD, SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE); - return 0; + return 1; } MemCheck_off(); @@ -2013,6 +2013,7 @@ int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm) } comp->id = id; comp->method = cm; + comp->name = cm->name; load_builtin_compressions(); if (ssl_comp_methods && sk_SSL_COMP_find(ssl_comp_methods, comp) >= 0) { OPENSSL_free(comp); diff --git a/deps/openssl/openssl/ssl/ssl_lib.c b/deps/openssl/openssl/ssl/ssl_lib.c index f8054dae6b6b10..24be376c9fdf6e 100644 --- a/deps/openssl/openssl/ssl/ssl_lib.c +++ b/deps/openssl/openssl/ssl/ssl_lib.c @@ -1838,13 +1838,21 @@ int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, static unsigned long ssl_session_hash(const SSL_SESSION *a) { + const unsigned char *session_id = a->session_id; unsigned long l; + unsigned char tmp_storage[4]; + + if (a->session_id_length < sizeof(tmp_storage)) { + memset(tmp_storage, 0, sizeof(tmp_storage)); + memcpy(tmp_storage, a->session_id, a->session_id_length); + session_id = tmp_storage; + } l = (unsigned long) - ((unsigned int)a->session_id[0]) | - ((unsigned int)a->session_id[1] << 8L) | - ((unsigned long)a->session_id[2] << 16L) | - ((unsigned long)a->session_id[3] << 24L); + ((unsigned long)session_id[0]) | + ((unsigned long)session_id[1] << 8L) | + ((unsigned long)session_id[2] << 16L) | + ((unsigned long)session_id[3] << 24L); return (l); } @@ -3186,6 +3194,9 @@ SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx) ssl->cert->alpn_proposed_len = ocert->alpn_proposed_len; ocert->alpn_proposed = NULL; ssl->cert->alpn_sent = ocert->alpn_sent; + + if (!custom_exts_copy_flags(&ssl->cert->srv_ext, &ocert->srv_ext)) + return NULL; #endif ssl_cert_free(ocert); } diff --git a/deps/openssl/openssl/ssl/ssl_locl.h b/deps/openssl/openssl/ssl/ssl_locl.h index d50edd18c91658..aeffc006347171 100644 --- a/deps/openssl/openssl/ssl/ssl_locl.h +++ b/deps/openssl/openssl/ssl/ssl_locl.h @@ -1158,7 +1158,7 @@ long ssl2_default_timeout(void); const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p); int ssl3_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p); -void ssl3_init_finished_mac(SSL *s); +int ssl3_init_finished_mac(SSL *s); int ssl3_send_server_certificate(SSL *s); int ssl3_send_newsession_ticket(SSL *s); int ssl3_send_cert_status(SSL *s); @@ -1430,7 +1430,7 @@ int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len, long ssl_get_algorithm2(SSL *s); int tls1_save_sigalgs(SSL *s, const unsigned char *data, int dsize); int tls1_process_sigalgs(SSL *s); -size_t tls12_get_psigalgs(SSL *s, const unsigned char **psigs); +size_t tls12_get_psigalgs(SSL *s, int sent, const unsigned char **psigs); int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s, const unsigned char *sig, EVP_PKEY *pkey); void ssl_set_client_disabled(SSL *s); @@ -1482,6 +1482,8 @@ int custom_ext_add(SSL *s, int server, unsigned char **pret, unsigned char *limit, int *al); int custom_exts_copy(custom_ext_methods *dst, const custom_ext_methods *src); +int custom_exts_copy_flags(custom_ext_methods *dst, + const custom_ext_methods *src); void custom_exts_free(custom_ext_methods *exts); # else diff --git a/deps/openssl/openssl/ssl/ssl_rsa.c b/deps/openssl/openssl/ssl/ssl_rsa.c index f679801a297c8f..af03d45c2e9ae9 100644 --- a/deps/openssl/openssl/ssl/ssl_rsa.c +++ b/deps/openssl/openssl/ssl/ssl_rsa.c @@ -964,6 +964,7 @@ int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file) int ret = 0; BIO *bin = NULL; size_t num_extensions = 0; + unsigned char *new_serverinfo; if (ctx == NULL || file == NULL) { SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, @@ -1014,12 +1015,13 @@ int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file) goto end; } /* Append the decoded extension to the serverinfo buffer */ - serverinfo = + new_serverinfo = OPENSSL_realloc(serverinfo, serverinfo_length + extension_length); - if (serverinfo == NULL) { + if (new_serverinfo == NULL) { SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_MALLOC_FAILURE); goto end; } + serverinfo = new_serverinfo; memcpy(serverinfo + serverinfo_length, extension, extension_length); serverinfo_length += extension_length; diff --git a/deps/openssl/openssl/ssl/ssl_sess.c b/deps/openssl/openssl/ssl/ssl_sess.c index c3369a44aea7e2..f50f5142126f80 100644 --- a/deps/openssl/openssl/ssl/ssl_sess.c +++ b/deps/openssl/openssl/ssl/ssl_sess.c @@ -1006,7 +1006,8 @@ int SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned char *sid_ctx, return 0; } s->sid_ctx_length = sid_ctx_len; - memcpy(s->sid_ctx, sid_ctx, sid_ctx_len); + if (s->sid_ctx != sid_ctx) + memcpy(s->sid_ctx, sid_ctx, sid_ctx_len); return 1; } diff --git a/deps/openssl/openssl/ssl/ssltest.c b/deps/openssl/openssl/ssl/ssltest.c index 890e47685350bb..b75cac61fbdc42 100644 --- a/deps/openssl/openssl/ssl/ssltest.c +++ b/deps/openssl/openssl/ssl/ssltest.c @@ -311,6 +311,10 @@ static const char *sn_client; static const char *sn_server1; static const char *sn_server2; static int sn_expect = 0; +static int s_ticket1 = 0; +static int s_ticket2 = 0; +static int c_ticket = 0; +static int ticket_expect = -1; static int servername_cb(SSL *s, int *ad, void *arg) { @@ -325,6 +329,9 @@ static int servername_cb(SSL *s, int *ad, void *arg) !strcasecmp(servername, sn_server2)) { BIO_printf(bio_stdout, "Switching server context.\n"); SSL_set_SSL_CTX(s, s_ctx2); + /* Copy over all the SSL_CTX options */ + SSL_clear_options(s, 0xFFFFFFFFL); + SSL_set_options(s, SSL_CTX_get_options(s_ctx2)); } } return SSL_TLSEXT_ERR_OK; @@ -349,6 +356,21 @@ static int verify_servername(SSL *client, SSL *server) return -1; } +static int verify_ticket(SSL* ssl) +{ + if (ticket_expect == -1) + return 0; + if (ticket_expect == 0 && + (ssl->session->tlsext_tick == NULL || + ssl->session->tlsext_ticklen == 0)) + return 1; + if (ticket_expect == 1 && + (ssl->session->tlsext_tick != NULL && + ssl->session->tlsext_ticklen != 0)) + return 1; + return -1; +} + /*- * next_protos_parse parses a comma separated list of strings into a string * in a format suitable for passing to SSL_CTX_set_next_protos_advertised. @@ -477,6 +499,42 @@ static int verify_alpn(SSL *client, SSL *server) return -1; } +#ifndef OPENSSL_NO_TLSEXT + +static int cb_ticket0(SSL* s, unsigned char* key_name, unsigned char *iv, EVP_CIPHER_CTX *ctx, HMAC_CTX *hctx, int enc) +{ + return 0; +} + +static int cb_ticket1(SSL* s, unsigned char* key_name, unsigned char *iv, EVP_CIPHER_CTX *ctx, HMAC_CTX *hctx, int enc) +{ + static unsigned char key[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; + static char name[] = "ticket11ticket11"; + if (SSL_get_options(s) & SSL_OP_NO_TICKET) + return 0; + if (enc) { + RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH); + EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv); + HMAC_Init_ex(hctx, key, sizeof(key), EVP_sha1(), NULL); + memcpy(key_name, name, 16); + return 1; + } else { + if (memcmp(key_name, name, 16) == 0) { + EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv); + HMAC_Init_ex(hctx, key, sizeof(key), EVP_sha1(), NULL); + return 1; + } + } + return 0; +} + +static int cb_ticket2(SSL* s, unsigned char* key_name, unsigned char *iv, EVP_CIPHER_CTX *ctx, HMAC_CTX *hctx, int enc) +{ + fprintf(stderr, "ticket callback for SNI context should never be called\n"); + EXIT(1); +} +#endif + #define SCT_EXT_TYPE 18 /* @@ -820,6 +878,12 @@ static void sv_usage(void) fprintf(stderr, " -sn_server2 - have server context 2 respond to this servername\n"); fprintf(stderr, " -sn_expect1 - expected server 1\n"); fprintf(stderr, " -sn_expect2 - expected server 2\n"); +#ifndef OPENSSL_NO_TLSEXT + fprintf(stderr, " -s_ticket1 - enable/disable session tickets on context 1\n"); + fprintf(stderr, " -s_ticket2 - enable/disable session tickets on context 2\n"); + fprintf(stderr, " -c_ticket - enable/disable session tickets on the client\n"); + fprintf(stderr, " -ticket_expect - indicate that the client should (or should not) have a ticket\n"); +#endif } static void print_details(SSL *c_ssl, const char *prefix) @@ -1175,13 +1239,21 @@ int main(int argc, char *argv[]) } else if (strcmp(*argv, "-time") == 0) { print_time = 1; } -#ifndef OPENSSL_NO_COMP else if (strcmp(*argv, "-zlib") == 0) { +#ifndef OPENSSL_NO_COMP comp = COMP_ZLIB; +#else + fprintf(stderr, + "ignoring -zlib, since I'm compiled without COMP\n"); +#endif } else if (strcmp(*argv, "-rle") == 0) { +#ifndef OPENSSL_NO_COMP comp = COMP_RLE; - } +#else + fprintf(stderr, + "ignoring -rle, since I'm compiled without COMP\n"); #endif + } else if (strcmp(*argv, "-named_curve") == 0) { if (--argc < 1) goto bad; @@ -1241,6 +1313,36 @@ int main(int argc, char *argv[]) sn_expect = 1; } else if (strcmp(*argv, "-sn_expect2") == 0) { sn_expect = 2; +#ifndef OPENSSL_NO_TLSEXT + } else if (strcmp(*argv, "-s_ticket1") == 0) { + if (--argc < 1) + goto bad; + argv++; + if (strcmp(*argv, "yes") == 0) + s_ticket1 = 1; + if (strcmp(*argv, "broken") == 0) + s_ticket1 = 2; + } else if (strcmp(*argv, "-s_ticket2") == 0) { + if (--argc < 1) + goto bad; + argv++; + if (strcmp(*argv, "yes") == 0) + s_ticket2 = 1; + } else if (strcmp(*argv, "-c_ticket") == 0) { + if (--argc < 1) + goto bad; + argv++; + if (strcmp(*argv, "yes") == 0) + c_ticket = 1; + } else if (strcmp(*argv, "-ticket_expect") == 0) { + if (--argc < 1) + goto bad; + argv++; + if (strcmp(*argv, "yes") == 0) + ticket_expect = 1; + else if (strcmp(*argv, "no") == 0) + ticket_expect = 0; +#endif } else { fprintf(stderr, "unknown option %s\n", *argv); badop = 1; @@ -1679,6 +1781,24 @@ int main(int argc, char *argv[]) if (sn_server1 || sn_server2) SSL_CTX_set_tlsext_servername_callback(s_ctx, servername_cb); +#ifndef OPENSSL_NO_TLSEXT + if (s_ticket1 == 0) + SSL_CTX_set_options(s_ctx, SSL_OP_NO_TICKET); + /* always set the callback */ + if (s_ticket1 == 2) + SSL_CTX_set_tlsext_ticket_key_cb(s_ctx, cb_ticket0); + else + SSL_CTX_set_tlsext_ticket_key_cb(s_ctx, cb_ticket1); + + if (!s_ticket2) + SSL_CTX_set_options(s_ctx2, SSL_OP_NO_TICKET); + /* always set the callback - this should never be called */ + SSL_CTX_set_tlsext_ticket_key_cb(s_ctx2, cb_ticket2); + + if (!c_ticket) + SSL_CTX_set_options(c_ctx, SSL_OP_NO_TICKET); +#endif + c_ssl = SSL_new(c_ctx); s_ssl = SSL_new(s_ctx); @@ -1742,6 +1862,8 @@ int main(int argc, char *argv[]) ret = 1; if (verify_servername(c_ssl, s_ssl) < 0) ret = 1; + if (verify_ticket(c_ssl) < 0) + ret = 1; SSL_free(s_ssl); SSL_free(c_ssl); diff --git a/deps/openssl/openssl/ssl/t1_ext.c b/deps/openssl/openssl/ssl/t1_ext.c index 79ed946a514226..0f4aba0226b423 100644 --- a/deps/openssl/openssl/ssl/t1_ext.c +++ b/deps/openssl/openssl/ssl/t1_ext.c @@ -179,6 +179,25 @@ int custom_ext_add(SSL *s, int server, return 1; } +/* Copy the flags from src to dst for any extensions that exist in both */ +int custom_exts_copy_flags(custom_ext_methods *dst, + const custom_ext_methods *src) +{ + size_t i; + custom_ext_method *methsrc = src->meths; + + for (i = 0; i < src->meths_count; i++, methsrc++) { + custom_ext_method *methdst = custom_ext_find(dst, methsrc->ext_type); + + if (methdst == NULL) + continue; + + methdst->ext_flags = methsrc->ext_flags; + } + + return 1; +} + /* Copy table of custom extensions */ int custom_exts_copy(custom_ext_methods *dst, const custom_ext_methods *src) { @@ -223,16 +242,14 @@ static int custom_ext_meth_add(custom_ext_methods *exts, /* Search for duplicate */ if (custom_ext_find(exts, ext_type)) return 0; - exts->meths = OPENSSL_realloc(exts->meths, - (exts->meths_count + - 1) * sizeof(custom_ext_method)); - - if (!exts->meths) { - exts->meths_count = 0; + meth = OPENSSL_realloc(exts->meths, + (exts->meths_count + 1) + * sizeof(custom_ext_method)); + if (meth == NULL) return 0; - } - meth = exts->meths + exts->meths_count; + exts->meths = meth; + meth += exts->meths_count; memset(meth, 0, sizeof(custom_ext_method)); meth->parse_cb = parse_cb; meth->add_cb = add_cb; diff --git a/deps/openssl/openssl/ssl/t1_lib.c b/deps/openssl/openssl/ssl/t1_lib.c index e60c88bd5b2766..6587e8bb685c94 100644 --- a/deps/openssl/openssl/ssl/t1_lib.c +++ b/deps/openssl/openssl/ssl/t1_lib.c @@ -1035,7 +1035,7 @@ static unsigned char suiteb_sigalgs[] = { tlsext_sigalg_ecdsa(TLSEXT_hash_sha384) }; # endif -size_t tls12_get_psigalgs(SSL *s, const unsigned char **psigs) +size_t tls12_get_psigalgs(SSL *s, int sent, const unsigned char **psigs) { /* * If Suite B mode use Suite B sigalgs only, ignore any other @@ -1057,7 +1057,7 @@ size_t tls12_get_psigalgs(SSL *s, const unsigned char **psigs) } # endif /* If server use client authentication sigalgs if not NULL */ - if (s->server && s->cert->client_sigalgs) { + if (s->server == sent && s->cert->client_sigalgs) { *psigs = s->cert->client_sigalgs; return s->cert->client_sigalgslen; } else if (s->cert->conf_sigalgs) { @@ -1121,7 +1121,7 @@ int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s, # endif /* Check signature matches a type we sent */ - sent_sigslen = tls12_get_psigalgs(s, &sent_sigs); + sent_sigslen = tls12_get_psigalgs(s, 1, &sent_sigs); for (i = 0; i < sent_sigslen; i += 2, sent_sigs += 2) { if (sig[0] == sent_sigs[0] && sig[1] == sent_sigs[1]) break; @@ -1169,7 +1169,7 @@ void ssl_set_client_disabled(SSL *s) * Now go through all signature algorithms seeing if we support any for * RSA, DSA, ECDSA. Do this for all versions not just TLS 1.2. */ - sigalgslen = tls12_get_psigalgs(s, &sigalgs); + sigalgslen = tls12_get_psigalgs(s, 1, &sigalgs); for (i = 0; i < sigalgslen; i += 2, sigalgs += 2) { switch (sigalgs[1]) { # ifndef OPENSSL_NO_RSA @@ -1440,7 +1440,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, if (SSL_CLIENT_USE_SIGALGS(s)) { size_t salglen; const unsigned char *salg; - salglen = tls12_get_psigalgs(s, &salg); + salglen = tls12_get_psigalgs(s, 1, &salg); /*- * check for enough space. @@ -1769,6 +1769,9 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, return NULL; s2n(TLSEXT_TYPE_session_ticket, ret); s2n(0, ret); + } else { + /* if we don't add the above TLSEXT, we can't add a session ticket later */ + s->tlsext_ticket_expected = 0; } if (s->tlsext_status_expected) { @@ -3574,8 +3577,14 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, p = sdec; sess = d2i_SSL_SESSION(NULL, &p, slen); + slen -= p - sdec; OPENSSL_free(sdec); if (sess) { + /* Some additional consistency checks */ + if (slen != 0 || sess->session_id_length != 0) { + SSL_SESSION_free(sess); + return 2; + } /* * The session ID, if non-empty, is used by some clients to detect * that the ticket has been accepted. So we copy it to the session @@ -3803,7 +3812,7 @@ static int tls1_set_shared_sigalgs(SSL *s) conf = c->conf_sigalgs; conflen = c->conf_sigalgslen; } else - conflen = tls12_get_psigalgs(s, &conf); + conflen = tls12_get_psigalgs(s, 0, &conf); if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE || is_suiteb) { pref = conf; preflen = conflen; diff --git a/deps/openssl/openssl/test/Makefile b/deps/openssl/openssl/test/Makefile index 8f272ef99d5ee2..a324eeb39ac317 100644 --- a/deps/openssl/openssl/test/Makefile +++ b/deps/openssl/openssl/test/Makefile @@ -307,6 +307,7 @@ test_ssl: keyU.ss certU.ss certCA.ss certP1.ss keyP1.ss certP2.ss keyP2.ss \ fi ../util/shlib_wrap.sh ./$(SSLTEST) -test_cipherlist @sh ./testssl keyU.ss certU.ss certCA.ss + @sh ./testssl keyU.ss certU.ss certCA.ss -rle @sh ./testsslproxy keyP1.ss certP1.ss intP1.ss @sh ./testsslproxy keyP2.ss certP2.ss intP2.ss diff --git a/deps/openssl/openssl/test/ssltest_old b/deps/openssl/openssl/test/ssltest_old new file mode 100755 index 00000000000000..3e3a27d41d7daf Binary files /dev/null and b/deps/openssl/openssl/test/ssltest_old differ diff --git a/deps/openssl/openssl/test/testssl b/deps/openssl/openssl/test/testssl index a6f9fa770b3647..d7dda6e9a5af4c 100644 --- a/deps/openssl/openssl/test/testssl +++ b/deps/openssl/openssl/test/testssl @@ -292,4 +292,25 @@ if [ -z "$extra" -a `uname -m` = "x86_64" ]; then $ssltest -cipher AES128-SHA256 -bytes 8m || exit 1 fi + +$ssltest -bio_pair -sn_client alice -sn_server1 alice -sn_server2 bob -s_ticket1 no -s_ticket2 no -c_ticket no -ticket_expect no || exit 1 +$ssltest -bio_pair -sn_client alice -sn_server1 alice -sn_server2 bob -s_ticket1 no -s_ticket2 no -c_ticket yes -ticket_expect no || exit 1 +$ssltest -bio_pair -sn_client alice -sn_server1 alice -sn_server2 bob -s_ticket1 no -s_ticket2 yes -c_ticket no -ticket_expect no || exit 1 +$ssltest -bio_pair -sn_client alice -sn_server1 alice -sn_server2 bob -s_ticket1 no -s_ticket2 yes -c_ticket yes -ticket_expect no || exit 1 +$ssltest -bio_pair -sn_client alice -sn_server1 alice -sn_server2 bob -s_ticket1 yes -s_ticket2 no -c_ticket no -ticket_expect no || exit 1 +$ssltest -bio_pair -sn_client alice -sn_server1 alice -sn_server2 bob -s_ticket1 yes -s_ticket2 no -c_ticket yes -ticket_expect yes || exit 1 +$ssltest -bio_pair -sn_client alice -sn_server1 alice -sn_server2 bob -s_ticket1 yes -s_ticket2 yes -c_ticket no -ticket_expect no || exit 1 +$ssltest -bio_pair -sn_client alice -sn_server1 alice -sn_server2 bob -s_ticket1 yes -s_ticket2 yes -c_ticket yes -ticket_expect yes || exit 1 + +$ssltest -bio_pair -sn_client bob -sn_server1 alice -sn_server2 bob -s_ticket1 no -s_ticket2 no -c_ticket no -ticket_expect no || exit 1 +$ssltest -bio_pair -sn_client bob -sn_server1 alice -sn_server2 bob -s_ticket1 no -s_ticket2 no -c_ticket yes -ticket_expect no || exit 1 +$ssltest -bio_pair -sn_client bob -sn_server1 alice -sn_server2 bob -s_ticket1 no -s_ticket2 yes -c_ticket no -ticket_expect no || exit 1 +$ssltest -bio_pair -sn_client bob -sn_server1 alice -sn_server2 bob -s_ticket1 no -s_ticket2 yes -c_ticket yes -ticket_expect no || exit 1 +$ssltest -bio_pair -sn_client bob -sn_server1 alice -sn_server2 bob -s_ticket1 yes -s_ticket2 no -c_ticket no -ticket_expect no || exit 1 +$ssltest -bio_pair -sn_client bob -sn_server1 alice -sn_server2 bob -s_ticket1 yes -s_ticket2 no -c_ticket yes -ticket_expect no || exit 1 +$ssltest -bio_pair -sn_client bob -sn_server1 alice -sn_server2 bob -s_ticket1 yes -s_ticket2 yes -c_ticket no -ticket_expect no || exit 1 +$ssltest -bio_pair -sn_client bob -sn_server1 alice -sn_server2 bob -s_ticket1 yes -s_ticket2 yes -c_ticket yes -ticket_expect yes || exit 1 + +$ssltest -bio_pair -s_ticket1 broken -c_ticket yes -ticket_expect no || exit 1 + exit 0 diff --git a/deps/openssl/openssl/test/testutil.h b/deps/openssl/openssl/test/testutil.h index 75f0c8ae01ee14..e40b37ed6e7a70 100644 --- a/deps/openssl/openssl/test/testutil.h +++ b/deps/openssl/openssl/test/testutil.h @@ -103,7 +103,7 @@ * TEST_CASE_NAME is defined as the name of the test case function where * possible; otherwise we get by with the file name and line number. */ -# if __STDC_VERSION__ < 199901L +# if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L # if defined(_MSC_VER) # define TEST_CASE_NAME __FUNCTION__ # else diff --git a/deps/openssl/openssl/test/v3ext b/deps/openssl/openssl/test/v3ext new file mode 100755 index 00000000000000..09a0c3aa326f4b Binary files /dev/null and b/deps/openssl/openssl/test/v3ext differ diff --git a/deps/openssl/openssl/test/x509aux b/deps/openssl/openssl/test/x509aux new file mode 100755 index 00000000000000..35378a8ff9aee5 Binary files /dev/null and b/deps/openssl/openssl/test/x509aux differ diff --git a/deps/openssl/openssl/util/domd b/deps/openssl/openssl/util/domd index bc2a85f7dd5076..5a92559c9b7a83 100755 --- a/deps/openssl/openssl/util/domd +++ b/deps/openssl/openssl/util/domd @@ -34,11 +34,11 @@ else ${PERL} $TOP/util/clean-depend.pl < Makefile > Makefile.new RC=$? fi -if ! cmp -s Makefile.save Makefile.new; then - mv Makefile.new Makefile -else +if cmp -s Makefile.save Makefile.new; then mv Makefile.save Makefile rm -f Makefile.new +else + mv Makefile.new Makefile fi # unfake the presence of Kerberos rm $TOP/krb5.h diff --git a/deps/openssl/openssl/util/mk1mf.pl b/deps/openssl/openssl/util/mk1mf.pl index 7a3ae11f7865fe..490a034e4037e6 100755 --- a/deps/openssl/openssl/util/mk1mf.pl +++ b/deps/openssl/openssl/util/mk1mf.pl @@ -1207,6 +1207,7 @@ sub read_options "no-ssl3-method" => 0, "no-tlsext" => \$no_tlsext, "no-tls1" => \$no_tls1, + "no-dtls1" => 0, "no-srp" => \$no_srp, "no-cms" => \$no_cms, "no-jpake" => \$no_jpake, diff --git a/deps/uv/.mailmap b/deps/uv/.mailmap index 8acf8fecd14003..618274c0d2e242 100644 --- a/deps/uv/.mailmap +++ b/deps/uv/.mailmap @@ -1,3 +1,4 @@ +A. Hauptmann Aaron Bieber Alan Gutierrez Andrius Bentkus @@ -39,3 +40,4 @@ Timothy J. Fontaine Yasuhiro Matsumoto Yazhong Liu Yuki Okumura +jBarz diff --git a/deps/uv/AUTHORS b/deps/uv/AUTHORS index 4719d2368aec9d..ab4e099f167379 100644 --- a/deps/uv/AUTHORS +++ b/deps/uv/AUTHORS @@ -284,3 +284,11 @@ muflub Daniel Bevenius Howard Hellyer Chris Araman +Vladimir Matveev +Jason Madden +Jamie Davis +Daniel Kahn Gillmor +Keane +James McCoy +Bernardo Ramos +Juan Cruz Viotti diff --git a/deps/uv/ChangeLog b/deps/uv/ChangeLog index da4c3b13f14eb2..71b210f44bddf1 100644 --- a/deps/uv/ChangeLog +++ b/deps/uv/ChangeLog @@ -1,3 +1,178 @@ +2017.05.31, Version 1.12.0 (Stable), d6ac141ac674657049598c36604f26e031fae917 + +Changes since version 1.11.0: + +* Now working on version 1.11.1 (cjihrig) + +* test: fix tests on OpenBSD (Santiago Gimeno) + +* test: fix -Wformat warning (Santiago Gimeno) + +* win,fs: avoid double freeing uv_fs_event_t.dirw (Vladimir Matveev) + +* unix: remove unused code in `uv__io_start` (Fedor Indutny) + +* signal: add uv_signal_start_oneshot method (Santiago Gimeno) + +* unix: factor out reusable POSIX hrtime impl (Brad King) + +* unix,win: add uv_os_{get,set,unset}env() (cjihrig) + +* win: add uv__convert_utf8_to_utf16() (cjihrig) + +* docs: improve UV_ENOBUFS scenario documentation (cjihrig) + +* unix: return UV_EINVAL for NULL env name (jBarz) + +* unix: filter getifaddrs results consistently (Brad King) + +* unix: factor out getifaddrs result filter (Brad King) + +* unix: factor out reusable BSD ifaddrs impl (Brad King) + +* unix: use union to follow strict aliasing rules (jBarz) + +* unix: simplify async watcher dispatch logic (Ben Noordhuis) + +* samples: update timer callback prototype (Ben Noordhuis) + +* unix: make loops and watchers usable after fork() (Jason Madden) + +* win: free uv__loops once empty (cjihrig) + +* tools: add make_dist_html.py script (Ben Noordhuis) + +* win,sunos: stop handle on uv_fs_event_start() err (cjihrig) + +* unix,windows: refactor request init logic (Ben Noordhuis) + +* win: fix memory leak inside uv__pipe_getname (A. Hauptmann) + +* fsevent: support for files without short name (Bartosz Sosnowski) + +* doc: fix multiple doc typos (Jamie Davis) + +* test,osx: fix flaky kill test (Santiago Gimeno) + +* unix: inline uv_pipe_bind() err_bind goto target (cjihrig) + +* unix,test: deadstore fixes (Rasmus Christian Pedersen) + +* win: fix memory leak inside uv_fs_access() (A. Hauptmann) + +* doc: fix docs/src/fs.rst build warning (Daniel Bevenius) + +* doc: minor grammar fix in Installation section (Daniel Bevenius) + +* doc: suggestions for design page (Daniel Bevenius) + +* doc: libuv does not touch uv_loop_t.data (Ben Noordhuis) + +* github: add ISSUE_TEMPLATE.md (Ben Noordhuis) + +* doc: add link to libuv/help to README (Ben Noordhuis) + +* udp: fix fast path in uv_udp_send() on unix (Fedor Indutny) + +* test: add test for uv_udp_send() fix (Trevor Norris) + +* doc: fix documentation for uv_handle_t.type (Daniel Kahn Gillmor) + +* zos: use proper prototype for epoll_init() (Ben Noordhuis) + +* doc: rename docs to "libuv documentation" (Saúl Ibarra Corretgé) + +* doc: update copyright years (Saúl Ibarra Corretgé) + +* doc: move TOC to a dedicated document (Saúl Ibarra Corretgé) + +* doc: move documentation section up (Saúl Ibarra Corretgé) + +* doc: move "upgrading" to a standalone document (Saúl Ibarra Corretgé) + +* doc: add initial version of the User Guide (Saúl Ibarra Corretgé) + +* doc: removed unused file (Saúl Ibarra Corretgé) + +* doc: update guide/about and mention new maintainership (Saúl Ibarra Corretgé) + +* doc: remove licensing note from guide/about (Saúl Ibarra Corretgé) + +* doc: add warning note to user guide (Saúl Ibarra Corretgé) + +* doc: change license to CC BY 4.0 (Saúl Ibarra Corretgé) + +* doc: remove ubvook reference from README (Saúl Ibarra Corretgé) + +* doc: add code samples from uvbook (unadapted) (Saúl Ibarra Corretgé) + +* doc: update supported linux/glibc baseline (Ben Noordhuis) + +* win: avoid leaking pipe handles to child processes (Jameson Nash) + +* win,test: support stdout output larger than 1kb (Bartosz Sosnowski) + +* win: remove __declspec(inline) from atomic op (Keane) + +* test: fix VC++ compilation warning (Rasmus Christian Pedersen) + +* build: add -Wstrict-prototypes (Jameson Nash) + +* zos: implement uv__io_fork, skip fs event tests (jBarz) + +* unix: do not close udp sockets on bind error (Marc Schlaich) + +* unix: remove FSEventStreamFlushSync() call (cjihrig) + +* build,openbsd: remove kvm-related code (James McCoy) + +* test: fix flaky tcp-write-queue-order (Santiago Gimeno) + +* unix,win: add uv_os_gethostname() (cjihrig) + +* zos: increase timeout for tcp_writealot (jBarz) + +* zos: do not inline OOB data by default (jBarz) + +* test: fix -Wstrict-prototypes compiler warnings (Ben Noordhuis) + +* unix: factor out reusable no-proctitle impl (Brad King) + +* test: factor out fsevents skip explanation (Brad King) + +* test: skip fork fsevent cases when lacking support (Brad King) + +* unix: factor out reusable no-fsevents impl (Brad King) + +* unix: factor out reusable sysinfo memory lookup (Brad King) + +* unix: factor out reusable sysinfo loadavg impl (Brad King) + +* unix: factor out reusable procfs exepath impl (Brad King) + +* unix: add a uv__io_poll impl using POSIX poll(2) (Brad King) + +* cygwin: implement support for cygwin and msys2 (Brad King) + +* cygwin: recognize EOF on named pipe closure (Brad King) + +* cygwin: fix uv_pipe_connect report of ENOTSOCK (Brad King) + +* cygwin: disable non-functional ipc handle send (Brad King) + +* test: skip self-connecting tests on cygwin (Brad King) + +* doc: mark uv_loop_fork() as experimental (cjihrig) + +* doc: add bzoz to maintainers (Bartosz Sosnowski) + +* doc: fix memory leak in tcp-echo-server example (Bernardo Ramos) + +* win: make uv__get_osfhandle() public (Juan Cruz Viotti) + +* doc: use valid pipe name in pipe-echo-server (Bernardo Ramos) + + 2017.02.02, Version 1.11.0 (Stable), 7452ef4e06a4f99ee26b694c65476401534f2725 Changes since version 1.10.2: diff --git a/deps/uv/LICENSE-docs b/deps/uv/LICENSE-docs new file mode 100644 index 00000000000000..53883b1c7add1f --- /dev/null +++ b/deps/uv/LICENSE-docs @@ -0,0 +1,396 @@ +Attribution 4.0 International + +======================================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More_considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution 4.0 International Public License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution 4.0 International Public License ("Public License"). To the +extent this Public License may be interpreted as a contract, You are +granted the Licensed Rights in consideration of Your acceptance of +these terms and conditions, and the Licensor grants You such rights in +consideration of benefits the Licensor receives from making the +Licensed Material available under these terms and conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + d. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + e. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + f. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + g. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + h. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + i. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + j. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + k. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part; and + + b. produce, reproduce, and Share Adapted Material. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + 4. If You Share Adapted Material You produce, the Adapter's + License You apply must not prevent recipients of the Adapted + Material from complying with this Public License. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material; and + + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + + +======================================================================= + +Creative Commons is not a party to its public +licenses. Notwithstanding, Creative Commons may elect to apply one of +its public licenses to material it publishes and in those instances +will be considered the “Licensor.” The text of the Creative Commons +public licenses is dedicated to the public domain under the CC0 Public +Domain Dedication. Except for the limited purpose of indicating that +material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the +public licenses. + +Creative Commons may be contacted at creativecommons.org. + diff --git a/deps/uv/MAINTAINERS.md b/deps/uv/MAINTAINERS.md index 27a3523ea455b2..d85deb0066b131 100644 --- a/deps/uv/MAINTAINERS.md +++ b/deps/uv/MAINTAINERS.md @@ -3,6 +3,7 @@ libuv is currently managed by the following individuals: +* **Bartosz Sosnowski** ([@bzoz](https://github.com/bzoz)) * **Ben Noordhuis** ([@bnoordhuis](https://github.com/bnoordhuis)) - GPG key: D77B 1E34 243F BAF0 5F8E 9CC3 4F55 C8C8 46AB 89B9 (pubkey-bnoordhuis) * **Bert Belder** ([@piscisaureus](https://github.com/piscisaureus)) diff --git a/deps/uv/Makefile.am b/deps/uv/Makefile.am index 036464e71ecc48..404674baf211d5 100644 --- a/deps/uv/Makefile.am +++ b/deps/uv/Makefile.am @@ -166,16 +166,19 @@ test_run_tests_SOURCES = test/blackhole-server.c \ test/test-eintr-handling.c \ test/test-embed.c \ test/test-emfile.c \ + test/test-env-vars.c \ test/test-error.c \ test/test-fail-always.c \ test/test-fs-event.c \ test/test-fs-poll.c \ test/test-fs.c \ + test/test-fork.c \ test/test-get-currentexe.c \ test/test-get-loadavg.c \ test/test-get-memory.c \ test/test-get-passwd.c \ test/test-getaddrinfo.c \ + test/test-gethostname.c \ test/test-getnameinfo.c \ test/test-getsockname.c \ test/test-handle-fileno.c \ @@ -272,6 +275,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \ test/test-udp-open.c \ test/test-udp-options.c \ test/test-udp-send-and-recv.c \ + test/test-udp-send-hang-loop.c \ test/test-udp-send-immediate.c \ test/test-udp-send-unreachable.c \ test/test-udp-try-send.c \ @@ -333,12 +337,26 @@ libuv_la_SOURCES += src/unix/android-ifaddrs.c \ src/unix/pthread-barrier.c endif +if CYGWIN +libuv_la_CFLAGS += -D_GNU_SOURCE +libuv_la_SOURCES += src/unix/cygwin.c \ + src/unix/bsd-ifaddrs.c \ + src/unix/no-fsevents.c \ + src/unix/no-proctitle.c \ + src/unix/posix-hrtime.c \ + src/unix/posix-poll.c \ + src/unix/procfs-exepath.c \ + src/unix/sysinfo-loadavg.c \ + src/unix/sysinfo-memory.c +endif + if DARWIN include_HEADERS += include/uv-darwin.h \ include/pthread-barrier.h libuv_la_CFLAGS += -D_DARWIN_USE_64_BIT_INODE=1 libuv_la_CFLAGS += -D_DARWIN_UNLIMITED_SELECT=1 -libuv_la_SOURCES += src/unix/darwin.c \ +libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \ + src/unix/darwin.c \ src/unix/darwin-proctitle.c \ src/unix/fsevents.c \ src/unix/kqueue.c \ @@ -349,13 +367,19 @@ endif if DRAGONFLY include_HEADERS += include/uv-bsd.h -libuv_la_SOURCES += src/unix/freebsd.c src/unix/kqueue.c +libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \ + src/unix/freebsd.c \ + src/unix/kqueue.c \ + src/unix/posix-hrtime.c test_run_tests_LDFLAGS += -lutil endif if FREEBSD include_HEADERS += include/uv-bsd.h -libuv_la_SOURCES += src/unix/freebsd.c src/unix/kqueue.c +libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \ + src/unix/freebsd.c \ + src/unix/kqueue.c \ + src/unix/posix-hrtime.c test_run_tests_LDFLAGS += -lutil endif @@ -366,26 +390,49 @@ libuv_la_SOURCES += src/unix/linux-core.c \ src/unix/linux-inotify.c \ src/unix/linux-syscalls.c \ src/unix/linux-syscalls.h \ - src/unix/proctitle.c + src/unix/procfs-exepath.c \ + src/unix/proctitle.c \ + src/unix/sysinfo-loadavg.c \ + src/unix/sysinfo-memory.c test_run_tests_LDFLAGS += -lutil endif +if MSYS +libuv_la_CFLAGS += -D_GNU_SOURCE +libuv_la_SOURCES += src/unix/cygwin.c \ + src/unix/bsd-ifaddrs.c \ + src/unix/no-fsevents.c \ + src/unix/no-proctitle.c \ + src/unix/posix-hrtime.c \ + src/unix/posix-poll.c \ + src/unix/procfs-exepath.c \ + src/unix/sysinfo-loadavg.c \ + src/unix/sysinfo-memory.c +endif + if NETBSD include_HEADERS += include/uv-bsd.h -libuv_la_SOURCES += src/unix/kqueue.c src/unix/netbsd.c +libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \ + src/unix/kqueue.c \ + src/unix/netbsd.c \ + src/unix/posix-hrtime.c test_run_tests_LDFLAGS += -lutil endif if OPENBSD include_HEADERS += include/uv-bsd.h -libuv_la_SOURCES += src/unix/kqueue.c src/unix/openbsd.c +libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \ + src/unix/kqueue.c \ + src/unix/openbsd.c \ + src/unix/posix-hrtime.c test_run_tests_LDFLAGS += -lutil endif if SUNOS include_HEADERS += include/uv-sunos.h libuv_la_CFLAGS += -D__EXTENSIONS__ -D_XOPEN_SOURCE=500 -libuv_la_SOURCES += src/unix/sunos.c +libuv_la_SOURCES += src/unix/no-proctitle.c \ + src/unix/sunos.c endif if OS390 @@ -407,6 +454,7 @@ libuv_la_CFLAGS += -D_UNIX03_THREADS \ libuv_la_LDFLAGS += -qXPLINK libuv_la_SOURCES += src/unix/pthread-fixes.c \ src/unix/pthread-barrier.c \ + src/unix/no-fsevents.c \ src/unix/os390.c \ src/unix/os390-syscalls.c \ src/unix/proctitle.c diff --git a/deps/uv/Makefile.mingw b/deps/uv/Makefile.mingw index 8139138fccf654..3acf9e14a9eab4 100644 --- a/deps/uv/Makefile.mingw +++ b/deps/uv/Makefile.mingw @@ -17,6 +17,7 @@ CC ?= gcc CFLAGS += -Wall \ -Wextra \ -Wno-unused-parameter \ + -Wstrict-prototypes \ -Iinclude \ -Isrc \ -Isrc/win \ diff --git a/deps/uv/README.md b/deps/uv/README.md index 284dfb47c3d951..e5d94faf0fa38e 100644 --- a/deps/uv/README.md +++ b/deps/uv/README.md @@ -44,15 +44,17 @@ The ABI/API changes can be tracked [here](http://abi-laboratory.pro/tracker/time ## Licensing libuv is licensed under the MIT license. Check the [LICENSE file](LICENSE). +The documentation is licensed under the CC BY 4.0 license. Check the [LICENSE-docs file](LICENSE-docs). ## Community + * [Support](https://github.com/libuv/help) * [Mailing list](http://groups.google.com/group/libuv) * [IRC chatroom (#libuv@irc.freenode.org)](http://webchat.freenode.net?channels=libuv&uio=d4) ## Documentation -### Official API documentation +### Official documentation Located in the docs/ subdirectory. It uses the [Sphinx](http://sphinx-doc.org/) framework, which makes it possible to build the documentation in multiple @@ -88,8 +90,6 @@ also serve as API specification and usage examples. ### Other resources - * [An Introduction to libuv](http://nikhilm.github.com/uvbook/) - — An overview of libuv with tutorials. * [LXJS 2012 talk](http://www.youtube.com/watch?v=nGn60vDSxQ4) — High-level introductory talk about libuv. * [libuv-dox](https://github.com/thlorenz/libuv-dox) diff --git a/deps/uv/SUPPORTED_PLATFORMS.md b/deps/uv/SUPPORTED_PLATFORMS.md index bff1050d6331c0..3a000c5dd25e35 100644 --- a/deps/uv/SUPPORTED_PLATFORMS.md +++ b/deps/uv/SUPPORTED_PLATFORMS.md @@ -2,7 +2,7 @@ | System | Support type | Supported versions | Notes | |---|---|---|---| -| GNU/Linux | Tier 1 | Linux >= 2.6.18 with glibc >= 2.5 | | +| GNU/Linux | Tier 1 | Linux >= 2.6.32 with glibc >= 2.12 | | | macOS | Tier 1 | macOS >= 10.7 | | | Windows | Tier 1 | Windows >= XP SP1 | MSVC 2008 and later are supported | | FreeBSD | Tier 1 | >= 9 (see note) | | diff --git a/deps/uv/appveyor.yml b/deps/uv/appveyor.yml index e8e79f051e89dc..c542e34b991168 100644 --- a/deps/uv/appveyor.yml +++ b/deps/uv/appveyor.yml @@ -1,4 +1,4 @@ -version: v1.11.0.build{build} +version: v1.12.0.build{build} install: - cinst -y nsis diff --git a/deps/uv/checksparse.sh b/deps/uv/checksparse.sh index 68e3bde39305da..9782718a23266c 100755 --- a/deps/uv/checksparse.sh +++ b/deps/uv/checksparse.sh @@ -93,6 +93,7 @@ test/test-cwd-and-chdir.c test/test-delayed-accept.c test/test-dlerror.c test/test-embed.c +test/test-env-vars.c test/test-error.c test/test-fail-always.c test/test-fs-event.c @@ -103,6 +104,7 @@ test/test-get-loadavg.c test/test-get-memory.c test/test-get-passwd.c test/test-getaddrinfo.c +test/test-gethostname.c test/test-getsockname.c test/test-homedir.c test/test-hrtime.c @@ -165,6 +167,7 @@ test/test-udp-multicast-ttl.c test/test-udp-open.c test/test-udp-options.c test/test-udp-send-and-recv.c +test/test-udp-send-hang-loop.c test/test-walk-handles.c test/test-watcher-cross-stop.c " diff --git a/deps/uv/common.gypi b/deps/uv/common.gypi index 470b73385d8398..94e760030335bc 100644 --- a/deps/uv/common.gypi +++ b/deps/uv/common.gypi @@ -180,6 +180,7 @@ '-Wendif-labels', '-W', '-Wno-unused-parameter', + '-Wstrict-prototypes', ], }, 'conditions': [ diff --git a/deps/uv/configure.ac b/deps/uv/configure.ac index 360652198e5acb..8ac06f7fc8c84e 100644 --- a/deps/uv/configure.ac +++ b/deps/uv/configure.ac @@ -13,7 +13,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_PREREQ(2.57) -AC_INIT([libuv], [1.11.0], [https://github.com/libuv/libuv/issues]) +AC_INIT([libuv], [1.12.0], [https://github.com/libuv/libuv/issues]) AC_CONFIG_MACRO_DIR([m4]) m4_include([m4/libuv-extra-automake-flags.m4]) m4_include([m4/as_case.m4]) @@ -33,6 +33,7 @@ CC_CHECK_CFLAGS_APPEND([-std=gnu89]) CC_CHECK_CFLAGS_APPEND([-Wall]) CC_CHECK_CFLAGS_APPEND([-Wextra]) CC_CHECK_CFLAGS_APPEND([-Wno-unused-parameter]) +CC_CHECK_CFLAGS_APPEND([-Wstrict-prototypes]) # AM_PROG_AR is not available in automake v0.11 but it's essential in v0.12. m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) # autoconf complains if AC_PROG_LIBTOOL precedes AM_PROG_AR. @@ -42,7 +43,6 @@ LT_INIT # TODO(bnoordhuis) Check for -pthread vs. -pthreads AC_CHECK_LIB([dl], [dlopen]) AC_CHECK_LIB([kstat], [kstat_lookup]) -AC_CHECK_LIB([kvm], [kvm_open]) AC_CHECK_LIB([nsl], [gethostbyname]) AC_CHECK_LIB([perfstat], [perfstat_cpu]) AC_CHECK_LIB([pthread], [pthread_mutex_init]) @@ -52,10 +52,12 @@ AC_CHECK_LIB([socket], [socket]) AC_SYS_LARGEFILE AM_CONDITIONAL([AIX], [AS_CASE([$host_os],[aix*], [true], [false])]) AM_CONDITIONAL([ANDROID], [AS_CASE([$host_os],[linux-android*],[true], [false])]) +AM_CONDITIONAL([CYGWIN], [AS_CASE([$host_os],[cygwin*], [true], [false])]) AM_CONDITIONAL([DARWIN], [AS_CASE([$host_os],[darwin*], [true], [false])]) AM_CONDITIONAL([DRAGONFLY],[AS_CASE([$host_os],[dragonfly*], [true], [false])]) AM_CONDITIONAL([FREEBSD], [AS_CASE([$host_os],[*freebsd*], [true], [false])]) AM_CONDITIONAL([LINUX], [AS_CASE([$host_os],[linux*], [true], [false])]) +AM_CONDITIONAL([MSYS], [AS_CASE([$host_os],[msys*], [true], [false])]) AM_CONDITIONAL([NETBSD], [AS_CASE([$host_os],[netbsd*], [true], [false])]) AM_CONDITIONAL([OPENBSD], [AS_CASE([$host_os],[openbsd*], [true], [false])]) AM_CONDITIONAL([OS390], [AS_CASE([$host_os],[openedition*], [true], [false])]) @@ -64,6 +66,9 @@ AM_CONDITIONAL([WINNT], [AS_CASE([$host_os],[mingw*], [true], [false]) AS_CASE([$host_os],[mingw*], [ LIBS="$LIBS -lws2_32 -lpsapi -liphlpapi -lshell32 -luserenv -luser32" ]) +AS_CASE([$host_os], [openbsd*], [], [ + AC_CHECK_LIB([kvm], [kvm_open]) +]) AC_CHECK_HEADERS([sys/ahafs_evProds.h]) AC_CHECK_PROG(PKG_CONFIG, pkg-config, yes) AM_CONDITIONAL([HAVE_PKG_CONFIG], [test "x$PKG_CONFIG" != "x"]) diff --git a/deps/uv/docs/src/api.rst b/deps/uv/docs/src/api.rst new file mode 100644 index 00000000000000..22f0640f549ec8 --- /dev/null +++ b/deps/uv/docs/src/api.rst @@ -0,0 +1,35 @@ +.. _api: + +API documentation +================= + +.. toctree:: + :maxdepth: 1 + + errors + version + loop + handle + request + timer + prepare + check + idle + async + poll + signal + process + stream + tcp + pipe + tty + udp + fs_event + fs_poll + fs + threadpool + dns + dll + threading + misc + diff --git a/deps/uv/docs/src/conf.py b/deps/uv/docs/src/conf.py index 3f8689d2e5c699..c9b4ea38c310a5 100644 --- a/deps/uv/docs/src/conf.py +++ b/deps/uv/docs/src/conf.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# libuv API documentation documentation build configuration file, created by +# libuv documentation documentation build configuration file, created by # sphinx-quickstart on Sun Jul 27 11:47:51 2014. # # This file is execfile()d with the current directory set to its @@ -64,7 +64,7 @@ def get_libuv_version(): # General information about the project. project = u'libuv API documentation' -copyright = u'libuv contributors' +copyright = u'2014-present, libuv contributors' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -130,10 +130,10 @@ def get_libuv_version(): # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". -html_title = 'libuv API documentation' +html_title = 'libuv documentation' # A shorter title for the navigation bar. Default is the same as html_title. -html_short_title = 'libuv %s API documentation' % version +html_short_title = 'libuv %s documentation' % version # The name of an image file (relative to this directory) to place at the top # of the sidebar. @@ -216,7 +216,7 @@ def get_libuv_version(): # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - ('index', 'libuv.tex', u'libuv API documentation', + ('index', 'libuv.tex', u'libuv documentation', u'libuv contributors', 'manual'), ] @@ -246,7 +246,7 @@ def get_libuv_version(): # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - ('index', 'libuv', u'libuv API documentation', + ('index', 'libuv', u'libuv documentation', [u'libuv contributors'], 1) ] @@ -260,7 +260,7 @@ def get_libuv_version(): # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'libuv', u'libuv API documentation', + ('index', 'libuv', u'libuv documentation', u'libuv contributors', 'libuv', 'Cross-platform asynchronous I/O', 'Miscellaneous'), ] @@ -281,10 +281,10 @@ def get_libuv_version(): # -- Options for Epub output ---------------------------------------------- # Bibliographic Dublin Core info. -epub_title = u'libuv API documentation' +epub_title = u'libuv documentation' epub_author = u'libuv contributors' epub_publisher = u'libuv contributors' -epub_copyright = u'2014, libuv contributors' +epub_copyright = u'2014-present, libuv contributors' # The basename for the epub file. It defaults to the project name. epub_basename = u'libuv' diff --git a/deps/uv/docs/src/design.rst b/deps/uv/docs/src/design.rst index 34c3cff68e54ca..487d08ba6255ad 100644 --- a/deps/uv/docs/src/design.rst +++ b/deps/uv/docs/src/design.rst @@ -7,7 +7,7 @@ Design overview libuv is cross-platform support library which was originally written for NodeJS. It's designed around the event-driven asynchronous I/O model. -The library provides much more than simply abstraction over different I/O polling mechanisms: +The library provides much more than a simple abstraction over different I/O polling mechanisms: 'handles' and 'streams' provide a high level abstraction for sockets and other entities; cross-platform file I/O and threading functionality is also provided, amongst other things. @@ -25,9 +25,10 @@ Handles and requests libuv provides users with 2 abstractions to work with, in combination with the event loop: handles and requests. -Handles represent long-lived objects capable of performing certain operations while active. Some -examples: a prepare handle gets its callback called once every loop iteration when active, and -a TCP server handle get its connection callback called every time there is a new connection. +Handles represent long-lived objects capable of performing certain operations while active. Some examples: + +- A prepare handle gets its callback called once every loop iteration when active. +- A TCP server handle that gets its connection callback called every time there is a new connection. Requests represent (typically) short-lived operations. These operations can be performed over a handle: write requests are used to write data on a handle; or standalone: getaddrinfo requests @@ -85,11 +86,11 @@ stages of a loop iteration: * If there are no active handles or requests, the timeout is 0. * If there are any idle handles active, the timeout is 0. * If there are any handles pending to be closed, the timeout is 0. - * If none of the above cases was matched, the timeout of the closest timer is taken, or + * If none of the above cases matches, the timeout of the closest timer is taken, or if there are no active timers, infinity. -#. The loop blocks for I/O. At this point the loop will block for I/O for the timeout calculated - on the previous step. All I/O related handles that were monitoring a given file descriptor +#. The loop blocks for I/O. At this point the loop will block for I/O for the duration calculated + in the previous step. All I/O related handles that were monitoring a given file descriptor for a read or write operation get their callbacks called at this point. #. Check handle callbacks are called. Check handles get their callbacks called right after the @@ -103,7 +104,7 @@ stages of a loop iteration: so there might be timers which are due, those timers get their callbacks called. #. Iteration ends. If the loop was run with ``UV_RUN_NOWAIT`` or ``UV_RUN_ONCE`` modes the - iteration is ended and :c:func:`uv_run` will return. If the loop was run with ``UV_RUN_DEFAULT`` + iteration ends and :c:func:`uv_run` will return. If the loop was run with ``UV_RUN_DEFAULT`` it will continue from the start if it's still *alive*, otherwise it will also end. @@ -128,7 +129,7 @@ For a thorough explanation of the cross-platform file I/O landscape, checkout libuv currently uses a global thread pool on which all loops can queue work on. 3 types of operations are currently run on this pool: - * Filesystem operations + * File system operations * DNS functions (getaddrinfo and getnameinfo) * User specified code via :c:func:`uv_queue_work` diff --git a/deps/uv/docs/src/fs.rst b/deps/uv/docs/src/fs.rst index 192ecc7056de8e..3f766e393f2fa7 100644 --- a/deps/uv/docs/src/fs.rst +++ b/deps/uv/docs/src/fs.rst @@ -1,15 +1,15 @@ .. _fs: -Filesystem operations -===================== +File system operations +====================== -libuv provides a wide variety of cross-platform sync and async filesystem +libuv provides a wide variety of cross-platform sync and async file system operations. All functions defined in this document take a callback, which is allowed to be NULL. If the callback is NULL the request is completed synchronously, otherwise it will be performed asynchronously. -All file operations are run on the threadpool, see :ref:`threadpool` for information +All file operations are run on the threadpool. See :ref:`threadpool` for information on the threadpool size. @@ -18,7 +18,7 @@ Data types .. c:type:: uv_fs_t - Filesystem request type. + File system request type. .. c:type:: uv_timespec_t @@ -58,7 +58,7 @@ Data types .. c:type:: uv_fs_type - Filesystem request type. + File system request type. :: @@ -216,7 +216,7 @@ API Unlike `scandir(3)`, this function does not return the "." and ".." entries. .. note:: - On Linux, getting the type of an entry is only supported by some filesystems (btrfs, ext2, + On Linux, getting the type of an entry is only supported by some file systems (btrfs, ext2, ext3 and ext4 at the time of this writing), check the :man:`getdents(2)` man page. .. c:function:: int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) @@ -291,7 +291,7 @@ API Equivalent to :man:`realpath(3)` on Unix. Windows uses `GetFinalPathNameByHandle `_. .. warning:: - This function has certain platform specific caveats that were discovered when used in Node. + This function has certain platform-specific caveats that were discovered when used in Node. * macOS and other BSDs: this function will fail with UV_ELOOP if more than 32 symlinks are found while resolving the given path. This limit is hardcoded and cannot be sidestepped. @@ -324,3 +324,15 @@ API These functions are not implemented on Windows. .. seealso:: The :c:type:`uv_req_t` API functions also apply. + +Helper functions +---------------- + +.. c:function:: uv_os_fd_t uv_get_osfhandle(int fd) + + For a file descriptor in the C runtime, get the OS-dependent handle. + On UNIX, returns the ``fd`` intact. On Windows, this calls `_get_osfhandle `_. + Note that the return value is still owned by the C runtime, + any attempts to close it or to use it after closing the fd may lead to malfunction. + + .. versionadded:: 1.12.0 diff --git a/deps/uv/docs/src/fs_event.rst b/deps/uv/docs/src/fs_event.rst index c08ade2ef597be..2af3e9802bd0a1 100644 --- a/deps/uv/docs/src/fs_event.rst +++ b/deps/uv/docs/src/fs_event.rst @@ -66,7 +66,7 @@ Data types UV_FS_EVENT_WATCH_ENTRY = 1, /* * By default uv_fs_event will try to use a kernel interface such as inotify - * or kqueue to detect events. This may not work on remote filesystems such + * or kqueue to detect events. This may not work on remote file systems such * as NFS mounts. This flag makes fs_event fall back to calling stat() on a * regular interval. * This flag is currently not implemented yet on any backend. @@ -74,7 +74,7 @@ Data types UV_FS_EVENT_STAT = 2, /* * By default, event watcher, when watching directory, is not registering - * (is ignoring) changes in it's subdirectories. + * (is ignoring) changes in its subdirectories. * This flag will override this behaviour on platforms that support it. */ UV_FS_EVENT_RECURSIVE = 4 @@ -113,10 +113,14 @@ API Get the path being monitored by the handle. The buffer must be preallocated by the user. Returns 0 on success or an error code < 0 in case of failure. On success, `buffer` will contain the path and `size` its length. If the buffer - is not big enough UV_ENOBUFS will be returned and len will be set to the - required size. + is not big enough `UV_ENOBUFS` will be returned and `size` will be set to + the required size, including the null terminator. .. versionchanged:: 1.3.0 the returned length no longer includes the terminating null byte, and the buffer is not null terminated. + .. versionchanged:: 1.9.0 the returned length includes the terminating null + byte on `UV_ENOBUFS`, and the buffer is null terminated + on success. + .. seealso:: The :c:type:`uv_handle_t` API functions also apply. diff --git a/deps/uv/docs/src/fs_poll.rst b/deps/uv/docs/src/fs_poll.rst index 4efb2440e0baf2..2912bad9349a35 100644 --- a/deps/uv/docs/src/fs_poll.rst +++ b/deps/uv/docs/src/fs_poll.rst @@ -63,10 +63,15 @@ API Get the path being monitored by the handle. The buffer must be preallocated by the user. Returns 0 on success or an error code < 0 in case of failure. On success, `buffer` will contain the path and `size` its length. If the buffer - is not big enough UV_ENOBUFS will be returned and len will be set to the - required size. + is not big enough `UV_ENOBUFS` will be returned and `size` will be set to + the required size. .. versionchanged:: 1.3.0 the returned length no longer includes the terminating null byte, and the buffer is not null terminated. + .. versionchanged:: 1.9.0 the returned length includes the terminating null + byte on `UV_ENOBUFS`, and the buffer is null terminated + on success. + + .. seealso:: The :c:type:`uv_handle_t` API functions also apply. diff --git a/deps/uv/docs/src/guide.rst b/deps/uv/docs/src/guide.rst new file mode 100644 index 00000000000000..126e08082c228b --- /dev/null +++ b/deps/uv/docs/src/guide.rst @@ -0,0 +1,22 @@ +.. _guide: + +User guide +========== + +.. warning:: + The contents of this guide have been recently incorporated into the libuv documentation + and it hasn't gone through thorough review yet. If you spot a mistake please file an + issue, or better yet, open a pull request! + +.. toctree:: + :maxdepth: 2 + + guide/introduction + guide/basics + guide/filesystem + guide/networking + guide/threads + guide/processes + guide/eventloops + guide/utilities + guide/about diff --git a/deps/uv/docs/src/handle.rst b/deps/uv/docs/src/handle.rst index 14aec51fff1692..a0f3d05fdb1b4a 100644 --- a/deps/uv/docs/src/handle.rst +++ b/deps/uv/docs/src/handle.rst @@ -86,9 +86,9 @@ Public members Pointer to the :c:type:`uv_loop_t` where the handle is running on. Readonly. -.. c:member:: uv_loop_t* uv_handle_t.type +.. c:member:: uv_handle_type uv_handle_t.type - Pointer to the :c:type:`uv_handle_type`. Readonly. + The :c:type:`uv_handle_type`, indicating the type of the underlying handle. Readonly. .. c:member:: void* uv_handle_t.data diff --git a/deps/uv/docs/src/index.rst b/deps/uv/docs/src/index.rst index fa89c4bffe580c..5ec2beb511cb00 100644 --- a/deps/uv/docs/src/index.rst +++ b/deps/uv/docs/src/index.rst @@ -1,6 +1,6 @@ -Welcome to the libuv API documentation -====================================== +Welcome to the libuv documentation +================================== Overview -------- @@ -37,59 +37,26 @@ Features * Threading and synchronization primitives -Downloads ---------- - -libuv can be downloaded from `here `_. - +Documentation +------------- -Installation ------------- +.. toctree:: + :maxdepth: 1 -Installation instructions can be found on `the README `_. + design + api + guide + upgrading -Upgrading +Downloads --------- -Migration guides for different libuv versions, starting with 1.0. - -.. toctree:: - :maxdepth: 1 - - migration_010_100 +libuv can be downloaded from `here `_. -Documentation -------------- +Installation +------------ -.. toctree:: - :maxdepth: 1 +Installation instructions can be found in `the README `_. - design - errors - version - loop - handle - request - timer - prepare - check - idle - async - poll - signal - process - stream - tcp - pipe - tty - udp - fs_event - fs_poll - fs - threadpool - dns - dll - threading - misc diff --git a/deps/uv/docs/src/loop.rst b/deps/uv/docs/src/loop.rst index 1f504cb391f169..02543171de488b 100644 --- a/deps/uv/docs/src/loop.rst +++ b/deps/uv/docs/src/loop.rst @@ -38,9 +38,8 @@ Public members .. c:member:: void* uv_loop_t.data - Space for user-defined arbitrary data. libuv does not use this field. libuv does, however, - initialize it to NULL in :c:func:`uv_loop_init`, and it poisons the value (on debug builds) - on :c:func:`uv_loop_close`. + Space for user-defined arbitrary data. libuv does not use and does not + touch this field. API @@ -165,3 +164,57 @@ API .. c:function:: void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg) Walk the list of handles: `walk_cb` will be executed with the given `arg`. + +.. c:function:: int uv_loop_fork(uv_loop_t* loop) + + .. versionadded:: 1.12.0 + + Reinitialize any kernel state necessary in the child process after + a :man:`fork(2)` system call. + + Previously started watchers will continue to be started in the + child process. + + It is necessary to explicitly call this function on every event + loop created in the parent process that you plan to continue to + use in the child, including the default loop (even if you don't + continue to use it in the parent). This function must be called + before calling :c:func:`uv_run` or any other API function using + the loop in the child. Failure to do so will result in undefined + behaviour, possibly including duplicate events delivered to both + parent and child or aborting the child process. + + When possible, it is preferred to create a new loop in the child + process instead of reusing a loop created in the parent. New loops + created in the child process after the fork should not use this + function. + + This function is not implemented on Windows, where it returns ``UV_ENOSYS``. + + .. caution:: + + This function is experimental. It may contain bugs, and is subject to + change or removal. API and ABI stability is not guaranteed. + + .. note:: + + On Mac OS X, if directory FS event handles were in use in the + parent process *for any event loop*, the child process will no + longer be able to use the most efficient FSEvent + implementation. Instead, uses of directory FS event handles in + the child will fall back to the same implementation used for + files and on other kqueue-based systems. + + .. caution:: + + On AIX and SunOS, FS event handles that were already started in + the parent process at the time of forking will *not* deliver + events in the child process; they must be closed and restarted. + On all other platforms, they will continue to work normally + without any further intervention. + + .. caution:: + + Any previous value returned from :c:func`uv_backend_fd` is now + invalid. That function must be called again to determine the + correct backend file descriptor. diff --git a/deps/uv/docs/src/misc.rst b/deps/uv/docs/src/misc.rst index 71934694623d9b..9d7c3617e864bb 100644 --- a/deps/uv/docs/src/misc.rst +++ b/deps/uv/docs/src/misc.rst @@ -270,12 +270,20 @@ API .. c:function:: int uv_cwd(char* buffer, size_t* size) - Gets the current working directory. + Gets the current working directory, and stores it in `buffer`. If the + current working directory is too large to fit in `buffer`, this function + returns `UV_ENOBUFS`, and sets `size` to the required length, including the + null terminator. .. versionchanged:: 1.1.0 On Unix the path no longer ends in a slash. + .. versionchanged:: 1.9.0 the returned length includes the terminating null + byte on `UV_ENOBUFS`, and the buffer is null terminated + on success. + + .. c:function:: int uv_chdir(const char* dir) Changes the current working directory. @@ -386,3 +394,49 @@ API stability guarantees. .. versionadded:: 1.8.0 + +.. c:function:: int uv_os_getenv(const char* name, char* buffer, size_t* size) + + Retrieves the environment variable specified by `name`, copies its value + into `buffer`, and sets `size` to the string length of the value. When + calling this function, `size` must be set to the amount of storage available + in `buffer`, including the null terminator. If the environment variable + exceeds the storage available in `buffer`, `UV_ENOBUFS` is returned, and + `size` is set to the amount of storage required to hold the value. If no + matching environment variable exists, `UV_ENOENT` is returned. + + .. warning:: + This function is not thread safe. + + .. versionadded:: 1.12.0 + +.. c:function:: int uv_os_setenv(const char* name, const char* value) + + Creates or updates the environment variable specified by `name` with + `value`. + + .. warning:: + This function is not thread safe. + + .. versionadded:: 1.12.0 + +.. c:function:: int uv_os_unsetenv(const char* name) + + Deletes the environment variable specified by `name`. If no such environment + variable exists, this function returns successfully. + + .. warning:: + This function is not thread safe. + + .. versionadded:: 1.12.0 + +.. c:function:: int uv_os_gethostname(char* buffer, size_t* size) + + Returns the hostname as a null-terminated string in `buffer`, and sets + `size` to the string length of the hostname. When calling this function, + `size` must be set to the amount of storage available in `buffer`, including + the null terminator. If the hostname exceeds the storage available in + `buffer`, `UV_ENOBUFS` is returned, and `size` is set to the amount of + storage required to hold the value. + + .. versionadded:: 1.12.0 diff --git a/deps/uv/docs/src/signal.rst b/deps/uv/docs/src/signal.rst index dc1223b90ac5e2..5b3b352bdd257d 100644 --- a/deps/uv/docs/src/signal.rst +++ b/deps/uv/docs/src/signal.rst @@ -70,6 +70,13 @@ API Start the handle with the given callback, watching for the given signal. +.. c:function:: int uv_signal_start_oneshot(uv_signal_t* signal, uv_signal_cb cb, int signum) + + .. versionadded:: 1.12.0 + + Same functionality as :c:func:`uv_signal_start` but the signal handler is reset the moment + the signal is received. + .. c:function:: int uv_signal_stop(uv_signal_t* signal) Stop the handle, the callback will no longer be called. diff --git a/deps/uv/docs/src/threadpool.rst b/deps/uv/docs/src/threadpool.rst index 18949507e75004..93bd236d35e9f5 100644 --- a/deps/uv/docs/src/threadpool.rst +++ b/deps/uv/docs/src/threadpool.rst @@ -5,7 +5,7 @@ Thread pool work scheduling =========================== libuv provides a threadpool which can be used to run user code and get notified -in the loop thread. This thread pool is internally used to run all filesystem +in the loop thread. This thread pool is internally used to run all file system operations, as well as getaddrinfo and getnameinfo requests. Its default size is 4, but it can be changed at startup time by setting the diff --git a/deps/uv/docs/src/upgrading.rst b/deps/uv/docs/src/upgrading.rst new file mode 100644 index 00000000000000..32840c2696a12e --- /dev/null +++ b/deps/uv/docs/src/upgrading.rst @@ -0,0 +1,11 @@ +.. _upgrading: + +Upgrading +========= + +Migration guides for different libuv versions, starting with 1.0. + +.. toctree:: + :maxdepth: 1 + + migration_010_100 diff --git a/deps/uv/include/uv-posix.h b/deps/uv/include/uv-posix.h new file mode 100644 index 00000000000000..9a96634db0e3a5 --- /dev/null +++ b/deps/uv/include/uv-posix.h @@ -0,0 +1,31 @@ +/* Copyright libuv project 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. + */ + +#ifndef UV_POSIX_H +#define UV_POSIX_H + +#define UV_PLATFORM_LOOP_FIELDS \ + struct pollfd* poll_fds; \ + size_t poll_fds_used; \ + size_t poll_fds_size; \ + unsigned char poll_fds_iterating; \ + +#endif /* UV_POSIX_H */ diff --git a/deps/uv/include/uv-unix.h b/deps/uv/include/uv-unix.h index 3030f719a27148..d7754509b1e27b 100644 --- a/deps/uv/include/uv-unix.h +++ b/deps/uv/include/uv-unix.h @@ -60,6 +60,8 @@ defined(__OpenBSD__) || \ defined(__NetBSD__) # include "uv-bsd.h" +#elif defined(__CYGWIN__) || defined(__MSYS__) +# include "uv-posix.h" #endif #ifndef PTHREAD_BARRIER_SERIAL_THREAD @@ -79,7 +81,6 @@ #endif struct uv__io_s; -struct uv__async; struct uv_loop_s; typedef void (*uv__io_cb)(struct uv_loop_s* loop, @@ -97,16 +98,6 @@ struct uv__io_s { UV_IO_PRIVATE_PLATFORM_FIELDS }; -typedef void (*uv__async_cb)(struct uv_loop_s* loop, - struct uv__async* w, - unsigned int nevents); - -struct uv__async { - uv__async_cb cb; - uv__io_t io_watcher; - int wfd; -}; - #ifndef UV_PLATFORM_SEM_T # define UV_PLATFORM_SEM_T sem_t #endif @@ -216,7 +207,9 @@ typedef struct { void* check_handles[2]; \ void* idle_handles[2]; \ void* async_handles[2]; \ - struct uv__async async_watcher; \ + void (*async_unused)(void); /* TODO(bnoordhuis) Remove in libuv v2. */ \ + uv__io_t async_io_watcher; \ + int async_wfd; \ struct { \ void* min; \ unsigned int nelts; \ diff --git a/deps/uv/include/uv-version.h b/deps/uv/include/uv-version.h index cf000487909477..34d4a43f9e5f22 100644 --- a/deps/uv/include/uv-version.h +++ b/deps/uv/include/uv-version.h @@ -31,7 +31,7 @@ */ #define UV_VERSION_MAJOR 1 -#define UV_VERSION_MINOR 11 +#define UV_VERSION_MINOR 12 #define UV_VERSION_PATCH 0 #define UV_VERSION_IS_RELEASE 1 #define UV_VERSION_SUFFIX "" diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h index 31f09f0f6af34a..f076094ccdc24c 100644 --- a/deps/uv/include/uv.h +++ b/deps/uv/include/uv.h @@ -274,6 +274,7 @@ UV_EXTERN void uv_loop_delete(uv_loop_t*); UV_EXTERN size_t uv_loop_size(void); UV_EXTERN int uv_loop_alive(const uv_loop_t* loop); UV_EXTERN int uv_loop_configure(uv_loop_t* loop, uv_loop_option option, ...); +UV_EXTERN int uv_loop_fork(uv_loop_t* loop); UV_EXTERN int uv_run(uv_loop_t*, uv_run_mode mode); UV_EXTERN void uv_stop(uv_loop_t*); @@ -1033,6 +1034,7 @@ UV_EXTERN int uv_get_process_title(char* buffer, size_t size); UV_EXTERN int uv_set_process_title(const char* title); UV_EXTERN int uv_resident_set_memory(size_t* rss); UV_EXTERN int uv_uptime(double* uptime); +UV_EXTERN uv_os_fd_t uv_get_osfhandle(int fd); typedef struct { long tv_sec; @@ -1073,6 +1075,12 @@ UV_EXTERN int uv_interface_addresses(uv_interface_address_t** addresses, UV_EXTERN void uv_free_interface_addresses(uv_interface_address_t* addresses, int count); +UV_EXTERN int uv_os_getenv(const char* name, char* buffer, size_t* size); +UV_EXTERN int uv_os_setenv(const char* name, const char* value); +UV_EXTERN int uv_os_unsetenv(const char* name); + +UV_EXTERN int uv_os_gethostname(char* buffer, size_t* size); + typedef enum { UV_FS_UNKNOWN = -1, @@ -1324,6 +1332,9 @@ UV_EXTERN int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle); UV_EXTERN int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum); +UV_EXTERN int uv_signal_start_oneshot(uv_signal_t* handle, + uv_signal_cb signal_cb, + int signum); UV_EXTERN int uv_signal_stop(uv_signal_t* handle); UV_EXTERN void uv_loadavg(double avg[3]); diff --git a/deps/uv/samples/socks5-proxy/client.c b/deps/uv/samples/socks5-proxy/client.c index ae9913a1c6e125..aa2a91c9a12e9f 100644 --- a/deps/uv/samples/socks5-proxy/client.c +++ b/deps/uv/samples/socks5-proxy/client.c @@ -95,7 +95,7 @@ static int do_kill(client_ctx *cx); static int do_almost_dead(client_ctx *cx); static int conn_cycle(const char *who, conn *a, conn *b); static void conn_timer_reset(conn *c); -static void conn_timer_expire(uv_timer_t *handle, int status); +static void conn_timer_expire(uv_timer_t *handle); static void conn_getaddrinfo(conn *c, const char *hostname); static void conn_getaddrinfo_done(uv_getaddrinfo_t *req, int status, @@ -582,10 +582,9 @@ static void conn_timer_reset(conn *c) { 0)); } -static void conn_timer_expire(uv_timer_t *handle, int status) { +static void conn_timer_expire(uv_timer_t *handle) { conn *c; - CHECK(0 == status); c = CONTAINER_OF(handle, conn, timer_handle); c->result = UV_ETIMEDOUT; do_next(c->client); diff --git a/deps/uv/src/threadpool.c b/deps/uv/src/threadpool.c index 2c5152b4200875..108934112c582a 100644 --- a/deps/uv/src/threadpool.c +++ b/deps/uv/src/threadpool.c @@ -23,18 +23,6 @@ #if !defined(_WIN32) # include "unix/internal.h" -#else -# include "win/req-inl.h" -/* TODO(saghul): unify internal req functions */ -static void uv__req_init(uv_loop_t* loop, - uv_req_t* req, - uv_req_type type) { - uv_req_init(loop, req); - req->type = type; - uv__req_register(loop, req); -} -# define uv__req_init(loop, req, type) \ - uv__req_init((loop), (uv_req_t*)(req), (type)) #endif #include @@ -139,7 +127,7 @@ UV_DESTRUCTOR(static void cleanup(void)) { #endif -static void init_once(void) { +static void init_threads(void) { unsigned int i; const char* val; @@ -177,6 +165,27 @@ static void init_once(void) { } +#ifndef _WIN32 +static void reset_once(void) { + uv_once_t child_once = UV_ONCE_INIT; + memcpy(&once, &child_once, sizeof(child_once)); +} +#endif + + +static void init_once(void) { +#ifndef _WIN32 + /* Re-initialize the threadpool after fork. + * Note that this discards the global mutex and condition as well + * as the work queue. + */ + if (pthread_atfork(NULL, NULL, &reset_once)) + abort(); +#endif + init_threads(); +} + + void uv__work_submit(uv_loop_t* loop, struct uv__work* w, void (*work)(struct uv__work* w), diff --git a/deps/uv/src/unix/aix.c b/deps/uv/src/unix/aix.c index 1d2cd4a80e97f6..388c9cca9707ee 100644 --- a/deps/uv/src/unix/aix.c +++ b/deps/uv/src/unix/aix.c @@ -96,6 +96,13 @@ void uv__platform_loop_delete(uv_loop_t* loop) { } +int uv__io_fork(uv_loop_t* loop) { + uv__platform_loop_delete(loop); + + return uv__platform_loop_init(loop); +} + + int uv__io_check_fd(uv_loop_t* loop, int fd) { struct poll_ctl pc; diff --git a/deps/uv/src/unix/async.c b/deps/uv/src/unix/async.c index 393cdebd4ea3fc..45c088ea1b39bc 100644 --- a/deps/uv/src/unix/async.c +++ b/deps/uv/src/unix/async.c @@ -33,16 +33,15 @@ #include #include -static void uv__async_event(uv_loop_t* loop, - struct uv__async* w, - unsigned int nevents); +static void uv__async_send(uv_loop_t* loop); +static int uv__async_start(uv_loop_t* loop); static int uv__async_eventfd(void); int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) { int err; - err = uv__async_start(loop, &loop->async_watcher, uv__async_event); + err = uv__async_start(loop); if (err) return err; @@ -63,7 +62,7 @@ int uv_async_send(uv_async_t* handle) { return 0; if (cmpxchgi(&handle->pending, 0, 1) == 0) - uv__async_send(&handle->loop->async_watcher); + uv__async_send(handle->loop); return 0; } @@ -75,44 +74,18 @@ void uv__async_close(uv_async_t* handle) { } -static void uv__async_event(uv_loop_t* loop, - struct uv__async* w, - unsigned int nevents) { +static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { + char buf[1024]; + ssize_t r; QUEUE queue; QUEUE* q; uv_async_t* h; - QUEUE_MOVE(&loop->async_handles, &queue); - while (!QUEUE_EMPTY(&queue)) { - q = QUEUE_HEAD(&queue); - h = QUEUE_DATA(q, uv_async_t, queue); - - QUEUE_REMOVE(q); - QUEUE_INSERT_TAIL(&loop->async_handles, q); - - if (cmpxchgi(&h->pending, 1, 0) == 0) - continue; - - if (h->async_cb == NULL) - continue; - h->async_cb(h); - } -} - + assert(w == &loop->async_io_watcher); -static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { - struct uv__async* wa; - char buf[1024]; - unsigned n; - ssize_t r; - - n = 0; for (;;) { r = read(w->fd, buf, sizeof(buf)); - if (r > 0) - n += r; - if (r == sizeof(buf)) continue; @@ -128,23 +101,26 @@ static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { abort(); } - wa = container_of(w, struct uv__async, io_watcher); + QUEUE_MOVE(&loop->async_handles, &queue); + while (!QUEUE_EMPTY(&queue)) { + q = QUEUE_HEAD(&queue); + h = QUEUE_DATA(q, uv_async_t, queue); + + QUEUE_REMOVE(q); + QUEUE_INSERT_TAIL(&loop->async_handles, q); -#if defined(__linux__) - if (wa->wfd == -1) { - uint64_t val; - assert(n == sizeof(val)); - memcpy(&val, buf, sizeof(val)); /* Avoid alignment issues. */ - wa->cb(loop, wa, val); - return; - } -#endif + if (cmpxchgi(&h->pending, 1, 0) == 0) + continue; + + if (h->async_cb == NULL) + continue; - wa->cb(loop, wa, n); + h->async_cb(h); + } } -void uv__async_send(struct uv__async* wa) { +static void uv__async_send(uv_loop_t* loop) { const void* buf; ssize_t len; int fd; @@ -152,14 +128,14 @@ void uv__async_send(struct uv__async* wa) { buf = ""; len = 1; - fd = wa->wfd; + fd = loop->async_wfd; #if defined(__linux__) if (fd == -1) { static const uint64_t val = 1; buf = &val; len = sizeof(val); - fd = wa->io_watcher.fd; /* eventfd */ + fd = loop->async_io_watcher.fd; /* eventfd */ } #endif @@ -178,17 +154,11 @@ void uv__async_send(struct uv__async* wa) { } -void uv__async_init(struct uv__async* wa) { - wa->io_watcher.fd = -1; - wa->wfd = -1; -} - - -int uv__async_start(uv_loop_t* loop, struct uv__async* wa, uv__async_cb cb) { +static int uv__async_start(uv_loop_t* loop) { int pipefd[2]; int err; - if (wa->io_watcher.fd != -1) + if (loop->async_io_watcher.fd != -1) return 0; err = uv__async_eventfd(); @@ -222,32 +192,41 @@ int uv__async_start(uv_loop_t* loop, struct uv__async* wa, uv__async_cb cb) { if (err < 0) return err; - uv__io_init(&wa->io_watcher, uv__async_io, pipefd[0]); - uv__io_start(loop, &wa->io_watcher, POLLIN); - wa->wfd = pipefd[1]; - wa->cb = cb; + uv__io_init(&loop->async_io_watcher, uv__async_io, pipefd[0]); + uv__io_start(loop, &loop->async_io_watcher, POLLIN); + loop->async_wfd = pipefd[1]; return 0; } -void uv__async_stop(uv_loop_t* loop, struct uv__async* wa) { - if (wa->io_watcher.fd == -1) +int uv__async_fork(uv_loop_t* loop) { + if (loop->async_io_watcher.fd == -1) /* never started */ + return 0; + + uv__async_stop(loop); + + return uv__async_start(loop); +} + + +void uv__async_stop(uv_loop_t* loop) { + if (loop->async_io_watcher.fd == -1) return; - if (wa->wfd != -1) { - if (wa->wfd != wa->io_watcher.fd) - uv__close(wa->wfd); - wa->wfd = -1; + if (loop->async_wfd != -1) { + if (loop->async_wfd != loop->async_io_watcher.fd) + uv__close(loop->async_wfd); + loop->async_wfd = -1; } - uv__io_stop(loop, &wa->io_watcher, POLLIN); - uv__close(wa->io_watcher.fd); - wa->io_watcher.fd = -1; + uv__io_stop(loop, &loop->async_io_watcher, POLLIN); + uv__close(loop->async_io_watcher.fd); + loop->async_io_watcher.fd = -1; } -static int uv__async_eventfd() { +static int uv__async_eventfd(void) { #if defined(__linux__) static int no_eventfd2; static int no_eventfd; diff --git a/deps/uv/src/unix/bsd-ifaddrs.c b/deps/uv/src/unix/bsd-ifaddrs.c new file mode 100644 index 00000000000000..414789451ab3d6 --- /dev/null +++ b/deps/uv/src/unix/bsd-ifaddrs.c @@ -0,0 +1,139 @@ +/* Copyright libuv project 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. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include + +#include +#include +#if !defined(__CYGWIN__) && !defined(__MSYS__) +#include +#endif + +static int uv__ifaddr_exclude(struct ifaddrs *ent) { + if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) + return 1; + if (ent->ifa_addr == NULL) + return 1; +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__) + /* + * On BSD getifaddrs returns information related to the raw underlying + * devices. We're not interested in this information. + */ + if (ent->ifa_addr->sa_family == AF_LINK) + return 1; +#elif defined(__NetBSD__) || defined(__OpenBSD__) + if (ent->ifa_addr->sa_family != PF_INET) + return 1; +#endif + return 0; +} + +int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { + struct ifaddrs* addrs; + struct ifaddrs* ent; + uv_interface_address_t* address; + int i; + + if (getifaddrs(&addrs) != 0) + return -errno; + + *count = 0; + + /* Count the number of interfaces */ + for (ent = addrs; ent != NULL; ent = ent->ifa_next) { + if (uv__ifaddr_exclude(ent)) + continue; + (*count)++; + } + + *addresses = uv__malloc(*count * sizeof(**addresses)); + + if (*addresses == NULL) { + freeifaddrs(addrs); + return -ENOMEM; + } + + address = *addresses; + + for (ent = addrs; ent != NULL; ent = ent->ifa_next) { + if (uv__ifaddr_exclude(ent)) + continue; + + address->name = uv__strdup(ent->ifa_name); + + if (ent->ifa_addr->sa_family == AF_INET6) { + address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); + } else { + address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); + } + + if (ent->ifa_netmask->sa_family == AF_INET6) { + address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); + } else { + address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); + } + + address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK); + + address++; + } + + /* Fill in physical addresses for each interface */ + for (ent = addrs; ent != NULL; ent = ent->ifa_next) { + if (uv__ifaddr_exclude(ent)) + continue; + + address = *addresses; + + for (i = 0; i < *count; i++) { + if (strcmp(address->name, ent->ifa_name) == 0) { +#if defined(__CYGWIN__) || defined(__MSYS__) + memset(address->phys_addr, 0, sizeof(address->phys_addr)); +#else + struct sockaddr_dl* sa_addr; + sa_addr = (struct sockaddr_dl*)(ent->ifa_addr); + memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); +#endif + } + address++; + } + } + + freeifaddrs(addrs); + + return 0; +} + + +void uv_free_interface_addresses(uv_interface_address_t* addresses, + int count) { + int i; + + for (i = 0; i < count; i++) { + uv__free(addresses[i].name); + } + + uv__free(addresses); +} diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c index 1ec549cccb5cfe..8276c604132995 100644 --- a/deps/uv/src/unix/core.c +++ b/deps/uv/src/unix/core.c @@ -28,6 +28,7 @@ #include #include #include +#include /* MAXHOSTNAMELEN on Linux and the BSDs */ #include #include #include @@ -42,6 +43,7 @@ #include #ifdef __sun +# include /* MAXHOSTNAMELEN on Solaris */ # include # include # include @@ -80,6 +82,11 @@ #include #endif +/* Fallback for the maximum hostname length */ +#ifndef MAXHOSTNAMELEN +# define MAXHOSTNAMELEN 256 +#endif + static int uv__run_pending(uv_loop_t* loop); /* Verify that uv_buf_t is ABI-compatible with struct iovec. */ @@ -538,6 +545,7 @@ int uv__nonblock_ioctl(int fd, int set) { } +#if !defined(__CYGWIN__) && !defined(__MSYS__) int uv__cloexec_ioctl(int fd, int set) { int r; @@ -550,6 +558,7 @@ int uv__cloexec_ioctl(int fd, int set) { return 0; } +#endif int uv__nonblock_fcntl(int fd, int set) { @@ -839,13 +848,8 @@ void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) { * every tick of the event loop but the other backends allow us to * short-circuit here if the event mask is unchanged. */ - if (w->events == w->pevents) { - if (w->events == 0 && !QUEUE_EMPTY(&w->watcher_queue)) { - QUEUE_REMOVE(&w->watcher_queue); - QUEUE_INIT(&w->watcher_queue); - } + if (w->events == w->pevents) return; - } #endif if (QUEUE_EMPTY(&w->watcher_queue)) @@ -1245,3 +1249,83 @@ int uv_translate_sys_error(int sys_errno) { /* If < 0 then it's already a libuv error. */ return sys_errno <= 0 ? sys_errno : -sys_errno; } + + +int uv_os_getenv(const char* name, char* buffer, size_t* size) { + char* var; + size_t len; + + if (name == NULL || buffer == NULL || size == NULL || *size == 0) + return -EINVAL; + + var = getenv(name); + + if (var == NULL) + return -ENOENT; + + len = strlen(var); + + if (len >= *size) { + *size = len + 1; + return -ENOBUFS; + } + + memcpy(buffer, var, len + 1); + *size = len; + + return 0; +} + + +int uv_os_setenv(const char* name, const char* value) { + if (name == NULL || value == NULL) + return -EINVAL; + + if (setenv(name, value, 1) != 0) + return -errno; + + return 0; +} + + +int uv_os_unsetenv(const char* name) { + if (unsetenv(name) != 0) + return -errno; + + return 0; +} + + +int uv_os_gethostname(char* buffer, size_t* size) { + /* + On some platforms, if the input buffer is not large enough, gethostname() + succeeds, but truncates the result. libuv can detect this and return ENOBUFS + instead by creating a large enough buffer and comparing the hostname length + to the size input. + */ + char buf[MAXHOSTNAMELEN + 1]; + size_t len; + + if (buffer == NULL || size == NULL || *size == 0) + return -EINVAL; + + if (gethostname(buf, sizeof(buf)) != 0) + return -errno; + + buf[sizeof(buf) - 1] = '\0'; /* Null terminate, just to be safe. */ + len = strlen(buf); + + if (len >= *size) { + *size = len + 1; + return -ENOBUFS; + } + + memcpy(buffer, buf, len + 1); + *size = len; + return 0; +} + + +uv_os_fd_t uv_get_osfhandle(int fd) { + return fd; +} diff --git a/deps/uv/src/unix/cygwin.c b/deps/uv/src/unix/cygwin.c new file mode 100644 index 00000000000000..5a887dd4c2d03e --- /dev/null +++ b/deps/uv/src/unix/cygwin.c @@ -0,0 +1,54 @@ +/* Copyright libuv project 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. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include + +int uv_uptime(double* uptime) { + struct sysinfo info; + + if (sysinfo(&info) < 0) + return -errno; + + *uptime = info.uptime; + return 0; +} + +int uv_resident_set_memory(size_t* rss) { + /* FIXME: read /proc/meminfo? */ + *rss = 0; + return UV_ENOSYS; +} + +int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { + /* FIXME: read /proc/stat? */ + *cpu_infos = NULL; + *count = 0; + return UV_ENOSYS; +} + +void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { + (void)cpu_infos; + (void)count; +} diff --git a/deps/uv/src/unix/darwin.c b/deps/uv/src/unix/darwin.c index cf95da21693b9a..df6dd1c61bbc24 100644 --- a/deps/uv/src/unix/darwin.c +++ b/deps/uv/src/unix/darwin.c @@ -25,10 +25,6 @@ #include #include -#include -#include -#include - #include #include #include /* _NSGetExecutablePath */ @@ -233,103 +229,3 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { uv__free(cpu_infos); } - - -int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { - struct ifaddrs *addrs, *ent; - uv_interface_address_t* address; - int i; - struct sockaddr_dl *sa_addr; - - if (getifaddrs(&addrs)) - return -errno; - - *count = 0; - - /* Count the number of interfaces */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family == AF_LINK)) { - continue; - } - - (*count)++; - } - - *addresses = uv__malloc(*count * sizeof(**addresses)); - if (!(*addresses)) { - freeifaddrs(addrs); - return -ENOMEM; - } - - address = *addresses; - - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) - continue; - - if (ent->ifa_addr == NULL) - continue; - - /* - * On Mac OS X getifaddrs returns information related to Mac Addresses for - * various devices, such as firewire, etc. These are not relevant here. - */ - if (ent->ifa_addr->sa_family == AF_LINK) - continue; - - address->name = uv__strdup(ent->ifa_name); - - if (ent->ifa_addr->sa_family == AF_INET6) { - address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); - } else { - address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); - } - - if (ent->ifa_netmask->sa_family == AF_INET6) { - address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); - } else { - address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); - } - - address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK); - - address++; - } - - /* Fill in physical addresses for each interface */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != AF_LINK)) { - continue; - } - - address = *addresses; - - for (i = 0; i < (*count); i++) { - if (strcmp(address->name, ent->ifa_name) == 0) { - sa_addr = (struct sockaddr_dl*)(ent->ifa_addr); - memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); - } - address++; - } - } - - freeifaddrs(addrs); - - return 0; -} - - -void uv_free_interface_addresses(uv_interface_address_t* addresses, - int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(addresses[i].name); - } - - uv__free(addresses); -} diff --git a/deps/uv/src/unix/freebsd.c b/deps/uv/src/unix/freebsd.c index cba44a3e0b078e..e52ae99dbe9030 100644 --- a/deps/uv/src/unix/freebsd.c +++ b/deps/uv/src/unix/freebsd.c @@ -25,10 +25,6 @@ #include #include -#include -#include -#include - #include #include #include @@ -41,9 +37,6 @@ #include /* sysconf */ #include -#undef NANOSEC -#define NANOSEC ((uint64_t) 1e9) - #ifndef CPUSTATES # define CPUSTATES 5U #endif @@ -67,13 +60,6 @@ void uv__platform_loop_delete(uv_loop_t* loop) { } -uint64_t uv__hrtime(uv_clocktype_t type) { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec); -} - - #ifdef __DragonFly__ int uv_exepath(char* buffer, size_t* size) { char abspath[PATH_MAX * 2 + 1]; @@ -358,103 +344,3 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { uv__free(cpu_infos); } - - -int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { - struct ifaddrs *addrs, *ent; - uv_interface_address_t* address; - int i; - struct sockaddr_dl *sa_addr; - - if (getifaddrs(&addrs)) - return -errno; - - *count = 0; - - /* Count the number of interfaces */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family == AF_LINK)) { - continue; - } - - (*count)++; - } - - *addresses = uv__malloc(*count * sizeof(**addresses)); - if (!(*addresses)) { - freeifaddrs(addrs); - return -ENOMEM; - } - - address = *addresses; - - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) - continue; - - if (ent->ifa_addr == NULL) - continue; - - /* - * On FreeBSD getifaddrs returns information related to the raw underlying - * devices. We're not interested in this information yet. - */ - if (ent->ifa_addr->sa_family == AF_LINK) - continue; - - address->name = uv__strdup(ent->ifa_name); - - if (ent->ifa_addr->sa_family == AF_INET6) { - address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); - } else { - address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); - } - - if (ent->ifa_netmask->sa_family == AF_INET6) { - address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); - } else { - address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); - } - - address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK); - - address++; - } - - /* Fill in physical addresses for each interface */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != AF_LINK)) { - continue; - } - - address = *addresses; - - for (i = 0; i < (*count); i++) { - if (strcmp(address->name, ent->ifa_name) == 0) { - sa_addr = (struct sockaddr_dl*)(ent->ifa_addr); - memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); - } - address++; - } - } - - freeifaddrs(addrs); - - return 0; -} - - -void uv_free_interface_addresses(uv_interface_address_t* addresses, - int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(addresses[i].name); - } - - uv__free(addresses); -} diff --git a/deps/uv/src/unix/fsevents.c b/deps/uv/src/unix/fsevents.c index d331a13172675e..643e233cfe9e94 100644 --- a/deps/uv/src/unix/fsevents.c +++ b/deps/uv/src/unix/fsevents.c @@ -378,9 +378,6 @@ static void uv__fsevents_destroy_stream(uv_loop_t* loop) { if (state->fsevent_stream == NULL) return; - /* Flush all accumulated events */ - pFSEventStreamFlushSync(state->fsevent_stream); - /* Stop emitting events */ pFSEventStreamStop(state->fsevent_stream); diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h index 1188e8fe70998a..2e3afa6c856827 100644 --- a/deps/uv/src/unix/internal.h +++ b/deps/uv/src/unix/internal.h @@ -162,7 +162,8 @@ struct uv__stream_queued_fds_s { defined(__DragonFly__) || \ defined(__FreeBSD__) || \ defined(__FreeBSD_kernel__) || \ - defined(__linux__) + defined(__linux__) || \ + defined(__OpenBSD__) #define uv__cloexec uv__cloexec_ioctl #define uv__nonblock uv__nonblock_ioctl #else @@ -191,12 +192,12 @@ void uv__io_feed(uv_loop_t* loop, uv__io_t* w); int uv__io_active(const uv__io_t* w, unsigned int events); int uv__io_check_fd(uv_loop_t* loop, int fd); void uv__io_poll(uv_loop_t* loop, int timeout); /* in milliseconds or -1 */ +int uv__io_fork(uv_loop_t* loop); /* async */ -void uv__async_send(struct uv__async* wa); -void uv__async_init(struct uv__async* wa); -int uv__async_start(uv_loop_t* loop, struct uv__async* wa, uv__async_cb cb); -void uv__async_stop(uv_loop_t* loop, struct uv__async* wa); +void uv__async_stop(uv_loop_t* loop); +int uv__async_fork(uv_loop_t* loop); + /* loop */ void uv__run_idle(uv_loop_t* loop); @@ -232,6 +233,7 @@ int uv__next_timeout(const uv_loop_t* loop); void uv__signal_close(uv_signal_t* handle); void uv__signal_global_once_init(void); void uv__signal_loop_cleanup(uv_loop_t* loop); +int uv__signal_loop_fork(uv_loop_t* loop); /* platform specific */ uint64_t uv__hrtime(uv_clocktype_t type); @@ -301,15 +303,6 @@ static const int kFSEventStreamEventFlagItemIsSymlink = 0x00040000; #endif /* defined(__APPLE__) */ -UV_UNUSED(static void uv__req_init(uv_loop_t* loop, - uv_req_t* req, - uv_req_type type)) { - req->type = type; - uv__req_register(loop, req); -} -#define uv__req_init(loop, req, type) \ - uv__req_init((loop), (uv_req_t*)(req), (type)) - UV_UNUSED(static void uv__update_time(uv_loop_t* loop)) { /* Use a fast time source if available. We only need millisecond precision. */ @@ -326,4 +319,8 @@ UV_UNUSED(static char* uv__basename_r(const char* path)) { return s + 1; } +#if defined(__linux__) +int uv__inotify_fork(uv_loop_t* loop, void* old_watchers); +#endif + #endif /* UV_UNIX_INTERNAL_H_ */ diff --git a/deps/uv/src/unix/kqueue.c b/deps/uv/src/unix/kqueue.c index fffd4626f17579..6bc60bbe46885e 100644 --- a/deps/uv/src/unix/kqueue.c +++ b/deps/uv/src/unix/kqueue.c @@ -48,6 +48,37 @@ int uv__kqueue_init(uv_loop_t* loop) { } +static int uv__has_forked_with_cfrunloop; + +int uv__io_fork(uv_loop_t* loop) { + int err; + uv__close(loop->backend_fd); + loop->backend_fd = -1; + err = uv__kqueue_init(loop); + if (err) + return err; + +#if defined(__APPLE__) + if (loop->cf_state != NULL) { + /* We cannot start another CFRunloop and/or thread in the child + process; CF aborts if you try or if you try to touch the thread + at all to kill it. So the best we can do is ignore it from now + on. This means we can't watch directories in the same way + anymore (like other BSDs). It also means we cannot properly + clean up the allocated resources; calling + uv__fsevents_loop_delete from uv_loop_close will crash the + process. So we sidestep the issue by pretending like we never + started it in the first place. + */ + uv__has_forked_with_cfrunloop = 1; + uv__free(loop->cf_state); + loop->cf_state = NULL; + } +#endif + return err; +} + + int uv__io_check_fd(uv_loop_t* loop, int fd) { struct kevent ev; int rc; @@ -404,6 +435,9 @@ int uv_fs_event_start(uv_fs_event_t* handle, handle->cb = cb; #if defined(__APPLE__) + if (uv__has_forked_with_cfrunloop) + goto fallback; + /* Nullify field to perform checks later */ handle->cf_cb = NULL; handle->realpath = NULL; @@ -438,7 +472,7 @@ int uv_fs_event_stop(uv_fs_event_t* handle) { uv__handle_stop(handle); #if defined(__APPLE__) - if (uv__fsevents_close(handle)) + if (uv__has_forked_with_cfrunloop || uv__fsevents_close(handle)) #endif /* defined(__APPLE__) */ { uv__io_close(handle->loop, &handle->event_watcher); diff --git a/deps/uv/src/unix/linux-core.c b/deps/uv/src/unix/linux-core.c index 58dd813ddf132c..2866e938545cb3 100644 --- a/deps/uv/src/unix/linux-core.c +++ b/deps/uv/src/unix/linux-core.c @@ -107,6 +107,24 @@ int uv__platform_loop_init(uv_loop_t* loop) { } +int uv__io_fork(uv_loop_t* loop) { + int err; + void* old_watchers; + + old_watchers = loop->inotify_watchers; + + uv__close(loop->backend_fd); + loop->backend_fd = -1; + uv__platform_loop_delete(loop); + + err = uv__platform_loop_init(loop); + if (err) + return err; + + return uv__inotify_fork(loop, old_watchers); +} + + void uv__platform_loop_delete(uv_loop_t* loop) { if (loop->inotify_fd == -1) return; uv__io_stop(loop, &loop->inotify_read_watcher, POLLIN); @@ -454,55 +472,6 @@ uint64_t uv__hrtime(uv_clocktype_t type) { } -void uv_loadavg(double avg[3]) { - struct sysinfo info; - - if (sysinfo(&info) < 0) return; - - avg[0] = (double) info.loads[0] / 65536.0; - avg[1] = (double) info.loads[1] / 65536.0; - avg[2] = (double) info.loads[2] / 65536.0; -} - - -int uv_exepath(char* buffer, size_t* size) { - ssize_t n; - - if (buffer == NULL || size == NULL || *size == 0) - return -EINVAL; - - n = *size - 1; - if (n > 0) - n = readlink("/proc/self/exe", buffer, n); - - if (n == -1) - return -errno; - - buffer[n] = '\0'; - *size = n; - - return 0; -} - - -uint64_t uv_get_free_memory(void) { - struct sysinfo info; - - if (sysinfo(&info) == 0) - return (uint64_t) info.freeram * info.mem_unit; - return 0; -} - - -uint64_t uv_get_total_memory(void) { - struct sysinfo info; - - if (sysinfo(&info) == 0) - return (uint64_t) info.totalram * info.mem_unit; - return 0; -} - - int uv_resident_set_memory(size_t* rss) { char buf[1024]; const char* s; @@ -868,6 +837,19 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { uv__free(cpu_infos); } +static int uv__ifaddr_exclude(struct ifaddrs *ent) { + if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) + return 1; + if (ent->ifa_addr == NULL) + return 1; + /* + * On Linux getifaddrs returns information related to the raw underlying + * devices. We're not interested in this information yet. + */ + if (ent->ifa_addr->sa_family == PF_PACKET) + return 1; + return 0; +} int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { @@ -887,11 +869,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, /* Count the number of interfaces */ for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family == PF_PACKET)) { + if (uv__ifaddr_exclude(ent)) continue; - } (*count)++; } @@ -908,17 +887,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, address = *addresses; for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) - continue; - - if (ent->ifa_addr == NULL) - continue; - - /* - * On Linux getifaddrs returns information related to the raw underlying - * devices. We're not interested in this information yet. - */ - if (ent->ifa_addr->sa_family == PF_PACKET) + if (uv__ifaddr_exclude(ent)) continue; address->name = uv__strdup(ent->ifa_name); @@ -942,11 +911,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, /* Fill in physical addresses for each interface */ for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != PF_PACKET)) { + if (uv__ifaddr_exclude(ent)) continue; - } address = *addresses; diff --git a/deps/uv/src/unix/linux-inotify.c b/deps/uv/src/unix/linux-inotify.c index 4708c051d3b540..5934c5d8cb060e 100644 --- a/deps/uv/src/unix/linux-inotify.c +++ b/deps/uv/src/unix/linux-inotify.c @@ -61,6 +61,8 @@ static void uv__inotify_read(uv_loop_t* loop, uv__io_t* w, unsigned int revents); +static void maybe_free_watcher_list(struct watcher_list* w, + uv_loop_t* loop); static int new_inotify_fd(void) { int err; @@ -108,6 +110,71 @@ static int init_inotify(uv_loop_t* loop) { } +int uv__inotify_fork(uv_loop_t* loop, void* old_watchers) { + /* Open the inotify_fd, and re-arm all the inotify watchers. */ + int err; + struct watcher_list* tmp_watcher_list_iter; + struct watcher_list* watcher_list; + struct watcher_list tmp_watcher_list; + QUEUE queue; + QUEUE* q; + uv_fs_event_t* handle; + char* tmp_path; + + if (old_watchers != NULL) { + /* We must restore the old watcher list to be able to close items + * out of it. + */ + loop->inotify_watchers = old_watchers; + + QUEUE_INIT(&tmp_watcher_list.watchers); + /* Note that the queue we use is shared with the start and stop() + * functions, making QUEUE_FOREACH unsafe to use. So we use the + * QUEUE_MOVE trick to safely iterate. Also don't free the watcher + * list until we're done iterating. c.f. uv__inotify_read. + */ + RB_FOREACH_SAFE(watcher_list, watcher_root, + CAST(&old_watchers), tmp_watcher_list_iter) { + watcher_list->iterating = 1; + QUEUE_MOVE(&watcher_list->watchers, &queue); + while (!QUEUE_EMPTY(&queue)) { + q = QUEUE_HEAD(&queue); + handle = QUEUE_DATA(q, uv_fs_event_t, watchers); + /* It's critical to keep a copy of path here, because it + * will be set to NULL by stop() and then deallocated by + * maybe_free_watcher_list + */ + tmp_path = uv__strdup(handle->path); + assert(tmp_path != NULL); + QUEUE_REMOVE(q); + QUEUE_INSERT_TAIL(&watcher_list->watchers, q); + uv_fs_event_stop(handle); + + QUEUE_INSERT_TAIL(&tmp_watcher_list.watchers, &handle->watchers); + handle->path = tmp_path; + } + watcher_list->iterating = 0; + maybe_free_watcher_list(watcher_list, loop); + } + + QUEUE_MOVE(&tmp_watcher_list.watchers, &queue); + while (!QUEUE_EMPTY(&queue)) { + q = QUEUE_HEAD(&queue); + QUEUE_REMOVE(q); + handle = QUEUE_DATA(q, uv_fs_event_t, watchers); + tmp_path = handle->path; + handle->path = NULL; + err = uv_fs_event_start(handle, handle->cb, tmp_path, 0); + uv__free(tmp_path); + if (err) + return err; + } + } + + return 0; +} + + static struct watcher_list* find_watcher(uv_loop_t* loop, int wd) { struct watcher_list w; w.wd = wd; diff --git a/deps/uv/src/unix/loop.c b/deps/uv/src/unix/loop.c index bd63c2f9d1d24a..bcd49242cea2bc 100644 --- a/deps/uv/src/unix/loop.c +++ b/deps/uv/src/unix/loop.c @@ -54,7 +54,8 @@ int uv_loop_init(uv_loop_t* loop) { loop->closing_handles = NULL; uv__update_time(loop); - uv__async_init(&loop->async_watcher); + loop->async_io_watcher.fd = -1; + loop->async_wfd = -1; loop->signal_pipefd[0] = -1; loop->signal_pipefd[1] = -1; loop->backend_fd = -1; @@ -108,10 +109,43 @@ int uv_loop_init(uv_loop_t* loop) { } +int uv_loop_fork(uv_loop_t* loop) { + int err; + unsigned int i; + uv__io_t* w; + + err = uv__io_fork(loop); + if (err) + return err; + + err = uv__async_fork(loop); + if (err) + return err; + + err = uv__signal_loop_fork(loop); + if (err) + return err; + + /* Rearm all the watchers that aren't re-queued by the above. */ + for (i = 0; i < loop->nwatchers; i++) { + w = loop->watchers[i]; + if (w == NULL) + continue; + + if (w->pevents != 0 && QUEUE_EMPTY(&w->watcher_queue)) { + w->events = 0; /* Force re-registration in uv__io_poll. */ + QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue); + } + } + + return 0; +} + + void uv__loop_close(uv_loop_t* loop) { uv__signal_loop_cleanup(loop); uv__platform_loop_delete(loop); - uv__async_stop(loop, &loop->async_watcher); + uv__async_stop(loop); if (loop->emfile_fd != -1) { uv__close(loop->emfile_fd); diff --git a/deps/uv/src/unix/netbsd.c b/deps/uv/src/unix/netbsd.c index 4a9e6cbc17c783..9b5546b7e6959b 100644 --- a/deps/uv/src/unix/netbsd.c +++ b/deps/uv/src/unix/netbsd.c @@ -27,14 +27,11 @@ #include #include -#include #include #include #include #include -#include -#include #include #include #include @@ -43,9 +40,6 @@ #include #include -#undef NANOSEC -#define NANOSEC ((uint64_t) 1e9) - static char *process_title; @@ -58,13 +52,6 @@ void uv__platform_loop_delete(uv_loop_t* loop) { } -uint64_t uv__hrtime(uv_clocktype_t type) { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec); -} - - void uv_loadavg(double avg[3]) { struct loadavg info; size_t size = sizeof(info); @@ -283,98 +270,3 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { uv__free(cpu_infos); } - - -int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { - struct ifaddrs *addrs, *ent; - uv_interface_address_t* address; - int i; - struct sockaddr_dl *sa_addr; - - if (getifaddrs(&addrs)) - return -errno; - - *count = 0; - - /* Count the number of interfaces */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != PF_INET)) { - continue; - } - (*count)++; - } - - *addresses = uv__malloc(*count * sizeof(**addresses)); - - if (!(*addresses)) { - freeifaddrs(addrs); - return -ENOMEM; - } - - address = *addresses; - - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) - continue; - - if (ent->ifa_addr == NULL) - continue; - - if (ent->ifa_addr->sa_family != PF_INET) - continue; - - address->name = uv__strdup(ent->ifa_name); - - if (ent->ifa_addr->sa_family == AF_INET6) { - address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); - } else { - address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); - } - - if (ent->ifa_netmask->sa_family == AF_INET6) { - address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); - } else { - address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); - } - - address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK); - - address++; - } - - /* Fill in physical addresses for each interface */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != AF_LINK)) { - continue; - } - - address = *addresses; - - for (i = 0; i < (*count); i++) { - if (strcmp(address->name, ent->ifa_name) == 0) { - sa_addr = (struct sockaddr_dl*)(ent->ifa_addr); - memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); - } - address++; - } - } - - freeifaddrs(addrs); - - return 0; -} - - -void uv_free_interface_addresses(uv_interface_address_t* addresses, int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(addresses[i].name); - } - - uv__free(addresses); -} diff --git a/deps/uv/src/unix/no-fsevents.c b/deps/uv/src/unix/no-fsevents.c new file mode 100644 index 00000000000000..38fb6ab0bb2c16 --- /dev/null +++ b/deps/uv/src/unix/no-fsevents.c @@ -0,0 +1,42 @@ +/* Copyright libuv project 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. + */ + +#include "uv.h" +#include "internal.h" + +#include + +int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { + return -ENOSYS; +} + +int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb, + const char* filename, unsigned int flags) { + return -ENOSYS; +} + +int uv_fs_event_stop(uv_fs_event_t* handle) { + return -ENOSYS; +} + +void uv__fs_event_close(uv_fs_event_t* handle) { + UNREACHABLE(); +} diff --git a/deps/uv/src/unix/no-proctitle.c b/deps/uv/src/unix/no-proctitle.c new file mode 100644 index 00000000000000..a5c19fbff58d38 --- /dev/null +++ b/deps/uv/src/unix/no-proctitle.c @@ -0,0 +1,42 @@ +/* Copyright libuv project 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. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include + +char** uv_setup_args(int argc, char** argv) { + return argv; +} + +int uv_set_process_title(const char* title) { + return 0; +} + +int uv_get_process_title(char* buffer, size_t size) { + if (buffer == NULL || size == 0) + return -EINVAL; + + buffer[0] = '\0'; + return 0; +} diff --git a/deps/uv/src/unix/openbsd.c b/deps/uv/src/unix/openbsd.c index 909288cc888893..56f0af15c3ef3f 100644 --- a/deps/uv/src/unix/openbsd.c +++ b/deps/uv/src/unix/openbsd.c @@ -28,21 +28,13 @@ #include #include -#include -#include -#include - #include #include -#include #include #include #include #include -#undef NANOSEC -#define NANOSEC ((uint64_t) 1e9) - static char *process_title; @@ -56,13 +48,6 @@ void uv__platform_loop_delete(uv_loop_t* loop) { } -uint64_t uv__hrtime(uv_clocktype_t type) { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec); -} - - void uv_loadavg(double avg[3]) { struct loadavg info; size_t size = sizeof(info); @@ -163,7 +148,7 @@ char** uv_setup_args(int argc, char** argv) { int uv_set_process_title(const char* title) { uv__free(process_title); process_title = uv__strdup(title); - setproctitle(title); + setproctitle("%s", title); return 0; } @@ -297,100 +282,3 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { uv__free(cpu_infos); } - - -int uv_interface_addresses(uv_interface_address_t** addresses, - int* count) { - struct ifaddrs *addrs, *ent; - uv_interface_address_t* address; - int i; - struct sockaddr_dl *sa_addr; - - if (getifaddrs(&addrs) != 0) - return -errno; - - *count = 0; - - /* Count the number of interfaces */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != PF_INET)) { - continue; - } - (*count)++; - } - - *addresses = uv__malloc(*count * sizeof(**addresses)); - - if (!(*addresses)) { - freeifaddrs(addrs); - return -ENOMEM; - } - - address = *addresses; - - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) - continue; - - if (ent->ifa_addr == NULL) - continue; - - if (ent->ifa_addr->sa_family != PF_INET) - continue; - - address->name = uv__strdup(ent->ifa_name); - - if (ent->ifa_addr->sa_family == AF_INET6) { - address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); - } else { - address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); - } - - if (ent->ifa_netmask->sa_family == AF_INET6) { - address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); - } else { - address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); - } - - address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK); - - address++; - } - - /* Fill in physical addresses for each interface */ - for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family != AF_LINK)) { - continue; - } - - address = *addresses; - - for (i = 0; i < (*count); i++) { - if (strcmp(address->name, ent->ifa_name) == 0) { - sa_addr = (struct sockaddr_dl*)(ent->ifa_addr); - memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); - } - address++; - } - } - - freeifaddrs(addrs); - - return 0; -} - - -void uv_free_interface_addresses(uv_interface_address_t* addresses, - int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(addresses[i].name); - } - - uv__free(addresses); -} diff --git a/deps/uv/src/unix/os390-syscalls.c b/deps/uv/src/unix/os390-syscalls.c index 2bf3b73815a5f4..7edf2358d43a49 100644 --- a/deps/uv/src/unix/os390-syscalls.c +++ b/deps/uv/src/unix/os390-syscalls.c @@ -120,7 +120,7 @@ static void maybe_resize(uv__os390_epoll* lst, unsigned int len) { } -static void epoll_init() { +static void epoll_init(void) { QUEUE_INIT(&global_epoll_queue); if (uv_mutex_init(&global_epoll_lock)) abort(); diff --git a/deps/uv/src/unix/os390.c b/deps/uv/src/unix/os390.c index be325a923091f2..2ba5abf35490d7 100644 --- a/deps/uv/src/unix/os390.c +++ b/deps/uv/src/unix/os390.c @@ -663,28 +663,6 @@ int uv__io_check_fd(uv_loop_t* loop, int fd) { return 0; } - -void uv__fs_event_close(uv_fs_event_t* handle) { - UNREACHABLE(); -} - - -int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { - return -ENOSYS; -} - - -int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb, - const char* filename, unsigned int flags) { - return -ENOSYS; -} - - -int uv_fs_event_stop(uv_fs_event_t* handle) { - return -ENOSYS; -} - - void uv__io_poll(uv_loop_t* loop, int timeout) { static const int max_safe_timeout = 1789569; struct epoll_event events[1024]; @@ -863,3 +841,9 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { void uv__set_process_title(const char* title) { /* do nothing */ } + +int uv__io_fork(uv_loop_t* loop) { + uv__platform_loop_delete(loop); + + return uv__platform_loop_init(loop); +} diff --git a/deps/uv/src/unix/pipe.c b/deps/uv/src/unix/pipe.c index b73994cb8de365..4a812955b0d1de 100644 --- a/deps/uv/src/unix/pipe.c +++ b/deps/uv/src/unix/pipe.c @@ -47,7 +47,6 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) { int err; pipe_fname = NULL; - sockfd = -1; /* Already bound? */ if (uv__stream_fd(handle) >= 0) @@ -76,7 +75,9 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) { /* Convert ENOENT to EACCES for compatibility with Windows. */ if (err == -ENOENT) err = -EACCES; - goto err_bind; + + uv__close(sockfd); + goto err_socket; } /* Success. */ @@ -85,9 +86,6 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) { handle->io_watcher.fd = sockfd; return 0; -err_bind: - uv__close(sockfd); - err_socket: uv__free((void*)pipe_fname); return err; @@ -183,6 +181,14 @@ void uv_pipe_connect(uv_connect_t* req, if (r == -1 && errno != EINPROGRESS) { err = -errno; +#if defined(__CYGWIN__) || defined(__MSYS__) + /* EBADF is supposed to mean that the socket fd is bad, but + Cygwin reports EBADF instead of ENOTSOCK when the file is + not a socket. We do not expect to see a bad fd here + (e.g. due to new_sock), so translate the error. */ + if (err == -EBADF) + err = -ENOTSOCK; +#endif goto out; } diff --git a/deps/uv/src/unix/posix-hrtime.c b/deps/uv/src/unix/posix-hrtime.c new file mode 100644 index 00000000000000..323dfc20392423 --- /dev/null +++ b/deps/uv/src/unix/posix-hrtime.c @@ -0,0 +1,35 @@ +/* Copyright libuv project 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. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include + +#undef NANOSEC +#define NANOSEC ((uint64_t) 1e9) + +uint64_t uv__hrtime(uv_clocktype_t type) { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec); +} diff --git a/deps/uv/src/unix/posix-poll.c b/deps/uv/src/unix/posix-poll.c new file mode 100644 index 00000000000000..3fba96e1bf154d --- /dev/null +++ b/deps/uv/src/unix/posix-poll.c @@ -0,0 +1,324 @@ +/* Copyright libuv project 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. + */ + +#include "uv.h" +#include "internal.h" + +/* POSIX defines poll() as a portable way to wait on file descriptors. + * Here we maintain a dynamically sized array of file descriptors and + * events to pass as the first argument to poll(). + */ + +#include +#include +#include +#include +#include + +int uv__platform_loop_init(uv_loop_t* loop) { + loop->poll_fds = NULL; + loop->poll_fds_used = 0; + loop->poll_fds_size = 0; + loop->poll_fds_iterating = 0; + return 0; +} + +void uv__platform_loop_delete(uv_loop_t* loop) { + uv__free(loop->poll_fds); + loop->poll_fds = NULL; +} + +int uv__io_fork(uv_loop_t* loop) { + uv__platform_loop_delete(loop); + return uv__platform_loop_init(loop); +} + +/* Allocate or dynamically resize our poll fds array. */ +static void uv__pollfds_maybe_resize(uv_loop_t* loop) { + size_t i; + size_t n; + struct pollfd* p; + + if (loop->poll_fds_used < loop->poll_fds_size) + return; + + n = loop->poll_fds_size ? loop->poll_fds_size * 2 : 64; + p = uv__realloc(loop->poll_fds, n * sizeof(*loop->poll_fds)); + if (p == NULL) + abort(); + + loop->poll_fds = p; + for (i = loop->poll_fds_size; i < n; i++) { + loop->poll_fds[i].fd = -1; + loop->poll_fds[i].events = 0; + loop->poll_fds[i].revents = 0; + } + loop->poll_fds_size = n; +} + +/* Primitive swap operation on poll fds array elements. */ +static void uv__pollfds_swap(uv_loop_t* loop, size_t l, size_t r) { + struct pollfd pfd; + pfd = loop->poll_fds[l]; + loop->poll_fds[l] = loop->poll_fds[r]; + loop->poll_fds[r] = pfd; +} + +/* Add a watcher's fd to our poll fds array with its pending events. */ +static void uv__pollfds_add(uv_loop_t* loop, uv__io_t* w) { + size_t i; + struct pollfd* pe; + + /* If the fd is already in the set just update its events. */ + assert(!loop->poll_fds_iterating); + for (i = 0; i < loop->poll_fds_used; ++i) { + if (loop->poll_fds[i].fd == w->fd) { + loop->poll_fds[i].events = w->pevents; + return; + } + } + + /* Otherwise, allocate a new slot in the set for the fd. */ + uv__pollfds_maybe_resize(loop); + pe = &loop->poll_fds[loop->poll_fds_used++]; + pe->fd = w->fd; + pe->events = w->pevents; +} + +/* Remove a watcher's fd from our poll fds array. */ +static void uv__pollfds_del(uv_loop_t* loop, int fd) { + size_t i; + assert(!loop->poll_fds_iterating); + for (i = 0; i < loop->poll_fds_used; ++i) { + if (loop->poll_fds[i].fd == fd) { + /* swap to last position and remove */ + --loop->poll_fds_used; + uv__pollfds_swap(loop, i, loop->poll_fds_used); + loop->poll_fds[loop->poll_fds_used].fd = -1; + loop->poll_fds[loop->poll_fds_used].events = 0; + loop->poll_fds[loop->poll_fds_used].revents = 0; + return; + } + } +} + + +void uv__io_poll(uv_loop_t* loop, int timeout) { + sigset_t* pset; + sigset_t set; + uint64_t time_base; + uint64_t time_diff; + QUEUE* q; + uv__io_t* w; + size_t i; + unsigned int nevents; + int nfds; + int have_signals; + struct pollfd* pe; + int fd; + + if (loop->nfds == 0) { + assert(QUEUE_EMPTY(&loop->watcher_queue)); + return; + } + + /* Take queued watchers and add their fds to our poll fds array. */ + while (!QUEUE_EMPTY(&loop->watcher_queue)) { + q = QUEUE_HEAD(&loop->watcher_queue); + QUEUE_REMOVE(q); + QUEUE_INIT(q); + + w = QUEUE_DATA(q, uv__io_t, watcher_queue); + assert(w->pevents != 0); + assert(w->fd >= 0); + assert(w->fd < (int) loop->nwatchers); + + uv__pollfds_add(loop, w); + + w->events = w->pevents; + } + + /* Prepare a set of signals to block around poll(), if any. */ + pset = NULL; + if (loop->flags & UV_LOOP_BLOCK_SIGPROF) { + pset = &set; + sigemptyset(pset); + sigaddset(pset, SIGPROF); + } + + assert(timeout >= -1); + time_base = loop->time; + + /* Loop calls to poll() and processing of results. If we get some + * results from poll() but they turn out not to be interesting to + * our caller then we need to loop around and poll() again. + */ + for (;;) { + if (pset != NULL) + if (pthread_sigmask(SIG_BLOCK, pset, NULL)) + abort(); + nfds = poll(loop->poll_fds, (nfds_t)loop->poll_fds_used, timeout); + if (pset != NULL) + if (pthread_sigmask(SIG_UNBLOCK, pset, NULL)) + abort(); + + /* Update loop->time unconditionally. It's tempting to skip the update when + * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the + * operating system didn't reschedule our process while in the syscall. + */ + SAVE_ERRNO(uv__update_time(loop)); + + if (nfds == 0) { + assert(timeout != -1); + return; + } + + if (nfds == -1) { + if (errno != EINTR) + abort(); + + if (timeout == -1) + continue; + + if (timeout == 0) + return; + + /* Interrupted by a signal. Update timeout and poll again. */ + goto update_timeout; + } + + /* Tell uv__platform_invalidate_fd not to manipulate our array + * while we are iterating over it. + */ + loop->poll_fds_iterating = 1; + + /* Initialize a count of events that we care about. */ + nevents = 0; + have_signals = 0; + + /* Loop over the entire poll fds array looking for returned events. */ + for (i = 0; i < loop->poll_fds_used; i++) { + pe = loop->poll_fds + i; + fd = pe->fd; + + /* Skip invalidated events, see uv__platform_invalidate_fd. */ + if (fd == -1) + continue; + + assert(fd >= 0); + assert((unsigned) fd < loop->nwatchers); + + w = loop->watchers[fd]; + + if (w == NULL) { + /* File descriptor that we've stopped watching, ignore. */ + uv__platform_invalidate_fd(loop, fd); + continue; + } + + /* Filter out events that user has not requested us to watch + * (e.g. POLLNVAL). + */ + pe->revents &= w->pevents | POLLERR | POLLHUP; + + if (pe->revents != 0) { + /* Run signal watchers last. */ + if (w == &loop->signal_io_watcher) { + have_signals = 1; + } else { + w->cb(loop, w, pe->revents); + } + + nevents++; + } + } + + if (have_signals != 0) + loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN); + + loop->poll_fds_iterating = 0; + + /* Purge invalidated fds from our poll fds array. */ + uv__pollfds_del(loop, -1); + + if (have_signals != 0) + return; /* Event loop should cycle now so don't poll again. */ + + if (nevents != 0) + return; + + if (timeout == 0) + return; + + if (timeout == -1) + continue; + +update_timeout: + assert(timeout > 0); + + time_diff = loop->time - time_base; + if (time_diff >= (uint64_t) timeout) + return; + + timeout -= time_diff; + } +} + +/* Remove the given fd from our poll fds array because no one + * is interested in its events anymore. + */ +void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) { + size_t i; + + if (loop->poll_fds_iterating) { + /* uv__io_poll is currently iterating. Just invalidate fd. */ + for (i = 0; i < loop->poll_fds_used; i++) + if (loop->poll_fds[i].fd == fd) { + loop->poll_fds[i].fd = -1; + loop->poll_fds[i].events = 0; + loop->poll_fds[i].revents = 0; + } + } else { + /* uv__io_poll is not iterating. Delete fd from the set. */ + uv__pollfds_del(loop, fd); + } +} + +/* Check whether the given fd is supported by poll(). */ +int uv__io_check_fd(uv_loop_t* loop, int fd) { + struct pollfd p[1]; + int rv; + + p[0].fd = fd; + p[0].events = POLLIN; + + do + rv = poll(p, 1, 0); + while (rv == -1 && (errno == EINTR || errno == EAGAIN)); + + if (rv == -1) + return -errno; + + if (p[0].revents & POLLNVAL) + return -EINVAL; + + return 0; +} diff --git a/deps/uv/src/unix/procfs-exepath.c b/deps/uv/src/unix/procfs-exepath.c new file mode 100644 index 00000000000000..5fdb6115505661 --- /dev/null +++ b/deps/uv/src/unix/procfs-exepath.c @@ -0,0 +1,45 @@ +/* Copyright libuv project 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. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include + +int uv_exepath(char* buffer, size_t* size) { + ssize_t n; + + if (buffer == NULL || size == NULL || *size == 0) + return -EINVAL; + + n = *size - 1; + if (n > 0) + n = readlink("/proc/self/exe", buffer, n); + + if (n == -1) + return -errno; + + buffer[n] = '\0'; + *size = n; + + return 0; +} diff --git a/deps/uv/src/unix/signal.c b/deps/uv/src/unix/signal.c index dbd8f86448d78c..cb09ead50a4c45 100644 --- a/deps/uv/src/unix/signal.c +++ b/deps/uv/src/unix/signal.c @@ -38,9 +38,14 @@ RB_HEAD(uv__signal_tree_s, uv_signal_s); static int uv__signal_unlock(void); +static int uv__signal_start(uv_signal_t* handle, + uv_signal_cb signal_cb, + int signum, + int oneshot); static void uv__signal_event(uv_loop_t* loop, uv__io_t* w, unsigned int events); static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2); static void uv__signal_stop(uv_signal_t* handle); +static void uv__signal_unregister_handler(int signum); static uv_once_t uv__signal_global_init_guard = UV_ONCE_INIT; @@ -53,8 +58,19 @@ RB_GENERATE_STATIC(uv__signal_tree_s, uv_signal_s, tree_entry, uv__signal_compare) +static void uv__signal_global_reinit(void); static void uv__signal_global_init(void) { + if (!uv__signal_lock_pipefd[0]) + /* pthread_atfork can register before and after handlers, one + * for each child. This only registers one for the child. That + * state is both persistent and cumulative, so if we keep doing + * it the handler functions will be called multiple times. Thus + * we only want to do it once. + */ + if (pthread_atfork(NULL, NULL, &uv__signal_global_reinit)) + abort(); + if (uv__make_pipe(uv__signal_lock_pipefd, 0)) abort(); @@ -63,6 +79,22 @@ static void uv__signal_global_init(void) { } +static void uv__signal_global_reinit(void) { + /* We can only use signal-safe functions here. + * That includes read/write and close, fortunately. + * We do all of this directly here instead of resetting + * uv__signal_global_init_guard because + * uv__signal_global_once_init is only called from uv_loop_init + * and this needs to function in existing loops. + */ + uv__close(uv__signal_lock_pipefd[0]); + uv__signal_lock_pipefd[0] = -1; + uv__close(uv__signal_lock_pipefd[1]); + uv__signal_lock_pipefd[1] = -1; + uv__signal_global_init(); +} + + void uv__signal_global_once_init(void) { uv_once(&uv__signal_global_init_guard, uv__signal_global_init); } @@ -122,6 +154,7 @@ static uv_signal_t* uv__signal_first_handle(int signum) { uv_signal_t* handle; lookup.signum = signum; + lookup.flags = 0; lookup.loop = NULL; handle = RB_NFIND(uv__signal_tree_s, &uv__signal_tree, &lookup); @@ -174,7 +207,7 @@ static void uv__signal_handler(int signum) { } -static int uv__signal_register_handler(int signum) { +static int uv__signal_register_handler(int signum, int oneshot) { /* When this function is called, the signal lock must be held. */ struct sigaction sa; @@ -183,6 +216,7 @@ static int uv__signal_register_handler(int signum) { if (sigfillset(&sa.sa_mask)) abort(); sa.sa_handler = uv__signal_handler; + sa.sa_flags = oneshot ? SA_RESETHAND : 0; /* XXX save old action so we can restore it later on? */ if (sigaction(signum, &sa, NULL)) @@ -228,6 +262,16 @@ static int uv__signal_loop_once_init(uv_loop_t* loop) { } +int uv__signal_loop_fork(uv_loop_t* loop) { + uv__io_stop(loop, &loop->signal_io_watcher, POLLIN); + uv__close(loop->signal_pipefd[0]); + uv__close(loop->signal_pipefd[1]); + loop->signal_pipefd[0] = -1; + loop->signal_pipefd[1] = -1; + return uv__signal_loop_once_init(loop); +} + + void uv__signal_loop_cleanup(uv_loop_t* loop) { QUEUE* q; @@ -287,8 +331,24 @@ void uv__signal_close(uv_signal_t* handle) { int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) { + return uv__signal_start(handle, signal_cb, signum, 0); +} + + +int uv_signal_start_oneshot(uv_signal_t* handle, + uv_signal_cb signal_cb, + int signum) { + return uv__signal_start(handle, signal_cb, signum, 1); +} + + +static int uv__signal_start(uv_signal_t* handle, + uv_signal_cb signal_cb, + int signum, + int oneshot) { sigset_t saved_sigmask; int err; + uv_signal_t* first_handle; assert(!uv__is_closing(handle)); @@ -318,9 +378,12 @@ int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) { /* If at this point there are no active signal watchers for this signum (in * any of the loops), it's time to try and register a handler for it here. + * Also in case there's only one-shot handlers and a regular handler comes in. */ - if (uv__signal_first_handle(signum) == NULL) { - err = uv__signal_register_handler(signum); + first_handle = uv__signal_first_handle(signum); + if (first_handle == NULL || + (!oneshot && (first_handle->flags & UV__SIGNAL_ONE_SHOT))) { + err = uv__signal_register_handler(signum, oneshot); if (err) { /* Registering the signal handler failed. Must be an invalid signal. */ uv__signal_unlock_and_unblock(&saved_sigmask); @@ -329,6 +392,9 @@ int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) { } handle->signum = signum; + if (oneshot) + handle->flags |= UV__SIGNAL_ONE_SHOT; + RB_INSERT(uv__signal_tree_s, &uv__signal_tree, handle); uv__signal_unlock_and_unblock(&saved_sigmask); @@ -390,6 +456,9 @@ static void uv__signal_event(uv_loop_t* loop, handle->dispatched_signals++; + if (handle->flags & UV__SIGNAL_ONE_SHOT) + uv__signal_stop(handle); + /* If uv_close was called while there were caught signals that were not * yet dispatched, the uv__finish_close was deferred. Make close pending * now if this has happened. @@ -414,12 +483,22 @@ static void uv__signal_event(uv_loop_t* loop, static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2) { + int f1; + int f2; /* Compare signums first so all watchers with the same signnum end up * adjacent. */ if (w1->signum < w2->signum) return -1; if (w1->signum > w2->signum) return 1; + /* Handlers without UV__SIGNAL_ONE_SHOT set will come first, so if the first + * handler returned is a one-shot handler, the rest will be too. + */ + f1 = w1->flags & UV__SIGNAL_ONE_SHOT; + f2 = w2->flags & UV__SIGNAL_ONE_SHOT; + if (f1 < f2) return -1; + if (f1 > f2) return 1; + /* Sort by loop pointer, so we can easily look up the first item after * { .signum = x, .loop = NULL }. */ @@ -443,6 +522,10 @@ int uv_signal_stop(uv_signal_t* handle) { static void uv__signal_stop(uv_signal_t* handle) { uv_signal_t* removed_handle; sigset_t saved_sigmask; + uv_signal_t* first_handle; + int rem_oneshot; + int first_oneshot; + int ret; /* If the watcher wasn't started, this is a no-op. */ if (handle->signum == 0) @@ -457,8 +540,17 @@ static void uv__signal_stop(uv_signal_t* handle) { /* Check if there are other active signal watchers observing this signal. If * not, unregister the signal handler. */ - if (uv__signal_first_handle(handle->signum) == NULL) + first_handle = uv__signal_first_handle(handle->signum); + if (first_handle == NULL) { uv__signal_unregister_handler(handle->signum); + } else { + rem_oneshot = handle->flags & UV__SIGNAL_ONE_SHOT; + first_oneshot = first_handle->flags & UV__SIGNAL_ONE_SHOT; + if (first_oneshot && !rem_oneshot) { + ret = uv__signal_register_handler(handle->signum, 1); + assert(ret == 0); + } + } uv__signal_unlock_and_unblock(&saved_sigmask); diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c index 7059df16a69a03..7b23d16ecf1407 100644 --- a/deps/uv/src/unix/stream.c +++ b/deps/uv/src/unix/stream.c @@ -390,7 +390,7 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) { int uv__stream_open(uv_stream_t* stream, int fd, int flags) { -#if defined(__APPLE__) || defined(__MVS__) +#if defined(__APPLE__) int enable; #endif @@ -409,7 +409,7 @@ int uv__stream_open(uv_stream_t* stream, int fd, int flags) { return -errno; } -#if defined(__APPLE__) || defined(__MVS__) +#if defined(__APPLE__) enable = 1; if (setsockopt(fd, SOL_SOCKET, SO_OOBINLINE, &enable, sizeof(enable)) && errno != ENOTSOCK && @@ -785,7 +785,12 @@ static void uv__write(uv_stream_t* stream) { struct msghdr msg; struct cmsghdr *cmsg; int fd_to_send = uv__handle_fd((uv_handle_t*) req->send_handle); - char scratch[64] = {0}; + union { + char data[64]; + struct cmsghdr alias; + } scratch; + + memset(&scratch, 0, sizeof(scratch)); assert(fd_to_send >= 0); @@ -795,7 +800,7 @@ static void uv__write(uv_stream_t* stream) { msg.msg_iovlen = iovcnt; msg.msg_flags = 0; - msg.msg_control = (void*) scratch; + msg.msg_control = &scratch.alias; msg.msg_controllen = CMSG_SPACE(sizeof(fd_to_send)); cmsg = CMSG_FIRSTHDR(&msg); @@ -1168,6 +1173,11 @@ static void uv__read(uv_stream_t* stream) { uv__stream_osx_interrupt_select(stream); } stream->read_cb(stream, 0, &buf); +#if defined(__CYGWIN__) || defined(__MSYS__) + } else if (errno == ECONNRESET && stream->type == UV_NAMED_PIPE) { + uv__stream_eof(stream, &buf); + return; +#endif } else { /* Error. User should call uv_close(). */ stream->read_cb(stream, -errno, &buf); @@ -1400,6 +1410,12 @@ int uv_write2(uv_write_t* req, */ if (uv__handle_fd((uv_handle_t*) send_handle) < 0) return -EBADF; + +#if defined(__CYGWIN__) || defined(__MSYS__) + /* Cygwin recvmsg always sets msg_controllen to zero, so we cannot send it. + See https://github.com/mirror/newlib-cygwin/blob/86fc4bf0/winsup/cygwin/fhandler_socket.cc#L1736-L1743 */ + return -ENOSYS; +#endif } /* It's legal for write_queue_size > 0 even when the write_queue is empty; diff --git a/deps/uv/src/unix/sunos.c b/deps/uv/src/unix/sunos.c index a43f7f1b1c021c..2dc02ae457cd06 100644 --- a/deps/uv/src/unix/sunos.c +++ b/deps/uv/src/unix/sunos.c @@ -99,6 +99,18 @@ void uv__platform_loop_delete(uv_loop_t* loop) { } +int uv__io_fork(uv_loop_t* loop) { +#if defined(PORT_SOURCE_FILE) + if (loop->fs_fd != -1) { + /* stop the watcher before we blow away its fileno */ + uv__io_stop(loop, &loop->fs_event_watcher, POLLIN); + } +#endif + uv__platform_loop_delete(loop); + return uv__platform_loop_init(loop); +} + + void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) { struct port_event* events; uintptr_t i; @@ -469,8 +481,10 @@ int uv_fs_event_start(uv_fs_event_t* handle, memset(&handle->fo, 0, sizeof handle->fo); handle->fo.fo_name = handle->path; err = uv__fs_event_rearm(handle); - if (err != 0) + if (err != 0) { + uv_fs_event_stop(handle); return err; + } if (first_run) { uv__io_init(&handle->loop->fs_event_watcher, uv__fs_event_read, portfd); @@ -531,25 +545,6 @@ void uv__fs_event_close(uv_fs_event_t* handle) { #endif /* defined(PORT_SOURCE_FILE) */ -char** uv_setup_args(int argc, char** argv) { - return argv; -} - - -int uv_set_process_title(const char* title) { - return 0; -} - - -int uv_get_process_title(char* buffer, size_t size) { - if (buffer == NULL || size == 0) - return -EINVAL; - - buffer[0] = '\0'; - return 0; -} - - int uv_resident_set_memory(size_t* rss) { psinfo_t psinfo; int err; @@ -746,6 +741,17 @@ static int uv__set_phys_addr(uv_interface_address_t* address, return 0; } + +static int uv__ifaddr_exclude(struct ifaddrs *ent) { + if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) + return 1; + if (ent->ifa_addr == NULL) + return 1; + if (ent->ifa_addr->sa_family == PF_PACKET) + return 1; + return 0; +} + int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { uv_interface_address_t* address; struct ifaddrs* addrs; @@ -759,12 +765,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { /* Count the number of interfaces */ for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) || - (ent->ifa_addr == NULL) || - (ent->ifa_addr->sa_family == PF_PACKET)) { + if (uv__ifaddr_exclude(ent)) continue; - } - (*count)++; } @@ -777,10 +779,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { address = *addresses; for (ent = addrs; ent != NULL; ent = ent->ifa_next) { - if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) - continue; - - if (ent->ifa_addr == NULL) + if (uv__ifaddr_exclude(ent)) continue; address->name = uv__strdup(ent->ifa_name); diff --git a/deps/uv/src/unix/sysinfo-loadavg.c b/deps/uv/src/unix/sysinfo-loadavg.c new file mode 100644 index 00000000000000..ebad0e89db597f --- /dev/null +++ b/deps/uv/src/unix/sysinfo-loadavg.c @@ -0,0 +1,36 @@ +/* Copyright libuv project 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. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include + +void uv_loadavg(double avg[3]) { + struct sysinfo info; + + if (sysinfo(&info) < 0) return; + + avg[0] = (double) info.loads[0] / 65536.0; + avg[1] = (double) info.loads[1] / 65536.0; + avg[2] = (double) info.loads[2] / 65536.0; +} diff --git a/deps/uv/src/unix/sysinfo-memory.c b/deps/uv/src/unix/sysinfo-memory.c new file mode 100644 index 00000000000000..23b4fc6e914ae9 --- /dev/null +++ b/deps/uv/src/unix/sysinfo-memory.c @@ -0,0 +1,42 @@ +/* Copyright libuv project 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. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include + +uint64_t uv_get_free_memory(void) { + struct sysinfo info; + + if (sysinfo(&info) == 0) + return (uint64_t) info.freeram * info.mem_unit; + return 0; +} + +uint64_t uv_get_total_memory(void) { + struct sysinfo info; + + if (sysinfo(&info) == 0) + return (uint64_t) info.totalram * info.mem_unit; + return 0; +} diff --git a/deps/uv/src/unix/udp.c b/deps/uv/src/unix/udp.c index 1cd49257865d0f..c556325de018b3 100644 --- a/deps/uv/src/unix/udp.c +++ b/deps/uv/src/unix/udp.c @@ -307,7 +307,7 @@ int uv__udp_bind(uv_udp_t* handle, if (flags & UV_UDP_REUSEADDR) { err = uv__set_reuse(fd); if (err) - goto out; + return err; } if (flags & UV_UDP_IPV6ONLY) { @@ -315,11 +315,11 @@ int uv__udp_bind(uv_udp_t* handle, yes = 1; if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof yes) == -1) { err = -errno; - goto out; + return err; } #else err = -ENOTSUP; - goto out; + return err; #endif } @@ -329,27 +329,25 @@ int uv__udp_bind(uv_udp_t* handle, /* OSX, other BSDs and SunoS fail with EAFNOSUPPORT when binding a * socket created with AF_INET to an AF_INET6 address or vice versa. */ err = -EINVAL; - goto out; + return err; } if (addr->sa_family == AF_INET6) handle->flags |= UV_HANDLE_IPV6; handle->flags |= UV_HANDLE_BOUND; - return 0; - -out: - uv__close(handle->io_watcher.fd); - handle->io_watcher.fd = -1; - return err; } static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, int domain, unsigned int flags) { - unsigned char taddr[sizeof(struct sockaddr_in6)]; + union { + struct sockaddr_in6 in6; + struct sockaddr_in in; + struct sockaddr addr; + } taddr; socklen_t addrlen; if (handle->io_watcher.fd != -1) @@ -358,7 +356,7 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, switch (domain) { case AF_INET: { - struct sockaddr_in* addr = (void*)&taddr; + struct sockaddr_in* addr = &taddr.in; memset(addr, 0, sizeof *addr); addr->sin_family = AF_INET; addr->sin_addr.s_addr = INADDR_ANY; @@ -367,7 +365,7 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, } case AF_INET6: { - struct sockaddr_in6* addr = (void*)&taddr; + struct sockaddr_in6* addr = &taddr.in6; memset(addr, 0, sizeof *addr); addr->sin6_family = AF_INET6; addr->sin6_addr = in6addr_any; @@ -379,7 +377,7 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, abort(); } - return uv__udp_bind(handle, (const struct sockaddr*) &taddr, addrlen, flags); + return uv__udp_bind(handle, &taddr.addr, addrlen, flags); } @@ -429,6 +427,13 @@ int uv__udp_send(uv_udp_send_t* req, if (empty_queue && !(handle->flags & UV_UDP_PROCESSING)) { uv__udp_sendmsg(handle); + + /* `uv__udp_sendmsg` may not be able to do non-blocking write straight + * away. In such cases the `io_watcher` has to be queued for asynchronous + * write. + */ + if (!QUEUE_EMPTY(&handle->write_queue)) + uv__io_start(handle->loop, &handle->io_watcher, POLLOUT); } else { uv__io_start(handle->loop, &handle->io_watcher, POLLOUT); } diff --git a/deps/uv/src/uv-common.h b/deps/uv/src/uv-common.h index 27902fdf8645f7..781a8559dc8428 100644 --- a/deps/uv/src/uv-common.h +++ b/deps/uv/src/uv-common.h @@ -55,16 +55,19 @@ extern int snprintf(char*, size_t, const char*, ...); #ifndef _WIN32 enum { + UV__SIGNAL_ONE_SHOT = 0x80000, /* On signal reception remove sighandler */ UV__HANDLE_INTERNAL = 0x8000, UV__HANDLE_ACTIVE = 0x4000, UV__HANDLE_REF = 0x2000, UV__HANDLE_CLOSING = 0 /* no-op on unix */ }; #else -# define UV__HANDLE_INTERNAL 0x80 -# define UV__HANDLE_ACTIVE 0x40 -# define UV__HANDLE_REF 0x20 -# define UV__HANDLE_CLOSING 0x01 +# define UV__SIGNAL_ONE_SHOT_DISPATCHED 0x200 +# define UV__SIGNAL_ONE_SHOT 0x100 +# define UV__HANDLE_INTERNAL 0x80 +# define UV__HANDLE_ACTIVE 0x40 +# define UV__HANDLE_REF 0x20 +# define UV__HANDLE_CLOSING 0x01 #endif int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap); @@ -215,6 +218,30 @@ void uv__fs_scandir_cleanup(uv_fs_t* req); } \ while (0) +/* Note: uses an open-coded version of SET_REQ_SUCCESS() because of + * a circular dependency between src/uv-common.h and src/win/internal.h. + */ +#if defined(_WIN32) +# define UV_REQ_INIT(req, typ) \ + do { \ + (req)->type = (typ); \ + (req)->u.io.overlapped.Internal = 0; /* SET_REQ_SUCCESS() */ \ + } \ + while (0) +#else +# define UV_REQ_INIT(req, typ) \ + do { \ + (req)->type = (typ); \ + } \ + while (0) +#endif + +#define uv__req_init(loop, req, typ) \ + do { \ + UV_REQ_INIT(req, typ); \ + uv__req_register(loop, req); \ + } \ + while (0) /* Allocator prototypes */ void *uv__calloc(size_t count, size_t size); diff --git a/deps/uv/src/win/async.c b/deps/uv/src/win/async.c index ad240ab897241e..0b636ed1e9137a 100644 --- a/deps/uv/src/win/async.c +++ b/deps/uv/src/win/async.c @@ -45,8 +45,7 @@ int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) { handle->async_cb = async_cb; req = &handle->async_req; - uv_req_init(loop, req); - req->type = UV_WAKEUP; + UV_REQ_INIT(req, UV_WAKEUP); req->data = handle; uv__handle_start(handle); diff --git a/deps/uv/src/win/atomicops-inl.h b/deps/uv/src/win/atomicops-inl.h index 61e006026c1867..6d8126f6921bbb 100644 --- a/deps/uv/src/win/atomicops-inl.h +++ b/deps/uv/src/win/atomicops-inl.h @@ -23,6 +23,7 @@ #define UV_WIN_ATOMICOPS_INL_H_ #include "uv.h" +#include "internal.h" /* Atomic set operation on char */ @@ -34,7 +35,7 @@ /* target to be aligned. */ #pragma intrinsic(_InterlockedOr8) -static char __declspec(inline) uv__atomic_exchange_set(char volatile* target) { +static char INLINE uv__atomic_exchange_set(char volatile* target) { return _InterlockedOr8(target, 1); } diff --git a/deps/uv/src/win/core.c b/deps/uv/src/win/core.c index e84186d4ecc840..9ed4e824c6e96b 100644 --- a/deps/uv/src/win/core.c +++ b/deps/uv/src/win/core.c @@ -83,13 +83,8 @@ static int uv__loops_capacity; #define UV__LOOPS_CHUNK_SIZE 8 static uv_mutex_t uv__loops_lock; -static void uv__loops_init() { +static void uv__loops_init(void) { uv_mutex_init(&uv__loops_lock); - uv__loops = uv__calloc(UV__LOOPS_CHUNK_SIZE, sizeof(uv_loop_t*)); - if (!uv__loops) - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - uv__loops_size = 0; - uv__loops_capacity = UV__LOOPS_CHUNK_SIZE; } static int uv__loops_add(uv_loop_t* loop) { @@ -138,6 +133,13 @@ static void uv__loops_remove(uv_loop_t* loop) { uv__loops[uv__loops_size - 1] = NULL; --uv__loops_size; + if (uv__loops_size == 0) { + uv__loops_capacity = 0; + uv__free(uv__loops); + uv__loops = NULL; + goto loop_removed; + } + /* If we didn't grow to big skip downsizing */ if (uv__loops_capacity < 4 * UV__LOOPS_CHUNK_SIZE) goto loop_removed; @@ -156,7 +158,7 @@ static void uv__loops_remove(uv_loop_t* loop) { uv_mutex_unlock(&uv__loops_lock); } -void uv__wake_all_loops() { +void uv__wake_all_loops(void) { int i; uv_loop_t* loop; @@ -332,6 +334,11 @@ int uv_backend_fd(const uv_loop_t* loop) { } +int uv_loop_fork(uv_loop_t* loop) { + return UV_ENOSYS; +} + + int uv_backend_timeout(const uv_loop_t* loop) { if (loop->stop_flag != 0) return 0; diff --git a/deps/uv/src/win/detect-wakeup.c b/deps/uv/src/win/detect-wakeup.c index a12179f7981d13..72dfb7a1771765 100644 --- a/deps/uv/src/win/detect-wakeup.c +++ b/deps/uv/src/win/detect-wakeup.c @@ -2,9 +2,9 @@ #include "internal.h" #include "winapi.h" -static void uv__register_system_resume_callback(); +static void uv__register_system_resume_callback(void); -void uv__init_detect_system_wakeup() { +void uv__init_detect_system_wakeup(void) { /* Try registering system power event callback. This is the cleanest * method, but it will only work on Win8 and above. */ @@ -20,7 +20,7 @@ static ULONG CALLBACK uv__system_resume_callback(PVOID Context, return 0; } -static void uv__register_system_resume_callback() { +static void uv__register_system_resume_callback(void) { _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS recipient; _HPOWERNOTIFY registration_handle; diff --git a/deps/uv/src/win/fs-event.c b/deps/uv/src/win/fs-event.c index 03e4adc058f9f3..95f843ad08edee 100644 --- a/deps/uv/src/win/fs-event.c +++ b/deps/uv/src/win/fs-event.c @@ -81,8 +81,17 @@ static void uv_relative_path(const WCHAR* filename, static int uv_split_path(const WCHAR* filename, WCHAR** dir, WCHAR** file) { - int len = wcslen(filename); - int i = len; + size_t len, i; + + if (filename == NULL) { + if (dir != NULL) + *dir = NULL; + *file = NULL; + return 0; + } + + len = wcslen(filename); + i = len; while (i > 0 && filename[--i] != '\\' && filename[i] != '/'); if (i == 0) { @@ -131,8 +140,7 @@ int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { handle->short_filew = NULL; handle->dirw = NULL; - uv_req_init(loop, (uv_req_t*)&handle->req); - handle->req.type = UV_FS_EVENT_REQ; + UV_REQ_INIT(&handle->req, UV_FS_EVENT_REQ); handle->req.data = handle; return 0; @@ -146,7 +154,8 @@ int uv_fs_event_start(uv_fs_event_t* handle, int name_size, is_path_dir; DWORD attr, last_error; WCHAR* dir = NULL, *dir_to_watch, *pathw = NULL; - WCHAR short_path[MAX_PATH]; + WCHAR short_path_buffer[MAX_PATH]; + WCHAR* short_path; if (uv__is_active(handle)) return UV_EINVAL; @@ -188,7 +197,6 @@ int uv_fs_event_start(uv_fs_event_t* handle, if (is_path_dir) { /* path is a directory, so that's the directory that we will watch. */ - handle->dirw = pathw; dir_to_watch = pathw; } else { /* @@ -197,9 +205,9 @@ int uv_fs_event_start(uv_fs_event_t* handle, */ /* Convert to short path. */ + short_path = short_path_buffer; if (!GetShortPathNameW(pathw, short_path, ARRAY_SIZE(short_path))) { - last_error = GetLastError(); - goto error; + short_path = NULL; } if (uv_split_path(pathw, &dir, &handle->filew) != 0) { @@ -274,6 +282,8 @@ int uv_fs_event_start(uv_fs_event_t* handle, goto error; } + assert(is_path_dir ? pathw != NULL : pathw == NULL); + handle->dirw = pathw; handle->req_pending = 1; return 0; @@ -305,6 +315,9 @@ int uv_fs_event_start(uv_fs_event_t* handle, handle->buffer = NULL; } + if (uv__is_active(handle)) + uv__handle_stop(handle); + return uv_translate_sys_error(last_error); } @@ -344,8 +357,11 @@ int uv_fs_event_stop(uv_fs_event_t* handle) { } -static int file_info_cmp(WCHAR* str, WCHAR* file_name, int file_name_len) { - int str_len; +static int file_info_cmp(WCHAR* str, WCHAR* file_name, size_t file_name_len) { + size_t str_len; + + if (str == NULL) + return -1; str_len = wcslen(str); diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c index 6902d4f1a69485..2d72cdc70fe7d8 100644 --- a/deps/uv/src/win/fs.c +++ b/deps/uv/src/win/fs.c @@ -114,7 +114,7 @@ const WCHAR UNC_PATH_PREFIX[] = L"\\\\?\\UNC\\"; const WCHAR UNC_PATH_PREFIX_LEN = 8; -void uv_fs_init() { +void uv_fs_init(void) { _fmode = _O_BINARY; } @@ -220,9 +220,7 @@ INLINE static int fs__capture_path(uv_fs_t* req, const char* path, INLINE static void uv_fs_req_init(uv_loop_t* loop, uv_fs_t* req, uv_fs_type fs_type, const uv_fs_cb cb) { - uv_req_init(loop, (uv_req_t*) req); - - req->type = UV_FS; + UV_REQ_INIT(req, UV_FS); req->loop = loop; req->flags = 0; req->fs_type = fs_type; @@ -1373,7 +1371,7 @@ static void fs__access(uv_fs_t* req) { * - or it's a directory. * (Directories cannot be read-only on Windows.) */ - if (!(req->flags & W_OK) || + if (!(req->fs.info.mode & W_OK) || !(attr & FILE_ATTRIBUTE_READONLY) || (attr & FILE_ATTRIBUTE_DIRECTORY)) { SET_REQ_RESULT(req, 0); @@ -2400,7 +2398,7 @@ int uv_fs_access(uv_loop_t* loop, if (err) return uv_translate_sys_error(err); - req->flags = flags; + req->fs.info.mode = flags; if (cb) { QUEUE_FS_TP_JOB(loop, req); diff --git a/deps/uv/src/win/getaddrinfo.c b/deps/uv/src/win/getaddrinfo.c index c13bfec350f27e..baab838898a62e 100644 --- a/deps/uv/src/win/getaddrinfo.c +++ b/deps/uv/src/win/getaddrinfo.c @@ -265,11 +265,9 @@ int uv_getaddrinfo(uv_loop_t* loop, return UV_EINVAL; } - uv_req_init(loop, (uv_req_t*)req); - + UV_REQ_INIT(req, UV_GETADDRINFO); req->getaddrinfo_cb = getaddrinfo_cb; req->addrinfo = NULL; - req->type = UV_GETADDRINFO; req->loop = loop; req->retcode = 0; diff --git a/deps/uv/src/win/getnameinfo.c b/deps/uv/src/win/getnameinfo.c index 66b64b883248e3..9f10cd2a5a1432 100644 --- a/deps/uv/src/win/getnameinfo.c +++ b/deps/uv/src/win/getnameinfo.c @@ -127,12 +127,11 @@ int uv_getnameinfo(uv_loop_t* loop, return UV_EINVAL; } - uv_req_init(loop, (uv_req_t*)req); + UV_REQ_INIT(req, UV_GETNAMEINFO); uv__req_register(loop, req); req->getnameinfo_cb = getnameinfo_cb; req->flags = flags; - req->type = UV_GETNAMEINFO; req->loop = loop; req->retcode = 0; diff --git a/deps/uv/src/win/handle.c b/deps/uv/src/win/handle.c index 72b49d979045ba..39150702ddcd07 100644 --- a/deps/uv/src/win/handle.c +++ b/deps/uv/src/win/handle.c @@ -152,3 +152,8 @@ void uv_close(uv_handle_t* handle, uv_close_cb cb) { int uv_is_closing(const uv_handle_t* handle) { return !!(handle->flags & (UV__HANDLE_CLOSING | UV_HANDLE_CLOSED)); } + + +uv_os_fd_t uv_get_osfhandle(int fd) { + return uv__get_osfhandle(fd); +} diff --git a/deps/uv/src/win/internal.h b/deps/uv/src/win/internal.h index b8cfde90e81f8b..444327d647f284 100644 --- a/deps/uv/src/win/internal.h +++ b/deps/uv/src/win/internal.h @@ -206,7 +206,7 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle); /* * TTY */ -void uv_console_init(); +void uv_console_init(void); int uv_tty_read_start(uv_tty_t* handle, uv_alloc_cb alloc_cb, uv_read_cb read_cb); @@ -259,7 +259,7 @@ void uv_prepare_invoke(uv_loop_t* loop); void uv_check_invoke(uv_loop_t* loop); void uv_idle_invoke(uv_loop_t* loop); -void uv__once_init(); +void uv__once_init(void); /* @@ -275,7 +275,7 @@ void uv_process_async_wakeup_req(uv_loop_t* loop, uv_async_t* handle, /* * Signal watcher */ -void uv_signals_init(); +void uv_signals_init(void); int uv__signal_dispatch(int signum); void uv_signal_close(uv_loop_t* loop, uv_signal_t* handle); @@ -302,7 +302,7 @@ int uv_translate_sys_error(int sys_errno); /* * FS */ -void uv_fs_init(); +void uv_fs_init(void); /* @@ -323,14 +323,15 @@ void uv__fs_poll_endgame(uv_loop_t* loop, uv_fs_poll_t* handle); /* * Utilities. */ -void uv__util_init(); +void uv__util_init(void); uint64_t uv__hrtime(double scale); -int uv_parent_pid(); -int uv_current_pid(); +int uv_parent_pid(void); +int uv_current_pid(void); __declspec(noreturn) void uv_fatal_error(const int errorno, const char* syscall); int uv__getpwuid_r(uv_passwd_t* pwd); int uv__convert_utf16_to_utf8(const WCHAR* utf16, int utf16len, char** utf8); +int uv__convert_utf8_to_utf16(const char* utf8, int utf8len, WCHAR** utf16); /* @@ -349,13 +350,13 @@ HANDLE uv__stdio_handle(BYTE* buffer, int fd); /* * Winapi and ntapi utility functions */ -void uv_winapi_init(); +void uv_winapi_init(void); /* * Winsock utility functions */ -void uv_winsock_init(); +void uv_winsock_init(void); int uv_ntstatus_to_winsock_error(NTSTATUS status); @@ -384,11 +385,11 @@ extern struct sockaddr_in6 uv_addr_ip6_any_; /* * Wake all loops with fake message */ -void uv__wake_all_loops(); +void uv__wake_all_loops(void); /* * Init system wake-up detection */ -void uv__init_detect_system_wakeup(); +void uv__init_detect_system_wakeup(void); #endif /* UV_WIN_INTERNAL_H_ */ diff --git a/deps/uv/src/win/pipe.c b/deps/uv/src/win/pipe.c index 2442be7301ebf8..edf30021217980 100644 --- a/deps/uv/src/win/pipe.c +++ b/deps/uv/src/win/pipe.c @@ -103,7 +103,7 @@ int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) { handle->pipe.conn.non_overlapped_writes_tail = NULL; handle->pipe.conn.readfile_thread = NULL; - uv_req_init(loop, (uv_req_t*) &handle->pipe.conn.ipc_header_write_req); + UV_REQ_INIT(&handle->pipe.conn.ipc_header_write_req, UV_UNKNOWN_REQ); return 0; } @@ -505,8 +505,7 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) { for (i = 0; i < handle->pipe.serv.pending_instances; i++) { req = &handle->pipe.serv.accept_reqs[i]; - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_ACCEPT; + UV_REQ_INIT(req, UV_ACCEPT); req->data = handle; req->pipeHandle = INVALID_HANDLE_VALUE; req->next_pending = NULL; @@ -626,8 +625,7 @@ void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle, HANDLE pipeHandle = INVALID_HANDLE_VALUE; DWORD duplex_flags; - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_CONNECT; + UV_REQ_INIT(req, UV_CONNECT); req->handle = (uv_stream_t*) handle; req->cb = cb; @@ -962,7 +960,7 @@ static DWORD WINAPI uv_pipe_zero_readfile_thread_proc(void* parameter) { uv_mutex_lock(m); /* mutex controls *setting* of readfile_thread */ if (DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &hThread, - 0, TRUE, DUPLICATE_SAME_ACCESS)) { + 0, FALSE, DUPLICATE_SAME_ACCESS)) { handle->pipe.conn.readfile_thread = hThread; } else { hThread = NULL; @@ -1239,8 +1237,7 @@ static int uv_pipe_write_impl(uv_loop_t* loop, assert(handle->handle != INVALID_HANDLE_VALUE); - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_WRITE; + UV_REQ_INIT(req, UV_WRITE); req->handle = (uv_stream_t*) handle; req->cb = cb; req->ipc_header = 0; @@ -1301,8 +1298,7 @@ static int uv_pipe_write_impl(uv_loop_t* loop, } } - uv_req_init(loop, (uv_req_t*) ipc_header_req); - ipc_header_req->type = UV_WRITE; + UV_REQ_INIT(ipc_header_req, UV_WRITE); ipc_header_req->handle = (uv_stream_t*) handle; ipc_header_req->cb = NULL; ipc_header_req->ipc_header = 1; @@ -2076,7 +2072,6 @@ static int uv__pipe_getname(const uv_pipe_t* handle, char* buffer, size_t* size) buffer[addrlen] = '\0'; err = 0; - goto cleanup; error: uv__free(name_info); diff --git a/deps/uv/src/win/poll.c b/deps/uv/src/win/poll.c index d479e521efe24f..a648ba711d569a 100644 --- a/deps/uv/src/win/poll.c +++ b/deps/uv/src/win/poll.c @@ -61,13 +61,13 @@ static void uv__init_overlapped_dummy(void) { } -static OVERLAPPED* uv__get_overlapped_dummy() { +static OVERLAPPED* uv__get_overlapped_dummy(void) { uv_once(&overlapped_dummy_init_guard_, uv__init_overlapped_dummy); return &overlapped_dummy_; } -static AFD_POLL_INFO* uv__get_afd_poll_info_dummy() { +static AFD_POLL_INFO* uv__get_afd_poll_info_dummy(void) { return &afd_poll_info_dummy_; } @@ -572,13 +572,11 @@ int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle, /* Initialize 2 poll reqs. */ handle->submitted_events_1 = 0; - uv_req_init(loop, (uv_req_t*) &(handle->poll_req_1)); - handle->poll_req_1.type = UV_POLL_REQ; + UV_REQ_INIT(&handle->poll_req_1, UV_POLL_REQ); handle->poll_req_1.data = handle; handle->submitted_events_2 = 0; - uv_req_init(loop, (uv_req_t*) &(handle->poll_req_2)); - handle->poll_req_2.type = UV_POLL_REQ; + UV_REQ_INIT(&handle->poll_req_2, UV_POLL_REQ); handle->poll_req_2.data = handle; return 0; diff --git a/deps/uv/src/win/process.c b/deps/uv/src/win/process.c index bdf88d2cdd944c..d141601607851b 100644 --- a/deps/uv/src/win/process.c +++ b/deps/uv/src/win/process.c @@ -148,8 +148,7 @@ static void uv_process_init(uv_loop_t* loop, uv_process_t* handle) { handle->child_stdio_buffer = NULL; handle->exit_cb_pending = 0; - uv_req_init(loop, (uv_req_t*)&handle->exit_req); - handle->exit_req.type = UV_PROCESS_EXIT; + UV_REQ_INIT(&handle->exit_req, UV_PROCESS_EXIT); handle->exit_req.data = handle; } diff --git a/deps/uv/src/win/req-inl.h b/deps/uv/src/win/req-inl.h index b5e502eef5521a..f2513b7d3e7b5b 100644 --- a/deps/uv/src/win/req-inl.h +++ b/deps/uv/src/win/req-inl.h @@ -34,6 +34,9 @@ #define SET_REQ_ERROR(req, error) \ SET_REQ_STATUS((req), NTSTATUS_FROM_WIN32((error))) +/* Note: used open-coded in UV_REQ_INIT() because of a circular dependency + * between src/uv-common.h and src/win/internal.h. + */ #define SET_REQ_SUCCESS(req) \ SET_REQ_STATUS((req), STATUS_SUCCESS) @@ -79,12 +82,6 @@ } -INLINE static void uv_req_init(uv_loop_t* loop, uv_req_t* req) { - req->type = UV_UNKNOWN_REQ; - SET_REQ_SUCCESS(req); -} - - INLINE static uv_req_t* uv_overlapped_to_req(OVERLAPPED* overlapped) { return CONTAINING_RECORD(overlapped, uv_req_t, u.io.overlapped); } diff --git a/deps/uv/src/win/signal.c b/deps/uv/src/win/signal.c index af7974c364465f..7b42dd99280a00 100644 --- a/deps/uv/src/win/signal.c +++ b/deps/uv/src/win/signal.c @@ -34,7 +34,12 @@ static CRITICAL_SECTION uv__signal_lock; static BOOL WINAPI uv__signal_control_handler(DWORD type); -void uv_signals_init() { +int uv__signal_start(uv_signal_t* handle, + uv_signal_cb signal_cb, + int signum, + int oneshot); + +void uv_signals_init(void) { InitializeCriticalSection(&uv__signal_lock); if (!SetConsoleCtrlHandler(uv__signal_control_handler, TRUE)) abort(); @@ -70,7 +75,9 @@ RB_GENERATE_STATIC(uv_signal_tree_s, uv_signal_s, tree_entry, uv__signal_compare int uv__signal_dispatch(int signum) { uv_signal_t lookup; uv_signal_t* handle; - int dispatched = 0; + int dispatched; + + dispatched = 0; EnterCriticalSection(&uv__signal_lock); @@ -83,11 +90,16 @@ int uv__signal_dispatch(int signum) { unsigned long previous = InterlockedExchange( (volatile LONG*) &handle->pending_signum, signum); + if (handle->flags & UV__SIGNAL_ONE_SHOT_DISPATCHED) + continue; + if (!previous) { POST_COMPLETION_FOR_REQ(handle->loop, &handle->signal_req); } dispatched = 1; + if (handle->flags & UV__SIGNAL_ONE_SHOT) + handle->flags |= UV__SIGNAL_ONE_SHOT_DISPATCHED; } LeaveCriticalSection(&uv__signal_lock); @@ -128,17 +140,13 @@ static BOOL WINAPI uv__signal_control_handler(DWORD type) { int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle) { - uv_req_t* req; - uv__handle_init(loop, (uv_handle_t*) handle, UV_SIGNAL); handle->pending_signum = 0; handle->signum = 0; handle->signal_cb = NULL; - req = &handle->signal_req; - uv_req_init(loop, req); - req->type = UV_SIGNAL_REQ; - req->data = handle; + UV_REQ_INIT(&handle->signal_req, UV_SIGNAL_REQ); + handle->signal_req.data = handle; return 0; } @@ -166,6 +174,21 @@ int uv_signal_stop(uv_signal_t* handle) { int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) { + return uv__signal_start(handle, signal_cb, signum, 0); +} + + +int uv_signal_start_oneshot(uv_signal_t* handle, + uv_signal_cb signal_cb, + int signum) { + return uv__signal_start(handle, signal_cb, signum, 1); +} + + +int uv__signal_start(uv_signal_t* handle, + uv_signal_cb signal_cb, + int signum, + int oneshot) { /* Test for invalid signal values. */ if (signum != SIGWINCH && (signum <= 0 || signum >= NSIG)) return UV_EINVAL; @@ -189,6 +212,9 @@ int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) { EnterCriticalSection(&uv__signal_lock); handle->signum = signum; + if (oneshot) + handle->flags |= UV__SIGNAL_ONE_SHOT; + RB_INSERT(uv_signal_tree_s, &uv__signal_tree, handle); LeaveCriticalSection(&uv__signal_lock); @@ -217,6 +243,9 @@ void uv_process_signal_req(uv_loop_t* loop, uv_signal_t* handle, if (dispatched_signum == handle->signum) handle->signal_cb(handle, dispatched_signum); + if (handle->flags & UV__SIGNAL_ONE_SHOT) + uv_signal_stop(handle); + if (handle->flags & UV__HANDLE_CLOSING) { /* When it is closing, it must be stopped at this point. */ assert(handle->signum == 0); diff --git a/deps/uv/src/win/stream-inl.h b/deps/uv/src/win/stream-inl.h index b7a3c11958c274..bf12148afe1605 100644 --- a/deps/uv/src/win/stream-inl.h +++ b/deps/uv/src/win/stream-inl.h @@ -43,10 +43,9 @@ INLINE static void uv_connection_init(uv_stream_t* handle) { handle->flags |= UV_HANDLE_CONNECTION; handle->stream.conn.write_reqs_pending = 0; - uv_req_init(handle->loop, (uv_req_t*) &(handle->read_req)); + UV_REQ_INIT(&handle->read_req, UV_READ); handle->read_req.event_handle = NULL; handle->read_req.wait_handle = INVALID_HANDLE_VALUE; - handle->read_req.type = UV_READ; handle->read_req.data = handle; handle->stream.conn.shutdown_req = NULL; diff --git a/deps/uv/src/win/stream.c b/deps/uv/src/win/stream.c index a2466e5e9db8ba..13cbfdcb9e6e5f 100644 --- a/deps/uv/src/win/stream.c +++ b/deps/uv/src/win/stream.c @@ -210,8 +210,7 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) { return UV_EPIPE; } - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_SHUTDOWN; + UV_REQ_INIT(req, UV_SHUTDOWN); req->handle = handle; req->cb = cb; diff --git a/deps/uv/src/win/tcp.c b/deps/uv/src/win/tcp.c index 0709696ff9afed..972539f4df49d0 100644 --- a/deps/uv/src/win/tcp.c +++ b/deps/uv/src/win/tcp.c @@ -555,7 +555,6 @@ static void uv_tcp_queue_read(uv_loop_t* loop, uv_tcp_t* handle) { int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) { - uv_loop_t* loop = handle->loop; unsigned int i, simultaneous_accepts; uv_tcp_accept_t* req; int err; @@ -612,8 +611,7 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) { for (i = 0; i < simultaneous_accepts; i++) { req = &handle->tcp.serv.accept_reqs[i]; - uv_req_init(loop, (uv_req_t*)req); - req->type = UV_ACCEPT; + UV_REQ_INIT(req, UV_ACCEPT); req->accept_socket = INVALID_SOCKET; req->data = handle; @@ -635,8 +633,7 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) { /* try to clean up {uv_simultaneous_server_accepts} requests. */ for (i = simultaneous_accepts; i < uv_simultaneous_server_accepts; i++) { req = &handle->tcp.serv.accept_reqs[i]; - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_ACCEPT; + UV_REQ_INIT(req, UV_ACCEPT); req->accept_socket = INVALID_SOCKET; req->data = handle; req->wait_handle = INVALID_HANDLE_VALUE; @@ -779,8 +776,7 @@ static int uv_tcp_try_connect(uv_connect_t* req, } } - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_CONNECT; + UV_REQ_INIT(req, UV_CONNECT); req->handle = (uv_stream_t*) handle; req->cb = cb; memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); @@ -863,8 +859,7 @@ int uv_tcp_write(uv_loop_t* loop, int result; DWORD bytes; - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_WRITE; + UV_REQ_INIT(req, UV_WRITE); req->handle = (uv_stream_t*) handle; req->cb = cb; diff --git a/deps/uv/src/win/tty.c b/deps/uv/src/win/tty.c index 1b7adf64ffcbdb..a6f583956fe6b3 100644 --- a/deps/uv/src/win/tty.c +++ b/deps/uv/src/win/tty.c @@ -138,7 +138,7 @@ typedef enum { static uv_vtermstate_t uv__vterm_state = UV_UNCHECKED; static void uv__determine_vterm_state(HANDLE handle); -void uv_console_init() { +void uv_console_init(void) { if (uv_sem_init(&uv_tty_output_lock, 1)) abort(); } @@ -2126,8 +2126,7 @@ int uv_tty_write(uv_loop_t* loop, uv_write_cb cb) { DWORD error; - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_WRITE; + UV_REQ_INIT(req, UV_WRITE); req->handle = (uv_stream_t*) handle; req->cb = cb; diff --git a/deps/uv/src/win/udp.c b/deps/uv/src/win/udp.c index 9bf1453e536d9a..2fd15cfa9a64fa 100644 --- a/deps/uv/src/win/udp.c +++ b/deps/uv/src/win/udp.c @@ -142,8 +142,7 @@ int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) { handle->func_wsarecvfrom = WSARecvFrom; handle->send_queue_size = 0; handle->send_queue_count = 0; - uv_req_init(loop, (uv_req_t*) &(handle->recv_req)); - handle->recv_req.type = UV_UDP_RECV; + UV_REQ_INIT(&handle->recv_req, UV_UDP_RECV); handle->recv_req.data = handle; /* If anything fails beyond this point we need to remove the handle from @@ -417,8 +416,7 @@ static int uv__send(uv_udp_send_t* req, uv_loop_t* loop = handle->loop; DWORD result, bytes; - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_UDP_SEND; + UV_REQ_INIT(req, UV_UDP_SEND); req->handle = handle; req->cb = cb; memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); diff --git a/deps/uv/src/win/util.c b/deps/uv/src/win/util.c index 050058afaa9a90..d2e7f772ce2977 100644 --- a/deps/uv/src/win/util.c +++ b/deps/uv/src/win/util.c @@ -59,6 +59,17 @@ # define UNLEN 256 #endif +/* + Max hostname length. The Windows gethostname() documentation states that 256 + bytes will always be large enough to hold the null-terminated hostname. +*/ +#ifndef MAXHOSTNAMELEN +# define MAXHOSTNAMELEN 256 +#endif + +/* Maximum environment variable size, including the terminating null */ +#define MAX_ENV_VAR_LENGTH 32767 + /* Cached copy of the process title, plus a mutex guarding it. */ static char *process_title; static CRITICAL_SECTION process_title_lock; @@ -74,7 +85,7 @@ static double hrtime_interval_ = 0; /* * One-time initialization code for functionality defined in util.c. */ -void uv__util_init() { +void uv__util_init(void) { LARGE_INTEGER perf_frequency; /* Initialize process title access mutex. */ @@ -320,7 +331,7 @@ uint64_t uv_get_total_memory(void) { } -int uv_parent_pid() { +int uv_parent_pid(void) { int parent_pid = -1; HANDLE handle; PROCESSENTRY32 pe; @@ -343,7 +354,7 @@ int uv_parent_pid() { } -int uv_current_pid() { +int uv_current_pid(void) { if (current_pid == 0) { current_pid = GetCurrentProcessId(); } @@ -405,7 +416,7 @@ int uv_set_process_title(const char* title) { } -static int uv__get_process_title() { +static int uv__get_process_title(void) { WCHAR title_w[MAX_TITLE_LENGTH]; if (!GetConsoleTitleW(title_w, sizeof(title_w) / sizeof(WCHAR))) { @@ -1322,6 +1333,47 @@ int uv__convert_utf16_to_utf8(const WCHAR* utf16, int utf16len, char** utf8) { } +/* + * Converts a UTF-8 string into a UTF-16 one. The resulting string is + * null-terminated. + * + * If utf8 is null terminated, utf8len can be set to -1, otherwise it must + * be specified. + */ +int uv__convert_utf8_to_utf16(const char* utf8, int utf8len, WCHAR** utf16) { + int bufsize; + + if (utf8 == NULL) + return UV_EINVAL; + + /* Check how much space we need */ + bufsize = MultiByteToWideChar(CP_UTF8, 0, utf8, utf8len, NULL, 0); + + if (bufsize == 0) + return uv_translate_sys_error(GetLastError()); + + /* Allocate the destination buffer adding an extra byte for the terminating + * NULL. If utf8len is not -1 MultiByteToWideChar will not add it, so + * we do it ourselves always, just in case. */ + *utf16 = uv__malloc(sizeof(WCHAR) * (bufsize + 1)); + + if (*utf16 == NULL) + return UV_ENOMEM; + + /* Convert to UTF-16 */ + bufsize = MultiByteToWideChar(CP_UTF8, 0, utf8, utf8len, *utf16, bufsize); + + if (bufsize == 0) { + uv__free(*utf16); + *utf16 = NULL; + return uv_translate_sys_error(GetLastError()); + } + + (*utf16)[bufsize] = '\0'; + return 0; +} + + int uv__getpwuid_r(uv_passwd_t* pwd) { HANDLE token; wchar_t username[UNLEN + 1]; @@ -1387,3 +1439,138 @@ int uv__getpwuid_r(uv_passwd_t* pwd) { int uv_os_get_passwd(uv_passwd_t* pwd) { return uv__getpwuid_r(pwd); } + + +int uv_os_getenv(const char* name, char* buffer, size_t* size) { + wchar_t var[MAX_ENV_VAR_LENGTH]; + wchar_t* name_w; + DWORD bufsize; + size_t len; + int r; + + if (name == NULL || buffer == NULL || size == NULL || *size == 0) + return UV_EINVAL; + + r = uv__convert_utf8_to_utf16(name, -1, &name_w); + + if (r != 0) + return r; + + len = GetEnvironmentVariableW(name_w, var, MAX_ENV_VAR_LENGTH); + uv__free(name_w); + assert(len < MAX_ENV_VAR_LENGTH); /* len does not include the null */ + + if (len == 0) { + r = GetLastError(); + + if (r == ERROR_ENVVAR_NOT_FOUND) + return UV_ENOENT; + + return uv_translate_sys_error(r); + } + + /* Check how much space we need */ + bufsize = WideCharToMultiByte(CP_UTF8, 0, var, -1, NULL, 0, NULL, NULL); + + if (bufsize == 0) { + return uv_translate_sys_error(GetLastError()); + } else if (bufsize > *size) { + *size = bufsize; + return UV_ENOBUFS; + } + + /* Convert to UTF-8 */ + bufsize = WideCharToMultiByte(CP_UTF8, + 0, + var, + -1, + buffer, + *size, + NULL, + NULL); + + if (bufsize == 0) + return uv_translate_sys_error(GetLastError()); + + *size = bufsize - 1; + return 0; +} + + +int uv_os_setenv(const char* name, const char* value) { + wchar_t* name_w; + wchar_t* value_w; + int r; + + if (name == NULL || value == NULL) + return UV_EINVAL; + + r = uv__convert_utf8_to_utf16(name, -1, &name_w); + + if (r != 0) + return r; + + r = uv__convert_utf8_to_utf16(value, -1, &value_w); + + if (r != 0) { + uv__free(name_w); + return r; + } + + r = SetEnvironmentVariableW(name_w, value_w); + uv__free(name_w); + uv__free(value_w); + + if (r == 0) + return uv_translate_sys_error(GetLastError()); + + return 0; +} + + +int uv_os_unsetenv(const char* name) { + wchar_t* name_w; + int r; + + if (name == NULL) + return UV_EINVAL; + + r = uv__convert_utf8_to_utf16(name, -1, &name_w); + + if (r != 0) + return r; + + r = SetEnvironmentVariableW(name_w, NULL); + uv__free(name_w); + + if (r == 0) + return uv_translate_sys_error(GetLastError()); + + return 0; +} + + +int uv_os_gethostname(char* buffer, size_t* size) { + char buf[MAXHOSTNAMELEN + 1]; + size_t len; + + if (buffer == NULL || size == NULL || *size == 0) + return UV_EINVAL; + + uv__once_init(); /* Initialize winsock */ + + if (gethostname(buf, sizeof(buf)) != 0) + return uv_translate_sys_error(WSAGetLastError()); + + buf[sizeof(buf) - 1] = '\0'; /* Null terminate, just to be safe. */ + len = strlen(buf); + + if (len >= *size) { + *size = len + 1; + return UV_ENOBUFS; + } + + memcpy(buffer, buf, len + 1); + *size = len; + return 0; +} diff --git a/deps/uv/src/win/winapi.c b/deps/uv/src/win/winapi.c index 1fa179b5724ed0..aa5d719fbea199 100644 --- a/deps/uv/src/win/winapi.c +++ b/deps/uv/src/win/winapi.c @@ -53,7 +53,7 @@ sGetFinalPathNameByHandleW pGetFinalPathNameByHandleW; sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification; -void uv_winapi_init() { +void uv_winapi_init(void) { HMODULE ntdll_module; HMODULE kernel32_module; HMODULE powrprof_module; diff --git a/deps/uv/src/win/winsock.c b/deps/uv/src/win/winsock.c index d2e667e9f7546a..e86d76b131caa4 100644 --- a/deps/uv/src/win/winsock.c +++ b/deps/uv/src/win/winsock.c @@ -80,7 +80,7 @@ static int error_means_no_support(DWORD error) { } -void uv_winsock_init() { +void uv_winsock_init(void) { WSADATA wsa_data; int errorno; SOCKET dummy; diff --git a/deps/uv/test/runner-win.c b/deps/uv/test/runner-win.c index 1b4a569aef54dd..0f1b56e777c6cb 100644 --- a/deps/uv/test/runner-win.c +++ b/deps/uv/test/runner-win.c @@ -209,22 +209,30 @@ long int process_output_size(process_info_t *p) { int process_copy_output(process_info_t* p, FILE* stream) { - DWORD read; char buf[1024]; + int fd, r; + FILE* f; - if (SetFilePointer(p->stdio_out, - 0, - 0, - FILE_BEGIN) == INVALID_SET_FILE_POINTER) { + fd = _open_osfhandle((intptr_t)p->stdio_out, _O_RDONLY | _O_TEXT); + if (fd == -1) + return -1; + f = _fdopen(fd, "rt"); + if (f == NULL) { + _close(fd); return -1; } - while (ReadFile(p->stdio_out, &buf, sizeof(buf), &read, NULL) && read > 0) - print_lines(buf, read, stream); + r = fseek(f, 0, SEEK_SET); + if (r < 0) + return -1; - if (GetLastError() != ERROR_HANDLE_EOF) + while (fgets(buf, sizeof(buf), f) != NULL) + print_lines(buf, strlen(buf), stream); + + if (ferror(f)) return -1; + fclose(f); return 0; } diff --git a/deps/uv/test/task.h b/deps/uv/test/task.h index 65a1132e49865d..67eb9804926824 100644 --- a/deps/uv/test/task.h +++ b/deps/uv/test/task.h @@ -209,4 +209,24 @@ UNUSED static int can_ipv6(void) { return supported; } +#if defined(__MVS__) || defined(__CYGWIN__) || defined(__MSYS__) +# define NO_FS_EVENTS "Filesystem watching not supported on this platform." +#endif + +#if defined(__MSYS__) +# define NO_SEND_HANDLE_ON_PIPE \ + "MSYS2 runtime does not support sending handles on pipes." +#elif defined(__CYGWIN__) +# define NO_SEND_HANDLE_ON_PIPE \ + "Cygwin runtime does not support sending handles on pipes." +#endif + +#if defined(__MSYS__) +# define NO_SELF_CONNECT \ + "MSYS2 runtime hangs on listen+connect in same process." +#elif defined(__CYGWIN__) +# define NO_SELF_CONNECT \ + "Cygwin runtime hangs on listen+connect in same process." +#endif + #endif /* TASK_H_ */ diff --git a/deps/uv/test/test-env-vars.c b/deps/uv/test/test-env-vars.c new file mode 100644 index 00000000000000..641050e675ffce --- /dev/null +++ b/deps/uv/test/test-env-vars.c @@ -0,0 +1,90 @@ +/* Copyright libuv 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. + */ + +#include "uv.h" +#include "task.h" +#include + +#define BUF_SIZE 10 + +TEST_IMPL(env_vars) { + const char* name = "UV_TEST_FOO"; + char buf[BUF_SIZE]; + size_t size; + int r; + + /* Reject invalid inputs when setting an environment variable */ + r = uv_os_setenv(NULL, "foo"); + ASSERT(r == UV_EINVAL); + r = uv_os_setenv(name, NULL); + ASSERT(r == UV_EINVAL); + r = uv_os_setenv(NULL, NULL); + ASSERT(r == UV_EINVAL); + + /* Reject invalid inputs when retrieving an environment variable */ + size = BUF_SIZE; + r = uv_os_getenv(NULL, buf, &size); + ASSERT(r == UV_EINVAL); + r = uv_os_getenv(name, NULL, &size); + ASSERT(r == UV_EINVAL); + r = uv_os_getenv(name, buf, NULL); + ASSERT(r == UV_EINVAL); + size = 0; + r = uv_os_getenv(name, buf, &size); + ASSERT(r == UV_EINVAL); + + /* Reject invalid inputs when deleting an environment variable */ + r = uv_os_unsetenv(NULL); + ASSERT(r == UV_EINVAL); + + /* Successfully set an environment variable */ + r = uv_os_setenv(name, "123456789"); + ASSERT(r == 0); + + /* Successfully read an environment variable */ + size = BUF_SIZE; + buf[0] = '\0'; + r = uv_os_getenv(name, buf, &size); + ASSERT(r == 0); + ASSERT(strcmp(buf, "123456789") == 0); + ASSERT(size == BUF_SIZE - 1); + + /* Return UV_ENOBUFS if the buffer cannot hold the environment variable */ + size = BUF_SIZE - 1; + buf[0] = '\0'; + r = uv_os_getenv(name, buf, &size); + ASSERT(r == UV_ENOBUFS); + ASSERT(size == BUF_SIZE); + + /* Successfully delete an environment variable */ + r = uv_os_unsetenv(name); + ASSERT(r == 0); + + /* Return UV_ENOENT retrieving an environment variable that does not exist */ + r = uv_os_getenv(name, buf, &size); + ASSERT(r == UV_ENOENT); + + /* Successfully delete an environment variable that does not exist */ + r = uv_os_unsetenv(name); + ASSERT(r == 0); + + return 0; +} diff --git a/deps/uv/test/test-fork.c b/deps/uv/test/test-fork.c new file mode 100644 index 00000000000000..3716a3ad975c17 --- /dev/null +++ b/deps/uv/test/test-fork.c @@ -0,0 +1,677 @@ +/* Copyright libuv project 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. + */ + +/* These tests are Unix only. */ +#ifndef _WIN32 + +#include +#include +#include +#include + +#include "uv.h" +#include "task.h" + +static int timer_cb_called; +static int socket_cb_called; + +static void timer_cb(uv_timer_t* timer) { + timer_cb_called++; + uv_close((uv_handle_t*) timer, NULL); +} + + +static int socket_cb_read_fd; +static int socket_cb_read_size; +static char socket_cb_read_buf[1024]; + + +static void socket_cb(uv_poll_t* poll, int status, int events) { + ssize_t cnt; + socket_cb_called++; + ASSERT(0 == status); + printf("Socket cb got events %d\n", events); + ASSERT(UV_READABLE == (events & UV_READABLE)); + if (socket_cb_read_fd) { + cnt = read(socket_cb_read_fd, socket_cb_read_buf, socket_cb_read_size); + ASSERT(cnt == socket_cb_read_size); + } + uv_close((uv_handle_t*) poll, NULL); +} + + +static void run_timer_loop_once(void) { + uv_loop_t* loop; + uv_timer_t timer_handle; + + loop = uv_default_loop(); + + timer_cb_called = 0; /* Reset for the child. */ + + ASSERT(0 == uv_timer_init(loop, &timer_handle)); + ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 1, 0)); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(1 == timer_cb_called); +} + + +static void assert_wait_child(pid_t child_pid) { + pid_t waited_pid; + int child_stat; + + waited_pid = waitpid(child_pid, &child_stat, 0); + printf("Waited pid is %d with status %d\n", waited_pid, child_stat); + if (waited_pid == -1) { + perror("Failed to wait"); + } + ASSERT(child_pid == waited_pid); + ASSERT(WIFEXITED(child_stat)); /* Clean exit, not a signal. */ + ASSERT(!WIFSIGNALED(child_stat)); + ASSERT(0 == WEXITSTATUS(child_stat)); +} + + +TEST_IMPL(fork_timer) { + /* Timers continue to work after we fork. */ + + /* + * Establish the loop before we fork to make sure that it + * has state to get reset after the fork. + */ + pid_t child_pid; + + run_timer_loop_once(); + child_pid = fork(); + ASSERT(child_pid != -1); + + if (child_pid != 0) { + /* parent */ + assert_wait_child(child_pid); + } else { + /* child */ + ASSERT(0 == uv_loop_fork(uv_default_loop())); + run_timer_loop_once(); + } + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(fork_socketpair) { + /* A socket opened in the parent and accept'd in the + child works after a fork. */ + pid_t child_pid; + int socket_fds[2]; + uv_poll_t poll_handle; + + /* Prime the loop. */ + run_timer_loop_once(); + + ASSERT(0 == socketpair(AF_UNIX, SOCK_STREAM, 0, socket_fds)); + + /* Create the server watcher in the parent, use it in the child. */ + ASSERT(0 == uv_poll_init(uv_default_loop(), &poll_handle, socket_fds[0])); + + child_pid = fork(); + ASSERT(child_pid != -1); + + if (child_pid != 0) { + /* parent */ + ASSERT(3 == send(socket_fds[1], "hi\n", 3, 0)); + assert_wait_child(child_pid); + } else { + /* child */ + ASSERT(0 == uv_loop_fork(uv_default_loop())); + ASSERT(0 == socket_cb_called); + ASSERT(0 == uv_poll_start(&poll_handle, UV_READABLE, socket_cb)); + printf("Going to run the loop in the child\n"); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + ASSERT(1 == socket_cb_called); + } + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(fork_socketpair_started) { + /* A socket opened in the parent and accept'd in the + child works after a fork, even if the watcher was already + started, and then stopped in the parent. */ + pid_t child_pid; + int socket_fds[2]; + int sync_pipe[2]; + char sync_buf[1]; + uv_poll_t poll_handle; + + ASSERT(0 == pipe(sync_pipe)); + + /* Prime the loop. */ + run_timer_loop_once(); + + ASSERT(0 == socketpair(AF_UNIX, SOCK_STREAM, 0, socket_fds)); + + /* Create and start the server watcher in the parent, use it in the child. */ + ASSERT(0 == uv_poll_init(uv_default_loop(), &poll_handle, socket_fds[0])); + ASSERT(0 == uv_poll_start(&poll_handle, UV_READABLE, socket_cb)); + + /* Run the loop AFTER the poll watcher is registered to make sure it + gets passed to the kernel. Use NOWAIT and expect a non-zero + return to prove the poll watcher is active. + */ + ASSERT(1 == uv_run(uv_default_loop(), UV_RUN_NOWAIT)); + + child_pid = fork(); + ASSERT(child_pid != -1); + + if (child_pid != 0) { + /* parent */ + ASSERT(0 == uv_poll_stop(&poll_handle)); + uv_close((uv_handle_t*)&poll_handle, NULL); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + ASSERT(0 == socket_cb_called); + ASSERT(1 == write(sync_pipe[1], "1", 1)); /* alert child */ + ASSERT(3 == send(socket_fds[1], "hi\n", 3, 0)); + + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + ASSERT(0 == socket_cb_called); + + assert_wait_child(child_pid); + } else { + /* child */ + printf("Child is %d\n", getpid()); + ASSERT(1 == read(sync_pipe[0], sync_buf, 1)); /* wait for parent */ + ASSERT(0 == uv_loop_fork(uv_default_loop())); + ASSERT(0 == socket_cb_called); + + printf("Going to run the loop in the child\n"); + socket_cb_read_fd = socket_fds[0]; + socket_cb_read_size = 3; + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + ASSERT(1 == socket_cb_called); + printf("Buf %s\n", socket_cb_read_buf); + ASSERT(0 == strcmp("hi\n", socket_cb_read_buf)); + } + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +static int fork_signal_cb_called; + +void fork_signal_to_child_cb(uv_signal_t* handle, int signum) +{ + fork_signal_cb_called = signum; + uv_close((uv_handle_t*)handle, NULL); +} + + +TEST_IMPL(fork_signal_to_child) { + /* A signal handler installed before forking + is run only in the child when the child is signalled. */ + uv_signal_t signal_handle; + pid_t child_pid; + int sync_pipe[2]; + char sync_buf[1]; + + fork_signal_cb_called = 0; /* reset */ + + ASSERT(0 == pipe(sync_pipe)); + + /* Prime the loop. */ + run_timer_loop_once(); + + ASSERT(0 == uv_signal_init(uv_default_loop(), &signal_handle)); + ASSERT(0 == uv_signal_start(&signal_handle, fork_signal_to_child_cb, SIGUSR1)); + + child_pid = fork(); + ASSERT(child_pid != -1); + + if (child_pid != 0) { + /* parent */ + ASSERT(1 == read(sync_pipe[0], sync_buf, 1)); /* wait for child */ + ASSERT(0 == kill(child_pid, SIGUSR1)); + /* Run the loop, make sure we don't get the signal. */ + printf("Running loop in parent\n"); + uv_unref((uv_handle_t*)&signal_handle); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_NOWAIT)); + ASSERT(0 == fork_signal_cb_called); + printf("Waiting for child in parent\n"); + assert_wait_child(child_pid); + } else { + /* child */ + ASSERT(0 == uv_loop_fork(uv_default_loop())); + ASSERT(1 == write(sync_pipe[1], "1", 1)); /* alert parent */ + /* Get the signal. */ + ASSERT(0 != uv_loop_alive(uv_default_loop())); + printf("Running loop in child\n"); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE)); + ASSERT(SIGUSR1 == fork_signal_cb_called); + } + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(fork_signal_to_child_closed) { + /* A signal handler installed before forking + doesn't get received anywhere when the child is signalled, + but isnt running the loop. */ + uv_signal_t signal_handle; + pid_t child_pid; + int sync_pipe[2]; + int sync_pipe2[2]; + char sync_buf[1]; + + fork_signal_cb_called = 0; /* reset */ + + ASSERT(0 == pipe(sync_pipe)); + ASSERT(0 == pipe(sync_pipe2)); + + /* Prime the loop. */ + run_timer_loop_once(); + + ASSERT(0 == uv_signal_init(uv_default_loop(), &signal_handle)); + ASSERT(0 == uv_signal_start(&signal_handle, fork_signal_to_child_cb, SIGUSR1)); + + child_pid = fork(); + ASSERT(child_pid != -1); + + if (child_pid != 0) { + /* parent */ + printf("Wating on child in parent\n"); + ASSERT(1 == read(sync_pipe[0], sync_buf, 1)); /* wait for child */ + printf("Parent killing child\n"); + ASSERT(0 == kill(child_pid, SIGUSR1)); + /* Run the loop, make sure we don't get the signal. */ + printf("Running loop in parent\n"); + uv_unref((uv_handle_t*)&signal_handle); /* so the loop can exit; + we *shouldn't* get any signals */ + run_timer_loop_once(); /* but while we share a pipe, we do, so + have something active. */ + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE)); + printf("Signal in parent %d\n", fork_signal_cb_called); + ASSERT(0 == fork_signal_cb_called); + ASSERT(1 == write(sync_pipe2[1], "1", 1)); /* alert child */ + printf("Waiting for child in parent\n"); + assert_wait_child(child_pid); + } else { + /* child */ + /* Our signal handler should still be installed. */ + ASSERT(0 == uv_loop_fork(uv_default_loop())); + printf("Checking loop in child\n"); + ASSERT(0 != uv_loop_alive(uv_default_loop())); + printf("Alerting parent in child\n"); + ASSERT(1 == write(sync_pipe[1], "1", 1)); /* alert parent */ + /* Don't run the loop. Wait for the parent to call us */ + printf("Waiting on parent in child\n"); + /* Wait for parent. read may fail if the parent tripped an ASSERT + and exited, so this isn't in an ASSERT. + */ + read(sync_pipe2[0], sync_buf, 1); + ASSERT(0 == fork_signal_cb_called); + printf("Exiting child \n"); + /* Note that we're deliberately not running the loop + * in the child, and also not closing the loop's handles, + * so the child default loop can't be cleanly closed. + * We need te explicitly exit to avoid an automatic failure + * in that case. + */ + exit(0); + } + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +static void create_file(const char* name) { + int r; + uv_file file; + uv_fs_t req; + + r = uv_fs_open(NULL, &req, name, O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR, NULL); + ASSERT(r >= 0); + file = r; + uv_fs_req_cleanup(&req); + r = uv_fs_close(NULL, &req, file, NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&req); +} + + +static void touch_file(const char* name) { + int r; + uv_file file; + uv_fs_t req; + uv_buf_t buf; + + r = uv_fs_open(NULL, &req, name, O_RDWR, 0, NULL); + ASSERT(r >= 0); + file = r; + uv_fs_req_cleanup(&req); + + buf = uv_buf_init("foo", 4); + r = uv_fs_write(NULL, &req, file, &buf, 1, -1, NULL); + ASSERT(r >= 0); + uv_fs_req_cleanup(&req); + + r = uv_fs_close(NULL, &req, file, NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&req); +} + + +static int timer_cb_touch_called; + +static void timer_cb_touch(uv_timer_t* timer) { + uv_close((uv_handle_t*)timer, NULL); + touch_file("watch_file"); + timer_cb_touch_called++; +} + + +static int fs_event_cb_called; + +static void fs_event_cb_file_current_dir(uv_fs_event_t* handle, + const char* filename, + int events, + int status) { + ASSERT(fs_event_cb_called == 0); + ++fs_event_cb_called; + ASSERT(status == 0); +#if defined(__APPLE__) || defined(__linux__) + ASSERT(strcmp(filename, "watch_file") == 0); +#else + ASSERT(filename == NULL || strcmp(filename, "watch_file") == 0); +#endif + uv_close((uv_handle_t*)handle, NULL); +} + + +static void assert_watch_file_current_dir(uv_loop_t* const loop, int file_or_dir) { + uv_timer_t timer; + uv_fs_event_t fs_event; + int r; + + /* Setup */ + remove("watch_file"); + create_file("watch_file"); + + r = uv_fs_event_init(loop, &fs_event); + ASSERT(r == 0); + /* watching a dir is the only way to get fsevents involved on apple + platforms */ + r = uv_fs_event_start(&fs_event, + fs_event_cb_file_current_dir, + file_or_dir == 1 ? "." : "watch_file", + 0); + ASSERT(r == 0); + + r = uv_timer_init(loop, &timer); + ASSERT(r == 0); + + r = uv_timer_start(&timer, timer_cb_touch, 100, 0); + ASSERT(r == 0); + + ASSERT(timer_cb_touch_called == 0); + ASSERT(fs_event_cb_called == 0); + + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(timer_cb_touch_called == 1); + ASSERT(fs_event_cb_called == 1); + + /* Cleanup */ + remove("watch_file"); + fs_event_cb_called = 0; + timer_cb_touch_called = 0; + uv_run(loop, UV_RUN_DEFAULT); /* flush pending closes */ +} + + +#define FS_TEST_FILE 0 +#define FS_TEST_DIR 1 + +static int _do_fork_fs_events_child(int file_or_dir) { + /* basic fsevents work in the child after a fork */ + pid_t child_pid; + uv_loop_t loop; + + /* Watch in the parent, prime the loop and/or threads. */ + assert_watch_file_current_dir(uv_default_loop(), file_or_dir); + child_pid = fork(); + ASSERT(child_pid != -1); + + if (child_pid != 0) { + /* parent */ + assert_wait_child(child_pid); + } else { + /* child */ + /* Ee can watch in a new loop, but dirs only work + if we're on linux. */ +#if defined(__APPLE__) + file_or_dir = FS_TEST_FILE; +#endif + printf("Running child\n"); + uv_loop_init(&loop); + printf("Child first watch\n"); + assert_watch_file_current_dir(&loop, file_or_dir); + ASSERT(0 == uv_loop_close(&loop)); + printf("Child second watch default loop\n"); + /* Ee can watch in the default loop. */ + ASSERT(0 == uv_loop_fork(uv_default_loop())); + /* On some platforms (OS X), if we don't update the time now, + * the timer cb fires before the event loop enters uv__io_poll, + * instead of after, meaning we don't see the change! This may be + * a general race. + */ + uv_update_time(uv_default_loop()); + assert_watch_file_current_dir(uv_default_loop(), file_or_dir); + + /* We can close the parent loop successfully too. This is + especially important on Apple platforms where if we're not + careful trying to touch the CFRunLoop, even just to shut it + down, that we allocated in the FS_TEST_DIR case would crash. */ + ASSERT(0 == uv_loop_close(uv_default_loop())); + + printf("Exiting child \n"); + } + + MAKE_VALGRIND_HAPPY(); + return 0; + +} + + +TEST_IMPL(fork_fs_events_child) { +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); +#endif + return _do_fork_fs_events_child(FS_TEST_FILE); +} + + +TEST_IMPL(fork_fs_events_child_dir) { +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); +#endif +#if defined(__APPLE__) || defined (__linux__) + return _do_fork_fs_events_child(FS_TEST_DIR); +#else + /* You can't spin up a cfrunloop thread on an apple platform + and then fork. See + http://objectivistc.tumblr.com/post/16187948939/you-must-exec-a-core-foundation-fork-safety-tale + */ + return 0; +#endif +} + + +TEST_IMPL(fork_fs_events_file_parent_child) { +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); +#endif +#if defined(__sun) || defined(_AIX) + /* It's not possible to implement this without additional + * bookkeeping on SunOS. For AIX it is possible, but has to be + * written. See https://github.com/libuv/libuv/pull/846#issuecomment-287170420 + */ + return 0; +#else + /* Establishing a started fs events watcher in the parent should + still work in the child. */ + uv_timer_t timer; + uv_fs_event_t fs_event; + int r; + pid_t child_pid; + uv_loop_t* loop; + + loop = uv_default_loop(); + + /* Setup */ + remove("watch_file"); + create_file("watch_file"); + + r = uv_fs_event_init(loop, &fs_event); + ASSERT(r == 0); + r = uv_fs_event_start(&fs_event, + fs_event_cb_file_current_dir, + "watch_file", + 0); + ASSERT(r == 0); + + r = uv_timer_init(loop, &timer); + ASSERT(r == 0); + + child_pid = fork(); + ASSERT(child_pid != -1); + if (child_pid != 0) { + /* parent */ + assert_wait_child(child_pid); + } else { + /* child */ + printf("Running child\n"); + ASSERT(0 == uv_loop_fork(loop)); + + r = uv_timer_start(&timer, timer_cb_touch, 100, 0); + ASSERT(r == 0); + + ASSERT(timer_cb_touch_called == 0); + ASSERT(fs_event_cb_called == 0); + printf("Running loop in child \n"); + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(timer_cb_touch_called == 1); + ASSERT(fs_event_cb_called == 1); + + /* Cleanup */ + remove("watch_file"); + fs_event_cb_called = 0; + timer_cb_touch_called = 0; + uv_run(loop, UV_RUN_DEFAULT); /* Flush pending closes. */ + } + + + MAKE_VALGRIND_HAPPY(); + return 0; +#endif +} + + +static int work_cb_count; +static int after_work_cb_count; + + +static void work_cb(uv_work_t* req) { + work_cb_count++; +} + + +static void after_work_cb(uv_work_t* req, int status) { + ASSERT(status == 0); + after_work_cb_count++; +} + + +static void assert_run_work(uv_loop_t* const loop) { + uv_work_t work_req; + int r; + + ASSERT(work_cb_count == 0); + ASSERT(after_work_cb_count == 0); + printf("Queue in %d\n", getpid()); + r = uv_queue_work(loop, &work_req, work_cb, after_work_cb); + ASSERT(r == 0); + printf("Running in %d\n", getpid()); + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(work_cb_count == 1); + ASSERT(after_work_cb_count == 1); + + /* cleanup */ + work_cb_count = 0; + after_work_cb_count = 0; +} + + +TEST_IMPL(fork_threadpool_queue_work_simple) { + /* The threadpool works in a child process. */ + + pid_t child_pid; + uv_loop_t loop; + + /* Prime the pool and default loop. */ + assert_run_work(uv_default_loop()); + + child_pid = fork(); + ASSERT(child_pid != -1); + + if (child_pid != 0) { + /* parent */ + /* We can still run work. */ + assert_run_work(uv_default_loop()); + assert_wait_child(child_pid); + } else { + /* child */ + /* We can work in a new loop. */ + printf("Running child in %d\n", getpid()); + uv_loop_init(&loop); + printf("Child first watch\n"); + assert_run_work(&loop); + uv_loop_close(&loop); + printf("Child second watch default loop\n"); + /* We can work in the default loop. */ + ASSERT(0 == uv_loop_fork(uv_default_loop())); + assert_run_work(uv_default_loop()); + printf("Exiting child \n"); + } + + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +#endif /* !_WIN32 */ diff --git a/deps/uv/test/test-fs-event.c b/deps/uv/test/test-fs-event.c index df8dc4c2f700fd..fba6b5440b0fc3 100644 --- a/deps/uv/test/test-fs-event.c +++ b/deps/uv/test/test-fs-event.c @@ -394,8 +394,8 @@ static void timer_cb_watch_twice(uv_timer_t* handle) { } TEST_IMPL(fs_event_watch_dir) { -#if defined(__MVS__) - RETURN_SKIP("Filesystem watching not supported on this platform."); +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); #endif uv_loop_t* loop = uv_default_loop(); @@ -477,8 +477,8 @@ TEST_IMPL(fs_event_watch_dir_recursive) { TEST_IMPL(fs_event_watch_file) { -#if defined(__MVS__) - RETURN_SKIP("Filesystem watching not supported on this platform."); +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); #endif uv_loop_t* loop = uv_default_loop(); @@ -522,8 +522,8 @@ TEST_IMPL(fs_event_watch_file_exact_path) { "file.js". The test verifies that no events occur for file.jsx. */ -#if defined(__MVS__) - RETURN_SKIP("Filesystem watching not supported on this platform."); +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); #endif uv_loop_t* loop; @@ -561,8 +561,8 @@ TEST_IMPL(fs_event_watch_file_exact_path) { } TEST_IMPL(fs_event_watch_file_twice) { -#if defined(__MVS__) - RETURN_SKIP("Filesystem watching not supported on this platform."); +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); #endif const char path[] = "test/fixtures/empty_file"; uv_fs_event_t watchers[2]; @@ -585,8 +585,8 @@ TEST_IMPL(fs_event_watch_file_twice) { } TEST_IMPL(fs_event_watch_file_current_dir) { -#if defined(__MVS__) - RETURN_SKIP("Filesystem watching not supported on this platform."); +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); #endif uv_timer_t timer; uv_loop_t* loop; @@ -658,8 +658,8 @@ TEST_IMPL(fs_event_watch_file_root_dir) { #endif TEST_IMPL(fs_event_no_callback_after_close) { -#if defined(__MVS__) - RETURN_SKIP("Filesystem watching not supported on this platform."); +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); #endif uv_loop_t* loop = uv_default_loop(); @@ -696,8 +696,8 @@ TEST_IMPL(fs_event_no_callback_after_close) { } TEST_IMPL(fs_event_no_callback_on_close) { -#if defined(__MVS__) - RETURN_SKIP("Filesystem watching not supported on this platform."); +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); #endif uv_loop_t* loop = uv_default_loop(); @@ -747,8 +747,8 @@ static void timer_cb(uv_timer_t* handle) { TEST_IMPL(fs_event_immediate_close) { -#if defined(__MVS__) - RETURN_SKIP("Filesystem watching not supported on this platform."); +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); #endif uv_timer_t timer; uv_loop_t* loop; @@ -772,8 +772,8 @@ TEST_IMPL(fs_event_immediate_close) { TEST_IMPL(fs_event_close_with_pending_event) { -#if defined(__MVS__) - RETURN_SKIP("Filesystem watching not supported on this platform."); +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); #endif uv_loop_t* loop; int r; @@ -818,8 +818,8 @@ static void fs_event_cb_close(uv_fs_event_t* handle, const char* filename, } TEST_IMPL(fs_event_close_in_callback) { -#if defined(__MVS__) - RETURN_SKIP("Filesystem watching not supported on this platform."); +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); #endif uv_loop_t* loop; int r; @@ -857,8 +857,8 @@ TEST_IMPL(fs_event_close_in_callback) { } TEST_IMPL(fs_event_start_and_close) { -#if defined(__MVS__) - RETURN_SKIP("Filesystem watching not supported on this platform."); +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); #endif uv_loop_t* loop; uv_fs_event_t fs_event1; @@ -892,8 +892,8 @@ TEST_IMPL(fs_event_start_and_close) { } TEST_IMPL(fs_event_getpath) { -#if defined(__MVS__) - RETURN_SKIP("Filesystem watching not supported on this platform."); +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); #endif uv_loop_t* loop = uv_default_loop(); int r; @@ -1027,3 +1027,21 @@ TEST_IMPL(fs_event_error_reporting) { } #endif /* defined(__APPLE__) */ + +TEST_IMPL(fs_event_watch_invalid_path) { +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); +#endif + + uv_loop_t* loop; + int r; + + loop = uv_default_loop(); + r = uv_fs_event_init(loop, &fs_event); + ASSERT(r == 0); + r = uv_fs_event_start(&fs_event, fs_event_cb_file, "<:;", 0); + ASSERT(r != 0); + ASSERT(uv_is_active((uv_handle_t*) &fs_event) == 0); + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/deps/uv/test/test-fs.c b/deps/uv/test/test-fs.c index 030245eadc5389..c482ab5c71c06a 100644 --- a/deps/uv/test/test-fs.c +++ b/deps/uv/test/test-fs.c @@ -125,7 +125,7 @@ static void check_permission(const char* filename, unsigned int mode) { ASSERT(req.result == 0); s = &req.statbuf; -#ifdef _WIN32 +#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MSYS__) /* * On Windows, chmod can only modify S_IWUSR (_S_IWRITE) bit, * so only testing for the specified flags. @@ -240,7 +240,7 @@ static void chown_cb(uv_fs_t* req) { static void chown_root_cb(uv_fs_t* req) { ASSERT(req->fs_type == UV_FS_CHOWN); -#ifdef _WIN32 +#if defined(_WIN32) || defined(__MSYS__) /* On windows, chown is a no-op and always succeeds. */ ASSERT(req->result == 0); #else @@ -250,7 +250,12 @@ static void chown_root_cb(uv_fs_t* req) { if (geteuid() == 0) ASSERT(req->result == 0); else +# if defined(__CYGWIN__) + /* On Cygwin, uid 0 is invalid (no root). */ + ASSERT(req->result == UV_EINVAL); +# else ASSERT(req->result == UV_EPERM); +# endif #endif chown_cb_count++; uv_fs_req_cleanup(req); @@ -641,6 +646,11 @@ TEST_IMPL(fs_file_loop) { */ if (r == UV_ENOTSUP || r == UV_EPERM) return 0; +#elif defined(__MSYS__) + /* MSYS2's approximation of symlinks with copies does not work for broken + links. */ + if (r == UV_ENOENT) + return 0; #endif ASSERT(r == 0); uv_fs_req_cleanup(&req); @@ -1485,6 +1495,7 @@ TEST_IMPL(fs_chown) { /* chown to root (fail) */ chown_cb_count = 0; r = uv_fs_chown(loop, &req, "test_file", 0, 0, chown_root_cb); + ASSERT(r == 0); uv_run(loop, UV_RUN_DEFAULT); ASSERT(chown_cb_count == 1); @@ -1734,6 +1745,10 @@ TEST_IMPL(fs_symlink) { ASSERT(r == 0); uv_fs_req_cleanup(&req); +#if defined(__MSYS__) + RETURN_SKIP("symlink reading is not supported on MSYS2"); +#endif + r = uv_fs_readlink(NULL, &req, "test_file_symlink_symlink", NULL); ASSERT(r == 0); ASSERT(strcmp(req.ptr, "test_file_symlink") == 0); @@ -1877,6 +1892,9 @@ TEST_IMPL(fs_symlink_dir) { r = uv_fs_lstat(NULL, &req, "test_dir_symlink", NULL); ASSERT(r == 0); +#if defined(__MSYS__) + RETURN_SKIP("symlink reading is not supported on MSYS2"); +#endif ASSERT(((uv_stat_t*)req.ptr)->st_mode & S_IFLNK); #ifdef _WIN32 ASSERT(((uv_stat_t*)req.ptr)->st_size == strlen(test_dir + 4)); @@ -2102,8 +2120,13 @@ TEST_IMPL(fs_futime) { uv_fs_req_cleanup(&req); r = uv_fs_futime(NULL, &req, file, atime, mtime, NULL); +#if defined(__CYGWIN__) || defined(__MSYS__) + ASSERT(r == UV_ENOSYS); + RETURN_SKIP("futime not supported on Cygwin"); +#else ASSERT(r == 0); ASSERT(req.result == 0); +#endif uv_fs_req_cleanup(&req); r = uv_fs_stat(NULL, &req, path, NULL); @@ -2412,6 +2435,9 @@ TEST_IMPL(fs_rename_to_existing_file) { TEST_IMPL(fs_read_file_eof) { +#if defined(__CYGWIN__) || defined(__MSYS__) + RETURN_SKIP("Cygwin pread at EOF may (incorrectly) return data!"); +#endif int r; /* Setup. */ @@ -2739,3 +2765,42 @@ TEST_IMPL(fs_read_write_null_arguments) { return 0; } + + +TEST_IMPL(get_osfhandle_valid_handle) { + int r; + uv_os_fd_t fd; + + /* Setup. */ + unlink("test_file"); + + loop = uv_default_loop(); + + r = uv_fs_open(NULL, + &open_req1, + "test_file", + O_RDWR | O_CREAT, + S_IWUSR | S_IRUSR, + NULL); + ASSERT(r >= 0); + ASSERT(open_req1.result >= 0); + uv_fs_req_cleanup(&open_req1); + + fd = uv_get_osfhandle(open_req1.result); +#ifdef _WIN32 + ASSERT(fd != INVALID_HANDLE_VALUE); +#else + ASSERT(fd >= 0); +#endif + + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); + + /* Cleanup. */ + unlink("test_file"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/deps/uv/test/test-gethostname.c b/deps/uv/test/test-gethostname.c new file mode 100644 index 00000000000000..5229804b569421 --- /dev/null +++ b/deps/uv/test/test-gethostname.c @@ -0,0 +1,62 @@ +/* Copyright libuv 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. + */ + +#include "uv.h" +#include "task.h" +#include + +#ifndef MAXHOSTNAMELEN +# define MAXHOSTNAMELEN 256 +#endif + +TEST_IMPL(gethostname) { + char buf[MAXHOSTNAMELEN + 1]; + size_t size; + size_t enobufs_size; + int r; + + /* Reject invalid inputs */ + size = 1; + r = uv_os_gethostname(NULL, &size); + ASSERT(r == UV_EINVAL); + r = uv_os_gethostname(buf, NULL); + ASSERT(r == UV_EINVAL); + size = 0; + r = uv_os_gethostname(buf, &size); + ASSERT(r == UV_EINVAL); + + /* Return UV_ENOBUFS if the buffer cannot hold the hostname */ + enobufs_size = 1; + buf[0] = '\0'; + r = uv_os_gethostname(buf, &enobufs_size); + ASSERT(r == UV_ENOBUFS); + ASSERT(buf[0] == '\0'); + ASSERT(enobufs_size > 1); + + /* Successfully get the hostname */ + size = MAXHOSTNAMELEN + 1; + r = uv_os_gethostname(buf, &size); + ASSERT(r == 0); + ASSERT(size > 1 && size == strlen(buf)); + ASSERT(size + 1 == enobufs_size); + + return 0; +} diff --git a/deps/uv/test/test-ip6-addr.c b/deps/uv/test/test-ip6-addr.c index 869b099e0fccaf..156fccde39deb6 100644 --- a/deps/uv/test/test-ip6-addr.c +++ b/deps/uv/test/test-ip6-addr.c @@ -32,6 +32,10 @@ TEST_IMPL(ip6_addr_link_local) { +#if defined(__CYGWIN__) || defined(__MSYS__) + /* FIXME: Does Cygwin support this? */ + RETURN_SKIP("FIXME: This test needs more investigation on Cygwin"); +#endif char string_address[INET6_ADDRSTRLEN]; uv_interface_address_t* addresses; uv_interface_address_t* address; diff --git a/deps/uv/test/test-ipc-send-recv.c b/deps/uv/test/test-ipc-send-recv.c index 133ae901493728..160c235078b939 100644 --- a/deps/uv/test/test-ipc-send-recv.c +++ b/deps/uv/test/test-ipc-send-recv.c @@ -224,10 +224,16 @@ static int run_ipc_send_recv_pipe(int inprocess) { } TEST_IMPL(ipc_send_recv_pipe) { +#if defined(NO_SEND_HANDLE_ON_PIPE) + RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE); +#endif return run_ipc_send_recv_pipe(0); } TEST_IMPL(ipc_send_recv_pipe_inprocess) { +#if defined(NO_SEND_HANDLE_ON_PIPE) + RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE); +#endif return run_ipc_send_recv_pipe(1); } @@ -259,10 +265,16 @@ static int run_ipc_send_recv_tcp(int inprocess) { } TEST_IMPL(ipc_send_recv_tcp) { +#if defined(NO_SEND_HANDLE_ON_PIPE) + RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE); +#endif return run_ipc_send_recv_tcp(0); } TEST_IMPL(ipc_send_recv_tcp_inprocess) { +#if defined(NO_SEND_HANDLE_ON_PIPE) + RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE); +#endif return run_ipc_send_recv_tcp(1); } @@ -335,7 +347,7 @@ static void read_cb(uv_stream_t* handle, } while (uv_pipe_pending_count(pipe) > 0); } -static void send_recv_start() { +static void send_recv_start(void) { int r; ASSERT(1 == uv_is_readable((uv_stream_t*)&ctx2.channel)); ASSERT(1 == uv_is_writable((uv_stream_t*)&ctx2.channel)); diff --git a/deps/uv/test/test-ipc.c b/deps/uv/test/test-ipc.c index f018c2d4d49b7f..a2fda2458546ba 100644 --- a/deps/uv/test/test-ipc.c +++ b/deps/uv/test/test-ipc.c @@ -411,6 +411,9 @@ static int run_ipc_test(const char* helper, uv_read_cb read_cb) { TEST_IMPL(ipc_listen_before_write) { +#if defined(NO_SEND_HANDLE_ON_PIPE) + RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE); +#endif int r = run_ipc_test("ipc_helper_listen_before_write", on_read); ASSERT(local_conn_accepted == 1); ASSERT(remote_conn_accepted == 1); @@ -421,6 +424,9 @@ TEST_IMPL(ipc_listen_before_write) { TEST_IMPL(ipc_listen_after_write) { +#if defined(NO_SEND_HANDLE_ON_PIPE) + RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE); +#endif int r = run_ipc_test("ipc_helper_listen_after_write", on_read); ASSERT(local_conn_accepted == 1); ASSERT(remote_conn_accepted == 1); @@ -431,6 +437,9 @@ TEST_IMPL(ipc_listen_after_write) { TEST_IMPL(ipc_tcp_connection) { +#if defined(NO_SEND_HANDLE_ON_PIPE) + RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE); +#endif int r = run_ipc_test("ipc_helper_tcp_connection", on_read_connection); ASSERT(read_cb_called == 1); ASSERT(tcp_write_cb_called == 1); @@ -491,6 +500,9 @@ TEST_IMPL(listen_no_simultaneous_accepts) { } TEST_IMPL(ipc_listen_after_bind_twice) { +#if defined(NO_SEND_HANDLE_ON_PIPE) + RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE); +#endif int r = run_ipc_test("ipc_helper_bind_twice", on_read_listen_after_bound_twice); ASSERT(read_cb_called == 2); ASSERT(exit_cb_called == 1); diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h index 3a1e82a919186b..3571aa2308397f 100644 --- a/deps/uv/test/test-list.h +++ b/deps/uv/test/test-list.h @@ -116,6 +116,7 @@ TEST_DECLARE (udp_create_early) TEST_DECLARE (udp_create_early_bad_bind) TEST_DECLARE (udp_create_early_bad_domain) TEST_DECLARE (udp_send_and_recv) +TEST_DECLARE (udp_send_hang_loop) TEST_DECLARE (udp_send_immediate) TEST_DECLARE (udp_send_unreachable) TEST_DECLARE (udp_multicast_join) @@ -153,6 +154,7 @@ TEST_DECLARE (shutdown_close_pipe) TEST_DECLARE (shutdown_eof) TEST_DECLARE (shutdown_twice) TEST_DECLARE (callback_stack) +TEST_DECLARE (env_vars) TEST_DECLARE (error_message) TEST_DECLARE (sys_error) TEST_DECLARE (timer) @@ -218,6 +220,7 @@ TEST_DECLARE (getaddrinfo_fail_sync) TEST_DECLARE (getaddrinfo_basic) TEST_DECLARE (getaddrinfo_basic_sync) TEST_DECLARE (getaddrinfo_concurrent) +TEST_DECLARE (gethostname) TEST_DECLARE (getnameinfo_basic_ip4) TEST_DECLARE (getnameinfo_basic_ip4_sync) TEST_DECLARE (getnameinfo_basic_ip6) @@ -286,6 +289,7 @@ TEST_DECLARE (fs_event_watch_file_current_dir) #ifdef _WIN32 TEST_DECLARE (fs_event_watch_file_root_dir) #endif +TEST_DECLARE (fs_event_watch_invalid_path) TEST_DECLARE (fs_event_no_callback_after_close) TEST_DECLARE (fs_event_no_callback_on_close) TEST_DECLARE (fs_event_immediate_close) @@ -301,6 +305,7 @@ TEST_DECLARE (fs_open_dir) TEST_DECLARE (fs_rename_to_existing_file) TEST_DECLARE (fs_write_multiple_bufs) TEST_DECLARE (fs_read_write_null_arguments) +TEST_DECLARE (get_osfhandle_valid_handle) TEST_DECLARE (fs_write_alotof_bufs) TEST_DECLARE (fs_write_alotof_bufs_with_offset) TEST_DECLARE (threadpool_queue_work_simple) @@ -354,6 +359,8 @@ TEST_DECLARE (spawn_fs_open) TEST_DECLARE (spawn_setuid_setgid) TEST_DECLARE (we_get_signal) TEST_DECLARE (we_get_signals) +TEST_DECLARE (we_get_signal_one_shot) +TEST_DECLARE (we_get_signals_mixed) TEST_DECLARE (signal_multiple_loops) TEST_DECLARE (closed_fd_events) #endif @@ -368,6 +375,18 @@ HELPER_DECLARE (pipe_echo_server) TEST_DECLARE (queue_foreach_delete) +#ifndef _WIN32 +TEST_DECLARE (fork_timer) +TEST_DECLARE (fork_socketpair) +TEST_DECLARE (fork_socketpair_started) +TEST_DECLARE (fork_signal_to_child) +TEST_DECLARE (fork_signal_to_child_closed) +TEST_DECLARE (fork_fs_events_child) +TEST_DECLARE (fork_fs_events_child_dir) +TEST_DECLARE (fork_fs_events_file_parent_child) +TEST_DECLARE (fork_threadpool_queue_work_simple) +#endif + TASK_LIST_START TEST_ENTRY_CUSTOM (platform_output, 0, 1, 5000) @@ -443,7 +462,11 @@ TASK_LIST_START TEST_ENTRY (tcp_write_after_connect) #endif +#ifdef __MVS__ + TEST_ENTRY_CUSTOM (tcp_writealot, 0, 0, 20000) +#else TEST_ENTRY (tcp_writealot) +#endif TEST_HELPER (tcp_writealot, tcp4_echo_server) TEST_ENTRY (tcp_write_fail) @@ -501,6 +524,7 @@ TASK_LIST_START TEST_ENTRY (udp_create_early_bad_bind) TEST_ENTRY (udp_create_early_bad_domain) TEST_ENTRY (udp_send_and_recv) + TEST_ENTRY (udp_send_hang_loop) TEST_ENTRY (udp_send_immediate) TEST_ENTRY (udp_send_unreachable) TEST_ENTRY (udp_dgram_too_big) @@ -548,6 +572,8 @@ TASK_LIST_START TEST_ENTRY (callback_stack) TEST_HELPER (callback_stack, tcp4_echo_server) + TEST_ENTRY (env_vars) + TEST_ENTRY (error_message) TEST_ENTRY (sys_error) @@ -635,6 +661,8 @@ TASK_LIST_START TEST_ENTRY (getaddrinfo_basic_sync) TEST_ENTRY (getaddrinfo_concurrent) + TEST_ENTRY (gethostname) + TEST_ENTRY (getnameinfo_basic_ip4) TEST_ENTRY (getnameinfo_basic_ip4_sync) TEST_ENTRY (getnameinfo_basic_ip6) @@ -704,6 +732,8 @@ TASK_LIST_START TEST_ENTRY (spawn_setuid_setgid) TEST_ENTRY (we_get_signal) TEST_ENTRY (we_get_signals) + TEST_ENTRY (we_get_signal_one_shot) + TEST_ENTRY (we_get_signals_mixed) TEST_ENTRY (signal_multiple_loops) TEST_ENTRY (closed_fd_events) #endif @@ -745,6 +775,7 @@ TASK_LIST_START #ifdef _WIN32 TEST_ENTRY (fs_event_watch_file_root_dir) #endif + TEST_ENTRY (fs_event_watch_invalid_path) TEST_ENTRY (fs_event_no_callback_after_close) TEST_ENTRY (fs_event_no_callback_on_close) TEST_ENTRY (fs_event_immediate_close) @@ -762,6 +793,7 @@ TASK_LIST_START TEST_ENTRY (fs_write_alotof_bufs) TEST_ENTRY (fs_write_alotof_bufs_with_offset) TEST_ENTRY (fs_read_write_null_arguments) + TEST_ENTRY (get_osfhandle_valid_handle) TEST_ENTRY (threadpool_queue_work_simple) TEST_ENTRY (threadpool_queue_work_einval) #if defined(__PPC__) || defined(__PPC64__) /* For linux PPC and AIX */ @@ -790,6 +822,18 @@ TASK_LIST_START TEST_ENTRY (queue_foreach_delete) +#ifndef _WIN32 + TEST_ENTRY (fork_timer) + TEST_ENTRY (fork_socketpair) + TEST_ENTRY (fork_socketpair_started) + TEST_ENTRY (fork_signal_to_child) + TEST_ENTRY (fork_signal_to_child_closed) + TEST_ENTRY (fork_fs_events_child) + TEST_ENTRY (fork_fs_events_child_dir) + TEST_ENTRY (fork_fs_events_file_parent_child) + TEST_ENTRY (fork_threadpool_queue_work_simple) +#endif + #if 0 /* These are for testing the test runner. */ TEST_ENTRY (fail_always) diff --git a/deps/uv/test/test-ping-pong.c b/deps/uv/test/test-ping-pong.c index c074178541b0a3..bdc967151ed8f2 100644 --- a/deps/uv/test/test-ping-pong.c +++ b/deps/uv/test/test-ping-pong.c @@ -27,7 +27,11 @@ static int completed_pingers = 0; +#if defined(__CYGWIN__) || defined(__MSYS__) +#define NUM_PINGS 100 /* fewer pings to avoid timeout */ +#else #define NUM_PINGS 1000 +#endif /* 64 bytes is enough for a pinger */ #define BUFSIZE 10240 diff --git a/deps/uv/test/test-pipe-bind-error.c b/deps/uv/test/test-pipe-bind-error.c index 38b57db6991fbc..9cf93165e41301 100644 --- a/deps/uv/test/test-pipe-bind-error.c +++ b/deps/uv/test/test-pipe-bind-error.c @@ -116,6 +116,9 @@ TEST_IMPL(pipe_bind_error_inval) { TEST_IMPL(pipe_listen_without_bind) { +#if defined(NO_SELF_CONNECT) + RETURN_SKIP(NO_SELF_CONNECT); +#endif uv_pipe_t server; int r; diff --git a/deps/uv/test/test-pipe-connect-multiple.c b/deps/uv/test/test-pipe-connect-multiple.c index 3de5a9a0bf4e83..0a60d4a9642433 100644 --- a/deps/uv/test/test-pipe-connect-multiple.c +++ b/deps/uv/test/test-pipe-connect-multiple.c @@ -70,6 +70,9 @@ static void connect_cb(uv_connect_t* connect_req, int status) { TEST_IMPL(pipe_connect_multiple) { +#if defined(NO_SELF_CONNECT) + RETURN_SKIP(NO_SELF_CONNECT); +#endif int i; int r; uv_loop_t* loop; diff --git a/deps/uv/test/test-pipe-getsockname.c b/deps/uv/test/test-pipe-getsockname.c index 4b4ceccc45ced5..d1628a67d5d032 100644 --- a/deps/uv/test/test-pipe-getsockname.c +++ b/deps/uv/test/test-pipe-getsockname.c @@ -87,6 +87,9 @@ static void pipe_server_connection_cb(uv_stream_t* handle, int status) { TEST_IMPL(pipe_getsockname) { +#if defined(NO_SELF_CONNECT) + RETURN_SKIP(NO_SELF_CONNECT); +#endif uv_loop_t* loop; char buf[1024]; size_t len; diff --git a/deps/uv/test/test-pipe-sendmsg.c b/deps/uv/test/test-pipe-sendmsg.c index f6d893b449433a..3bf427f8aa0634 100644 --- a/deps/uv/test/test-pipe-sendmsg.c +++ b/deps/uv/test/test-pipe-sendmsg.c @@ -102,6 +102,9 @@ static void read_cb(uv_stream_t* handle, TEST_IMPL(pipe_sendmsg) { +#if defined(NO_SEND_HANDLE_ON_PIPE) + RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE); +#endif uv_pipe_t p; int r; int fds[2]; diff --git a/deps/uv/test/test-pipe-server-close.c b/deps/uv/test/test-pipe-server-close.c index 1dcdfffaf7cb2d..ea9977dd843e2a 100644 --- a/deps/uv/test/test-pipe-server-close.c +++ b/deps/uv/test/test-pipe-server-close.c @@ -61,6 +61,9 @@ static void pipe_server_connection_cb(uv_stream_t* handle, int status) { TEST_IMPL(pipe_server_close) { +#if defined(NO_SELF_CONNECT) + RETURN_SKIP(NO_SELF_CONNECT); +#endif uv_loop_t* loop; int r; diff --git a/deps/uv/test/test-platform-output.c b/deps/uv/test/test-platform-output.c index b8955080104756..72c176edc459fb 100644 --- a/deps/uv/test/test-platform-output.c +++ b/deps/uv/test/test-platform-output.c @@ -47,8 +47,12 @@ TEST_IMPL(platform_output) { printf("uv_cwd: %s\n", buffer); err = uv_resident_set_memory(&rss); +#if defined(__CYGWIN__) || defined(__MSYS__) + ASSERT(err == UV_ENOSYS); +#else ASSERT(err == 0); printf("uv_resident_set_memory: %llu\n", (unsigned long long) rss); +#endif err = uv_uptime(&uptime); ASSERT(err == 0); @@ -73,6 +77,9 @@ TEST_IMPL(platform_output) { (unsigned long long) rusage.ru_maxrss); err = uv_cpu_info(&cpus, &count); +#if defined(__CYGWIN__) || defined(__MSYS__) + ASSERT(err == UV_ENOSYS); +#else ASSERT(err == 0); printf("uv_cpu_info:\n"); @@ -88,6 +95,7 @@ TEST_IMPL(platform_output) { printf(" times.nice: %llu\n", (unsigned long long) cpus[i].cpu_times.nice); } +#endif uv_free_cpu_info(cpus, count); err = uv_interface_addresses(&interfaces, &count); diff --git a/deps/uv/test/test-poll.c b/deps/uv/test/test-poll.c index 6c1f98b7eff552..7cfc159a2b3d03 100644 --- a/deps/uv/test/test-poll.c +++ b/deps/uv/test/test-poll.c @@ -574,6 +574,9 @@ static void start_poll_test(void) { TEST_IMPL(poll_duplex) { +#if defined(NO_SELF_CONNECT) + RETURN_SKIP(NO_SELF_CONNECT); +#endif test_mode = DUPLEX; start_poll_test(); return 0; @@ -581,6 +584,9 @@ TEST_IMPL(poll_duplex) { TEST_IMPL(poll_unidirectional) { +#if defined(NO_SELF_CONNECT) + RETURN_SKIP(NO_SELF_CONNECT); +#endif test_mode = UNIDIRECTIONAL; start_poll_test(); return 0; @@ -594,7 +600,8 @@ TEST_IMPL(poll_unidirectional) { */ TEST_IMPL(poll_bad_fdtype) { #if !defined(__DragonFly__) && !defined(__FreeBSD__) && !defined(__sun) && \ - !defined(_AIX) && !defined(__MVS__) && !defined(__FreeBSD_kernel__) + !defined(_AIX) && !defined(__MVS__) && !defined(__FreeBSD_kernel__) && \ + !defined(__OpenBSD__) && !defined(__CYGWIN__) && !defined(__MSYS__) uv_poll_t poll_handle; int fd; diff --git a/deps/uv/test/test-process-title.c b/deps/uv/test/test-process-title.c index 5d5ede9d60291c..886f83a7d30fe1 100644 --- a/deps/uv/test/test-process-title.c +++ b/deps/uv/test/test-process-title.c @@ -41,7 +41,7 @@ static void set_title(const char* title) { } -static void uv_get_process_title_edge_cases() { +static void uv_get_process_title_edge_cases(void) { char buffer[512]; int r; @@ -60,7 +60,7 @@ static void uv_get_process_title_edge_cases() { TEST_IMPL(process_title) { -#if defined(__sun) +#if defined(__sun) || defined(__CYGWIN__) || defined(__MSYS__) RETURN_SKIP("uv_(get|set)_process_title is not implemented."); #else /* Check for format string vulnerabilities. */ diff --git a/deps/uv/test/test-ref.c b/deps/uv/test/test-ref.c index 39f4b0fc739174..05728c83365bfe 100644 --- a/deps/uv/test/test-ref.c +++ b/deps/uv/test/test-ref.c @@ -194,8 +194,8 @@ TEST_IMPL(timer_ref2) { TEST_IMPL(fs_event_ref) { -#if defined(__MVS__) - RETURN_SKIP("Filesystem watching not supported on this platform."); +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); #endif uv_fs_event_t h; uv_fs_event_init(uv_default_loop(), &h); diff --git a/deps/uv/test/test-shutdown-twice.c b/deps/uv/test/test-shutdown-twice.c index 75c054354995b3..d7aae89914dad6 100644 --- a/deps/uv/test/test-shutdown-twice.c +++ b/deps/uv/test/test-shutdown-twice.c @@ -67,6 +67,7 @@ TEST_IMPL(shutdown_twice) { loop = uv_default_loop(); r = uv_tcp_init(loop, &h); + ASSERT(r == 0); r = uv_tcp_connect(&connect_req, &h, diff --git a/deps/uv/test/test-signal-multiple-loops.c b/deps/uv/test/test-signal-multiple-loops.c index 158129919bd772..11193dcf50b227 100644 --- a/deps/uv/test/test-signal-multiple-loops.c +++ b/deps/uv/test/test-signal-multiple-loops.c @@ -193,6 +193,13 @@ static void loop_creating_worker(void* context) { TEST_IMPL(signal_multiple_loops) { +#if defined(__CYGWIN__) || defined(__MSYS__) + /* FIXME: This test needs more investigation. Somehow the `read` in + uv__signal_lock fails spuriously with EACCES or even EAGAIN even + though it is supposed to be blocking. Also the test hangs during + thread setup occasionally. */ + RETURN_SKIP("FIXME: This test needs more investigation on Cygwin"); +#endif uv_thread_t loop_creating_threads[NUM_LOOP_CREATING_THREADS]; uv_thread_t signal_handling_threads[NUM_SIGNAL_HANDLING_THREADS]; enum signal_action action; diff --git a/deps/uv/test/test-signal.c b/deps/uv/test/test-signal.c index c0424c60a0995e..9a881510c72151 100644 --- a/deps/uv/test/test-signal.c +++ b/deps/uv/test/test-signal.c @@ -70,17 +70,17 @@ struct timer_ctx { }; struct signal_ctx { - enum { CLOSE, STOP } stop_or_close; + enum { CLOSE, STOP, NOOP } stop_or_close; unsigned int ncalls; uv_signal_t handle; int signum; + int one_shot; }; static void signal_cb(uv_signal_t* handle, int signum) { struct signal_ctx* ctx = container_of(handle, struct signal_ctx, handle); ASSERT(signum == ctx->signum); - if (++ctx->ncalls == NSIGNALS) { if (ctx->stop_or_close == STOP) uv_signal_stop(handle); @@ -91,6 +91,14 @@ static void signal_cb(uv_signal_t* handle, int signum) { } } +static void signal_cb_one_shot(uv_signal_t* handle, int signum) { + struct signal_ctx* ctx = container_of(handle, struct signal_ctx, handle); + ASSERT(signum == ctx->signum); + ASSERT(++ctx->ncalls == 1); + if (ctx->stop_or_close == CLOSE) + uv_close((uv_handle_t*)handle, NULL); +} + static void timer_cb(uv_timer_t* handle) { struct timer_ctx* ctx = container_of(handle, struct timer_ctx, handle); @@ -102,15 +110,21 @@ static void timer_cb(uv_timer_t* handle) { } -static void start_watcher(uv_loop_t* loop, int signum, struct signal_ctx* ctx) { +static void start_watcher(uv_loop_t* loop, + int signum, + struct signal_ctx* ctx, + int one_shot) { ctx->ncalls = 0; ctx->signum = signum; ctx->stop_or_close = CLOSE; + ctx->one_shot = one_shot; ASSERT(0 == uv_signal_init(loop, &ctx->handle)); - ASSERT(0 == uv_signal_start(&ctx->handle, signal_cb, signum)); + if (one_shot) + ASSERT(0 == uv_signal_start_oneshot(&ctx->handle, signal_cb_one_shot, signum)); + else + ASSERT(0 == uv_signal_start(&ctx->handle, signal_cb, signum)); } - static void start_timer(uv_loop_t* loop, int signum, struct timer_ctx* ctx) { ctx->ncalls = 0; ctx->signum = signum; @@ -126,7 +140,7 @@ TEST_IMPL(we_get_signal) { loop = uv_default_loop(); start_timer(loop, SIGCHLD, &tc); - start_watcher(loop, SIGCHLD, &sc); + start_watcher(loop, SIGCHLD, &sc, 0); sc.stop_or_close = STOP; /* stop, don't close the signal handle */ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); ASSERT(tc.ncalls == NSIGNALS); @@ -158,10 +172,10 @@ TEST_IMPL(we_get_signals) { unsigned int i; loop = uv_default_loop(); - start_watcher(loop, SIGUSR1, sc + 0); - start_watcher(loop, SIGUSR1, sc + 1); - start_watcher(loop, SIGUSR2, sc + 2); - start_watcher(loop, SIGUSR2, sc + 3); + start_watcher(loop, SIGUSR1, sc + 0, 0); + start_watcher(loop, SIGUSR1, sc + 1, 0); + start_watcher(loop, SIGUSR2, sc + 2, 0); + start_watcher(loop, SIGUSR2, sc + 3, 0); start_timer(loop, SIGUSR1, tc + 0); start_timer(loop, SIGUSR2, tc + 1); ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); @@ -176,4 +190,116 @@ TEST_IMPL(we_get_signals) { return 0; } +TEST_IMPL(we_get_signal_one_shot) { + struct signal_ctx sc; + struct timer_ctx tc; + uv_loop_t* loop; + + loop = uv_default_loop(); + start_timer(loop, SIGCHLD, &tc); + start_watcher(loop, SIGCHLD, &sc, 1); + sc.stop_or_close = NOOP; + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(tc.ncalls == NSIGNALS); + ASSERT(sc.ncalls == 1); + + start_timer(loop, SIGCHLD, &tc); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(sc.ncalls == 1); + + sc.ncalls = 0; + sc.stop_or_close = CLOSE; /* now close it when it's done */ + uv_signal_start_oneshot(&sc.handle, signal_cb_one_shot, SIGCHLD); + start_timer(loop, SIGCHLD, &tc); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(tc.ncalls == NSIGNALS); + ASSERT(sc.ncalls == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(we_get_signals_mixed) { + struct signal_ctx sc[4]; + struct timer_ctx tc; + uv_loop_t* loop; + + loop = uv_default_loop(); + + /* 2 one-shot */ + start_timer(loop, SIGCHLD, &tc); + start_watcher(loop, SIGCHLD, sc + 0, 1); + start_watcher(loop, SIGCHLD, sc + 1, 1); + sc[0].stop_or_close = CLOSE; + sc[1].stop_or_close = CLOSE; + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(tc.ncalls == NSIGNALS); + ASSERT(sc[0].ncalls == 1); + ASSERT(sc[1].ncalls == 1); + + /* 2 one-shot, 1 normal then remove normal */ + start_timer(loop, SIGCHLD, &tc); + start_watcher(loop, SIGCHLD, sc + 0, 1); + start_watcher(loop, SIGCHLD, sc + 1, 1); + sc[0].stop_or_close = CLOSE; + sc[1].stop_or_close = CLOSE; + start_watcher(loop, SIGCHLD, sc + 2, 0); + uv_close((uv_handle_t*)&(sc[2]).handle, NULL); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(tc.ncalls == NSIGNALS); + ASSERT(sc[0].ncalls == 1); + ASSERT(sc[1].ncalls == 1); + ASSERT(sc[2].ncalls == 0); + + /* 2 normal, 1 one-shot then remove one-shot */ + start_timer(loop, SIGCHLD, &tc); + start_watcher(loop, SIGCHLD, sc + 0, 0); + start_watcher(loop, SIGCHLD, sc + 1, 0); + sc[0].stop_or_close = CLOSE; + sc[1].stop_or_close = CLOSE; + start_watcher(loop, SIGCHLD, sc + 2, 1); + uv_close((uv_handle_t*)&(sc[2]).handle, NULL); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(tc.ncalls == NSIGNALS); + ASSERT(sc[0].ncalls == NSIGNALS); + ASSERT(sc[1].ncalls == NSIGNALS); + ASSERT(sc[2].ncalls == 0); + + /* 2 normal, 2 one-shot then remove 2 normal */ + start_timer(loop, SIGCHLD, &tc); + start_watcher(loop, SIGCHLD, sc + 0, 0); + start_watcher(loop, SIGCHLD, sc + 1, 0); + start_watcher(loop, SIGCHLD, sc + 2, 1); + start_watcher(loop, SIGCHLD, sc + 3, 1); + sc[2].stop_or_close = CLOSE; + sc[3].stop_or_close = CLOSE; + uv_close((uv_handle_t*)&(sc[0]).handle, NULL); + uv_close((uv_handle_t*)&(sc[1]).handle, NULL); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(tc.ncalls == NSIGNALS); + ASSERT(sc[0].ncalls == 0); + ASSERT(sc[1].ncalls == 0); + ASSERT(sc[2].ncalls == 1); + ASSERT(sc[2].ncalls == 1); + + /* 1 normal, 1 one-shot, 2 normal then remove 1st normal, 2nd normal */ + start_timer(loop, SIGCHLD, &tc); + start_watcher(loop, SIGCHLD, sc + 0, 0); + start_watcher(loop, SIGCHLD, sc + 1, 1); + start_watcher(loop, SIGCHLD, sc + 2, 0); + start_watcher(loop, SIGCHLD, sc + 3, 0); + sc[3].stop_or_close = CLOSE; + uv_close((uv_handle_t*)&(sc[0]).handle, NULL); + uv_close((uv_handle_t*)&(sc[2]).handle, NULL); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(tc.ncalls == NSIGNALS); + ASSERT(sc[0].ncalls == 0); + ASSERT(sc[1].ncalls == 1); + ASSERT(sc[2].ncalls == 0); + ASSERT(sc[3].ncalls == NSIGNALS); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + #endif /* _WIN32 */ diff --git a/deps/uv/test/test-spawn.c b/deps/uv/test/test-spawn.c index 53a036969b6252..52fc7f6cc5e95d 100644 --- a/deps/uv/test/test-spawn.c +++ b/deps/uv/test/test-spawn.c @@ -90,7 +90,16 @@ static void kill_cb(uv_process_t* process, #else ASSERT(exit_status == 0); #endif - ASSERT(no_term_signal || term_signal == 15); +#if defined(__APPLE__) + /* + * At least starting with Darwin Kernel Version 16.4.0, sending a SIGTERM to a + * process that is still starting up kills it with SIGKILL instead of SIGTERM. + * See: https://github.com/libuv/libuv/issues/1226 + */ + ASSERT(no_term_signal || term_signal == SIGTERM || term_signal == SIGKILL); +#else + ASSERT(no_term_signal || term_signal == SIGTERM); +#endif uv_close((uv_handle_t*)process, close_cb); /* @@ -1288,7 +1297,11 @@ TEST_IMPL(spawn_setuid_fails) { options.uid = 0; r = uv_spawn(uv_default_loop(), &process, &options); +#if defined(__CYGWIN__) + ASSERT(r == UV_EINVAL); +#else ASSERT(r == UV_EPERM); +#endif r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); ASSERT(r == 0); @@ -1319,7 +1332,11 @@ TEST_IMPL(spawn_setgid_fails) { options.gid = 0; r = uv_spawn(uv_default_loop(), &process, &options); +#if defined(__CYGWIN__) + ASSERT(r == UV_EINVAL); +#else ASSERT(r == UV_EPERM); +#endif r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); ASSERT(r == 0); @@ -1528,6 +1545,17 @@ TEST_IMPL(spawn_reads_child_path) { exepath[len] = 0; strcpy(path, "PATH="); strcpy(path + 5, exepath); +#if defined(__CYGWIN__) || defined(__MSYS__) + /* Carry over the dynamic linker path in case the test runner + is linked against cyguv-1.dll or msys-uv-1.dll, see above. */ + { + char* syspath = getenv("PATH"); + if (syspath != NULL) { + strcat(path, ":"); + strcat(path, syspath); + } + } +#endif env[0] = path; env[1] = getenv(dyld_path_var); diff --git a/deps/uv/test/test-tcp-create-socket-early.c b/deps/uv/test/test-tcp-create-socket-early.c index 1a508e474aa700..b87e7324184be1 100644 --- a/deps/uv/test/test-tcp-create-socket-early.c +++ b/deps/uv/test/test-tcp-create-socket-early.c @@ -164,7 +164,7 @@ TEST_IMPL(tcp_create_early_bad_bind) { #endif r = uv_tcp_bind(&client, (const struct sockaddr*) &addr, 0); -#ifndef _WIN32 +#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(__MSYS__) ASSERT(r == UV_EINVAL); #else ASSERT(r == UV_EFAULT); diff --git a/deps/uv/test/test-tcp-write-queue-order.c b/deps/uv/test/test-tcp-write-queue-order.c index d50289c3c26fe1..5119be6d330932 100644 --- a/deps/uv/test/test-tcp-write-queue-order.c +++ b/deps/uv/test/test-tcp-write-queue-order.c @@ -89,6 +89,9 @@ static void connection_cb(uv_stream_t* tcp, int status) { ASSERT(0 == uv_tcp_init(tcp->loop, &incoming)); ASSERT(0 == uv_accept(tcp, (uv_stream_t*) &incoming)); + ASSERT(0 == uv_timer_init(uv_default_loop(), &timer)); + ASSERT(0 == uv_timer_start(&timer, timer_cb, 1, 0)); + connection_cb_called++; } @@ -120,9 +123,6 @@ TEST_IMPL(tcp_write_queue_order) { connect_cb)); ASSERT(0 == uv_send_buffer_size((uv_handle_t*) &client, &buffer_size)); - ASSERT(0 == uv_timer_init(uv_default_loop(), &timer)); - ASSERT(0 == uv_timer_start(&timer, timer_cb, 100, 0)); - ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); ASSERT(connect_cb_called == 1); diff --git a/deps/uv/test/test-threadpool-cancel.c b/deps/uv/test/test-threadpool-cancel.c index 917f5f475160aa..dd13d8ae4bf1fa 100644 --- a/deps/uv/test/test-threadpool-cancel.c +++ b/deps/uv/test/test-threadpool-cancel.c @@ -60,7 +60,10 @@ static void saturate_threadpool(void) { char buf[64]; size_t i; - snprintf(buf, sizeof(buf), "UV_THREADPOOL_SIZE=%zu", ARRAY_SIZE(pause_reqs)); + snprintf(buf, + sizeof(buf), + "UV_THREADPOOL_SIZE=%lu", + (unsigned long)ARRAY_SIZE(pause_reqs)); putenv(buf); loop = uv_default_loop(); diff --git a/deps/uv/test/test-tty.c b/deps/uv/test/test-tty.c index 6fc2c95c98590c..e761822fa349fc 100644 --- a/deps/uv/test/test-tty.c +++ b/deps/uv/test/test-tty.c @@ -244,7 +244,7 @@ TEST_IMPL(tty_empty_write) { ASSERT(r == 0); bufs[0].len = 0; - bufs[0].base = &dummy; + bufs[0].base = &dummy[0]; r = uv_try_write((uv_stream_t*) &tty_out, bufs, 1); ASSERT(r == 0); diff --git a/deps/uv/test/test-udp-create-socket-early.c b/deps/uv/test/test-udp-create-socket-early.c index 3f3027404700f4..f7e46abc98da54 100644 --- a/deps/uv/test/test-udp-create-socket-early.c +++ b/deps/uv/test/test-udp-create-socket-early.c @@ -104,7 +104,7 @@ TEST_IMPL(udp_create_early_bad_bind) { #endif r = uv_udp_bind(&client, (const struct sockaddr*) &addr, 0); -#ifndef _WIN32 +#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(__MSYS__) ASSERT(r == UV_EINVAL); #else ASSERT(r == UV_EFAULT); diff --git a/deps/uv/test/test-udp-ipv6.c b/deps/uv/test/test-udp-ipv6.c index a65f09e0c6d765..54b364da9ebc75 100644 --- a/deps/uv/test/test-udp-ipv6.c +++ b/deps/uv/test/test-udp-ipv6.c @@ -163,6 +163,11 @@ static void do_test(uv_udp_recv_cb recv_cb, int bind_flags) { TEST_IMPL(udp_dual_stack) { +#if defined(__CYGWIN__) || defined(__MSYS__) + /* FIXME: Does Cygwin support this? */ + RETURN_SKIP("FIXME: This test needs more investigation on Cygwin"); +#endif + if (!can_ipv6()) RETURN_SKIP("IPv6 not supported"); diff --git a/deps/uv/test/test-udp-send-hang-loop.c b/deps/uv/test/test-udp-send-hang-loop.c new file mode 100644 index 00000000000000..6253ff7a4134c0 --- /dev/null +++ b/deps/uv/test/test-udp-send-hang-loop.c @@ -0,0 +1,99 @@ +/* Copyright The libuv project and 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. + */ + +#include "uv.h" +#include "task.h" + +#include +#include +#include + +#define CHECK_OBJECT(handle, type, parent) \ + ASSERT((type*)(handle) == &(parent)) + +static uv_udp_t client; +static uv_idle_t idle_handle; +static uv_udp_send_t send_req; +static uv_buf_t buf; +static struct sockaddr_in addr; +static char send_data[1024]; + +static int loop_hang_called; + +static void send_cb(uv_udp_send_t* req, int status); + + +static void idle_cb(uv_idle_t* handle) { + int r; + + ASSERT(send_req.handle == NULL); + CHECK_OBJECT(handle, uv_idle_t, idle_handle); + ASSERT(0 == uv_idle_stop(handle)); + + /* It probably would have stalled by now if it's going to stall at all. */ + if (++loop_hang_called > 1000) { + uv_close((uv_handle_t*) &client, NULL); + uv_close((uv_handle_t*) &idle_handle, NULL); + return; + } + + r = uv_udp_send(&send_req, + &client, + &buf, + 1, + (const struct sockaddr*) &addr, + send_cb); + ASSERT(r == 0); +} + + +static void send_cb(uv_udp_send_t* req, int status) { + ASSERT(req != NULL); + ASSERT(status == 0); + CHECK_OBJECT(req->handle, uv_udp_t, client); + CHECK_OBJECT(req, uv_udp_send_t, send_req); + req->handle = NULL; + + ASSERT(0 == uv_idle_start(&idle_handle, idle_cb)); +} + + +TEST_IMPL(udp_send_hang_loop) { + ASSERT(0 == uv_idle_init(uv_default_loop(), &idle_handle)); + + /* 192.0.2.0/8 is "TEST-NET" and reserved for documentation. + * Good for us, though. Since we want to have something unreachable. + */ + ASSERT(0 == uv_ip4_addr("192.0.2.3", TEST_PORT, &addr)); + + ASSERT(0 == uv_udp_init(uv_default_loop(), &client)); + + buf = uv_buf_init(send_data, sizeof(send_data)); + + ASSERT(0 == uv_idle_start(&idle_handle, idle_cb)); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(loop_hang_called > 1000); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/deps/uv/test/test-udp-send-immediate.c b/deps/uv/test/test-udp-send-immediate.c index 0999f6b3425286..215f72257233a1 100644 --- a/deps/uv/test/test-udp-send-immediate.c +++ b/deps/uv/test/test-udp-send-immediate.c @@ -136,6 +136,7 @@ TEST_IMPL(udp_send_immediate) { 1, (const struct sockaddr*) &addr, cl_send_cb); + ASSERT(r == 0); uv_run(uv_default_loop(), UV_RUN_DEFAULT); diff --git a/deps/uv/test/test-watcher-cross-stop.c b/deps/uv/test/test-watcher-cross-stop.c index 6ff48d44c88178..29a82a5c374029 100644 --- a/deps/uv/test/test-watcher-cross-stop.c +++ b/deps/uv/test/test-watcher-cross-stop.c @@ -26,7 +26,12 @@ #include /* NOTE: Number should be big enough to trigger this problem */ +#if defined(__CYGWIN__) || defined(__MSYS__) +/* Cygwin crashes or hangs in socket() with too many AF_INET sockets. */ +static uv_udp_t sockets[1250]; +#else static uv_udp_t sockets[2500]; +#endif static uv_udp_send_t reqs[ARRAY_SIZE(sockets)]; static char slab[1]; static unsigned int recv_cb_called; diff --git a/deps/uv/tools/make_dist_html.py b/deps/uv/tools/make_dist_html.py new file mode 100644 index 00000000000000..7a19d3e1151fb8 --- /dev/null +++ b/deps/uv/tools/make_dist_html.py @@ -0,0 +1,124 @@ +#!/usr/bin/python + +from __future__ import print_function + +import itertools +import os +import re +import subprocess + +HTML = r''' + + + + + + + + + {groups}
    + + +''' + +GROUPS = r''' + + {groups[0]} + {groups[1]} + {groups[2]} + {groups[3]} + +''' + +GROUP = r''' + + + + + + + + {rows} +
    versiontarballgpgwindows
    +''' + +ROW = r''' + + + {tag} + + + tarball + + {maybe_gpg} + {maybe_exe} + +''' + +GPG = r''' +gpg +''' + +# The binaries don't have a predictable name, link to the directory instead. +EXE = r''' +exe +''' + +def version(tag): + return map(int, re.match('^v(\d+)\.(\d+)\.(\d+)', tag).groups()) + +def major_minor(tag): + return version(tag)[:2] + +def row_for(tag): + maybe_gpg = '' + maybe_exe = '' + # We didn't start signing releases and producing Windows installers + # until v1.7.0. + if version(tag) >= version('v1.7.0'): + maybe_gpg = GPG.format(**locals()) + maybe_exe = EXE.format(**locals()) + return ROW.format(**locals()) + +def group_for(tags): + rows = ''.join(row_for(tag) for tag in tags) + return GROUP.format(rows=rows) + +# Partition in groups of |n|. +def groups_for(groups, n=4): + html = '' + groups = groups[:] + [''] * (n - 1) + while len(groups) >= n: + html += GROUPS.format(groups=groups) + groups = groups[n:] + return html + +if __name__ == '__main__': + os.chdir(os.path.dirname(__file__)) + tags = subprocess.check_output(['git', 'tag']) + tags = [tag for tag in tags.split('\n') if tag.startswith('v')] + tags.sort(key=version, reverse=True) + groups = [group_for(list(g)) for _, g in itertools.groupby(tags, major_minor)] + groups = groups_for(groups) + html = HTML.format(groups=groups).strip() + html = re.sub('>\\s+<', '><', html) + print(html) diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp index 49d5d22f96784b..a3a42787b37b78 100644 --- a/deps/uv/uv.gyp +++ b/deps/uv/uv.gyp @@ -36,7 +36,7 @@ ], 'xcode_settings': { 'GCC_SYMBOLS_PRIVATE_EXTERN': 'YES', # -fvisibility=hidden - 'WARNING_CFLAGS': [ '-Wall', '-Wextra', '-Wno-unused-parameter' ], + 'WARNING_CFLAGS': [ '-Wall', '-Wextra', '-Wno-unused-parameter', '-Wstrict-prototypes' ], 'OTHER_CFLAGS': [ '-g', '--std=gnu89', '-pedantic' ], } }, @@ -210,6 +210,7 @@ '-Wall', '-Wextra', '-Wno-unused-parameter', + '-Wstrict-prototypes', ], }], [ 'OS in "mac ios"', { @@ -236,6 +237,9 @@ 'src/unix/linux-inotify.c', 'src/unix/linux-syscalls.c', 'src/unix/linux-syscalls.h', + 'src/unix/procfs-exepath.c', + 'src/unix/sysinfo-loadavg.c', + 'src/unix/sysinfo-memory.c', ], 'link_settings': { 'libraries': [ '-ldl', '-lrt' ], @@ -250,13 +254,19 @@ 'src/unix/pthread-fixes.c', 'src/unix/android-ifaddrs.c', 'src/unix/pthread-barrier.c' + 'src/unix/procfs-exepath.c', + 'src/unix/sysinfo-loadavg.c', + 'src/unix/sysinfo-memory.c', ], 'link_settings': { 'libraries': [ '-ldl' ], }, }], [ 'OS=="solaris"', { - 'sources': [ 'src/unix/sunos.c' ], + 'sources': [ + 'src/unix/no-proctitle.c', + 'src/unix/sunos.c', + ], 'defines': [ '__EXTENSIONS__', '_XOPEN_SOURCE=500', @@ -298,9 +308,13 @@ 'link_settings': { 'libraries': [ '-lkvm' ], }, + 'sources': [ 'src/unix/posix-hrtime.c' ], }], [ 'OS in "ios mac freebsd dragonflybsd openbsd netbsd".split()', { - 'sources': [ 'src/unix/kqueue.c' ], + 'sources': [ + 'src/unix/bsd-ifaddrs.c', + 'src/unix/kqueue.c', + ], }], ['uv_library=="shared_library"', { 'defines': [ 'BUILDING_UV_SHARED=1' ] @@ -309,6 +323,7 @@ 'sources': [ 'src/unix/pthread-fixes.c', 'src/unix/pthread-barrier.c', + 'src/unix/no-fsevents.c', 'src/unix/os390.c', 'src/unix/os390-syscalls.c' ] @@ -343,13 +358,16 @@ 'test/test-error.c', 'test/test-embed.c', 'test/test-emfile.c', + 'test/test-env-vars.c', 'test/test-fail-always.c', + 'test/test-fork.c', 'test/test-fs.c', 'test/test-fs-event.c', 'test/test-get-currentexe.c', 'test/test-get-memory.c', 'test/test-get-passwd.c', 'test/test-getaddrinfo.c', + 'test/test-gethostname.c', 'test/test-getnameinfo.c', 'test/test-getsockname.c', 'test/test-handle-fileno.c', @@ -445,6 +463,7 @@ 'test/test-udp-open.c', 'test/test-udp-options.c', 'test/test-udp-send-and-recv.c', + 'test/test-udp-send-hang-loop.c', 'test/test-udp-send-immediate.c', 'test/test-udp-send-unreachable.c', 'test/test-udp-multicast-join.c', diff --git a/doc/.eslintrc.yaml b/doc/.eslintrc.yaml index b4fbf847be7aaf..5b7ea75de5ce4a 100644 --- a/doc/.eslintrc.yaml +++ b/doc/.eslintrc.yaml @@ -1,6 +1,8 @@ ## Docs-specific linter rules rules: + object-curly-spacing: [2, always] + # ease some restrictions in doc examples no-restricted-properties: 0 no-undef: 0 @@ -10,3 +12,4 @@ rules: # add new ECMAScript features gradually no-var: 2 prefer-const: 2 + prefer-rest-params: 2 diff --git a/doc/api/_toc.md b/doc/api/_toc.md index 29fffbc59fc1e2..4865334ec02b39 100644 --- a/doc/api/_toc.md +++ b/doc/api/_toc.md @@ -6,6 +6,7 @@
    * [Assertion Testing](assert.html) +* [Async Hooks](async_hooks.html) * [Buffer](buffer.html) * [C++ Addons](addons.html) * [C/C++ Addons - N-API](n-api.html) diff --git a/doc/api/all.md b/doc/api/all.md index a4741e64274c7b..7122fe96fa0128 100644 --- a/doc/api/all.md +++ b/doc/api/all.md @@ -1,8 +1,10 @@ @include documentation @include synopsis @include assert +@include async_hooks @include buffer @include addons +@include n-api @include child_process @include cluster @include cli diff --git a/doc/api/assert.md b/doc/api/assert.md index 3eb95f0ba29cbb..1a040a927bc7f9 100644 --- a/doc/api/assert.md +++ b/doc/api/assert.md @@ -131,10 +131,10 @@ Generally identical to `assert.deepEqual()` with three exceptions: ```js const assert = require('assert'); -assert.deepEqual({a: 1}, {a: '1'}); +assert.deepEqual({ a: 1 }, { a: '1' }); // OK, because 1 == '1' -assert.deepStrictEqual({a: 1}, {a: '1'}); +assert.deepStrictEqual({ a: 1 }, { a: '1' }); // AssertionError: { a: 1 } deepStrictEqual { a: '1' } // because 1 !== '1' using strict equality @@ -248,7 +248,7 @@ assert.equal(1, '1'); assert.equal(1, 2); // AssertionError: 1 == 2 -assert.equal({a: {b: 1}}, {a: {b: 1}}); +assert.equal({ a: { b: 1 } }, { a: { b: 1 } }); //AssertionError: { a: { b: 1 } } == { a: { b: 1 } } ``` @@ -368,10 +368,10 @@ Tests for deep strict inequality. Opposite of [`assert.deepStrictEqual()`][]. ```js const assert = require('assert'); -assert.notDeepEqual({a: 1}, {a: '1'}); +assert.notDeepEqual({ a: 1 }, { a: '1' }); // AssertionError: { a: 1 } notDeepEqual { a: '1' } -assert.notDeepStrictEqual({a: 1}, {a: '1'}); +assert.notDeepStrictEqual({ a: 1 }, { a: '1' }); // OK ``` diff --git a/doc/api/async_hooks.md b/doc/api/async_hooks.md new file mode 100644 index 00000000000000..709a12d3869fdf --- /dev/null +++ b/doc/api/async_hooks.md @@ -0,0 +1,557 @@ +# Async Hooks + +> Stability: 1 - Experimental + +The `async_hooks` module provides an API to register callbacks tracking the +lifetime of asynchronous resources created inside a Node.js application. +It can be accessed using: + +```js +const async_hooks = require('async_hooks'); +``` + +## Terminology + +An asynchronous resource represents an object with an associated callback. +This callback may be called multiple times, for example, the `connection` event +in `net.createServer`, or just a single time like in `fs.open`. A resource +can also be closed before the callback is called. AsyncHook does not +explicitly distinguish between these different cases but will represent them +as the abstract concept that is a resource. + +## Public API + +### Overview + +Following is a simple overview of the public API. + +```js +const async_hooks = require('async_hooks'); + +// Return the ID of the current execution context. +const cid = async_hooks.currentId(); + +// Return the ID of the handle responsible for triggering the callback of the +// current execution scope to call. +const tid = async_hooks.triggerId(); + +// Create a new AsyncHook instance. All of these callbacks are optional. +const asyncHook = async_hooks.createHook({ init, before, after, destroy }); + +// Allow callbacks of this AsyncHook instance to call. This is not an implicit +// action after running the constructor, and must be explicitly run to begin +// executing callbacks. +asyncHook.enable(); + +// Disable listening for new asynchronous events. +asyncHook.disable(); + +// +// The following are the callbacks that can be passed to createHook(). +// + +// init is called during object construction. The resource may not have +// completed construction when this callback runs, therefore all fields of the +// resource referenced by "asyncId" may not have been populated. +function init(asyncId, type, triggerId, resource) { } + +// before is called just before the resource's callback is called. It can be +// called 0-N times for handles (e.g. TCPWrap), and will be called exactly 1 +// time for requests (e.g. FSReqWrap). +function before(asyncId) { } + +// after is called just after the resource's callback has finished. +function after(asyncId) { } + +// destroy is called when an AsyncWrap instance is destroyed. +function destroy(asyncId) { } +``` + +#### `async_hooks.createHook(callbacks)` + + + +* `callbacks` {Object} the callbacks to register +* Returns: `{AsyncHook}` instance used for disabling and enabling hooks + +Registers functions to be called for different lifetime events of each async +operation. + +The callbacks `init()`/`before()`/`after()`/`destroy()` are called for the +respective asynchronous event during a resource's lifetime. + +All callbacks are optional. So, for example, if only resource cleanup needs to +be tracked then only the `destroy` callback needs to be passed. The +specifics of all functions that can be passed to `callbacks` is in the section +[`Hook Callbacks`][]. + +##### Error Handling + +If any `AsyncHook` callbacks throw, the application will print the stack trace +and exit. The exit path does follow that of an uncaught exception but +all `uncaughtException` listeners are removed, thus forcing the process to +exit. The `'exit'` callbacks will still be called unless the application is run +with `--abort-on-uncaught-exception`, in which case a stack trace will be +printed and the application exits, leaving a core file. + +The reason for this error handling behavior is that these callbacks are running +at potentially volatile points in an object's lifetime, for example during +class construction and destruction. Because of this, it is deemed necessary to +bring down the process quickly in order to prevent an unintentional abort in the +future. This is subject to change in the future if a comprehensive analysis is +performed to ensure an exception can follow the normal control flow without +unintentional side effects. + + +##### Printing in AsyncHooks callbacks + +Because printing to the console is an asynchronous operation, `console.log()` +will cause the AsyncHooks callbacks to be called. Using `console.log()` or +similar asynchronous operations inside an AsyncHooks callback function will thus +cause an infinite recursion. An easily solution to this when debugging is +to use a synchronous logging operation such as `fs.writeSync(1, msg)`. This +will print to stdout because `1` is the file descriptor for stdout and will +not invoke AsyncHooks recursively because it is synchronous. + +```js +const fs = require('fs'); +const util = require('util'); + +function debug(...args) { + // use a function like this one when debugging inside an AsyncHooks callback + fs.writeSync(1, `${util.format(...args)}\n`); +} +``` + +If an asynchronous operation is needed for logging, it is possible to keep +track of what caused the asynchronous operation using the information +provided by AsyncHooks itself. The logging should then be skipped when +it was the logging itself that caused AsyncHooks callback to call. By +doing this the otherwise infinite recursion is broken. + +#### `asyncHook.enable()` + +* Returns {AsyncHook} A reference to `asyncHook`. + +Enable the callbacks for a given `AsyncHook` instance. If no callbacks are +provided enabling is a noop. + +The `AsyncHook` instance is by default disabled. If the `AsyncHook` instance +should be enabled immediately after creation, the following pattern can be used. + +```js +const async_hooks = require('async_hooks'); + +const hook = async_hooks.createHook(callbacks).enable(); +``` + +#### `asyncHook.disable()` + +* Returns {AsyncHook} A reference to `asyncHook`. + +Disable the callbacks for a given `AsyncHook` instance from the global pool of +AsyncHook callbacks to be executed. Once a hook has been disabled it will not +be called again until enabled. + +For API consistency `disable()` also returns the `AsyncHook` instance. + +#### Hook Callbacks + +Key events in the lifetime of asynchronous events have been categorized into +four areas: instantiation, before/after the callback is called, and when the +instance is destructed. + +##### `init(asyncId, type, triggerId, resource)` + +* `asyncId` {number} a unique ID for the async resource +* `type` {string} the type of the async resource +* `triggerId` {number} the unique ID of the async resource in whose + execution context this async resource was created +* `resource` {Object} reference to the resource representing the async operation, + needs to be released during _destroy_ + +Called when a class is constructed that has the _possibility_ to emit an +asynchronous event. This _does not_ mean the instance must call +`before`/`after` before `destroy` is called, only that the possibility +exists. + +This behavior can be observed by doing something like opening a resource then +closing it before the resource can be used. The following snippet demonstrates +this. + +```js +require('net').createServer().listen(function() { this.close(); }); +// OR +clearTimeout(setTimeout(() => {}, 10)); +``` + +Every new resource is assigned a unique ID. + +###### `type` + +The `type` is a string that represents the type of resource that caused +`init` to call. Generally it will be the name of the resource's constructor. +The resource types provided by the built-in Node.js modules are: + +``` +FSEVENTWRAP, FSREQWRAP, GETADDRINFOREQWRAP, GETNAMEINFOREQWRAP, HTTPPARSER, +JSSTREAM, PIPECONNECTWRAP, PIPEWRAP, PROCESSWRAP, QUERYWRAP, SHUTDOWNWRAP, +SIGNALWRAP, STATWATCHER, TCPCONNECTWRAP, TCPWRAP, TIMERWRAP, TTYWRAP, +UDPSENDWRAP, UDPWRAP, WRITEWRAP, ZLIB, SSLCONNECTION, PBKDF2REQUEST, +RANDOMBYTESREQUEST, TLSWRAP +``` + +Users are be able to define their own `type` when using the public embedder API. + +*Note:* It is possible to have type name collisions. Embedders are encouraged +to use a unique prefixes, such as the npm package name, to prevent collisions +when listening to the hooks. + +###### `triggerid` + +`triggerId` is the `asyncId` of the resource that caused (or "triggered") the +new resource to initialize and that caused `init` to call. This is different +from `async_hooks.currentId()` that only shows *when* a resource was created, +while `triggerId` shows *why* a resource was created. + + +The following is a simple demonstration of `triggerId`: + +```js +async_hooks.createHook({ + init(asyncId, type, triggerId) { + const cId = async_hooks.currentId(); + fs.writeSync( + 1, `${type}(${asyncId}): trigger: ${triggerId} scope: ${cId}\n`); + } +}).enable(); + +require('net').createServer((conn) => {}).listen(8080); +``` + +Output when hitting the server with `nc localhost 8080`: + +``` +TCPWRAP(2): trigger: 1 scope: 1 +TCPWRAP(4): trigger: 2 scope: 0 +``` + +The first `TCPWRAP` is the server which receives the connections. + +The second `TCPWRAP` is the new connection from the client. When a new +connection is made the `TCPWrap` instance is immediately constructed. This +happens outside of any JavaScript stack (side note: a `currentId()` of `0` +means it's being executed from C++, with no JavaScript stack above it). +With only that information it would be impossible to link resources together in +terms of what caused them to be created, so `triggerId` is given the task of +propagating what resource is responsible for the new resource's existence. + +###### `resource` + +`resource` is an object that represents the actual resource. This can contain +useful information such as the hostname for the `GETADDRINFOREQWRAP` resource +type, which will be used when looking up the ip for the hostname in +`net.Server.listen`. The API for getting this information is currently not +considered public, but using the Embedder API users can provide and document +their own resource objects. Such as resource object could for example contain +the SQL query being executed. + +*Note:* In some cases the resource object is reused for performance reasons, +it is thus not safe to use it as a key in a `WeakMap` or add properties to it. + +###### asynchronous context example + +Below is another example with additional information about the calls to +`init` between the `before` and `after` calls, specifically what the +callback to `listen()` will look like. The output formatting is slightly more +elaborate to make calling context easier to see. + +```js +let indent = 0; +async_hooks.createHook({ + init(asyncId, type, triggerId) { + const cId = async_hooks.currentId(); + const indentStr = ' '.repeat(indent); + fs.writeSync( + 1, + `${indentStr}${type}(${asyncId}): trigger: ${triggerId} scope: ${cId}\n`); + }, + before(asyncId) { + const indentStr = ' '.repeat(indent); + fs.writeSync(1, `${indentStr}before: ${asyncId}\n`); + indent += 2; + }, + after(asyncId) { + indent -= 2; + const indentStr = ' '.repeat(indent); + fs.writeSync(1, `${indentStr}after: ${asyncId}\n`); + }, + destroy(asyncId) { + const indentStr = ' '.repeat(indent); + fs.writeSync(1, `${indentStr}destroy: ${asyncId}\n`); + }, +}).enable(); + +require('net').createServer(() => {}).listen(8080, () => { + // Let's wait 10ms before logging the server started. + setTimeout(() => { + console.log('>>>', async_hooks.currentId()); + }, 10); +}); +``` + +Output from only starting the server: + +``` +TCPWRAP(2): trigger: 1 scope: 1 +TickObject(3): trigger: 2 scope: 1 +before: 3 + Timeout(4): trigger: 3 scope: 3 + TIMERWRAP(5): trigger: 3 scope: 3 +after: 3 +destroy: 3 +before: 5 + before: 4 + TTYWRAP(6): trigger: 4 scope: 4 + SIGNALWRAP(7): trigger: 4 scope: 4 + TTYWRAP(8): trigger: 4 scope: 4 +>>> 4 + TickObject(9): trigger: 4 scope: 4 + after: 4 +after: 5 +before: 9 +after: 9 +destroy: 4 +destroy: 9 +destroy: 5 +``` + +*Note*: As illustrated in the example, `currentId()` and `scope` each specify +the value of the current execution context; which is delineated by calls to +`before` and `after`. + +Only using `scope` to graph resource allocation results in the following: + +``` +TTYWRAP(6) -> Timeout(4) -> TIMERWRAP(5) -> TickObject(3) -> root(1) +``` + +The `TCPWRAP` isn't part of this graph; even though it was the reason for +`console.log()` being called. This is because binding to a port without a +hostname is actually synchronous, but to maintain a completely asynchronous API +the user's callback is placed in a `process.nextTick()`. + +The graph only shows *when* a resource was created, not *why*, so to track +the *why* use `triggerId`. + + +##### `before(asyncId)` + +* `asyncId` {number} + +When an asynchronous operation is initiated (such as a TCP server receiving a +new connection) or completes (such as writing data to disk) a callback is +called to notify the user. The `before` callback is called just before said +callback is executed. `asyncId` is the unique identifier assigned to the +resource about to execute the callback. + +The `before` callback will be called 0 to N times. The `before` callback +will typically be called 0 times if the asynchronous operation was cancelled +or for example if no connections are received by a TCP server. Asynchronous +like the TCP server will typically call the `before` callback multiple times, +while other operations like `fs.open()` will only call it once. + + +##### `after(asyncId)` + +* `asyncId` {number} + +Called immediately after the callback specified in `before` is completed. + +*Note:* If an uncaught exception occurs during execution of the callback then +`after` will run after the `'uncaughtException'` event is emitted or a +`domain`'s handler runs. + + +##### `destroy(asyncId)` + +* `asyncId` {number} + +Called after the resource corresponding to `asyncId` is destroyed. It is also called +asynchronously from the embedder API `emitDestroy()`. + +*Note:* Some resources depend on GC for cleanup, so if a reference is made to +the `resource` object passed to `init` it's possible that `destroy` is +never called, causing a memory leak in the application. Of course if +the resource doesn't depend on GC then this isn't an issue. + +#### `async_hooks.currentId()` + +* Returns {number} the `asyncId` of the current execution context. Useful to track + when something calls. + +For example: + +```js +console.log(async_hooks.currentId()); // 1 - bootstrap +fs.open(path, 'r', (err, fd) => { + console.log(async_hooks.currentId()); // 6 - open() +}); +``` + +It is important to note that the ID returned fom `currentId()` is related to +execution timing, not causality (which is covered by `triggerId()`). For +example: + +```js +const server = net.createServer(function onConnection(conn) { + // Returns the ID of the server, not of the new connection, because the + // onConnection callback runs in the execution scope of the server's + // MakeCallback(). + async_hooks.currentId(); + +}).listen(port, function onListening() { + // Returns the ID of a TickObject (i.e. process.nextTick()) because all + // callbacks passed to .listen() are wrapped in a nextTick(). + async_hooks.currentId(); +}); +``` + +#### `async_hooks.triggerId()` + +* Returns {number} the ID of the resource responsible for calling the callback + that is currently being executed. + +For example: + +```js +const server = net.createServer((conn) => { + // The resource that caused (or triggered) this callback to be called + // was that of the new connection. Thus the return value of triggerId() + // is the asyncId of "conn". + async_hooks.triggerId(); + +}).listen(port, () => { + // Even though all callbacks passed to .listen() are wrapped in a nextTick() + // the callback itself exists because the call to the server's .listen() + // was made. So the return value would be the ID of the server. + async_hooks.triggerId(); +}); +``` + +## JavaScript Embedder API + +Library developers that handle their own I/O, a connection pool, or +callback queues will need to hook into the AsyncWrap API so that all the +appropriate callbacks are called. To accommodate this a JavaScript API is +provided. + +### `class AsyncResource()` + +The class `AsyncResource` was designed to be extended by the embedder's async +resources. Using this users can easily trigger the lifetime events of their +own resources. + +The `init` hook will trigger when an `AsyncResource` is instantiated. + +It is important that `before`/`after` calls are unwound +in the same order they are called. Otherwise an unrecoverable exception +will occur and node will abort. + +The following is an overview of the `AsyncResource` API. + +```js +const { AsyncResource } = require('async_hooks'); + +// AsyncResource() is meant to be extended. Instantiating a +// new AsyncResource() also triggers init. If triggerId is omitted then +// async_hook.currentId() is used. +const asyncResource = new AsyncResource(type, triggerId); + +// Call AsyncHooks before callbacks. +asyncResource.emitBefore(); + +// Call AsyncHooks after callbacks. +asyncResource.emitAfter(); + +// Call AsyncHooks destroy callbacks. +asyncResource.emitDestroy(); + +// Return the unique ID assigned to the AsyncResource instance. +asyncResource.asyncId(); + +// Return the trigger ID for the AsyncResource instance. +asyncResource.triggerId(); +``` + +#### `AsyncResource(type[, triggerId])` + +* arguments + * `type` {string} the type of ascyc event + * `triggerId` {number} the ID of the execution context that created this async + event + +Example usage: + +```js +class DBQuery extends AsyncResource { + constructor(db) { + super('DBQuery'); + this.db = db; + } + + getInfo(query, callback) { + this.db.get(query, (err, data) => { + this.emitBefore(); + callback(err, data); + this.emitAfter(); + }); + } + + close() { + this.db = null; + this.emitDestroy(); + } +} +``` + +#### `asyncResource.emitBefore()` + +* Returns {undefined} + +Call all `before` callbacks and let them know a new asynchronous execution +context is being entered. If nested calls to `emitBefore()` are made, the stack +of `asyncId`s will be tracked and properly unwound. + +#### `asyncResource.emitAfter()` + +* Returns {undefined} + +Call all `after` callbacks. If nested calls to `emitBefore()` were made, then +make sure the stack is unwound properly. Otherwise an error will be thrown. + +If the user's callback throws an exception then `emitAfter()` will +automatically be called for all `asyncId`s on the stack if the error is handled by +a domain or `'uncaughtException'` handler. + +#### `asyncResource.emitDestroy()` + +* Returns {undefined} + +Call all `destroy` hooks. This should only ever be called once. An error will +be thrown if it is called more than once. This **must** be manually called. If +the resource is left to be collected by the GC then the `destroy` hooks will +never be called. + +#### `asyncResource.asyncId()` + +* Returns {number} the unique `asyncId` assigned to the resource. + +#### `asyncResource.triggerId()` + +* Returns {number} the same `triggerId` that is passed to the `AsyncResource` +constructor. + +[`Hook Callbacks`]: #hook-callbacks diff --git a/doc/api/buffer.md b/doc/api/buffer.md index 0d98a2f1c1b5c4..5de805b6e9831e 100644 --- a/doc/api/buffer.md +++ b/doc/api/buffer.md @@ -2609,7 +2609,7 @@ sensitive data. Use [`buf.fill(0)`][`buf.fill()`] to initialize a `SlowBuffer` t Example: ```js -const SlowBuffer = require('buffer').SlowBuffer; +const { SlowBuffer } = require('buffer'); const buf = new SlowBuffer(5); diff --git a/doc/api/child_process.md b/doc/api/child_process.md index 4800d5bc9302a9..2120e36f4be32e 100644 --- a/doc/api/child_process.md +++ b/doc/api/child_process.md @@ -7,7 +7,7 @@ a manner that is similar, but not identical, to popen(3). This capability is primarily provided by the [`child_process.spawn()`][] function: ```js -const spawn = require('child_process').spawn; +const { spawn } = require('child_process'); const ls = spawn('ls', ['-lh', '/usr']); ls.stdout.on('data', (data) => { @@ -87,7 +87,7 @@ spaces it needs to be quoted. ```js // On Windows Only ... -const spawn = require('child_process').spawn; +const { spawn } = require('child_process'); const bat = spawn('cmd.exe', ['/c', 'my.bat']); bat.stdout.on('data', (data) => { @@ -105,7 +105,7 @@ bat.on('exit', (code) => { ```js // OR... -const exec = require('child_process').exec; +const { exec } = require('child_process'); exec('my.bat', (err, stdout, stderr) => { if (err) { console.error(err); @@ -168,7 +168,7 @@ containing shell metacharacters may be used to trigger arbitrary command execution. ```js -const exec = require('child_process').exec; +const { exec } = require('child_process'); exec('cat *.js bad_file | wc -l', (error, stdout, stderr) => { if (error) { console.error(`exec error: ${error}`); @@ -224,7 +224,7 @@ const util = require('util'); const exec = util.promisify(require('child_process').exec); async function lsExample() { - const {stdout, stderr} = await exec('ls'); + const { stdout, stderr } = await exec('ls'); console.log('stdout:', stdout); console.log('stderr:', stderr); } @@ -264,7 +264,7 @@ The same options as [`child_process.exec()`][] are supported. Since a shell is n spawned, behaviors such as I/O redirection and file globbing are not supported. ```js -const execFile = require('child_process').execFile; +const { execFile } = require('child_process'); const child = execFile('node', ['--version'], (error, stdout, stderr) => { if (error) { throw error; @@ -287,7 +287,7 @@ a Promise for an object with `stdout` and `stderr` properties. const util = require('util'); const execFile = util.promisify(require('child_process').execFile); async function getVersion() { - const {stdout} = await execFile('node', ['--version']); + const { stdout } = await execFile('node', ['--version']); console.log(stdout); } getVersion(); @@ -410,7 +410,7 @@ Example of running `ls -lh /usr`, capturing `stdout`, `stderr`, and the exit code: ```js -const spawn = require('child_process').spawn; +const { spawn } = require('child_process'); const ls = spawn('ls', ['-lh', '/usr']); ls.stdout.on('data', (data) => { @@ -430,7 +430,7 @@ ls.on('close', (code) => { Example: A very elaborate way to run `ps ax | grep ssh` ```js -const spawn = require('child_process').spawn; +const { spawn } = require('child_process'); const ps = spawn('ps', ['ax']); const grep = spawn('grep', ['ssh']); @@ -468,7 +468,7 @@ grep.on('close', (code) => { Example of checking for failed exec: ```js -const spawn = require('child_process').spawn; +const { spawn } = require('child_process'); const child = spawn('bad_command'); child.on('error', (err) => { @@ -515,7 +515,7 @@ Example of a long-running process, by detaching and also ignoring its parent `stdio` file descriptors, in order to ignore the parent's termination: ```js -const spawn = require('child_process').spawn; +const { spawn } = require('child_process'); const child = spawn(process.argv[0], ['child_program.js'], { detached: true, @@ -529,7 +529,7 @@ Alternatively one can redirect the child process' output into files: ```js const fs = require('fs'); -const spawn = require('child_process').spawn; +const { spawn } = require('child_process'); const out = fs.openSync('./out.log', 'a'); const err = fs.openSync('./out.log', 'a'); @@ -601,7 +601,7 @@ pipes between the parent and child. The value is one of the following: Example: ```js -const spawn = require('child_process').spawn; +const { spawn } = require('child_process'); // Child will use parent's stdios spawn('prg', [], { stdio: 'inherit' }); @@ -933,7 +933,7 @@ is given, the process will be sent the `'SIGTERM'` signal. See signal(7) for a list of available signals. ```js -const spawn = require('child_process').spawn; +const { spawn } = require('child_process'); const grep = spawn('grep', ['ssh']); grep.on('close', (code, signal) => { @@ -963,7 +963,7 @@ as in this example: ```js 'use strict'; -const spawn = require('child_process').spawn; +const { spawn } = require('child_process'); const child = spawn( 'sh', @@ -994,7 +994,7 @@ Returns the process identifier (PID) of the child process. Example: ```js -const spawn = require('child_process').spawn; +const { spawn } = require('child_process'); const grep = spawn('grep', ['ssh']); console.log(`Spawned child pid: ${grep.pid}`); diff --git a/doc/api/console.md b/doc/api/console.md index 606e13e601800c..3411d3ce0afba2 100644 --- a/doc/api/console.md +++ b/doc/api/console.md @@ -65,14 +65,14 @@ changes: The `Console` class can be used to create a simple logger with configurable output streams and can be accessed using either `require('console').Console` -or `console.Console`: +or `console.Console` (or their destructured counterparts): ```js -const Console = require('console').Console; +const { Console } = require('console'); ``` ```js -const Console = console.Console; +const { Console } = console; ``` ### new Console(stdout[, stderr]) diff --git a/doc/api/fs.md b/doc/api/fs.md index 9ee328e6523218..fc3e5d95665b2f 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -94,6 +94,12 @@ Error: EISDIR: illegal operation on a directory, read ``` +*Note:* On Windows Node.js follows the concept of per-drive working directory. +This behavior can be observed when using a drive path without a backslash. For +example `fs.readdirSync('c:\\')` can potentially return a different result than +`fs.readdirSync('c:')`. For more information, see +[this MSDN page][MSDN-Rel-Path]. + ## WHATWG URL object support -Objects returned from [`fs.stat()`][], [`fs.lstat()`][] and [`fs.fstat()`][] and their -synchronous counterparts are of this type. +Objects returned from [`fs.stat()`][], [`fs.lstat()`][] and [`fs.fstat()`][] and +their synchronous counterparts are of this type. - `stats.isFile()` - `stats.isDirectory()` @@ -323,20 +333,23 @@ Stats { size: 527, blksize: 4096, blocks: 8, + atimeMs: 1318289051000.1, + mtimeMs: 1318289051000.1, + ctimeMs: 1318289051000.1, + birthtimeMs: 1318289051000.1, atime: Mon, 10 Oct 2011 23:24:11 GMT, mtime: Mon, 10 Oct 2011 23:24:11 GMT, ctime: Mon, 10 Oct 2011 23:24:11 GMT, birthtime: Mon, 10 Oct 2011 23:24:11 GMT } ``` -Please note that `atime`, `mtime`, `birthtime`, and `ctime` are -instances of [`Date`][MDN-Date] object and appropriate methods should be used -to compare the values of these objects. For most general uses -[`getTime()`][MDN-Date-getTime] will return the number of milliseconds elapsed -since _1 January 1970 00:00:00 UTC_ and this integer should be sufficient for -any comparison, however there are additional methods which can be used for -displaying fuzzy information. More details can be found in the -[MDN JavaScript Reference][MDN-Date] page. +*Note*: `atimeMs`, `mtimeMs`, `ctimeMs`, `birthtimeMs` are [numbers][MDN-Number] +that hold the corresponding times in milliseconds. Their precision is platform +specific. `atime`, `mtime`, `ctime`, and `birthtime` are [`Date`][MDN-Date] +object alternate representations of the various times. The `Date` and number +values are not connected. Assigning a new number value, or mutating the `Date` +value, will not be reflected in the corresponding alternate representation. + ### Stat Time Values @@ -787,7 +800,7 @@ file was created. An example to read the last 10 bytes of a file which is 100 bytes long: ```js -fs.createReadStream('sample.txt', {start: 90, end: 99}); +fs.createReadStream('sample.txt', { start: 90, end: 99 }); ``` If `options` is a string, then it specifies the encoding. @@ -2835,6 +2848,8 @@ The following constants are meant for use with the [`fs.Stats`][] object's [FS Constants]: #fs_fs_constants_1 [MDN-Date-getTime]: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/getTime [MDN-Date]: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date +[MDN-Number]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type +[MSDN-Rel-Path]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247.aspx#fully_qualified_vs._relative_paths [Readable Stream]: stream.html#stream_class_stream_readable [Writable Stream]: stream.html#stream_class_stream_writable [inode]: https://en.wikipedia.org/wiki/Inode diff --git a/doc/api/http.md b/doc/api/http.md index cd66a2063b22f8..b19ffb6d8e1fb0 100644 --- a/doc/api/http.md +++ b/doc/api/http.md @@ -157,6 +157,42 @@ socket/stream from this function, or by passing the socket/stream to `callback`. `callback` has a signature of `(err, stream)`. +### agent.keepSocketAlive(socket) + + +* `socket` {net.Socket} + +Called when `socket` is detached from a request and could be persisted by the +Agent. Default behavior is to: + +```js +socket.unref(); +socket.setKeepAlive(agent.keepAliveMsecs); +``` + +This method can be overridden by a particular `Agent` subclass. If this +method returns a falsy value, the socket will be destroyed instead of persisting +it for use with the next request. + +### agent.reuseSocket(socket, request) + + +* `socket` {net.Socket} +* `request` {http.ClientRequest} + +Called when `socket` is attached to `request` after being persisted because of +the keep-alive options. Default behavior is to: + +```js +socket.ref(); +``` + +This method can be overridden by a particular `Agent` subclass. + ### agent.destroy() -* `options` {Object | string} Accepts the same `options` as +* `options` {Object | string | URL} Accepts the same `options` as [`http.request()`][], with the `method` always set to `GET`. Properties that are inherited from the prototype are ignored. * `callback` {Function} @@ -1636,9 +1676,13 @@ requests. ## http.request(options[, callback]) -* `options` {Object | string} +* `options` {Object | string | URL} * `protocol` {string} Protocol to use. Defaults to `http:`. * `host` {string} A domain name or IP address of the server to issue the request to. Defaults to `localhost`. @@ -1677,8 +1721,9 @@ added: v0.3.6 Node.js maintains several connections per server to make HTTP requests. This function allows one to transparently issue requests. -`options` can be an object or a string. If `options` is a string, it is -automatically parsed with [`url.parse()`][]. +`options` can be an object, a string, or a [`URL`][] object. If `options` is a +string, it is automatically parsed with [`url.parse()`][]. If it is a [`URL`][] +object, it will be automatically converted to an ordinary `options` object. The optional `callback` parameter will be added as a one time listener for the [`'response'`][] event. @@ -1750,6 +1795,18 @@ There are a few special headers that should be noted. * Sending an Authorization header will override using the `auth` option to compute basic authentication. +Example using a [`URL`][] as `options`: + +```js +const { URL } = require('url'); + +const options = new URL('http://abc:xyz@example.com'); + +const req = http.request(options, (res) => { + // ... +}); +``` + [`'checkContinue'`]: #http_event_checkcontinue [`'listening'`]: net.html#net_event_listening [`'request'`]: #http_event_request @@ -1757,6 +1814,7 @@ There are a few special headers that should be noted. [`Agent`]: #http_class_http_agent [`EventEmitter`]: events.html#events_class_eventemitter [`TypeError`]: errors.html#errors_class_typeerror +[`URL`]: url.html#url_the_whatwg_url_api [`agent.createConnection()`]: #http_agent_createconnection_options_callback [`destroy()`]: #http_agent_destroy [`http.Agent`]: #http_class_http_agent diff --git a/doc/api/https.md b/doc/api/https.md index 0f42366a705255..f4000335a00770 100644 --- a/doc/api/https.md +++ b/doc/api/https.md @@ -115,15 +115,20 @@ See [`http.listen()`][] for details. ## https.get(options[, callback]) -- `options` {Object | string} Accepts the same `options` as +- `options` {Object | string | URL} Accepts the same `options` as [`https.request()`][], with the `method` always set to `GET`. - `callback` {Function} Like [`http.get()`][] but for HTTPS. -`options` can be an object or a string. If `options` is a string, it is -automatically parsed with [`url.parse()`][]. +`options` can be an object, a string, or a [`URL`][] object. If `options` is a +string, it is automatically parsed with [`url.parse()`][]. If it is a [`URL`][] +object, it will be automatically converted to an ordinary `options` object. Example: @@ -153,8 +158,12 @@ Global instance of [`https.Agent`][] for all HTTPS client requests. ## https.request(options[, callback]) -- `options` {Object | string} Accepts all `options` from [`http.request()`][], +- `options` {Object | string | URL} Accepts all `options` from [`http.request()`][], with some differences in default values: - `protocol` Defaults to `https:` - `port` Defaults to `443`. @@ -168,8 +177,9 @@ The following additional `options` from [`tls.connect()`][] are also accepted wh custom [`Agent`][]: `pfx`, `key`, `passphrase`, `cert`, `ca`, `ciphers`, `rejectUnauthorized`, `secureProtocol`, `servername` -`options` can be an object or a string. If `options` is a string, it is -automatically parsed with [`url.parse()`][]. +`options` can be an object, a string, or a [`URL`][] object. If `options` is a +string, it is automatically parsed with [`url.parse()`][]. If it is a [`URL`][] +object, it will be automatically converted to an ordinary `options` object. Example: @@ -235,7 +245,20 @@ const req = https.request(options, (res) => { }); ``` +Example using a [`URL`][] as `options`: + +```js +const { URL } = require('url'); + +const options = new URL('https://abc:xyz@example.com'); + +const req = https.request(options, (res) => { + // ... +}); +``` + [`Agent`]: #https_class_https_agent +[`URL`]: url.html#url_the_whatwg_url_api [`http.Agent`]: http.html#http_class_http_agent [`http.Server#keepAliveTimeout`]: http.html#http_server_keepalivetimeout [`http.Server#setTimeout()`]: http.html#http_server_settimeout_msecs_callback diff --git a/doc/api/inspector.md b/doc/api/inspector.md index f90b823b78f511..3336874b949269 100644 --- a/doc/api/inspector.md +++ b/doc/api/inspector.md @@ -10,6 +10,30 @@ It can be accessed using: const inspector = require('inspector'); ``` +## inspector.open([port[, host[, wait]]]) + +* port {number} Port to listen on for inspector connections. Optional, + defaults to what was specified on the CLI. +* host {string} Host to listen on for inspector connections. Optional, + defaults to what was specified on the CLI. +* wait {boolean} Block until a client has connected. Optional, defaults + to false. + +Activate inspector on host and port. Equivalent to `node +--inspect=[[host:]port]`, but can be done programatically after node has +started. + +If wait is `true`, will block until a client has connected to the inspect port +and flow control has been passed to the debugger client. + +### inspector.close() + +Deactivate the inspector. Blocks until there are no active connections. + +### inspector.url() + +Return the URL of the active inspector, or `undefined` if there is none. + ## Class: inspector.Session The `inspector.Session` is used for dispatching messages to the V8 inspector @@ -58,7 +82,9 @@ event, and prints the reason for program suspension whenever program execution is suspended (through breakpoints, for example): ```js -session.on('Debugger.paused', ({params}) => console.log(params.hitBreakpoints)); +session.on('Debugger.paused', ({ params }) => { + console.log(params.hitBreakpoints); +}); // [ '/node/test/inspector/test-bindings.js:11:0' ] ``` @@ -108,6 +134,7 @@ with an error. [`session.connect()`] will need to be called to be able to send messages again. Reconnected session will lose all inspector state, such as enabled agents or configured breakpoints. + [`session.connect()`]: #sessionconnect [`Debugger.paused`]: https://chromedevtools.github.io/devtools-protocol/v8/Debugger/#event-paused [`EventEmitter`]: events.html#events_class_eventemitter diff --git a/doc/api/n-api.md b/doc/api/n-api.md index e98233215a9c97..668e3fab18f8a5 100644 --- a/doc/api/n-api.md +++ b/doc/api/n-api.md @@ -60,6 +60,14 @@ For example: #include ``` +As the feature is experimental it must be enabled with the +following command line +[option](https://nodejs.org/dist/latest-v8.x/docs/api/cli.html#cli_napi_modules): + +```bash +--napi-modules +``` + ## Basic N-API Data Types N-API exposes the following fundamental datatypes as abstractions that are @@ -530,7 +538,7 @@ Taking the earlier example, adding calls to [`napi_open_handle_scope`][] and is valid throughout the execution of the loop: ```C -for (int i = 0; i < 1000000; i++) {napi_ +for (int i = 0; i < 1000000; i++) { napi_handle_scope scope; napi_status status = napi_open_handle_scope(env, &scope); if (status != napi_ok) { @@ -695,7 +703,7 @@ added: v8.0.0 NODE_EXTERN napi_status napi_create_reference(napi_env env, napi_value value, int initial_refcount, - ndapi_ref* result); + napi_ref* result); ``` - `[in] env`: The environment that the API is invoked under. @@ -1059,20 +1067,24 @@ napi_status napi_create_external(napi_env env, ``` - `[in] env`: The environment that the API is invoked under. -- `[in] data`: Raw pointer to the external data being wrapped. -- `[in] finalize_cb`: Optional callback to call when the wrapped object +- `[in] data`: Raw pointer to the external data. +- `[in] finalize_cb`: Optional callback to call when the external value is being collected. - `[in] finalize_hint`: Optional hint to pass to the finalize callback during collection. -- `[out] result`: A `napi_value` representing an external object. +- `[out] result`: A `napi_value` representing an external value. Returns `napi_ok` if the API succeeded. -This API allocates a JavaScript object with external data attached to it. -This is used to wrap native objects and project them into JavaScript. -The API allows the caller to pass in a finalize callback, in case the -underlying native resource needs to be cleaned up when the wrapper -JavaScript object gets collected. +This API allocates a JavaScript value with external data attached to it. This +is used to pass external data through JavaScript code, so it can be retrieved +later by native code. The API allows the caller to pass in a finalize callback, +in case the underlying native resource needs to be cleaned up when the external +JavaScript value gets collected. + +*Note*: The created value is not an object, and therefore does not support +additional properties. It is considered a distinct value type: calling +`napi_typeof()` with an external value yields `napi_external`. #### napi_create_external_arraybuffer ```js -const Readable = require('stream').Readable; +const { Readable } = require('stream'); const myReadable = new Readable({ read(size) { @@ -1682,7 +1697,7 @@ The following is a basic example of a Readable stream that emits the numerals from 1 to 1,000,000 in ascending order, and then ends. ```js -const Readable = require('stream').Readable; +const { Readable } = require('stream'); class Counter extends Readable { constructor(opt) { @@ -1739,7 +1754,7 @@ constructor and implement *both* the `readable._read()` and For example: ```js -const Duplex = require('stream').Duplex; +const { Duplex } = require('stream'); class MyDuplex extends Duplex { constructor(options) { @@ -1752,7 +1767,7 @@ class MyDuplex extends Duplex { Or, when using pre-ES6 style constructors: ```js -const Duplex = require('stream').Duplex; +const { Duplex } = require('stream'); const util = require('util'); function MyDuplex(options) { @@ -1766,7 +1781,7 @@ util.inherits(MyDuplex, Duplex); Or, using the Simplified Constructor approach: ```js -const Duplex = require('stream').Duplex; +const { Duplex } = require('stream'); const myDuplex = new Duplex({ read(size) { @@ -1789,7 +1804,7 @@ incoming written data via the [Writable][] interface that is read back out via the [Readable][] interface. ```js -const Duplex = require('stream').Duplex; +const { Duplex } = require('stream'); const kSource = Symbol('source'); class MyDuplex extends Duplex { @@ -1830,7 +1845,7 @@ that accepts JavaScript numbers that are converted to hexadecimal strings on the Readable side. ```js -const Transform = require('stream').Transform; +const { Transform } = require('stream'); // All Transform streams are also Duplex Streams const myTransform = new Transform({ @@ -1895,7 +1910,7 @@ the output on the Readable side is not consumed. For example: ```js -const Transform = require('stream').Transform; +const { Transform } = require('stream'); class MyTransform extends Transform { constructor(options) { @@ -1908,7 +1923,7 @@ class MyTransform extends Transform { Or, when using pre-ES6 style constructors: ```js -const Transform = require('stream').Transform; +const { Transform } = require('stream'); const util = require('util'); function MyTransform(options) { @@ -1922,7 +1937,7 @@ util.inherits(MyTransform, Transform); Or, using the Simplified Constructor approach: ```js -const Transform = require('stream').Transform; +const { Transform } = require('stream'); const myTransform = new Transform({ transform(chunk, encoding, callback) { diff --git a/doc/api/string_decoder.md b/doc/api/string_decoder.md index 6b94b6bc3fb896..5757ba6e2b3440 100644 --- a/doc/api/string_decoder.md +++ b/doc/api/string_decoder.md @@ -7,13 +7,13 @@ strings in a manner that preserves encoded multi-byte UTF-8 and UTF-16 characters. It can be accessed using: ```js -const StringDecoder = require('string_decoder').StringDecoder; +const { StringDecoder } = require('string_decoder'); ``` The following example shows the basic use of the `StringDecoder` class. ```js -const StringDecoder = require('string_decoder').StringDecoder; +const { StringDecoder } = require('string_decoder'); const decoder = new StringDecoder('utf8'); const cent = Buffer.from([0xC2, 0xA2]); @@ -32,7 +32,7 @@ In the following example, the three UTF-8 encoded bytes of the European Euro symbol (`€`) are written over three separate operations: ```js -const StringDecoder = require('string_decoder').StringDecoder; +const { StringDecoder } = require('string_decoder'); const decoder = new StringDecoder('utf8'); decoder.write(Buffer.from([0xE2])); diff --git a/doc/api/tls.md b/doc/api/tls.md index 6fabd83d9ce3e7..6229c7a79faed4 100644 --- a/doc/api/tls.md +++ b/doc/api/tls.md @@ -782,7 +782,7 @@ changes: verification fails; `err.code` contains the OpenSSL error code. Defaults to `true`. * `NPNProtocols` {string[]|Buffer[]|Uint8Array[]|Buffer|Uint8Array} - An array of strings, Buffer`s or `Uint8Array`s, or a single `Buffer` or + An array of strings, `Buffer`s or `Uint8Array`s, or a single `Buffer` or `Uint8Array` containing supported NPN protocols. `Buffer`s should have the format `[len][name][len][name]...` e.g. `0x05hello0x05world`, where the first byte is the length of the next protocol name. Passing an array is @@ -1034,7 +1034,7 @@ changes: connection which is not authorized with the list of supplied CAs. This option only has an effect if `requestCert` is `true`. Defaults to `true`. * `NPNProtocols` {string[]|Buffer[]|Uint8Array[]|Buffer|Uint8Array} - An array of strings, Buffer`s or `Uint8Array`s, or a single `Buffer` or + An array of strings, `Buffer`s or `Uint8Array`s, or a single `Buffer` or `Uint8Array` containing supported NPN protocols. `Buffer`s should have the format `[len][name][len][name]...` e.g. `0x05hello0x05world`, where the first byte is the length of the next protocol name. Passing an array is diff --git a/doc/api/url.md b/doc/api/url.md index 06a5618949bf7f..b6a6173fe488b8 100644 --- a/doc/api/url.md +++ b/doc/api/url.md @@ -55,7 +55,7 @@ properties of a WHATWG `URL` object. Parsing the URL string using the WHATWG API: ```js -const URL = require('url').URL; +const { URL } = require('url'); const myURL = new URL('https://user:pass@sub.host.com:8080/p/a/t/h?query=string#hash'); ``` @@ -92,6 +92,7 @@ Creates a new `URL` object by parsing the `input` relative to the `base`. If `base` is passed as a string, it will be parsed equivalent to `new URL(base)`. ```js +const { URL } = require('url'); const myURL = new URL('/foo', 'https://example.org/'); // https://example.org/foo ``` @@ -101,7 +102,8 @@ that an effort will be made to coerce the given values into strings. For instance: ```js -const myURL = new URL({toString: () => 'https://example.org/'}); +const { URL } = require('url'); +const myURL = new URL({ toString: () => 'https://example.org/' }); // https://example.org/ ``` @@ -109,6 +111,7 @@ Unicode characters appearing within the hostname of `input` will be automatically converted to ASCII using the [Punycode][] algorithm. ```js +const { URL } = require('url'); const myURL = new URL('https://你好你好'); // https://xn--6qqa088eba/ ``` @@ -122,6 +125,7 @@ Additional [examples of parsed URLs][] may be found in the WHATWG URL Standard. Gets and sets the fragment portion of the URL. ```js +const { URL } = require('url'); const myURL = new URL('https://example.org/foo#bar'); console.log(myURL.hash); // Prints #bar @@ -143,6 +147,7 @@ percent-encode may vary somewhat from what the [`url.parse()`][] and Gets and sets the host portion of the URL. ```js +const { URL } = require('url'); const myURL = new URL('https://example.org:81/foo'); console.log(myURL.host); // Prints example.org:81 @@ -163,6 +168,7 @@ Gets and sets the hostname portion of the URL. The key difference between port. ```js +const { URL } = require('url'); const myURL = new URL('https://example.org:81/foo'); console.log(myURL.hostname); // Prints example.org @@ -181,11 +187,13 @@ Invalid hostname values assigned to the `hostname` property are ignored. Gets and sets the serialized URL. ```js +const { URL } = require('url'); const myURL = new URL('https://example.org/foo'); console.log(myURL.href); // Prints https://example.org/foo myURL.href = 'https://example.com/bar'; +console.log(myURL.href); // Prints https://example.com/bar ``` @@ -208,12 +216,14 @@ may be contained within the hostname will be encoded as-is without [Punycode][] encoding. ```js +const { URL } = require('url'); const myURL = new URL('https://example.org/foo/bar?baz'); console.log(myURL.origin); // Prints https://example.org ``` ```js +const { URL } = require('url'); const idnURL = new URL('https://你好你好'); console.log(idnURL.origin); // Prints https://你好你好 @@ -229,6 +239,7 @@ console.log(idnURL.hostname); Gets and sets the password portion of the URL. ```js +const { URL } = require('url'); const myURL = new URL('https://abc:xyz@example.com'); console.log(myURL.password); // Prints xyz @@ -250,6 +261,7 @@ percent-encode may vary somewhat from what the [`url.parse()`][] and Gets and sets the path portion of the URL. ```js +const { URL } = require('url'); const myURL = new URL('https://example.org/abc/xyz?123'); console.log(myURL.pathname); // Prints /abc/xyz @@ -271,6 +283,7 @@ to percent-encode may vary somewhat from what the [`url.parse()`][] and Gets and sets the port portion of the URL. ```js +const { URL } = require('url'); const myURL = new URL('https://example.org:8888'); console.log(myURL.port); // Prints 8888 @@ -326,13 +339,14 @@ lies outside the range denoted above, it is ignored. Gets and sets the protocol portion of the URL. ```js +const { URL } = require('url'); const myURL = new URL('https://example.org'); console.log(myURL.protocol); // Prints https: myURL.protocol = 'ftp'; console.log(myURL.href); - // Prints ftp://example.org + // Prints ftp://example.org/ ``` Invalid URL protocol values assigned to the `protocol` property are ignored. @@ -344,6 +358,7 @@ Invalid URL protocol values assigned to the `protocol` property are ignored. Gets and sets the serialized query portion of the URL. ```js +const { URL } = require('url'); const myURL = new URL('https://example.org/abc?123'); console.log(myURL.search); // Prints ?123 @@ -374,13 +389,14 @@ documentation for details. Gets and sets the username portion of the URL. ```js +const { URL } = require('url'); const myURL = new URL('https://abc:xyz@example.com'); console.log(myURL.username); // Prints abc myURL.username = '123'; console.log(myURL.href); - // Prints https://123:xyz@example.com + // Prints https://123:xyz@example.com/ ``` Any invalid URL characters appearing in the value assigned the `username` @@ -411,6 +427,7 @@ This method is automatically called when an `URL` object is serialized with [`JSON.stringify()`][]. ```js +const { URL } = require('url'); const myURLs = [ new URL('https://www.example.com'), new URL('https://test.example.org') @@ -515,7 +532,7 @@ const params = new URLSearchParams({ query: ['first', 'second'] }); console.log(params.getAll('query')); - // Prints ['first,second'] + // Prints [ 'first,second' ] console.log(params.toString()); // Prints 'user=abc&query=first%2Csecond' ``` @@ -571,7 +588,8 @@ console.log(params.toString()); new URLSearchParams([ ['user', 'abc', 'error'] ]); - // Throws TypeError: Each query pair must be a name/value tuple + // Throws TypeError [ERR_INVALID_TUPLE]: + // Each query pair must be an iterable [name, value] tuple ``` #### urlSearchParams.append(name, value) @@ -605,7 +623,7 @@ Alias for [`urlSearchParams[@@iterator]()`][`urlSearchParams@@iterator()`]. Iterates over each name-value pair in the query and invokes the given function. ```js -const URL = require('url').URL; +const { URL } = require('url'); const myURL = new URL('https://example.org/?a=b&c=d'); myURL.searchParams.forEach((value, name, searchParams) => { console.log(name, value, myURL.searchParams === searchParams); @@ -694,6 +712,7 @@ with the same name is preserved. This method can be used, in particular, to increase cache hits. ```js +const { URLSearchParams } = require('url'); const params = new URLSearchParams('query[]=abc&type=search&query[]=123'); params.sort(); console.log(params.toString()); @@ -808,6 +827,7 @@ of the output. For example: ```js +const { URL } = require('url'); const myURL = new URL('https://a:b@你好你好?abc#foo'); console.log(myURL.href); @@ -816,8 +836,8 @@ console.log(myURL.href); console.log(myURL.toString()); // Prints https://a:b@xn--6qqa088eba/?abc#foo -console.log(url.format(myURL, {fragment: false, unicode: true, auth: false})); - // Prints 'https://你好你好?abc' +console.log(url.format(myURL, { fragment: false, unicode: true, auth: false })); + // Prints 'https://你好你好/?abc' ``` ## Legacy URL API @@ -1041,6 +1061,7 @@ manner similar to that of a Web browser resolving an anchor tag HREF. For example: ```js +const url = require('url'); url.resolve('/one/two/three', 'four'); // '/one/two/four' url.resolve('http://example.com/', '/one'); // 'http://example.com/one' url.resolve('http://example.com/one', '/two'); // 'http://example.com/two' @@ -1096,7 +1117,7 @@ using the [Punycode][] algorithm. Note, however, that a hostname *may* contain *both* Punycode encoded and percent-encoded characters. For example: ```js -const URL = require('url').URL; +const { URL } = require('url'); const myURL = new URL('https://%CF%80.com/foo'); console.log(myURL.href); // Prints https://xn--1xa.com/foo diff --git a/doc/api/util.md b/doc/api/util.md index 6e35185d024c33..839bdadf76e1ec 100644 --- a/doc/api/util.md +++ b/doc/api/util.md @@ -55,6 +55,7 @@ added: v0.8.0 The `util.deprecate()` method wraps the given `function` or class in such a way that it is marked as deprecated. + ```js const util = require('util'); @@ -196,9 +197,6 @@ ES6 example using `class` and `extends` const EventEmitter = require('events'); class MyStream extends EventEmitter { - constructor() { - super(); - } write(data) { this.emit('data', data); } @@ -329,8 +327,8 @@ class Box { // Five space padding because that's the size of "Box< ". const padding = ' '.repeat(5); const inner = util.inspect(this.value, newOptions) - .replace(/\n/g, '\n' + padding); - return options.stylize('Box', 'special') + '< ' + inner + ' >'; + .replace(/\n/g, `\n${padding}`); + return `${options.stylize('Box', 'special')}< ${inner} >`; } } @@ -392,7 +390,7 @@ option properties directly is also supported. ```js const util = require('util'); -const arr = Array(101); +const arr = Array(101).fill(0); console.log(arr); // logs the truncated array util.inspect.defaultOptions.maxArrayLength = null; diff --git a/doc/api/vm.md b/doc/api/vm.md index aa36319ac20ffc..288dcaf9e383d1 100644 --- a/doc/api/vm.md +++ b/doc/api/vm.md @@ -442,18 +442,17 @@ to the `http` module passed to it. For instance: 'use strict'; const vm = require('vm'); -const code = -`(function(require) { +const code = ` +(function(require) { + const http = require('http'); - const http = require('http'); + http.createServer((request, response) => { + response.writeHead(200, { 'Content-Type': 'text/plain' }); + response.end('Hello World\\n'); + }).listen(8124); - http.createServer( (request, response) => { - response.writeHead(200, {'Content-Type': 'text/plain'}); - response.end('Hello World\\n'); - }).listen(8124); - - console.log('Server running at http://127.0.0.1:8124/'); - })`; + console.log('Server running at http://127.0.0.1:8124/'); +})`; vm.runInThisContext(code)(require); ``` diff --git a/doc/api/zlib.md b/doc/api/zlib.md index b7b9170b784a70..462103bd642813 100644 --- a/doc/api/zlib.md +++ b/doc/api/zlib.md @@ -102,10 +102,10 @@ http.createServer((request, response) => { // Note: This is not a conformant accept-encoding parser. // See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3 - if (acceptEncoding.match(/\bdeflate\b/)) { + if (/\bdeflate\b/.test(acceptEncoding)) { response.writeHead(200, { 'Content-Encoding': 'deflate' }); raw.pipe(zlib.createDeflate()).pipe(response); - } else if (acceptEncoding.match(/\bgzip\b/)) { + } else if (/\bgzip\b/.test(acceptEncoding)) { response.writeHead(200, { 'Content-Encoding': 'gzip' }); raw.pipe(zlib.createGzip()).pipe(response); } else { @@ -119,7 +119,7 @@ By default, the `zlib` methods will throw an error when decompressing truncated data. However, if it is known that the data is incomplete, or the desire is to inspect only the beginning of a compressed file, it is possible to suppress the default error handling by changing the flushing -method that is used to compressed the last chunk of input data: +method that is used to decompress the last chunk of input data: ```js // This is a truncated version of the buffer from the above examples @@ -127,7 +127,7 @@ const buffer = Buffer.from('eJzT0yMA', 'base64'); zlib.unzip( buffer, - {finishFlush: zlib.constants.Z_SYNC_FLUSH}, + { finishFlush: zlib.constants.Z_SYNC_FLUSH }, (err, buffer) => { if (!err) { console.log(buffer.toString()); @@ -301,6 +301,7 @@ ignored by the decompression classes. * `strategy` {integer} (compression only) * `dictionary` {Buffer|TypedArray|DataView} (deflate/inflate only, empty dictionary by default) +* `info` {boolean} (If `true`, returns an object with `buffer` and `engine`) See the description of `deflateInit2` and `inflateInit2` at for more information on these. @@ -385,6 +386,17 @@ added: v0.5.8 Not exported by the `zlib` module. It is documented here because it is the base class of the compressor/decompressor classes. +### zlib.bytesRead + + +* {number} + +The `zlib.bytesRead` property specifies the number of bytes read by the engine +before the bytes are processed (compressed or decompressed, as appropriate for +the derived class). + ### zlib.flush([kind], callback) -## Notes +### Notes 1Node.js 0.12 and older are intentionally omitted from this document as their support is ending soon. diff --git a/doc/guides/writing-and-running-benchmarks.md b/doc/guides/writing-and-running-benchmarks.md index f608dbd624c2e4..148082de4b6b3f 100644 --- a/doc/guides/writing-and-running-benchmarks.md +++ b/doc/guides/writing-and-running-benchmarks.md @@ -335,7 +335,7 @@ the code inside the `main` function if it's more than just declaration. ```js 'use strict'; const common = require('../common.js'); -const SlowBuffer = require('buffer').SlowBuffer; +const { SlowBuffer } = require('buffer'); const configs = { // Number of operations, specified here so they show up in the report. diff --git a/doc/guides/writing-tests.md b/doc/guides/writing-tests.md index 4d15f73ae8395e..688e13a3237d9f 100644 --- a/doc/guides/writing-tests.md +++ b/doc/guides/writing-tests.md @@ -38,7 +38,7 @@ const server = http.createServer(common.mustCall((req, res) => { // 10 server.listen(0, () => { // 13 http.get({ // 14 port: server.address().port, // 15 - headers: {'Test': 'Düsseldorf'} // 16 + headers: { 'Test': 'Düsseldorf' } // 16 }, common.mustCall((res) => { // 17 assert.strictEqual(res.statusCode, 200); // 18 server.close(); // 19 @@ -232,8 +232,8 @@ For performance considerations, we only use a selected subset of ES.Next features in JavaScript code in the `lib` directory. However, when writing tests, for the ease of backporting, it is encouraged to use those ES.Next features that can be used directly without a flag in [all maintained branches] -(https://github.com/nodejs/lts), you can check [node.green](http://node.green) -for all available features in each release. +(https://github.com/nodejs/lts). [node.green](http://node.green/) lists +available features in each release. For example: @@ -274,8 +274,8 @@ These imported tests will be wrapped like this: /* eslint-enable */ ``` -If you want to improve tests that have been imported this way, please send -a PR to the upstream project first. When your proposed change is merged in +To improve tests that have been imported this way, please send +a PR to the upstream project first. When the proposed change is merged in the upstream project, send another PR here to update Node.js accordingly. Be sure to update the hash in the URL following `WPT Refs:`. @@ -319,14 +319,14 @@ static void at_exit_callback(void* arg) { ``` Next add the test to the `sources` in the `cctest` target in node.gyp: -``` +```console 'sources': [ 'test/cctest/test_env.cc', ... ], ``` The test can be executed by running the `cctest` target: -``` +```console $ make cctest ``` diff --git a/doc/onboarding-extras.md b/doc/onboarding-extras.md index a9f4885501e537..3f174843397b3d 100644 --- a/doc/onboarding-extras.md +++ b/doc/onboarding-extras.md @@ -22,11 +22,12 @@ | `lib/timers` | @fishrock123, @misterdjules | | `lib/util` | @bnoordhuis, @cjihrig, @evanlucas | | `lib/zlib` | @addaleax, @bnoordhuis, @indutny | -| `src/async-wrap.*` | @trevnorris | +| `src/async-wrap.*` | @nodejs/async_hooks | +| `src/node_api.*` | @nodejs/n-api | | `src/node_crypto.*` | @nodejs/crypto | | `test/*` | @nodejs/testing | | `tools/eslint`, `.eslintrc` | @not-an-aardvark, @silverwind, @trott | -| async_hooks | @nodejs/diagnostics | +| async_hooks | @nodejs/async_hooks for bugs/reviews (+ @nodejs/diagnostics for API) | | performance | @nodejs/performance | | upgrading V8 | @nodejs/v8, @nodejs/post-mortem | | upgrading npm | @fishrock123, @MylesBorins | diff --git a/doc/releases.md b/doc/releases.md index eafc906026d6b5..f1f82fdb9816bb 100644 --- a/doc/releases.md +++ b/doc/releases.md @@ -296,7 +296,7 @@ Create a new blog post by running the [nodejs.org release-post.js script](https: * The links to the download files won't be complete unless you waited for the ARMv6 builds. Any downloads that are missing will have `*Coming soon*` next to them. It's your responsibility to manually update these later when you have the outstanding builds. * The SHASUMS256.txt.asc content is at the bottom of the post. When you update the list of tarballs you'll need to copy/paste the new contents of this file to reflect those changes. * Always use pull-requests on the nodejs.org repo. Be respectful of that working group, but you shouldn't have to wait for PR sign-off. Opening a PR and merging it immediately _should_ be fine. However, please follow the following commit message format: -``` +```console Blog: vX.Y.Z release post Refs: diff --git a/lib/_http_agent.js b/lib/_http_agent.js index d791a961c76fe2..9f0efe82d14313 100644 --- a/lib/_http_agent.js +++ b/lib/_http_agent.js @@ -90,15 +90,16 @@ function Agent(options) { if (count > self.maxSockets || freeLen >= self.maxFreeSockets) { socket.destroy(); - } else { + } else if (self.keepSocketAlive(socket)) { freeSockets = freeSockets || []; self.freeSockets[name] = freeSockets; - socket.setKeepAlive(true, self.keepAliveMsecs); - socket.unref(); socket[async_id_symbol] = -1; socket._httpMessage = null; self.removeSocket(socket, options); freeSockets.push(socket); + } else { + // Implementation doesn't want to keep socket alive + socket.destroy(); } } else { socket.destroy(); @@ -168,13 +169,13 @@ Agent.prototype.addRequest = function addRequest(req, options, port/*legacy*/, var socket = this.freeSockets[name].shift(); // Assign the handle a new asyncId and run any init() hooks. socket._handle.asyncReset(); - debug('have free socket'); + socket[async_id_symbol] = socket._handle.getAsyncId(); // don't leak if (!this.freeSockets[name].length) delete this.freeSockets[name]; - socket.ref(); + this.reuseSocket(socket, req); req.onSocket(socket); this.sockets[name].push(socket); } else if (sockLen < this.maxSockets) { @@ -305,6 +306,18 @@ Agent.prototype.removeSocket = function removeSocket(s, options) { } }; +Agent.prototype.keepSocketAlive = function keepSocketAlive(socket) { + socket.setKeepAlive(true, this.keepAliveMsecs); + socket.unref(); + + return true; +}; + +Agent.prototype.reuseSocket = function reuseSocket(socket, req) { + debug('have free socket'); + socket.ref(); +}; + Agent.prototype.destroy = function destroy() { var sets = [this.freeSockets, this.sockets]; for (var s = 0; s < sets.length; s++) { diff --git a/lib/_http_client.js b/lib/_http_client.js index 7707fa74cf784a..3c6950794ac9e8 100644 --- a/lib/_http_client.js +++ b/lib/_http_client.js @@ -451,7 +451,7 @@ function socketOnData(d) { var ret = parser.execute(d); if (ret instanceof Error) { - debug('parse error'); + debug('parse error', ret); freeParser(parser, req, socket); socket.destroy(); req.emit('error', ret); diff --git a/lib/_http_incoming.js b/lib/_http_incoming.js index 9151836ad83551..6e5aff1cc9c1f2 100644 --- a/lib/_http_incoming.js +++ b/lib/_http_incoming.js @@ -314,6 +314,9 @@ function _addHeaderLine(field, value, dest) { IncomingMessage.prototype._dump = function _dump() { if (!this._dumped) { this._dumped = true; + // If there is buffered data, it may trigger 'data' events. + // Remove 'data' event listeners explicitly. + this.removeAllListeners('data'); this.resume(); } }; diff --git a/lib/_http_server.js b/lib/_http_server.js index 03fbd47f974108..9143fa1fc46bcb 100644 --- a/lib/_http_server.js +++ b/lib/_http_server.js @@ -462,7 +462,7 @@ function socketOnError(e) { function onParserExecuteCommon(server, socket, parser, state, ret, d) { if (ret instanceof Error) { - debug('parse error'); + debug('parse error', ret); socketOnError.call(socket, ret); } else if (parser.incoming && parser.incoming.upgrade) { // Upgrade or CONNECT diff --git a/lib/assert.js b/lib/assert.js index 0f0f3f165aeeb2..bd36c9a16d1b38 100644 --- a/lib/assert.js +++ b/lib/assert.js @@ -262,29 +262,35 @@ function _deepEqual(actual, expected, strict, memos) { // Use memos to handle cycles. if (!memos) { memos = { - actual: { map: new Map(), position: 0 }, - expected: { map: new Map(), position: 0 } + actual: new Map(), + expected: new Map(), + position: 0 }; - } - - const actualPosition = memos.actual.map.get(actual); - if (actualPosition !== undefined) { - if (actualPosition === memos.expected.map.get(expected)) { - return true; - } } else { - memos.actual.map.set(actual, memos.actual.position++); + memos.position++; } - if (!memos.expected.map.has(expected)) { - memos.expected.map.set(expected, memos.expected.position++); + + if (memos.actual.has(actual)) { + return memos.actual.get(actual) === memos.expected.get(expected); } - return objEquiv(actual, expected, strict, memos); + memos.actual.set(actual, memos.position); + memos.expected.set(expected, memos.position); + + const areEq = objEquiv(actual, expected, strict, memos); + + memos.actual.delete(actual); + memos.expected.delete(expected); + + return areEq; } -function setHasSimilarElement(set, val1, strict, memo) { - if (set.has(val1)) +function setHasSimilarElement(set, val1, usedEntries, strict, memo) { + if (set.has(val1)) { + if (usedEntries) + usedEntries.add(val1); return true; + } // In strict mode the only things which can match a primitive or a function // will already be detected by set.has(val1). @@ -293,8 +299,14 @@ function setHasSimilarElement(set, val1, strict, memo) { // Otherwise go looking. for (const val2 of set) { - if (_deepEqual(val1, val2, strict, memo)) + if (usedEntries && usedEntries.has(val2)) + continue; + + if (_deepEqual(val1, val2, strict, memo)) { + if (usedEntries) + usedEntries.add(val2); return true; + } } return false; @@ -311,21 +323,33 @@ function setEquiv(a, b, strict, memo) { if (a.size !== b.size) return false; + // This is a set of the entries in b which have been consumed in our pairwise + // comparison. + // + // When the sets contain only value types (eg, lots of numbers), and we're in + // strict mode, we don't need to match off the entries in a pairwise way. In + // that case this initialization is done lazily to avoid the allocation & + // bookkeeping cost. Unfortunately, we can't get away with that in non-strict + // mode. + let usedEntries = null; + for (const val1 of a) { + if (usedEntries == null && (!strict || typeof val1 === 'object')) + usedEntries = new Set(); + // If the value doesn't exist in the second set by reference, and its an // object or an array we'll need to go hunting for something thats // deep-equal to it. Note that this is O(n^2) complexity, and will get // slower if large, very similar sets / maps are nested inside. // Unfortunately there's no real way around this. - if (!setHasSimilarElement(b, val1, strict, memo)) { + if (!setHasSimilarElement(b, val1, usedEntries, strict, memo)) return false; - } } return true; } -function mapHasSimilarEntry(map, key1, item1, strict, memo) { +function mapHasSimilarEntry(map, key1, item1, usedEntries, strict, memo) { // To be able to handle cases like: // Map([[1, 'a'], ['1', 'b']]) vs Map([['1', 'a'], [1, 'b']]) // or: @@ -335,8 +359,11 @@ function mapHasSimilarEntry(map, key1, item1, strict, memo) { // This check is not strictly necessary. The loop performs this check, but // doing it here improves performance of the common case when reference-equal // keys exist (which includes all primitive-valued keys). - if (map.has(key1) && _deepEqual(item1, map.get(key1), strict, memo)) + if (map.has(key1) && _deepEqual(item1, map.get(key1), strict, memo)) { + if (usedEntries) + usedEntries.add(key1); return true; + } if (strict && (util.isPrimitive(key1) || util.isFunction(key1))) return false; @@ -346,8 +373,13 @@ function mapHasSimilarEntry(map, key1, item1, strict, memo) { if (key2 === key1) continue; + if (usedEntries && usedEntries.has(key2)) + continue; + if (_deepEqual(key1, key2, strict, memo) && _deepEqual(item1, item2, strict, memo)) { + if (usedEntries) + usedEntries.add(key2); return true; } } @@ -363,10 +395,15 @@ function mapEquiv(a, b, strict, memo) { if (a.size !== b.size) return false; + let usedEntries = null; + for (const [key1, item1] of a) { + if (usedEntries == null && (!strict || typeof key1 === 'object')) + usedEntries = new Set(); + // Just like setEquiv above, this hunt makes this function O(n^2) when // using objects and lists as keys - if (!mapHasSimilarEntry(b, key1, item1, strict, memo)) + if (!mapHasSimilarEntry(b, key1, item1, usedEntries, strict, memo)) return false; } diff --git a/lib/async_hooks.js b/lib/async_hooks.js index d5d5407b1de19b..aec73ed770f069 100644 --- a/lib/async_hooks.js +++ b/lib/async_hooks.js @@ -205,15 +205,15 @@ class AsyncResource { } this[trigger_id_symbol] = triggerId; - // Return immediately if there's nothing to do. - if (async_hook_fields[kInit] === 0) - return; - if (typeof type !== 'string' || type.length <= 0) throw new TypeError('type must be a string with length > 0'); if (!Number.isSafeInteger(triggerId) || triggerId < 0) throw new RangeError('triggerId must be an unsigned integer'); + // Return immediately if there's nothing to do. + if (async_hook_fields[kInit] === 0) + return; + processing_hook = true; for (var i = 0; i < active_hooks_array.length; i++) { if (typeof active_hooks_array[i][init_symbol] === 'function') { diff --git a/lib/dns.js b/lib/dns.js index 49cd9c929415b8..99f920bd208fad 100644 --- a/lib/dns.js +++ b/lib/dns.js @@ -60,33 +60,29 @@ function errnoException(err, syscall, hostname) { return ex; } - -// c-ares invokes a callback either synchronously or asynchronously, -// but the dns API should always invoke a callback asynchronously. -// -// This function makes sure that the callback is invoked asynchronously. -// It returns a function that invokes the callback within nextTick(). -// -// To avoid invoking unnecessary nextTick(), `immediately` property of -// returned function should be set to true after c-ares returned. -// -// Usage: -// -// function someAPI(callback) { -// callback = makeAsync(callback); -// channel.someAPI(..., callback); -// callback.immediately = true; -// } -function makeAsync(callback) { - return function asyncCallback(...args) { - if (asyncCallback.immediately) { - // The API already returned, we can invoke the callback immediately. - callback.apply(null, args); - } else { - args.unshift(callback); - process.nextTick.apply(null, args); - } - }; +const digits = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0-15 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 16-31 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 32-47 + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, // 48-63 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 64-79 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 80-95 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 96-111 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // 112-127 +]; +function isIPv4(str) { + if (!digits[str.charCodeAt(0)]) return false; + if (str.length === 1) return false; + if (str.charCodeAt(1) === 46/*'.'*/) + return true; + else if (!digits[str.charCodeAt(1)]) + return false; + if (str.length === 2) return false; + if (str.charCodeAt(2) === 46/*'.'*/) + return true; + else if (!digits[str.charCodeAt(2)]) + return false; + return (str.length > 3 && str.charCodeAt(3) === 46/*'.'*/); } @@ -97,25 +93,26 @@ function onlookup(err, addresses) { if (this.family) { this.callback(null, addresses[0], this.family); } else { - this.callback(null, addresses[0], addresses[0].indexOf(':') >= 0 ? 6 : 4); + this.callback(null, addresses[0], isIPv4(addresses[0]) ? 4 : 6); } } function onlookupall(err, addresses) { - var results = []; if (err) { return this.callback(errnoException(err, 'getaddrinfo', this.hostname)); } + var family = this.family; for (var i = 0; i < addresses.length; i++) { - results.push({ - address: addresses[i], - family: this.family || (addresses[i].indexOf(':') >= 0 ? 6 : 4) - }); + const addr = addresses[i]; + addresses[i] = { + address: addr, + family: family || (isIPv4(addr) ? 4 : 6) + }; } - this.callback(null, results); + this.callback(null, addresses); } @@ -153,13 +150,11 @@ function lookup(hostname, options, callback) { if (family !== 0 && family !== 4 && family !== 6) throw new TypeError('Invalid argument: family must be 4 or 6'); - callback = makeAsync(callback); - if (!hostname) { if (all) { - callback(null, []); + process.nextTick(callback, null, []); } else { - callback(null, null, family === 6 ? 6 : 4); + process.nextTick(callback, null, null, family === 6 ? 6 : 4); } return {}; } @@ -167,9 +162,10 @@ function lookup(hostname, options, callback) { var matchedFamily = isIP(hostname); if (matchedFamily) { if (all) { - callback(null, [{address: hostname, family: matchedFamily}]); + process.nextTick( + callback, null, [{address: hostname, family: matchedFamily}]); } else { - callback(null, hostname, matchedFamily); + process.nextTick(callback, null, hostname, matchedFamily); } return {}; } @@ -182,11 +178,9 @@ function lookup(hostname, options, callback) { var err = cares.getaddrinfo(req, hostname, family, hints); if (err) { - callback(errnoException(err, 'getaddrinfo', hostname)); + process.nextTick(callback, errnoException(err, 'getaddrinfo', hostname)); return {}; } - - callback.immediately = true; return req; } @@ -217,7 +211,6 @@ function lookupService(host, port, callback) { throw new TypeError('"callback" argument must be a function'); port = +port; - callback = makeAsync(callback); var req = new GetNameInfoReqWrap(); req.callback = callback; @@ -227,8 +220,6 @@ function lookupService(host, port, callback) { var err = cares.getnameinfo(req, host, port); if (err) throw errnoException(err, 'getnameinfo', host); - - callback.immediately = true; return req; } @@ -263,7 +254,6 @@ function resolver(bindingName) { throw new Error('"callback" argument must be a function'); } - callback = makeAsync(callback); var req = new QueryReqWrap(); req.bindingName = bindingName; req.callback = callback; @@ -272,7 +262,6 @@ function resolver(bindingName) { req.ttl = !!(options && options.ttl); var err = binding(req, name); if (err) throw errnoException(err, bindingName); - callback.immediately = true; return req; }; } diff --git a/lib/events.js b/lib/events.js index 1609d66192e333..742b629d87fcc1 100644 --- a/lib/events.js +++ b/lib/events.js @@ -306,10 +306,25 @@ EventEmitter.prototype.prependListener = }; function onceWrapper() { - this.target.removeListener(this.type, this.wrapFn); if (!this.fired) { + this.target.removeListener(this.type, this.wrapFn); this.fired = true; - this.listener.apply(this.target, arguments); + switch (arguments.length) { + case 0: + return this.listener.call(this.target); + case 1: + return this.listener.call(this.target, arguments[0]); + case 2: + return this.listener.call(this.target, arguments[0], arguments[1]); + case 3: + return this.listener.call(this.target, arguments[0], arguments[1], + arguments[2]); + default: + const args = new Array(arguments.length); + for (var i = 0; i < args.length; ++i) + args[i] = arguments[i]; + this.listener.apply(this.target, args); + } } } @@ -336,7 +351,7 @@ EventEmitter.prototype.prependOnceListener = return this; }; -// emits a 'removeListener' event iff the listener was removed +// Emits a 'removeListener' event if and only if the listener was removed. EventEmitter.prototype.removeListener = function removeListener(type, listener) { var list, events, position, i, originalListener; diff --git a/lib/fs.js b/lib/fs.js index e1b34326e48ffe..6273c975c120ce 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -28,7 +28,7 @@ const constants = process.binding('constants').fs; const { S_IFIFO, S_IFLNK, S_IFMT, S_IFREG, S_IFSOCK } = constants; const util = require('util'); const pathModule = require('path'); -const { isUint8Array } = process.binding('util'); +const { isUint8Array, createPromise, promiseResolve } = process.binding('util'); const binding = process.binding('fs'); const fs = exports; @@ -196,6 +196,10 @@ function Stats( this.ino = ino; this.size = size; this.blocks = blocks; + this.atimeMs = atim_msec; + this.mtimeMs = mtim_msec; + this.ctimeMs = ctim_msec; + this.birthtimeMs = birthtim_msec; this.atime = new Date(atim_msec + 0.5); this.mtime = new Date(mtim_msec + 0.5); this.ctime = new Date(ctim_msec + 0.5); @@ -308,6 +312,15 @@ fs.exists = function(path, callback) { } }; +Object.defineProperty(fs.exists, internalUtil.promisify.custom, { + value: (path) => { + const promise = createPromise(); + fs.exists(path, (exists) => promiseResolve(promise, exists)); + return promise; + } +}); + + fs.existsSync = function(path) { try { handleError((path = getPathFromURL(path))); @@ -2007,7 +2020,7 @@ ReadStream.prototype.close = function(cb) { if (this.closed || typeof this.fd !== 'number') { if (typeof this.fd !== 'number') { - this.once('open', this.close.bind(this, null)); + this.once('open', closeOnOpen); return; } return process.nextTick(() => this.emit('close')); @@ -2025,6 +2038,11 @@ ReadStream.prototype.close = function(cb) { this.fd = null; }; +// needed because as it will be called with arguments +// that does not match this.close() signature +function closeOnOpen(fd) { + this.close(); +} fs.createWriteStream = function(path, options) { return new WriteStream(path, options); diff --git a/lib/inspector.js b/lib/inspector.js index 1edc9fc3beebeb..e4c401a9951da7 100644 --- a/lib/inspector.js +++ b/lib/inspector.js @@ -1,8 +1,8 @@ 'use strict'; -const connect = process.binding('inspector').connect; const EventEmitter = require('events'); const util = require('util'); +const { connect, open, url } = process.binding('inspector'); if (!connect) throw new Error('Inspector is not available'); @@ -83,5 +83,8 @@ class Session extends EventEmitter { } module.exports = { + open: (port, host, wait) => open(port, host, !!wait), + close: process._debugEnd, + url: url, Session }; diff --git a/lib/internal/errors.js b/lib/internal/errors.js index 1ca0f59d793b41..153cf45bbbba07 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -114,6 +114,7 @@ E('ERR_ARG_NOT_ITERABLE', '%s must be iterable'); E('ERR_ASSERTION', (msg) => msg); E('ERR_INVALID_ARG_TYPE', invalidArgType); E('ERR_INVALID_CALLBACK', 'callback must be a function'); +E('ERR_INVALID_FD', (fd) => `"fd" must be a positive integer: ${fd}`); E('ERR_INVALID_FILE_URL_HOST', 'File URL host %s'); E('ERR_INVALID_FILE_URL_PATH', 'File URL path %s'); E('ERR_INVALID_HANDLE_TYPE', 'This handle type cannot be sent'); diff --git a/lib/internal/process/warning.js b/lib/internal/process/warning.js index 033005e6ed6c89..3208fb098d0a97 100644 --- a/lib/internal/process/warning.js +++ b/lib/internal/process/warning.js @@ -90,7 +90,7 @@ function setupProcessWarnings() { if (isDeprecation && process.noDeprecation) return; const trace = process.traceProcessWarnings || (isDeprecation && process.traceDeprecation); - let msg = `${prefix}`; + var msg = `${prefix}`; if (warning.code) msg += `[${warning.code}] `; if (trace && warning.stack) { diff --git a/lib/internal/url.js b/lib/internal/url.js index bb33f75b090109..14c22e4ff467b6 100644 --- a/lib/internal/url.js +++ b/lib/internal/url.js @@ -814,7 +814,8 @@ class URLSearchParams { constructor(init = undefined) { if (init === null || init === undefined) { this[searchParams] = []; - } else if (typeof init === 'object') { + } else if ((typeof init === 'object' && init !== null) || + typeof init === 'function') { const method = init[Symbol.iterator]; if (method === this[Symbol.iterator]) { // While the spec does not have this branch, we can use it as a @@ -830,12 +831,16 @@ class URLSearchParams { // Note: per spec we have to first exhaust the lists then process them const pairs = []; for (const pair of init) { - if (typeof pair !== 'object' || + if ((typeof pair !== 'object' && typeof pair !== 'function') || + pair === null || typeof pair[Symbol.iterator] !== 'function') { throw new errors.TypeError('ERR_INVALID_TUPLE', 'Each query pair', '[name, value]'); } - pairs.push(Array.from(pair)); + const convertedPair = []; + for (const element of pair) + convertedPair.push(toUSVString(element)); + pairs.push(convertedPair); } this[searchParams] = []; @@ -844,17 +849,21 @@ class URLSearchParams { throw new errors.TypeError('ERR_INVALID_TUPLE', 'Each query pair', '[name, value]'); } - const key = toUSVString(pair[0]); - const value = toUSVString(pair[1]); - this[searchParams].push(key, value); + this[searchParams].push(pair[0], pair[1]); } } else { // record + // Need to use reflection APIs for full spec compliance. this[searchParams] = []; - for (var key of Object.keys(init)) { - key = toUSVString(key); - const value = toUSVString(init[key]); - this[searchParams].push(key, value); + const keys = Reflect.ownKeys(init); + for (var i = 0; i < keys.length; i++) { + const key = keys[i]; + const desc = Reflect.getOwnPropertyDescriptor(init, key); + if (desc !== undefined && desc.enumerable) { + const typedKey = toUSVString(key); + const typedValue = toUSVString(init[key]); + this[searchParams].push(typedKey, typedValue); + } } } } else { @@ -1289,7 +1298,6 @@ function domainToUnicode(domain) { function urlToOptions(url) { var options = { protocol: url.protocol, - host: url.host, hostname: url.hostname, hash: url.hash, search: url.search, diff --git a/lib/net.js b/lib/net.js index 07344ea7c7794c..67c231ef25607a 100644 --- a/lib/net.js +++ b/lib/net.js @@ -497,6 +497,8 @@ Socket.prototype.end = function(data, encoding) { this.read(0); else maybeDestroy(this); + + return this; }; @@ -949,8 +951,8 @@ Socket.prototype.connect = function() { // TODO(joyeecheung): use destructuring when V8 is fast enough normalized = normalizeArgs(args); } - const options = normalized[0]; - const cb = normalized[1]; + var options = normalized[0]; + var cb = normalized[1]; if (this.write !== Socket.prototype.write) this.write = Socket.prototype.write; diff --git a/lib/readline.js b/lib/readline.js index 60864f40afdbc1..6a1ed150d72cd2 100644 --- a/lib/readline.js +++ b/lib/readline.js @@ -1039,6 +1039,9 @@ function emitKeypressEvents(stream, iface) { } else { stream.on('newListener', onNewListener); } + if (iface) { + iface.once('close', () => { stream.removeListener('data', onData); }); + } } /** diff --git a/lib/tty.js b/lib/tty.js index d467c827810491..1d6cc5c6886614 100644 --- a/lib/tty.js +++ b/lib/tty.js @@ -27,7 +27,7 @@ const TTY = process.binding('tty_wrap').TTY; const isTTY = process.binding('tty_wrap').isTTY; const inherits = util.inherits; const errnoException = util._errnoException; - +const errors = require('internal/errors'); exports.isatty = function(fd) { return isTTY(fd); @@ -38,7 +38,7 @@ function ReadStream(fd, options) { if (!(this instanceof ReadStream)) return new ReadStream(fd, options); if (fd >> 0 !== fd || fd < 0) - throw new RangeError('fd must be positive integer: ' + fd); + throw new errors.RangeError('ERR_INVALID_FD', fd); options = util._extend({ highWaterMark: 0, @@ -67,7 +67,7 @@ function WriteStream(fd) { if (!(this instanceof WriteStream)) return new WriteStream(fd); if (fd >> 0 !== fd || fd < 0) - throw new RangeError('fd must be positive integer: ' + fd); + throw new errors.RangeError('ERR_INVALID_FD', fd); net.Socket.call(this, { handle: new TTY(fd, false), diff --git a/lib/util.js b/lib/util.js index d73b12dcfd59b3..56a8ff68c822db 100644 --- a/lib/util.js +++ b/lib/util.js @@ -68,63 +68,51 @@ exports.format = function(f) { return objects.join(' '); } - var argLen = arguments.length; - - if (argLen === 1) return f; + if (arguments.length === 1) return f; var str = ''; var a = 1; var lastPos = 0; for (var i = 0; i < f.length;) { if (f.charCodeAt(i) === 37/*'%'*/ && i + 1 < f.length) { + if (f.charCodeAt(i + 1) !== 37/*'%'*/ && a >= arguments.length) { + ++i; + continue; + } switch (f.charCodeAt(i + 1)) { case 100: // 'd' - if (a >= argLen) - break; if (lastPos < i) str += f.slice(lastPos, i); str += Number(arguments[a++]); - lastPos = i = i + 2; - continue; + break; case 105: // 'i' - if (a >= argLen) - break; if (lastPos < i) str += f.slice(lastPos, i); str += parseInt(arguments[a++]); - lastPos = i = i + 2; - continue; + break; case 102: // 'f' - if (a >= argLen) - break; if (lastPos < i) str += f.slice(lastPos, i); str += parseFloat(arguments[a++]); - lastPos = i = i + 2; - continue; + break; case 106: // 'j' - if (a >= argLen) - break; if (lastPos < i) str += f.slice(lastPos, i); str += tryStringify(arguments[a++]); - lastPos = i = i + 2; - continue; + break; case 115: // 's' - if (a >= argLen) - break; if (lastPos < i) str += f.slice(lastPos, i); str += String(arguments[a++]); - lastPos = i = i + 2; - continue; + break; case 37: // '%' if (lastPos < i) str += f.slice(lastPos, i); str += '%'; - lastPos = i = i + 2; - continue; + break; } + lastPos = i = i + 2; + continue; } ++i; } @@ -132,7 +120,7 @@ exports.format = function(f) { str = f; else if (lastPos < f.length) str += f.slice(lastPos); - while (a < argLen) { + while (a < arguments.length) { const x = arguments[a++]; if (x === null || (typeof x !== 'object' && typeof x !== 'symbol')) { str += ' ' + x; diff --git a/lib/zlib.js b/lib/zlib.js index c1cc0a2c54f007..a25901ac6ef16d 100644 --- a/lib/zlib.js +++ b/lib/zlib.js @@ -22,7 +22,6 @@ 'use strict'; const Buffer = require('buffer').Buffer; -const internalUtil = require('internal/util'); const Transform = require('_stream_transform'); const binding = process.binding('zlib'); const assert = require('assert').ok; @@ -31,7 +30,7 @@ const kRangeErrorMessage = 'Cannot create final Buffer. It would be larger ' + `than 0x${kMaxLength.toString(16)} bytes`; const constants = process.binding('constants').zlib; -const createClassWrapper = internalUtil.createClassWrapper; +const { inherits } = require('util'); // translation table for return codes. const codes = { @@ -77,6 +76,13 @@ function isInvalidStrategy(strategy) { // constants.Z_DEFAULT_STRATEGY (0) } +function responseData(engine, buffer) { + if (engine._opts.info) { + return { buffer, engine }; + } + return buffer; +} + function zlibBuffer(engine, buffer, callback) { // Streams do not support non-Buffer ArrayBufferViews yet. Convert it to a // Buffer without copying. @@ -121,7 +127,7 @@ function zlibBuffer(engine, buffer, callback) { buffers = []; engine.close(); - callback(err, buf); + callback(err, responseData(engine, buf)); } } @@ -134,7 +140,7 @@ function zlibBufferSync(engine, buffer) { var flushFlag = engine._finishFlushFlag; - return engine._processChunk(buffer, flushFlag); + return responseData(engine, engine._processChunk(buffer, flushFlag)); } function zlibOnError(message, errno) { @@ -163,315 +169,322 @@ function flushCallback(level, strategy, callback) { // This thing manages the queue of requests, and returns // true or false if there is anything in the queue when // you call the .write() method. -class Zlib extends Transform { - constructor(opts, mode) { - opts = opts || {}; - super(opts); +function Zlib(opts, mode) { + opts = opts || {}; + Transform.call(this, opts); - this._opts = opts; - this._chunkSize = opts.chunkSize || constants.Z_DEFAULT_CHUNK; + this.bytesRead = 0; - if (opts.flush && isInvalidFlushFlag(opts.flush)) { - throw new RangeError('Invalid flush flag: ' + opts.flush); - } - if (opts.finishFlush && isInvalidFlushFlag(opts.finishFlush)) { - throw new RangeError('Invalid flush flag: ' + opts.finishFlush); - } + this._opts = opts; + this._chunkSize = opts.chunkSize || constants.Z_DEFAULT_CHUNK; + + if (opts.flush && isInvalidFlushFlag(opts.flush)) { + throw new RangeError('Invalid flush flag: ' + opts.flush); + } + if (opts.finishFlush && isInvalidFlushFlag(opts.finishFlush)) { + throw new RangeError('Invalid flush flag: ' + opts.finishFlush); + } - this._flushFlag = opts.flush || constants.Z_NO_FLUSH; - this._finishFlushFlag = opts.finishFlush !== undefined ? - opts.finishFlush : constants.Z_FINISH; + this._flushFlag = opts.flush || constants.Z_NO_FLUSH; + this._finishFlushFlag = opts.finishFlush !== undefined ? + opts.finishFlush : constants.Z_FINISH; - if (opts.chunkSize !== undefined) { - if (opts.chunkSize < constants.Z_MIN_CHUNK) { - throw new RangeError('Invalid chunk size: ' + opts.chunkSize); - } + if (opts.chunkSize !== undefined) { + if (opts.chunkSize < constants.Z_MIN_CHUNK) { + throw new RangeError('Invalid chunk size: ' + opts.chunkSize); } + } - if (opts.windowBits !== undefined) { - if (opts.windowBits < constants.Z_MIN_WINDOWBITS || - opts.windowBits > constants.Z_MAX_WINDOWBITS) { - throw new RangeError('Invalid windowBits: ' + opts.windowBits); - } + if (opts.windowBits !== undefined) { + if (opts.windowBits < constants.Z_MIN_WINDOWBITS || + opts.windowBits > constants.Z_MAX_WINDOWBITS) { + throw new RangeError('Invalid windowBits: ' + opts.windowBits); } + } - if (opts.level !== undefined) { - if (opts.level < constants.Z_MIN_LEVEL || - opts.level > constants.Z_MAX_LEVEL) { - throw new RangeError('Invalid compression level: ' + opts.level); - } + if (opts.level !== undefined) { + if (opts.level < constants.Z_MIN_LEVEL || + opts.level > constants.Z_MAX_LEVEL) { + throw new RangeError('Invalid compression level: ' + opts.level); } + } - if (opts.memLevel !== undefined) { - if (opts.memLevel < constants.Z_MIN_MEMLEVEL || - opts.memLevel > constants.Z_MAX_MEMLEVEL) { - throw new RangeError('Invalid memLevel: ' + opts.memLevel); - } + if (opts.memLevel !== undefined) { + if (opts.memLevel < constants.Z_MIN_MEMLEVEL || + opts.memLevel > constants.Z_MAX_MEMLEVEL) { + throw new RangeError('Invalid memLevel: ' + opts.memLevel); } + } - if (opts.strategy !== undefined && isInvalidStrategy(opts.strategy)) - throw new TypeError('Invalid strategy: ' + opts.strategy); + if (opts.strategy !== undefined && isInvalidStrategy(opts.strategy)) + throw new TypeError('Invalid strategy: ' + opts.strategy); - if (opts.dictionary !== undefined) { - if (!ArrayBuffer.isView(opts.dictionary)) { - throw new TypeError( - 'Invalid dictionary: it should be a Buffer, TypedArray, or DataView'); - } + if (opts.dictionary !== undefined) { + if (!ArrayBuffer.isView(opts.dictionary)) { + throw new TypeError( + 'Invalid dictionary: it should be a Buffer, TypedArray, or DataView'); } + } - this._handle = new binding.Zlib(mode); - this._handle.onerror = zlibOnError.bind(this); - this._hadError = false; + this._handle = new binding.Zlib(mode); + this._handle.onerror = zlibOnError.bind(this); + this._hadError = false; - var level = constants.Z_DEFAULT_COMPRESSION; - if (Number.isFinite(opts.level)) { - level = opts.level; - } + var level = constants.Z_DEFAULT_COMPRESSION; + if (Number.isFinite(opts.level)) { + level = opts.level; + } - var strategy = constants.Z_DEFAULT_STRATEGY; - if (Number.isFinite(opts.strategy)) { - strategy = opts.strategy; - } + var strategy = constants.Z_DEFAULT_STRATEGY; + if (Number.isFinite(opts.strategy)) { + strategy = opts.strategy; + } - var windowBits = constants.Z_DEFAULT_WINDOWBITS; - if (Number.isFinite(opts.windowBits)) { - windowBits = opts.windowBits; - } + var windowBits = constants.Z_DEFAULT_WINDOWBITS; + if (Number.isFinite(opts.windowBits)) { + windowBits = opts.windowBits; + } - var memLevel = constants.Z_DEFAULT_MEMLEVEL; - if (Number.isFinite(opts.memLevel)) { - memLevel = opts.memLevel; - } + var memLevel = constants.Z_DEFAULT_MEMLEVEL; + if (Number.isFinite(opts.memLevel)) { + memLevel = opts.memLevel; + } - this._handle.init(windowBits, - level, - memLevel, - strategy, - opts.dictionary); + this._handle.init(windowBits, + level, + memLevel, + strategy, + opts.dictionary); - this._buffer = Buffer.allocUnsafe(this._chunkSize); - this._offset = 0; - this._level = level; - this._strategy = strategy; + this._buffer = Buffer.allocUnsafe(this._chunkSize); + this._offset = 0; + this._level = level; + this._strategy = strategy; - this.once('end', this.close); - } + this.once('end', this.close); +} +inherits(Zlib, Transform); - get _closed() { +Object.defineProperty(Zlib.prototype, '_closed', { + configurable: true, + enumerable: true, + get() { return !this._handle; } +}); - params(level, strategy, callback) { - if (level < constants.Z_MIN_LEVEL || - level > constants.Z_MAX_LEVEL) { - throw new RangeError('Invalid compression level: ' + level); - } - if (isInvalidStrategy(strategy)) - throw new TypeError('Invalid strategy: ' + strategy); - - if (this._level !== level || this._strategy !== strategy) { - this.flush(constants.Z_SYNC_FLUSH, - flushCallback.bind(this, level, strategy, callback)); - } else { - process.nextTick(callback); - } +Zlib.prototype.params = function params(level, strategy, callback) { + if (level < constants.Z_MIN_LEVEL || + level > constants.Z_MAX_LEVEL) { + throw new RangeError('Invalid compression level: ' + level); } + if (isInvalidStrategy(strategy)) + throw new TypeError('Invalid strategy: ' + strategy); - reset() { - assert(this._handle, 'zlib binding closed'); - return this._handle.reset(); + if (this._level !== level || this._strategy !== strategy) { + this.flush(constants.Z_SYNC_FLUSH, + flushCallback.bind(this, level, strategy, callback)); + } else { + process.nextTick(callback); } +}; - // This is the _flush function called by the transform class, - // internally, when the last chunk has been written. - _flush(callback) { - this._transform(Buffer.alloc(0), '', callback); - } +Zlib.prototype.reset = function reset() { + assert(this._handle, 'zlib binding closed'); + return this._handle.reset(); +}; - flush(kind, callback) { - var ws = this._writableState; +// This is the _flush function called by the transform class, +// internally, when the last chunk has been written. +Zlib.prototype._flush = function _flush(callback) { + this._transform(Buffer.alloc(0), '', callback); +}; - if (typeof kind === 'function' || (kind === undefined && !callback)) { - callback = kind; - kind = constants.Z_FULL_FLUSH; - } +Zlib.prototype.flush = function flush(kind, callback) { + var ws = this._writableState; - if (ws.ended) { - if (callback) - process.nextTick(callback); - } else if (ws.ending) { - if (callback) - this.once('end', callback); - } else if (ws.needDrain) { - if (callback) { - const drainHandler = () => this.flush(kind, callback); - this.once('drain', drainHandler); - } - } else { - this._flushFlag = kind; - this.write(Buffer.alloc(0), '', callback); - } + if (typeof kind === 'function' || (kind === undefined && !callback)) { + callback = kind; + kind = constants.Z_FULL_FLUSH; } - close(callback) { - _close(this, callback); - process.nextTick(emitCloseNT, this); + if (ws.ended) { + if (callback) + process.nextTick(callback); + } else if (ws.ending) { + if (callback) + this.once('end', callback); + } else if (ws.needDrain) { + if (callback) { + const drainHandler = () => this.flush(kind, callback); + this.once('drain', drainHandler); + } + } else { + this._flushFlag = kind; + this.write(Buffer.alloc(0), '', callback); } +}; - _transform(chunk, encoding, cb) { - var flushFlag; - var ws = this._writableState; - var ending = ws.ending || ws.ended; - var last = ending && (!chunk || ws.length === chunk.byteLength); - - if (chunk !== null && !ArrayBuffer.isView(chunk)) - return cb(new TypeError('invalid input')); - - if (!this._handle) - return cb(new Error('zlib binding closed')); - - // If it's the last chunk, or a final flush, we use the Z_FINISH flush flag - // (or whatever flag was provided using opts.finishFlush). - // If it's explicitly flushing at some other time, then we use - // Z_FULL_FLUSH. Otherwise, use Z_NO_FLUSH for maximum compression - // goodness. - if (last) - flushFlag = this._finishFlushFlag; - else { - flushFlag = this._flushFlag; - // once we've flushed the last of the queue, stop flushing and - // go back to the normal behavior. - if (chunk.byteLength >= ws.length) { - this._flushFlag = this._opts.flush || constants.Z_NO_FLUSH; - } - } +Zlib.prototype.close = function close(callback) { + _close(this, callback); + process.nextTick(emitCloseNT, this); +}; - this._processChunk(chunk, flushFlag, cb); +Zlib.prototype._transform = function _transform(chunk, encoding, cb) { + var flushFlag; + var ws = this._writableState; + var ending = ws.ending || ws.ended; + var last = ending && (!chunk || ws.length === chunk.byteLength); + + if (chunk !== null && !ArrayBuffer.isView(chunk)) + return cb(new TypeError('invalid input')); + + if (!this._handle) + return cb(new Error('zlib binding closed')); + + // If it's the last chunk, or a final flush, we use the Z_FINISH flush flag + // (or whatever flag was provided using opts.finishFlush). + // If it's explicitly flushing at some other time, then we use + // Z_FULL_FLUSH. Otherwise, use Z_NO_FLUSH for maximum compression + // goodness. + if (last) + flushFlag = this._finishFlushFlag; + else { + flushFlag = this._flushFlag; + // once we've flushed the last of the queue, stop flushing and + // go back to the normal behavior. + if (chunk.byteLength >= ws.length) { + this._flushFlag = this._opts.flush || constants.Z_NO_FLUSH; + } } - _processChunk(chunk, flushFlag, cb) { - var availInBefore = chunk && chunk.byteLength; - var availOutBefore = this._chunkSize - this._offset; - var inOff = 0; - - var self = this; - - var async = typeof cb === 'function'; - - if (!async) { - var buffers = []; - var nread = 0; - - var error; - this.on('error', function(er) { - error = er; - }); - - assert(this._handle, 'zlib binding closed'); - do { - var res = this._handle.writeSync(flushFlag, - chunk, // in - inOff, // in_off - availInBefore, // in_len - this._buffer, // out - this._offset, //out_off - availOutBefore); // out_len - } while (!this._hadError && callback(res[0], res[1])); - - if (this._hadError) { - throw error; - } + this._processChunk(chunk, flushFlag, cb); +}; - if (nread >= kMaxLength) { - _close(this); - throw new RangeError(kRangeErrorMessage); - } +Zlib.prototype._processChunk = function _processChunk(chunk, flushFlag, cb) { + var availInBefore = chunk && chunk.byteLength; + var availOutBefore = this._chunkSize - this._offset; + var inOff = 0; + + var self = this; + + var async = typeof cb === 'function'; - var buf = Buffer.concat(buffers, nread); + if (!async) { + var buffers = []; + var nread = 0; + + var error; + this.on('error', function(er) { + error = er; + }); + + assert(this._handle, 'zlib binding closed'); + do { + var res = this._handle.writeSync(flushFlag, + chunk, // in + inOff, // in_off + availInBefore, // in_len + this._buffer, // out + this._offset, //out_off + availOutBefore); // out_len + } while (!this._hadError && callback(res[0], res[1])); + + if (this._hadError) { + throw error; + } + + if (nread >= kMaxLength) { _close(this); + throw new RangeError(kRangeErrorMessage); + } + + var buf = Buffer.concat(buffers, nread); + _close(this); - return buf; + return buf; + } + + assert(this._handle, 'zlib binding closed'); + var req = this._handle.write(flushFlag, + chunk, // in + inOff, // in_off + availInBefore, // in_len + this._buffer, // out + this._offset, //out_off + availOutBefore); // out_len + + req.buffer = chunk; + req.callback = callback; + + function callback(availInAfter, availOutAfter) { + // When the callback is used in an async write, the callback's + // context is the `req` object that was created. The req object + // is === this._handle, and that's why it's important to null + // out the values after they are done being used. `this._handle` + // can stay in memory longer than the callback and buffer are needed. + if (this) { + this.buffer = null; + this.callback = null; } - assert(this._handle, 'zlib binding closed'); - var req = this._handle.write(flushFlag, - chunk, // in - inOff, // in_off - availInBefore, // in_len - this._buffer, // out - this._offset, //out_off - availOutBefore); // out_len - - req.buffer = chunk; - req.callback = callback; - - function callback(availInAfter, availOutAfter) { - // When the callback is used in an async write, the callback's - // context is the `req` object that was created. The req object - // is === this._handle, and that's why it's important to null - // out the values after they are done being used. `this._handle` - // can stay in memory longer than the callback and buffer are needed. - if (this) { - this.buffer = null; - this.callback = null; - } + if (self._hadError) + return; - if (self._hadError) - return; - - var have = availOutBefore - availOutAfter; - assert(have >= 0, 'have should not go down'); - - if (have > 0) { - var out = self._buffer.slice(self._offset, self._offset + have); - self._offset += have; - // serve some output to the consumer. - if (async) { - self.push(out); - } else { - buffers.push(out); - nread += out.byteLength; - } - } + var have = availOutBefore - availOutAfter; + assert(have >= 0, 'have should not go down'); - // exhausted the output buffer, or used all the input create a new one. - if (availOutAfter === 0 || self._offset >= self._chunkSize) { - availOutBefore = self._chunkSize; - self._offset = 0; - self._buffer = Buffer.allocUnsafe(self._chunkSize); - } + self.bytesRead += availInBefore - availInAfter; - if (availOutAfter === 0) { - // Not actually done. Need to reprocess. - // Also, update the availInBefore to the availInAfter value, - // so that if we have to hit it a third (fourth, etc.) time, - // it'll have the correct byte counts. - inOff += (availInBefore - availInAfter); - availInBefore = availInAfter; - - if (!async) - return true; - - var newReq = self._handle.write(flushFlag, - chunk, - inOff, - availInBefore, - self._buffer, - self._offset, - self._chunkSize); - newReq.callback = callback; // this same function - newReq.buffer = chunk; - return; + if (have > 0) { + var out = self._buffer.slice(self._offset, self._offset + have); + self._offset += have; + // serve some output to the consumer. + if (async) { + self.push(out); + } else { + buffers.push(out); + nread += out.byteLength; } + } - if (!async) - return false; + // exhausted the output buffer, or used all the input create a new one. + if (availOutAfter === 0 || self._offset >= self._chunkSize) { + availOutBefore = self._chunkSize; + self._offset = 0; + self._buffer = Buffer.allocUnsafe(self._chunkSize); + } + + if (availOutAfter === 0) { + // Not actually done. Need to reprocess. + // Also, update the availInBefore to the availInAfter value, + // so that if we have to hit it a third (fourth, etc.) time, + // it'll have the correct byte counts. + inOff += (availInBefore - availInAfter); + availInBefore = availInAfter; - // finished with the chunk. - cb(); + if (!async) + return true; + + var newReq = self._handle.write(flushFlag, + chunk, + inOff, + availInBefore, + self._buffer, + self._offset, + self._chunkSize); + newReq.callback = callback; // this same function + newReq.buffer = chunk; + return; } + + if (!async) + return false; + + // finished with the chunk. + cb(); } -} +}; function _close(engine, callback) { if (callback) @@ -491,47 +504,54 @@ function emitCloseNT(self) { // generic zlib // minimal 2-byte header -class Deflate extends Zlib { - constructor(opts) { - super(opts, constants.DEFLATE); - } +function Deflate(opts) { + if (!(this instanceof Deflate)) + return new Deflate(opts); + Zlib.call(this, opts, constants.DEFLATE); } +inherits(Deflate, Zlib); -class Inflate extends Zlib { - constructor(opts) { - super(opts, constants.INFLATE); - } +function Inflate(opts) { + if (!(this instanceof Inflate)) + return new Inflate(opts); + Zlib.call(this, opts, constants.INFLATE); } +inherits(Inflate, Zlib); -class Gzip extends Zlib { - constructor(opts) { - super(opts, constants.GZIP); - } +function Gzip(opts) { + if (!(this instanceof Gzip)) + return new Gzip(opts); + Zlib.call(this, opts, constants.GZIP); } +inherits(Gzip, Zlib); -class Gunzip extends Zlib { - constructor(opts) { - super(opts, constants.GUNZIP); - } +function Gunzip(opts) { + if (!(this instanceof Gunzip)) + return new Gunzip(opts); + Zlib.call(this, opts, constants.GUNZIP); } +inherits(Gunzip, Zlib); -class DeflateRaw extends Zlib { - constructor(opts) { - super(opts, constants.DEFLATERAW); - } +function DeflateRaw(opts) { + if (!(this instanceof DeflateRaw)) + return new DeflateRaw(opts); + Zlib.call(this, opts, constants.DEFLATERAW); } +inherits(DeflateRaw, Zlib); -class InflateRaw extends Zlib { - constructor(opts) { - super(opts, constants.INFLATERAW); - } +function InflateRaw(opts) { + if (!(this instanceof InflateRaw)) + return new InflateRaw(opts); + Zlib.call(this, opts, constants.INFLATERAW); } +inherits(InflateRaw, Zlib); -class Unzip extends Zlib { - constructor(opts) { - super(opts, constants.UNZIP); - } +function Unzip(opts) { + if (!(this instanceof Unzip)) + return new Unzip(opts); + Zlib.call(this, opts, constants.UNZIP); } +inherits(Unzip, Zlib); function createConvenienceMethod(type, sync) { if (sync) { @@ -558,13 +578,13 @@ function createProperty(type) { } module.exports = { - Deflate: createClassWrapper(Deflate), - Inflate: createClassWrapper(Inflate), - Gzip: createClassWrapper(Gzip), - Gunzip: createClassWrapper(Gunzip), - DeflateRaw: createClassWrapper(DeflateRaw), - InflateRaw: createClassWrapper(InflateRaw), - Unzip: createClassWrapper(Unzip), + Deflate, + Inflate, + Gzip, + Gunzip, + DeflateRaw, + InflateRaw, + Unzip, // Convenience methods. // compress/decompress a string or buffer in one step. diff --git a/src/async-wrap.cc b/src/async-wrap.cc index 0ea6c64a8be582..0f5c800f40d939 100644 --- a/src/async-wrap.cc +++ b/src/async-wrap.cc @@ -138,10 +138,8 @@ RetainedObjectInfo* WrapperInfo(uint16_t class_id, Local wrapper) { // end RetainedAsyncInfo -static void DestroyIdsCb(uv_idle_t* handle) { - uv_idle_stop(handle); - - Environment* env = Environment::from_destroy_ids_idle_handle(handle); +static void DestroyIdsCb(uv_timer_t* handle) { + Environment* env = Environment::from_destroy_ids_timer_handle(handle); HandleScope handle_scope(env->isolate()); Context::Scope context_scope(env->context()); @@ -149,23 +147,23 @@ static void DestroyIdsCb(uv_idle_t* handle) { TryCatch try_catch(env->isolate()); - std::vector destroy_ids_list; - destroy_ids_list.swap(*env->destroy_ids_list()); - for (auto current_id : destroy_ids_list) { - // Want each callback to be cleaned up after itself, instead of cleaning - // them all up after the while() loop completes. - HandleScope scope(env->isolate()); - Local argv = Number::New(env->isolate(), current_id); - MaybeLocal ret = fn->Call( - env->context(), Undefined(env->isolate()), 1, &argv); - - if (ret.IsEmpty()) { - ClearFatalExceptionHandlers(env); - FatalException(env->isolate(), try_catch); + do { + std::vector destroy_ids_list; + destroy_ids_list.swap(*env->destroy_ids_list()); + for (auto current_id : destroy_ids_list) { + // Want each callback to be cleaned up after itself, instead of cleaning + // them all up after the while() loop completes. + HandleScope scope(env->isolate()); + Local argv = Number::New(env->isolate(), current_id); + MaybeLocal ret = fn->Call( + env->context(), Undefined(env->isolate()), 1, &argv); + + if (ret.IsEmpty()) { + ClearFatalExceptionHandlers(env); + FatalException(env->isolate(), try_catch); + } } - } - - env->destroy_ids_list()->clear(); + } while (!env->destroy_ids_list()->empty()); } @@ -174,7 +172,7 @@ static void PushBackDestroyId(Environment* env, double id) { return; if (env->destroy_ids_list()->empty()) - uv_idle_start(env->destroy_ids_idle_handle(), DestroyIdsCb); + uv_timer_start(env->destroy_ids_timer_handle(), DestroyIdsCb, 0, 0); env->destroy_ids_list()->push_back(id); } @@ -296,6 +294,23 @@ static void PromiseHook(PromiseHookType type, Local promise, PromiseWrap* wrap = Unwrap(promise); if (type == PromiseHookType::kInit || wrap == nullptr) { bool silent = type != PromiseHookType::kInit; + // set parent promise's async Id as this promise's triggerId + if (parent->IsPromise()) { + // parent promise exists, current promise + // is a chained promise, so we set parent promise's id as + // current promise's triggerId + Local parent_promise = parent.As(); + auto parent_wrap = Unwrap(parent_promise); + + if (parent_wrap == nullptr) { + // create a new PromiseWrap for parent promise with silent parameter + parent_wrap = new PromiseWrap(env, parent_promise, true); + parent_wrap->MakeWeak(parent_wrap); + } + // get id from parentWrap + double trigger_id = parent_wrap->get_id(); + env->set_init_trigger_id(trigger_id); + } wrap = new PromiseWrap(env, promise, silent); wrap->MakeWeak(wrap); } else if (type == PromiseHookType::kResolve) { diff --git a/src/env-inl.h b/src/env-inl.h index e2a58761fd026d..cf7304c98dba76 100644 --- a/src/env-inl.h +++ b/src/env-inl.h @@ -146,7 +146,7 @@ inline bool Environment::AsyncHooks::pop_ids(double async_id) { if (uid_fields_[kCurrentAsyncId] != async_id) { fprintf(stderr, "Error: async hook stack has become corrupted (" - "actual: %'.f, expected: %'.f)\n", + "actual: %.f, expected: %.f)\n", uid_fields_[kCurrentAsyncId], async_id); Environment* env = Environment::GetCurrent(isolate_); @@ -356,13 +356,13 @@ inline uv_idle_t* Environment::immediate_idle_handle() { return &immediate_idle_handle_; } -inline Environment* Environment::from_destroy_ids_idle_handle( - uv_idle_t* handle) { - return ContainerOf(&Environment::destroy_ids_idle_handle_, handle); +inline Environment* Environment::from_destroy_ids_timer_handle( + uv_timer_t* handle) { + return ContainerOf(&Environment::destroy_ids_timer_handle_, handle); } -inline uv_idle_t* Environment::destroy_ids_idle_handle() { - return &destroy_ids_idle_handle_; +inline uv_timer_t* Environment::destroy_ids_timer_handle() { + return &destroy_ids_timer_handle_; } inline void Environment::RegisterHandleCleanup(uv_handle_t* handle, diff --git a/src/env.cc b/src/env.cc index 034625b375446c..0bf4b573aafd69 100644 --- a/src/env.cc +++ b/src/env.cc @@ -49,8 +49,7 @@ void Environment::Start(int argc, uv_unref(reinterpret_cast(&idle_prepare_handle_)); uv_unref(reinterpret_cast(&idle_check_handle_)); - uv_idle_init(event_loop(), destroy_ids_idle_handle()); - uv_unref(reinterpret_cast(destroy_ids_idle_handle())); + uv_timer_init(event_loop(), destroy_ids_timer_handle()); auto close_and_finish = [](Environment* env, uv_handle_t* handle, void* arg) { handle->data = env; @@ -102,16 +101,6 @@ void Environment::CleanupHandles() { while (handle_cleanup_waiting_ != 0) uv_run(event_loop(), UV_RUN_ONCE); - // Closing the destroy_ids_idle_handle_ within the handle cleanup queue - // prevents the async wrap destroy hook from being called. - uv_handle_t* handle = - reinterpret_cast(&destroy_ids_idle_handle_); - handle->data = this; - handle_cleanup_waiting_ = 1; - uv_close(handle, [](uv_handle_t* handle) { - static_cast(handle->data)->FinishHandleCleanup(handle); - }); - while (handle_cleanup_waiting_ != 0) uv_run(event_loop(), UV_RUN_ONCE); } diff --git a/src/env.h b/src/env.h index c8c8232cc07fd4..7179a6081cc417 100644 --- a/src/env.h +++ b/src/env.h @@ -526,10 +526,10 @@ class Environment { inline uint32_t watched_providers() const; static inline Environment* from_immediate_check_handle(uv_check_t* handle); - static inline Environment* from_destroy_ids_idle_handle(uv_idle_t* handle); + static inline Environment* from_destroy_ids_timer_handle(uv_timer_t* handle); inline uv_check_t* immediate_check_handle(); inline uv_idle_t* immediate_idle_handle(); - inline uv_idle_t* destroy_ids_idle_handle(); + inline uv_timer_t* destroy_ids_timer_handle(); // Register clean-up cb to be called on environment destruction. inline void RegisterHandleCleanup(uv_handle_t* handle, @@ -662,7 +662,7 @@ class Environment { IsolateData* const isolate_data_; uv_check_t immediate_check_handle_; uv_idle_t immediate_idle_handle_; - uv_idle_t destroy_ids_idle_handle_; + uv_timer_t destroy_ids_timer_handle_; uv_prepare_t idle_prepare_handle_; uv_check_t idle_check_handle_; AsyncHooks async_hooks_; diff --git a/src/inspector_agent.cc b/src/inspector_agent.cc index 5daef2e1ba9ffe..948719ed702c5a 100644 --- a/src/inspector_agent.cc +++ b/src/inspector_agent.cc @@ -40,8 +40,8 @@ using v8_inspector::StringBuffer; using v8_inspector::StringView; using v8_inspector::V8Inspector; -static uv_sem_t inspector_io_thread_semaphore; -static uv_async_t start_inspector_thread_async; +static uv_sem_t start_io_thread_semaphore; +static uv_async_t start_io_thread_async; class StartIoTask : public v8::Task { public: @@ -61,36 +61,36 @@ std::unique_ptr ToProtocolString(Isolate* isolate, return StringBuffer::create(StringView(*buffer, buffer.length())); } -// Called from the main thread. -void StartInspectorIoThreadAsyncCallback(uv_async_t* handle) { +// Called on the main thread. +void StartIoThreadAsyncCallback(uv_async_t* handle) { static_cast(handle->data)->StartIoThread(false); } -void StartIoCallback(Isolate* isolate, void* agent) { +void StartIoInterrupt(Isolate* isolate, void* agent) { static_cast(agent)->StartIoThread(false); } #ifdef __POSIX__ -static void EnableInspectorIOThreadSignalHandler(int signo) { - uv_sem_post(&inspector_io_thread_semaphore); +static void StartIoThreadWakeup(int signo) { + uv_sem_post(&start_io_thread_semaphore); } -inline void* InspectorIoThreadSignalThreadMain(void* unused) { +inline void* StartIoThreadMain(void* unused) { for (;;) { - uv_sem_wait(&inspector_io_thread_semaphore); - Agent* agent = static_cast(start_inspector_thread_async.data); + uv_sem_wait(&start_io_thread_semaphore); + Agent* agent = static_cast(start_io_thread_async.data); if (agent != nullptr) - agent->RequestIoStart(); + agent->RequestIoThreadStart(); } return nullptr; } -static int RegisterDebugSignalHandler() { +static int StartDebugSignalHandler() { // Start a watchdog thread for calling v8::Debug::DebugBreak() because // it's not safe to call directly from the signal handler, it can // deadlock with the thread it interrupts. - CHECK_EQ(0, uv_sem_init(&inspector_io_thread_semaphore, 0)); + CHECK_EQ(0, uv_sem_init(&start_io_thread_semaphore, 0)); pthread_attr_t attr; CHECK_EQ(0, pthread_attr_init(&attr)); // Don't shrink the thread's stack on FreeBSD. Said platform decided to @@ -101,11 +101,13 @@ static int RegisterDebugSignalHandler() { #endif // __FreeBSD__ CHECK_EQ(0, pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)); sigset_t sigmask; + // Mask all signals. sigfillset(&sigmask); CHECK_EQ(0, pthread_sigmask(SIG_SETMASK, &sigmask, &sigmask)); pthread_t thread; const int err = pthread_create(&thread, &attr, - InspectorIoThreadSignalThreadMain, nullptr); + StartIoThreadMain, nullptr); + // Restore original mask CHECK_EQ(0, pthread_sigmask(SIG_SETMASK, &sigmask, nullptr)); CHECK_EQ(0, pthread_attr_destroy(&attr)); if (err != 0) { @@ -115,7 +117,7 @@ static int RegisterDebugSignalHandler() { // receiving the signal would terminate the process. return -err; } - RegisterSignalHandler(SIGUSR1, EnableInspectorIOThreadSignalHandler); + RegisterSignalHandler(SIGUSR1, StartIoThreadWakeup); // Unblock SIGUSR1. A pending SIGUSR1 signal will now be delivered. sigemptyset(&sigmask); sigaddset(&sigmask, SIGUSR1); @@ -126,10 +128,10 @@ static int RegisterDebugSignalHandler() { #ifdef _WIN32 -DWORD WINAPI EnableDebugThreadProc(void* arg) { - Agent* agent = static_cast(start_inspector_thread_async.data); +DWORD WINAPI StartIoThreadProc(void* arg) { + Agent* agent = static_cast(start_io_thread_async.data); if (agent != nullptr) - agent->RequestIoStart(); + agent->RequestIoThreadStart(); return 0; } @@ -138,7 +140,7 @@ static int GetDebugSignalHandlerMappingName(DWORD pid, wchar_t* buf, return _snwprintf(buf, buf_len, L"node-debug-handler-%u", pid); } -static int RegisterDebugSignalHandler() { +static int StartDebugSignalHandler() { wchar_t mapping_name[32]; HANDLE mapping_handle; DWORD pid; @@ -173,7 +175,7 @@ static int RegisterDebugSignalHandler() { return -1; } - *handler = EnableDebugThreadProc; + *handler = StartIoThreadProc; UnmapViewOfFile(static_cast(handler)); @@ -201,11 +203,11 @@ class JsBindingsSessionDelegate : public InspectorSessionDelegate { callback_.Reset(); } - bool WaitForFrontendMessage() override { + bool WaitForFrontendMessageWhilePaused() override { return false; } - void OnMessage(const v8_inspector::StringView& message) override { + void SendMessageToFrontend(const v8_inspector::StringView& message) override { Isolate* isolate = env_->isolate(); v8::HandleScope handle_scope(isolate); Context::Scope context_scope(env_->context()); @@ -391,7 +393,7 @@ class ChannelImpl final : public v8_inspector::V8Inspector::Channel { } bool waitForFrontendMessage() { - return delegate_->WaitForFrontendMessage(); + return delegate_->WaitForFrontendMessageWhilePaused(); } void schedulePauseOnNextStatement(const std::string& reason) { @@ -418,7 +420,7 @@ class ChannelImpl final : public v8_inspector::V8Inspector::Channel { void flushProtocolNotifications() override { } void sendMessageToFrontend(const StringView& message) { - delegate_->OnMessage(message); + delegate_->SendMessageToFrontend(message); } InspectorSessionDelegate* const delegate_; @@ -434,7 +436,7 @@ class NodeInspectorClient : public v8_inspector::V8InspectorClient { platform_(platform), terminated_(false), running_nested_loop_(false) { - inspector_ = V8Inspector::create(env->isolate(), this); + client_ = V8Inspector::create(env->isolate(), this); } void runMessageLoopOnPause(int context_group_id) override { @@ -459,11 +461,11 @@ class NodeInspectorClient : public v8_inspector::V8InspectorClient { std::unique_ptr name_buffer = Utf8ToStringView(name); v8_inspector::V8ContextInfo info(context, CONTEXT_GROUP_ID, name_buffer->string()); - inspector_->contextCreated(info); + client_->contextCreated(info); } void contextDestroyed(Local context) { - inspector_->contextDestroyed(context); + client_->contextDestroyed(context); } void quitMessageLoopOnPause() override { @@ -473,7 +475,7 @@ class NodeInspectorClient : public v8_inspector::V8InspectorClient { void connectFrontend(InspectorSessionDelegate* delegate) { CHECK_EQ(channel_, nullptr); channel_ = std::unique_ptr( - new ChannelImpl(inspector_.get(), delegate)); + new ChannelImpl(client_.get(), delegate)); } void disconnectFrontend() { @@ -507,7 +509,7 @@ class NodeInspectorClient : public v8_inspector::V8InspectorClient { Isolate* isolate = context->GetIsolate(); - inspector_->exceptionThrown( + client_->exceptionThrown( context, StringView(DETAILS, sizeof(DETAILS) - 1), error, @@ -515,7 +517,7 @@ class NodeInspectorClient : public v8_inspector::V8InspectorClient { ToProtocolString(isolate, message->GetScriptResourceName())->string(), message->GetLineNumber(context).FromMaybe(0), message->GetStartColumn(context).FromMaybe(0), - inspector_->createStackTrace(stack_trace), + client_->createStackTrace(stack_trace), script_id); } @@ -528,12 +530,12 @@ class NodeInspectorClient : public v8_inspector::V8InspectorClient { v8::Platform* platform_; bool terminated_; bool running_nested_loop_; - std::unique_ptr inspector_; + std::unique_ptr client_; std::unique_ptr channel_; }; Agent::Agent(Environment* env) : parent_env_(env), - inspector_(nullptr), + client_(nullptr), platform_(nullptr), enabled_(false) {} @@ -546,19 +548,21 @@ bool Agent::Start(v8::Platform* platform, const char* path, const DebugOptions& options) { path_ = path == nullptr ? "" : path; debug_options_ = options; - inspector_ = + client_ = std::unique_ptr( new NodeInspectorClient(parent_env_, platform)); - inspector_->contextCreated(parent_env_->context(), "Node.js Main Context"); + client_->contextCreated(parent_env_->context(), "Node.js Main Context"); platform_ = platform; CHECK_EQ(0, uv_async_init(uv_default_loop(), - &start_inspector_thread_async, - StartInspectorIoThreadAsyncCallback)); - start_inspector_thread_async.data = this; - uv_unref(reinterpret_cast(&start_inspector_thread_async)); + &start_io_thread_async, + StartIoThreadAsyncCallback)); + start_io_thread_async.data = this; + uv_unref(reinterpret_cast(&start_io_thread_async)); - RegisterDebugSignalHandler(); + // Ignore failure, SIGUSR1 won't work, but that should not block node start. + StartDebugSignalHandler(); if (options.inspector_enabled()) { + // This will return false if listen failed on the inspector port. return StartIoThread(options.wait_for_connect()); } return true; @@ -568,14 +572,14 @@ bool Agent::StartIoThread(bool wait_for_connect) { if (io_ != nullptr) return true; - CHECK_NE(inspector_, nullptr); + CHECK_NE(client_, nullptr); enabled_ = true; io_ = std::unique_ptr( new InspectorIo(parent_env_, platform_, path_, debug_options_, wait_for_connect)); if (!io_->Start()) { - inspector_.reset(); + client_.reset(); return false; } @@ -612,20 +616,16 @@ void Agent::Stop() { void Agent::Connect(InspectorSessionDelegate* delegate) { enabled_ = true; - inspector_->connectFrontend(delegate); + client_->connectFrontend(delegate); } bool Agent::IsConnected() { return io_ && io_->IsConnected(); } -bool Agent::IsStarted() { - return !!inspector_; -} - void Agent::WaitForDisconnect() { - CHECK_NE(inspector_, nullptr); - inspector_->contextDestroyed(parent_env_->context()); + CHECK_NE(client_, nullptr); + client_->contextDestroyed(parent_env_->context()); if (io_ != nullptr) { io_->WaitForDisconnect(); } @@ -634,63 +634,109 @@ void Agent::WaitForDisconnect() { void Agent::FatalException(Local error, Local message) { if (!IsStarted()) return; - inspector_->FatalException(error, message); + client_->FatalException(error, message); WaitForDisconnect(); } void Agent::Dispatch(const StringView& message) { - CHECK_NE(inspector_, nullptr); - inspector_->dispatchMessageFromFrontend(message); + CHECK_NE(client_, nullptr); + client_->dispatchMessageFromFrontend(message); } void Agent::Disconnect() { - CHECK_NE(inspector_, nullptr); - inspector_->disconnectFrontend(); + CHECK_NE(client_, nullptr); + client_->disconnectFrontend(); } void Agent::RunMessageLoop() { - CHECK_NE(inspector_, nullptr); - inspector_->runMessageLoopOnPause(CONTEXT_GROUP_ID); + CHECK_NE(client_, nullptr); + client_->runMessageLoopOnPause(CONTEXT_GROUP_ID); } InspectorSessionDelegate* Agent::delegate() { - CHECK_NE(inspector_, nullptr); - ChannelImpl* channel = inspector_->channel(); + CHECK_NE(client_, nullptr); + ChannelImpl* channel = client_->channel(); if (channel == nullptr) return nullptr; return channel->delegate(); } void Agent::PauseOnNextJavascriptStatement(const std::string& reason) { - ChannelImpl* channel = inspector_->channel(); + ChannelImpl* channel = client_->channel(); if (channel != nullptr) channel->schedulePauseOnNextStatement(reason); } +void Open(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + inspector::Agent* agent = env->inspector_agent(); + bool wait_for_connect = false; + + if (args.Length() > 0 && args[0]->IsUint32()) { + uint32_t port = args[0]->Uint32Value(); + agent->options().set_port(static_cast(port)); + } + + if (args.Length() > 1 && args[1]->IsString()) { + node::Utf8Value host(env->isolate(), args[1].As()); + agent->options().set_host_name(*host); + } + + if (args.Length() > 2 && args[2]->IsBoolean()) { + wait_for_connect = args[2]->BooleanValue(); + } + + agent->StartIoThread(wait_for_connect); +} + +void Url(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + inspector::Agent* agent = env->inspector_agent(); + inspector::InspectorIo* io = agent->io(); + + if (!io) return; + + std::vector ids = io->GetTargetIds(); + + if (ids.empty()) return; + + std::string url = "ws://"; + url += io->host(); + url += ":"; + url += std::to_string(io->port()); + url += "/"; + url += ids[0]; + + args.GetReturnValue().Set(OneByteString(env->isolate(), url.c_str())); +} + + // static -void Agent::InitJSBindings(Local target, Local unused, - Local context, void* priv) { +void Agent::InitInspector(Local target, Local unused, + Local context, void* priv) { Environment* env = Environment::GetCurrent(context); Agent* agent = env->inspector_agent(); env->SetMethod(target, "consoleCall", InspectorConsoleCall); if (agent->debug_options_.wait_for_connect()) env->SetMethod(target, "callAndPauseOnStart", CallAndPauseOnStart); env->SetMethod(target, "connect", ConnectJSBindingsSession); + env->SetMethod(target, "open", Open); + env->SetMethod(target, "url", Url); } -void Agent::RequestIoStart() { +void Agent::RequestIoThreadStart() { // We need to attempt to interrupt V8 flow (in case Node is running - // continuous JS code) and to wake up libuv thread (in case Node is wating + // continuous JS code) and to wake up libuv thread (in case Node is waiting // for IO events) - uv_async_send(&start_inspector_thread_async); + uv_async_send(&start_io_thread_async); v8::Isolate* isolate = parent_env_->isolate(); platform_->CallOnForegroundThread(isolate, new StartIoTask(this)); - isolate->RequestInterrupt(StartIoCallback, this); - uv_async_send(&start_inspector_thread_async); + isolate->RequestInterrupt(StartIoInterrupt, this); + uv_async_send(&start_io_thread_async); } } // namespace inspector } // namespace node NODE_MODULE_CONTEXT_AWARE_BUILTIN(inspector, - node::inspector::Agent::InitJSBindings); + node::inspector::Agent::InitInspector); diff --git a/src/inspector_agent.h b/src/inspector_agent.h index 2bc65f76640261..80967212cd7aef 100644 --- a/src/inspector_agent.h +++ b/src/inspector_agent.h @@ -38,8 +38,9 @@ namespace inspector { class InspectorSessionDelegate { public: virtual ~InspectorSessionDelegate() = default; - virtual bool WaitForFrontendMessage() = 0; - virtual void OnMessage(const v8_inspector::StringView& message) = 0; + virtual bool WaitForFrontendMessageWhilePaused() = 0; + virtual void SendMessageToFrontend(const v8_inspector::StringView& message) + = 0; }; class InspectorIo; @@ -50,39 +51,55 @@ class Agent { explicit Agent(node::Environment* env); ~Agent(); + // Create client_, may create io_ if option enabled bool Start(v8::Platform* platform, const char* path, const DebugOptions& options); + // Stop and destroy io_ void Stop(); - bool IsStarted(); + bool IsStarted() { return !!client_; } + + // IO thread started, and client connected bool IsConnected(); + + void WaitForDisconnect(); void FatalException(v8::Local error, v8::Local message); + + // These methods are called by the WS protocol and JS binding to create + // inspector sessions. The inspector responds by using the delegate to send + // messages back. void Connect(InspectorSessionDelegate* delegate); - InspectorSessionDelegate* delegate(); void Disconnect(); void Dispatch(const v8_inspector::StringView& message); + InspectorSessionDelegate* delegate(); + void RunMessageLoop(); - bool enabled() { - return enabled_; - } + bool enabled() { return enabled_; } void PauseOnNextJavascriptStatement(const std::string& reason); - static void InitJSBindings(v8::Local target, - v8::Local unused, - v8::Local context, - void* priv); - bool StartIoThread(bool wait_for_connect); + // Initialize 'inspector' module bindings + static void InitInspector(v8::Local target, + v8::Local unused, + v8::Local context, + void* priv); + InspectorIo* io() { return io_.get(); } - // Can be called from any thread - void RequestIoStart(); + + // Can only be called from the the main thread. + bool StartIoThread(bool wait_for_connect); + + // Calls StartIoThread() from off the main thread. + void RequestIoThreadStart(); + + DebugOptions& options() { return debug_options_; } private: node::Environment* parent_env_; - std::unique_ptr inspector_; + std::unique_ptr client_; std::unique_ptr io_; v8::Platform* platform_; bool enabled_; diff --git a/src/inspector_io.cc b/src/inspector_io.cc index 6dcc1e0fdd3e67..69eed62ab4729a 100644 --- a/src/inspector_io.cc +++ b/src/inspector_io.cc @@ -28,16 +28,32 @@ template using TransportAndIo = std::pair; std::string GetProcessTitle() { - // uv_get_process_title will trim the title if it is too long. char title[2048]; int err = uv_get_process_title(title, sizeof(title)); if (err == 0) { return title; } else { + // Title is too long, or could not be retrieved. return "Node.js"; } } +std::string ScriptPath(uv_loop_t* loop, const std::string& script_name) { + std::string script_path; + + if (!script_name.empty()) { + uv_fs_t req; + req.ptr = nullptr; + if (0 == uv_fs_realpath(loop, &req, script_name.c_str(), nullptr)) { + CHECK_NE(req.ptr, nullptr); + script_path = std::string(static_cast(req.ptr)); + } + uv_fs_req_cleanup(&req); + } + + return script_path; +} + // UUID RFC: https://www.ietf.org/rfc/rfc4122.txt // Used ver 4 - with numbers std::string GenerateID() { @@ -97,6 +113,7 @@ int CloseAsyncAndLoop(uv_async_t* async) { return uv_loop_close(async->loop); } +// Delete main_thread_req_ on async handle close void ReleasePairOnAsyncClose(uv_handle_t* async) { AsyncAndAgent* pair = node::ContainerOf(&AsyncAndAgent::first, reinterpret_cast(async)); @@ -117,19 +134,26 @@ std::unique_ptr Utf8ToStringView(const std::string& message) { class IoSessionDelegate : public InspectorSessionDelegate { public: explicit IoSessionDelegate(InspectorIo* io) : io_(io) { } - bool WaitForFrontendMessage() override; - void OnMessage(const v8_inspector::StringView& message) override; + bool WaitForFrontendMessageWhilePaused() override; + void SendMessageToFrontend(const v8_inspector::StringView& message) override; private: InspectorIo* io_; }; +// Passed to InspectorSocketServer to handle WS inspector protocol events, +// mostly session start, message received, and session end. class InspectorIoDelegate: public node::inspector::SocketServerDelegate { public: InspectorIoDelegate(InspectorIo* io, const std::string& script_path, const std::string& script_name, bool wait); + // Calls PostIncomingMessage() with appropriate InspectorAction: + // kStartSession bool StartSession(int session_id, const std::string& target_id) override; + // kSendMessage void MessageReceived(int session_id, const std::string& message) override; + // kEndSession void EndSession(int session_id) override; + std::vector GetTargetIds() override; std::string GetTargetTitle(const std::string& id) override; std::string GetTargetUrl(const std::string& id) override; @@ -137,6 +161,7 @@ class InspectorIoDelegate: public node::inspector::SocketServerDelegate { void ServerDone() override { io_->ServerDone(); } + private: InspectorIo* io_; bool connected_; @@ -172,27 +197,27 @@ InspectorIo::InspectorIo(Environment* env, v8::Platform* platform, bool wait_for_connect) : options_(options), thread_(), delegate_(nullptr), state_(State::kNew), parent_env_(env), - io_thread_req_(), platform_(platform), + thread_req_(), platform_(platform), dispatching_messages_(false), session_id_(0), script_name_(path), - wait_for_connect_(wait_for_connect) { + wait_for_connect_(wait_for_connect), port_(-1) { main_thread_req_ = new AsyncAndAgent({uv_async_t(), env->inspector_agent()}); CHECK_EQ(0, uv_async_init(env->event_loop(), &main_thread_req_->first, - InspectorIo::MainThreadAsyncCb)); + InspectorIo::MainThreadReqAsyncCb)); uv_unref(reinterpret_cast(&main_thread_req_->first)); - CHECK_EQ(0, uv_sem_init(&start_sem_, 0)); + CHECK_EQ(0, uv_sem_init(&thread_start_sem_, 0)); } InspectorIo::~InspectorIo() { - uv_sem_destroy(&start_sem_); + uv_sem_destroy(&thread_start_sem_); uv_close(reinterpret_cast(&main_thread_req_->first), ReleasePairOnAsyncClose); } bool InspectorIo::Start() { CHECK_EQ(state_, State::kNew); - CHECK_EQ(uv_thread_create(&thread_, InspectorIo::ThreadCbIO, this), 0); - uv_sem_wait(&start_sem_); + CHECK_EQ(uv_thread_create(&thread_, InspectorIo::ThreadMain, this), 0); + uv_sem_wait(&thread_start_sem_); if (state_ == State::kError) { return false; @@ -234,75 +259,66 @@ void InspectorIo::WaitForDisconnect() { } // static -void InspectorIo::ThreadCbIO(void* io) { - static_cast(io)->WorkerRunIO(); +void InspectorIo::ThreadMain(void* io) { + static_cast(io)->ThreadMain(); } // static template -void InspectorIo::WriteCbIO(uv_async_t* async) { - TransportAndIo* io_and_transport = +void InspectorIo::IoThreadAsyncCb(uv_async_t* async) { + TransportAndIo* transport_and_io = static_cast*>(async->data); - if (io_and_transport == nullptr) { + if (transport_and_io == nullptr) { return; } - MessageQueue outgoing_messages; - InspectorIo* io = io_and_transport->second; - io->SwapBehindLock(&io->outgoing_message_queue_, &outgoing_messages); - for (const auto& outgoing : outgoing_messages) { + Transport* transport = transport_and_io->first; + InspectorIo* io = transport_and_io->second; + MessageQueue outgoing_message_queue; + io->SwapBehindLock(&io->outgoing_message_queue_, &outgoing_message_queue); + for (const auto& outgoing : outgoing_message_queue) { switch (std::get<0>(outgoing)) { case TransportAction::kKill: - io_and_transport->first->TerminateConnections(); + transport->TerminateConnections(); // Fallthrough case TransportAction::kStop: - io_and_transport->first->Stop(nullptr); + transport->Stop(nullptr); break; case TransportAction::kSendMessage: std::string message = StringViewToUtf8(std::get<2>(outgoing)->string()); - io_and_transport->first->Send(std::get<1>(outgoing), message); + transport->Send(std::get<1>(outgoing), message); break; } } } template -void InspectorIo::WorkerRunIO() { +void InspectorIo::ThreadMain() { uv_loop_t loop; loop.data = nullptr; int err = uv_loop_init(&loop); CHECK_EQ(err, 0); - io_thread_req_.data = nullptr; - err = uv_async_init(&loop, &io_thread_req_, WriteCbIO); + thread_req_.data = nullptr; + err = uv_async_init(&loop, &thread_req_, IoThreadAsyncCb); CHECK_EQ(err, 0); - std::string script_path; - if (!script_name_.empty()) { - uv_fs_t req; - req.ptr = nullptr; - if (0 == uv_fs_realpath(&loop, &req, script_name_.c_str(), nullptr)) { - CHECK_NE(req.ptr, nullptr); - script_path = std::string(static_cast(req.ptr)); - } - uv_fs_req_cleanup(&req); - } + std::string script_path = ScriptPath(&loop, script_name_); InspectorIoDelegate delegate(this, script_path, script_name_, wait_for_connect_); delegate_ = &delegate; - InspectorSocketServer server(&delegate, - options_.host_name(), - options_.port()); + Transport server(&delegate, &loop, options_.host_name(), options_.port()); TransportAndIo queue_transport(&server, this); - io_thread_req_.data = &queue_transport; - if (!server.Start(&loop)) { + thread_req_.data = &queue_transport; + if (!server.Start()) { state_ = State::kError; // Safe, main thread is waiting on semaphore - CHECK_EQ(0, CloseAsyncAndLoop(&io_thread_req_)); - uv_sem_post(&start_sem_); + CHECK_EQ(0, CloseAsyncAndLoop(&thread_req_)); + uv_sem_post(&thread_start_sem_); return; } + port_ = server.port(); // Safe, main thread is waiting on semaphore. if (!wait_for_connect_) { - uv_sem_post(&start_sem_); + uv_sem_post(&thread_start_sem_); } uv_run(&loop, UV_RUN_DEFAULT); - io_thread_req_.data = nullptr; + thread_req_.data = nullptr; CHECK_EQ(uv_loop_close(&loop), 0); delegate_ = nullptr; } @@ -338,7 +354,12 @@ void InspectorIo::PostIncomingMessage(InspectorAction action, int session_id, NotifyMessageReceived(); } -void InspectorIo::WaitForFrontendMessage() { +std::vector InspectorIo::GetTargetIds() const { + return delegate_ ? delegate_->GetTargetIds() : std::vector(); +} + +void InspectorIo::WaitForFrontendMessageWhilePaused() { + dispatching_messages_ = false; Mutex::ScopedLock scoped_lock(state_lock_); if (incoming_message_queue_.empty()) incoming_message_cond_.Wait(scoped_lock); @@ -357,11 +378,15 @@ void InspectorIo::DispatchMessages() { if (dispatching_messages_) return; dispatching_messages_ = true; - MessageQueue tasks; + bool had_messages = false; do { - tasks.clear(); - SwapBehindLock(&incoming_message_queue_, &tasks); - for (const auto& task : tasks) { + if (dispatching_message_queue_.empty()) + SwapBehindLock(&incoming_message_queue_, &dispatching_message_queue_); + had_messages = !dispatching_message_queue_.empty(); + while (!dispatching_message_queue_.empty()) { + MessageQueue::value_type task; + std::swap(dispatching_message_queue_.front(), task); + dispatching_message_queue_.pop_front(); StringView message = std::get<2>(task)->string(); switch (std::get<0>(task)) { case InspectorAction::kStartSession: @@ -388,12 +413,12 @@ void InspectorIo::DispatchMessages() { break; } } - } while (!tasks.empty()); + } while (had_messages); dispatching_messages_ = false; } // static -void InspectorIo::MainThreadAsyncCb(uv_async_t* req) { +void InspectorIo::MainThreadReqAsyncCb(uv_async_t* req) { AsyncAndAgent* pair = node::ContainerOf(&AsyncAndAgent::first, req); // Note that this may be called after io was closed or even after a new // one was created and ran. @@ -408,7 +433,7 @@ void InspectorIo::Write(TransportAction action, int session_id, return; AppendMessage(&outgoing_message_queue_, action, session_id, StringBuffer::create(inspector_message)); - int err = uv_async_send(&io_thread_req_); + int err = uv_async_send(&thread_req_); CHECK_EQ(0, err); } @@ -469,12 +494,13 @@ std::string InspectorIoDelegate::GetTargetUrl(const std::string& id) { return "file://" + script_path_; } -bool IoSessionDelegate::WaitForFrontendMessage() { - io_->WaitForFrontendMessage(); +bool IoSessionDelegate::WaitForFrontendMessageWhilePaused() { + io_->WaitForFrontendMessageWhilePaused(); return true; } -void IoSessionDelegate::OnMessage(const v8_inspector::StringView& message) { +void IoSessionDelegate::SendMessageToFrontend( + const v8_inspector::StringView& message) { io_->Write(TransportAction::kSendMessage, io_->session_id_, message); } diff --git a/src/inspector_io.h b/src/inspector_io.h index dc7e148252a0e2..6ef2ea54c4745d 100644 --- a/src/inspector_io.h +++ b/src/inspector_io.h @@ -6,9 +6,9 @@ #include "node_mutex.h" #include "uv.h" +#include #include #include -#include #if !HAVE_INSPECTOR #error("This header can only be used when inspector is enabled") @@ -50,28 +50,35 @@ class InspectorIo { bool wait_for_connect); ~InspectorIo(); - // Start the inspector agent thread + // Start the inspector agent thread, waiting for it to initialize, + // and waiting as well for a connection if wait_for_connect. bool Start(); - // Stop the inspector agent + // Stop the inspector agent thread. void Stop(); bool IsStarted(); bool IsConnected(); - void WaitForDisconnect(); + void WaitForDisconnect(); + // Called from thread to queue an incoming message and trigger + // DispatchMessages() on the main thread. void PostIncomingMessage(InspectorAction action, int session_id, const std::string& message); void ResumeStartup() { - uv_sem_post(&start_sem_); + uv_sem_post(&thread_start_sem_); } void ServerDone() { - uv_close(reinterpret_cast(&io_thread_req_), nullptr); + uv_close(reinterpret_cast(&thread_req_), nullptr); } + int port() const { return port_; } + std::string host() const { return options_.host_name(); } + std::vector GetTargetIds() const; + private: template using MessageQueue = - std::vector>>; enum class State { kNew, @@ -82,53 +89,73 @@ class InspectorIo { kShutDown }; - static void ThreadCbIO(void* agent); - static void MainThreadAsyncCb(uv_async_t* req); + // Callback for main_thread_req_'s uv_async_t + static void MainThreadReqAsyncCb(uv_async_t* req); + + // Wrapper for agent->ThreadMain() + static void ThreadMain(void* agent); + + // Runs a uv_loop_t + template void ThreadMain(); + // Called by ThreadMain's loop when triggered by thread_req_, writes + // messages from outgoing_message_queue to the InspectorSockerServer + template static void IoThreadAsyncCb(uv_async_t* async); - template static void WriteCbIO(uv_async_t* async); - template void WorkerRunIO(); void SetConnected(bool connected); void DispatchMessages(); + // Write action to outgoing_message_queue, and wake the thread void Write(TransportAction action, int session_id, const v8_inspector::StringView& message); + // Thread-safe append of message to a queue. Return true if the queue + // used to be empty. template bool AppendMessage(MessageQueue* vector, ActionType action, int session_id, std::unique_ptr buffer); + // Used as equivalent of a thread-safe "pop" of an entire queue's content. template void SwapBehindLock(MessageQueue* vector1, MessageQueue* vector2); - void WaitForFrontendMessage(); + // Wait on incoming_message_cond_ + void WaitForFrontendMessageWhilePaused(); + // Broadcast incoming_message_cond_ void NotifyMessageReceived(); - bool StartThread(bool wait); - - // Message queues - ConditionVariable incoming_message_cond_; const DebugOptions options_; - uv_sem_t start_sem_; - Mutex state_lock_; + + // The IO thread runs its own uv_loop to implement the TCP server off + // the main thread. uv_thread_t thread_; + // Used by Start() to wait for thread to initialize, or for it to initialize + // and receive a connection if wait_for_connect was requested. + uv_sem_t thread_start_sem_; InspectorIoDelegate* delegate_; State state_; node::Environment* parent_env_; - uv_async_t io_thread_req_; + // Attached to the uv_loop in ThreadMain() + uv_async_t thread_req_; // Note that this will live while the async is being closed - likely, past // the parent object lifespan std::pair* main_thread_req_; std::unique_ptr session_delegate_; v8::Platform* platform_; + + // Message queues + ConditionVariable incoming_message_cond_; + Mutex state_lock_; // Locked before mutating either queue. MessageQueue incoming_message_queue_; MessageQueue outgoing_message_queue_; + MessageQueue dispatching_message_queue_; + bool dispatching_messages_; int session_id_; std::string script_name_; std::string script_path_; - const std::string id_; const bool wait_for_connect_; + int port_; friend class DispatchMessagesTask; friend class IoSessionDelegate; diff --git a/src/inspector_socket.cc b/src/inspector_socket.cc index 495cb3b3aa3e99..85984b7fa11a05 100644 --- a/src/inspector_socket.cc +++ b/src/inspector_socket.cc @@ -68,7 +68,7 @@ static void dispose_inspector(uv_handle_t* handle) { } static void close_connection(InspectorSocket* inspector) { - uv_handle_t* socket = reinterpret_cast(&inspector->client); + uv_handle_t* socket = reinterpret_cast(&inspector->tcp); if (!uv_is_closing(socket)) { uv_read_stop(reinterpret_cast(socket)); uv_close(socket, dispose_inspector); @@ -107,7 +107,7 @@ static int write_to_client(InspectorSocket* inspector, // Freed in write_request_cleanup WriteRequest* wr = new WriteRequest(inspector, msg, len); - uv_stream_t* stream = reinterpret_cast(&inspector->client); + uv_stream_t* stream = reinterpret_cast(&inspector->tcp); return uv_write(&wr->req, stream, &wr->buf, 1, write_cb) < 0; } @@ -253,7 +253,7 @@ static void invoke_read_callback(InspectorSocket* inspector, int status, const uv_buf_t* buf) { if (inspector->ws_state->read_cb) { inspector->ws_state->read_cb( - reinterpret_cast(&inspector->client), status, buf); + reinterpret_cast(&inspector->tcp), status, buf); } } @@ -304,7 +304,7 @@ static int parse_ws_frames(InspectorSocket* inspector) { uv_buf_t buffer; size_t len = output.size(); inspector->ws_state->alloc_cb( - reinterpret_cast(&inspector->client), + reinterpret_cast(&inspector->tcp), len, &buffer); CHECK_GE(buffer.len, len); memcpy(buffer.base, &output[0], len); @@ -360,14 +360,14 @@ static void websockets_data_cb(uv_stream_t* stream, ssize_t nread, } int inspector_read_start(InspectorSocket* inspector, - uv_alloc_cb alloc_cb, uv_read_cb read_cb) { + uv_alloc_cb alloc_cb, uv_read_cb read_cb) { ASSERT(inspector->ws_mode); ASSERT(!inspector->shutting_down || read_cb == nullptr); inspector->ws_state->close_sent = false; inspector->ws_state->alloc_cb = alloc_cb; inspector->ws_state->read_cb = read_cb; int err = - uv_read_start(reinterpret_cast(&inspector->client), + uv_read_start(reinterpret_cast(&inspector->tcp), prepare_buffer, websockets_data_cb); if (err < 0) { @@ -377,7 +377,7 @@ int inspector_read_start(InspectorSocket* inspector, } void inspector_read_stop(InspectorSocket* inspector) { - uv_read_stop(reinterpret_cast(&inspector->client)); + uv_read_stop(reinterpret_cast(&inspector->tcp)); inspector->ws_state->alloc_cb = nullptr; inspector->ws_state->read_cb = nullptr; } @@ -426,7 +426,7 @@ static int path_cb(http_parser* parser, const char* at, size_t length) { } static void handshake_complete(InspectorSocket* inspector) { - uv_read_stop(reinterpret_cast(&inspector->client)); + uv_read_stop(reinterpret_cast(&inspector->tcp)); handshake_cb callback = inspector->http_parsing_state->callback; inspector->ws_state = new ws_state_s(); inspector->ws_mode = true; @@ -448,7 +448,7 @@ static void report_handshake_failure_cb(uv_handle_t* handle) { } static void close_and_report_handshake_failure(InspectorSocket* inspector) { - uv_handle_t* socket = reinterpret_cast(&inspector->client); + uv_handle_t* socket = reinterpret_cast(&inspector->tcp); if (uv_is_closing(socket)) { report_handshake_failure_cb(socket); } else { @@ -474,7 +474,7 @@ static void handshake_failed(InspectorSocket* inspector) { } // init_handshake references message_complete_cb -static void init_handshake(InspectorSocket* inspector); +static void init_handshake(InspectorSocket* socket); static int message_complete_cb(http_parser* parser) { InspectorSocket* inspector = static_cast(parser->data); @@ -513,7 +513,7 @@ static int message_complete_cb(http_parser* parser) { return 0; } -static void data_received_cb(uv_stream_s* client, ssize_t nread, +static void data_received_cb(uv_stream_s* tcp, ssize_t nread, const uv_buf_t* buf) { #if DUMP_READS if (nread >= 0) { @@ -523,7 +523,7 @@ static void data_received_cb(uv_stream_s* client, ssize_t nread, printf("[%s:%d] %s\n", __FUNCTION__, __LINE__, uv_err_name(nread)); } #endif - InspectorSocket* inspector = inspector_from_stream(client); + InspectorSocket* inspector = inspector_from_stream(tcp); reclaim_uv_buf(inspector, buf, nread); if (nread < 0 || nread == UV_EOF) { close_and_report_handshake_failure(inspector); @@ -542,15 +542,15 @@ static void data_received_cb(uv_stream_s* client, ssize_t nread, } } -static void init_handshake(InspectorSocket* inspector) { - http_parsing_state_s* state = inspector->http_parsing_state; +static void init_handshake(InspectorSocket* socket) { + http_parsing_state_s* state = socket->http_parsing_state; CHECK_NE(state, nullptr); state->current_header.clear(); state->ws_key.clear(); state->path.clear(); state->done = false; http_parser_init(&state->parser, HTTP_REQUEST); - state->parser.data = inspector; + state->parser.data = socket; http_parser_settings* settings = &state->parser_settings; http_parser_settings_init(settings); settings->on_header_field = header_field_cb; @@ -559,26 +559,26 @@ static void init_handshake(InspectorSocket* inspector) { settings->on_url = path_cb; } -int inspector_accept(uv_stream_t* server, InspectorSocket* inspector, +int inspector_accept(uv_stream_t* server, InspectorSocket* socket, handshake_cb callback) { ASSERT_NE(callback, nullptr); - CHECK_EQ(inspector->http_parsing_state, nullptr); + CHECK_EQ(socket->http_parsing_state, nullptr); - inspector->http_parsing_state = new http_parsing_state_s(); - uv_stream_t* client = reinterpret_cast(&inspector->client); - int err = uv_tcp_init(server->loop, &inspector->client); + socket->http_parsing_state = new http_parsing_state_s(); + uv_stream_t* tcp = reinterpret_cast(&socket->tcp); + int err = uv_tcp_init(server->loop, &socket->tcp); if (err == 0) { - err = uv_accept(server, client); + err = uv_accept(server, tcp); } if (err == 0) { - init_handshake(inspector); - inspector->http_parsing_state->callback = callback; - err = uv_read_start(client, prepare_buffer, + init_handshake(socket); + socket->http_parsing_state->callback = callback; + err = uv_read_start(tcp, prepare_buffer, data_received_cb); } if (err != 0) { - uv_close(reinterpret_cast(client), NULL); + uv_close(reinterpret_cast(tcp), NULL); } return err; } @@ -594,10 +594,10 @@ void inspector_write(InspectorSocket* inspector, const char* data, } void inspector_close(InspectorSocket* inspector, - inspector_cb callback) { + inspector_cb callback) { // libuv throws assertions when closing stream that's already closed - we // need to do the same. - ASSERT(!uv_is_closing(reinterpret_cast(&inspector->client))); + ASSERT(!uv_is_closing(reinterpret_cast(&inspector->tcp))); ASSERT(!inspector->shutting_down); inspector->shutting_down = true; inspector->ws_state->close_cb = callback; @@ -612,9 +612,9 @@ void inspector_close(InspectorSocket* inspector, } bool inspector_is_active(const InspectorSocket* inspector) { - const uv_handle_t* client = - reinterpret_cast(&inspector->client); - return !inspector->shutting_down && !uv_is_closing(client); + const uv_handle_t* tcp = + reinterpret_cast(&inspector->tcp); + return !inspector->shutting_down && !uv_is_closing(tcp); } void InspectorSocket::reinit() { diff --git a/src/inspector_socket.h b/src/inspector_socket.h index 558d87bcb76bf1..7cd8254fb3f4d2 100644 --- a/src/inspector_socket.h +++ b/src/inspector_socket.h @@ -48,6 +48,7 @@ struct ws_state_s { bool received_close; }; +// HTTP Wrapper around a uv_tcp_t class InspectorSocket { public: InspectorSocket() : data(nullptr), http_parsing_state(nullptr), @@ -58,7 +59,7 @@ class InspectorSocket { struct http_parsing_state_s* http_parsing_state; struct ws_state_s* ws_state; std::vector buffer; - uv_tcp_t client; + uv_tcp_t tcp; bool ws_mode; bool shutting_down; bool connection_eof; @@ -82,7 +83,7 @@ void inspector_write(InspectorSocket* inspector, bool inspector_is_active(const InspectorSocket* inspector); inline InspectorSocket* inspector_from_stream(uv_tcp_t* stream) { - return node::ContainerOf(&InspectorSocket::client, stream); + return node::ContainerOf(&InspectorSocket::tcp, stream); } inline InspectorSocket* inspector_from_stream(uv_stream_t* stream) { diff --git a/src/inspector_socket_server.cc b/src/inspector_socket_server.cc index 1e1d0ff5676695..f3e56b6ceb53e0 100644 --- a/src/inspector_socket_server.cc +++ b/src/inspector_socket_server.cc @@ -230,9 +230,9 @@ class SocketSession { private: enum class State { kHttp, kWebSocket, kClosing, kEOF, kDeclined }; - static void CloseCallback_(InspectorSocket* socket, int code); - static void ReadCallback_(uv_stream_t* stream, ssize_t read, - const uv_buf_t* buf); + static void CloseCallback(InspectorSocket* socket, int code); + static void ReadCallback(uv_stream_t* stream, ssize_t read, + const uv_buf_t* buf); void OnRemoteDataIO(ssize_t read, const uv_buf_t* buf); const int id_; InspectorSocket socket_; @@ -242,9 +242,10 @@ class SocketSession { }; InspectorSocketServer::InspectorSocketServer(SocketServerDelegate* delegate, + uv_loop_t* loop, const std::string& host, int port, - FILE* out) : loop_(nullptr), + FILE* out) : loop_(loop), delegate_(delegate), host_(host), port_(port), @@ -255,7 +256,6 @@ InspectorSocketServer::InspectorSocketServer(SocketServerDelegate* delegate, state_ = ServerState::kNew; } - // static bool InspectorSocketServer::HandshakeCallback(InspectorSocket* socket, inspector_handshake_event event, @@ -361,7 +361,7 @@ void InspectorSocketServer::SendListResponse(InspectorSocket* socket) { } if (!connected) { std::string host; - GetSocketHost(&socket->client, &host); + GetSocketHost(&socket->tcp, &host); std::string address = GetWsUrl(host, port_, id); std::ostringstream frontend_url; frontend_url << "chrome-devtools://devtools/bundled"; @@ -374,9 +374,8 @@ void InspectorSocketServer::SendListResponse(InspectorSocket* socket) { SendHttpResponse(socket, MapsToString(response)); } -bool InspectorSocketServer::Start(uv_loop_t* loop) { +bool InspectorSocketServer::Start() { CHECK_EQ(state_, ServerState::kNew); - loop_ = loop; sockaddr_in addr; uv_tcp_init(loop_, &server_); uv_ip4_addr(host_.c_str(), port_, &addr); @@ -470,11 +469,11 @@ SocketSession::SocketSession(InspectorSocketServer* server, int id) void SocketSession::Close() { CHECK_NE(state_, State::kClosing); state_ = State::kClosing; - inspector_close(&socket_, CloseCallback_); + inspector_close(&socket_, CloseCallback); } // static -void SocketSession::CloseCallback_(InspectorSocket* socket, int code) { +void SocketSession::CloseCallback(InspectorSocket* socket, int code) { SocketSession* session = SocketSession::From(socket); CHECK_EQ(State::kClosing, session->state_); session->server_->SessionTerminated(session); @@ -483,12 +482,12 @@ void SocketSession::CloseCallback_(InspectorSocket* socket, int code) { void SocketSession::FrontendConnected() { CHECK_EQ(State::kHttp, state_); state_ = State::kWebSocket; - inspector_read_start(&socket_, OnBufferAlloc, ReadCallback_); + inspector_read_start(&socket_, OnBufferAlloc, ReadCallback); } // static -void SocketSession::ReadCallback_(uv_stream_t* stream, ssize_t read, - const uv_buf_t* buf) { +void SocketSession::ReadCallback(uv_stream_t* stream, ssize_t read, + const uv_buf_t* buf) { InspectorSocket* socket = inspector_from_stream(stream); SocketSession::From(socket)->OnRemoteDataIO(read, buf); } diff --git a/src/inspector_socket_server.h b/src/inspector_socket_server.h index 8c8e2aaade9332..4c606ee77a15f3 100644 --- a/src/inspector_socket_server.h +++ b/src/inspector_socket_server.h @@ -30,17 +30,30 @@ class SocketServerDelegate { virtual void ServerDone() = 0; }; +// HTTP Server, writes messages requested as TransportActions, and responds +// to HTTP requests and WS upgrades. + + + class InspectorSocketServer { public: using ServerCallback = void (*)(InspectorSocketServer*); InspectorSocketServer(SocketServerDelegate* delegate, + uv_loop_t* loop, const std::string& host, int port, FILE* out = stderr); - bool Start(uv_loop_t* loop); + // Start listening on host/port + bool Start(); + + // Called by the TransportAction sent with InspectorIo::Write(): + // kKill and kStop void Stop(ServerCallback callback); + // kSendMessage void Send(int session_id, const std::string& message); + // kKill void TerminateConnections(); + int port() { return port_; } diff --git a/src/node.cc b/src/node.cc index 60fba9ad2fa553..68f134ffe99b79 100644 --- a/src/node.cc +++ b/src/node.cc @@ -40,6 +40,10 @@ #include "node_i18n.h" #endif +#if HAVE_INSPECTOR +#include "inspector_io.h" +#endif + #if defined HAVE_DTRACE || defined HAVE_ETW #include "node_dtrace.h" #endif @@ -260,6 +264,9 @@ static struct { #if HAVE_INSPECTOR bool StartInspector(Environment *env, const char* script_path, const node::DebugOptions& options) { + // Inspector agent can't fail to start, but if it was configured to listen + // right away on the websocket port and fails to bind/etc, this will return + // false. return env->inspector_agent()->Start(platform_, script_path, options); } @@ -3048,7 +3055,15 @@ static Local GetFeatures(Environment* env) { static void DebugPortGetter(Local property, const PropertyCallbackInfo& info) { - info.GetReturnValue().Set(debug_options.port()); + int port = debug_options.port(); +#if HAVE_INSPECTOR + if (port == 0) { + Environment* env = Environment::GetCurrent(info); + if (env->inspector_agent()->IsStarted()) + port = env->inspector_agent()->io()->port(); + } +#endif // HAVE_INSPECTOR + info.GetReturnValue().Set(port); } @@ -3388,13 +3403,7 @@ void SetupProcessObject(Environment* env, READONLY_PROPERTY(process, "traceDeprecation", True(env->isolate())); } - // TODO(refack): move the following 4 to `node_config` - // --inspect - if (debug_options.inspector_enabled()) { - READONLY_DONT_ENUM_PROPERTY(process, - "_inspectorEnbale", True(env->isolate())); - } - + // TODO(refack): move the following 3 to `node_config` // --inspect-brk if (debug_options.wait_for_connect()) { READONLY_DONT_ENUM_PROPERTY(process, @@ -3620,7 +3629,7 @@ static void PrintHelp() { " -r, --require module to preload (option can be " "repeated)\n" " - script read from stdin (default; " - "interactive mode if a tty)" + "interactive mode if a tty)\n" #if HAVE_INSPECTOR " --inspect[=[host:]port] activate inspector on host:port\n" " (default: 127.0.0.1:9229)\n" @@ -3998,8 +4007,8 @@ static void ParseArgs(int* argc, } -static void StartDebug(Environment* env, const char* path, - DebugOptions debug_options) { +static void StartInspector(Environment* env, const char* path, + DebugOptions debug_options) { #if HAVE_INSPECTOR CHECK(!env->inspector_agent()->IsStarted()); v8_platform.StartInspector(env, path, debug_options); @@ -4491,7 +4500,7 @@ inline int Start(Isolate* isolate, IsolateData* isolate_data, env.Start(argc, argv, exec_argc, exec_argv, v8_is_profiling); const char* path = argc > 1 ? argv[1] : nullptr; - StartDebug(&env, path, debug_options); + StartInspector(&env, path, debug_options); if (debug_options.inspector_enabled() && !v8_platform.InspectorStarted(&env)) return 12; // Signal internal error. diff --git a/src/node_api.cc b/src/node_api.cc index 719ceacb4bdbd3..0c8abd0998e734 100644 --- a/src/node_api.cc +++ b/src/node_api.cc @@ -819,9 +819,6 @@ napi_status napi_define_class(napi_env env, v8::Local tpl = v8::FunctionTemplate::New( isolate, v8impl::FunctionCallbackWrapper::Invoke, cbdata); - // we need an internal field to stash the wrapped object - tpl->InstanceTemplate()->SetInternalFieldCount(1); - v8::Local name_string; CHECK_NEW_FROM_UTF8(env, name_string, utf8name); tpl->SetClassName(name_string); @@ -1950,14 +1947,24 @@ napi_status napi_wrap(napi_env env, CHECK_ARG(env, js_object); v8::Isolate* isolate = env->isolate; - v8::Local obj = - v8impl::V8LocalValueFromJsValue(js_object).As(); + v8::Local context = isolate->GetCurrentContext(); - // Only objects that were created from a NAPI constructor's prototype - // via napi_define_class() can be (un)wrapped. - RETURN_STATUS_IF_FALSE(env, obj->InternalFieldCount() > 0, napi_invalid_arg); + v8::Local value = v8impl::V8LocalValueFromJsValue(js_object); + RETURN_STATUS_IF_FALSE(env, value->IsObject(), napi_invalid_arg); + v8::Local obj = value.As(); + + // Create a wrapper object with an internal field to hold the wrapped pointer. + v8::Local wrapperTemplate = + v8::ObjectTemplate::New(isolate); + wrapperTemplate->SetInternalFieldCount(1); + v8::Local wrapper = + wrapperTemplate->NewInstance(context).ToLocalChecked(); + wrapper->SetInternalField(0, v8::External::New(isolate, native_object)); - obj->SetInternalField(0, v8::External::New(isolate, native_object)); + // Insert the wrapper into the object's prototype chain. + v8::Local proto = obj->GetPrototype(); + wrapper->SetPrototype(proto); + obj->SetPrototype(wrapper); if (result != nullptr) { // The returned reference should be deleted via napi_delete_reference() @@ -1988,11 +1995,18 @@ napi_status napi_unwrap(napi_env env, napi_value js_object, void** result) { RETURN_STATUS_IF_FALSE(env, value->IsObject(), napi_invalid_arg); v8::Local obj = value.As(); - // Only objects that were created from a NAPI constructor's prototype - // via napi_define_class() can be (un)wrapped. - RETURN_STATUS_IF_FALSE(env, obj->InternalFieldCount() > 0, napi_invalid_arg); - - v8::Local unwrappedValue = obj->GetInternalField(0); + // Search the object's prototype chain for the wrapper with an internal field. + // Usually the wrapper would be the first in the chain, but it is OK for + // other objects to be inserted in the prototype chain. + v8::Local wrapper = obj; + do { + v8::Local proto = wrapper->GetPrototype(); + RETURN_STATUS_IF_FALSE( + env, !proto.IsEmpty() && proto->IsObject(), napi_invalid_arg); + wrapper = proto.As(); + } while (wrapper->InternalFieldCount() != 1); + + v8::Local unwrappedValue = wrapper->GetInternalField(0); RETURN_STATUS_IF_FALSE(env, unwrappedValue->IsExternal(), napi_invalid_arg); *result = unwrappedValue.As()->Value(); diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 85d05a25061a69..8c2121687600dd 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -5136,6 +5136,8 @@ void ECDH::ComputeSecret(const FunctionCallbackInfo& args) { ECDH* ecdh; ASSIGN_OR_RETURN_UNWRAP(&ecdh, args.Holder()); + MarkPopErrorOnReturn mark_pop_error_on_return; + if (!ecdh->IsKeyPairValid()) return env->ThrowError("Invalid key pair"); @@ -5282,6 +5284,8 @@ void ECDH::SetPublicKey(const FunctionCallbackInfo& args) { THROW_AND_RETURN_IF_NOT_BUFFER(args[0], "Public key"); + MarkPopErrorOnReturn mark_pop_error_on_return; + EC_POINT* pub = ecdh->BufferToPoint(Buffer::Data(args[0].As()), Buffer::Length(args[0].As())); if (pub == nullptr) diff --git a/src/node_debug_options.cc b/src/node_debug_options.cc index 3f1a2e56e89985..d82e92170a9304 100644 --- a/src/node_debug_options.cc +++ b/src/node_debug_options.cc @@ -21,8 +21,9 @@ int parse_and_validate_port(const std::string& port) { char* endptr; errno = 0; const long result = strtol(port.c_str(), &endptr, 10); // NOLINT(runtime/int) - if (errno != 0 || *endptr != '\0'|| result < 1024 || result > 65535) { - fprintf(stderr, "Debug port must be in range 1024 to 65535.\n"); + if (errno != 0 || *endptr != '\0'|| + (result != 0 && result < 1024) || result > 65535) { + fprintf(stderr, "Debug port must be 0 or in range 1024 to 65535.\n"); exit(12); } return static_cast(result); diff --git a/src/node_debug_options.h b/src/node_debug_options.h index 6fdd30384fc3e8..99364f40989f6a 100644 --- a/src/node_debug_options.h +++ b/src/node_debug_options.h @@ -21,6 +21,7 @@ class DebugOptions { } bool wait_for_connect() const { return break_first_line_; } std::string host_name() const { return host_name_; } + void set_host_name(std::string host_name) { host_name_ = host_name; } int port() const; void set_port(int port) { port_ = port; } diff --git a/src/node_http_parser.cc b/src/node_http_parser.cc index 40e106cd46fd3c..a339043bdca5bd 100644 --- a/src/node_http_parser.cc +++ b/src/node_http_parser.cc @@ -496,6 +496,7 @@ class Parser : public AsyncWrap { static void Consume(const FunctionCallbackInfo& args) { Parser* parser; ASSIGN_OR_RETURN_UNWRAP(&parser, args.Holder()); + CHECK(args[0]->IsExternal()); Local stream_obj = args[0].As(); StreamBase* stream = static_cast(stream_obj->Value()); CHECK_NE(stream, nullptr); diff --git a/src/node_i18n.cc b/src/node_i18n.cc index dc50f9995a695e..f35bf2685592a4 100644 --- a/src/node_i18n.cc +++ b/src/node_i18n.cc @@ -450,6 +450,9 @@ int32_t ToUnicode(MaybeStackBuffer* buf, &info, &status); + // Do not check info.errors like we do with ToASCII since ToUnicode always + // returns a string, despite any possible errors that may have occurred. + if (status == U_BUFFER_OVERFLOW_ERROR) { status = U_ZERO_ERROR; buf->AllocateSufficientStorage(len); @@ -477,9 +480,18 @@ int32_t ToUnicode(MaybeStackBuffer* buf, int32_t ToASCII(MaybeStackBuffer* buf, const char* input, size_t length, - bool lenient) { + enum idna_mode mode) { UErrorCode status = U_ZERO_ERROR; - uint32_t options = UIDNA_NONTRANSITIONAL_TO_ASCII | UIDNA_CHECK_BIDI; + uint32_t options = // CheckHyphens = false; handled later + UIDNA_CHECK_BIDI | // CheckBidi = true + UIDNA_CHECK_CONTEXTJ | // CheckJoiners = true + UIDNA_NONTRANSITIONAL_TO_ASCII; // Nontransitional_Processing + if (mode == IDNA_STRICT) { + options |= UIDNA_USE_STD3_RULES; // UseSTD3ASCIIRules = beStrict + // VerifyDnsLength = beStrict; + // handled later + } + UIDNA* uidna = uidna_openUTS46(options, &status); if (U_FAILURE(status)) return -1; @@ -501,21 +513,17 @@ int32_t ToASCII(MaybeStackBuffer* buf, &status); } - // The WHATWG URL "domain to ASCII" algorithm explicitly sets the - // VerifyDnsLength flag to false, which disables the domain name length - // verification step in ToASCII (as specified by UTS #46). Unfortunately, - // ICU4C's IDNA module does not support disabling this flag through `options`, - // so just filter out the errors that may be caused by the verification step - // afterwards. - info.errors &= ~UIDNA_ERROR_EMPTY_LABEL; - info.errors &= ~UIDNA_ERROR_LABEL_TOO_LONG; - info.errors &= ~UIDNA_ERROR_DOMAIN_NAME_TOO_LONG; - - // These error conditions are mandated unconditionally by UTS #46 version - // 9.0.0 (rev. 17), but were found to be incompatible with actual domain - // names in the wild. As such, in the current UTS #46 draft (rev. 18) these - // checks are made optional depending on the CheckHyphens flag, which will be - // disabled in WHATWG URL's "domain to ASCII" algorithm soon. + // In UTS #46 which specifies ToASCII, certain error conditions are + // configurable through options, and the WHATWG URL Standard promptly elects + // to disable some of them to accomodate for real-world use cases. + // Unfortunately, ICU4C's IDNA module does not support disabling some of + // these options through `options` above, and thus continues throwing + // unnecessary errors. To counter this situation, we just filter out the + // errors that may have happened afterwards, before deciding whether to + // return an error from this function. + + // CheckHyphens = false + // (Specified in the current UTS #46 draft rev. 18.) // Refs: // - https://github.com/whatwg/url/issues/53 // - https://github.com/whatwg/url/pull/309 @@ -526,7 +534,14 @@ int32_t ToASCII(MaybeStackBuffer* buf, info.errors &= ~UIDNA_ERROR_LEADING_HYPHEN; info.errors &= ~UIDNA_ERROR_TRAILING_HYPHEN; - if (U_FAILURE(status) || (!lenient && info.errors != 0)) { + if (mode != IDNA_STRICT) { + // VerifyDnsLength = beStrict + info.errors &= ~UIDNA_ERROR_EMPTY_LABEL; + info.errors &= ~UIDNA_ERROR_LABEL_TOO_LONG; + info.errors &= ~UIDNA_ERROR_DOMAIN_NAME_TOO_LONG; + } + + if (U_FAILURE(status) || (mode != IDNA_LENIENT && info.errors != 0)) { len = -1; buf->SetLength(0); } else { @@ -564,9 +579,10 @@ static void ToASCII(const FunctionCallbackInfo& args) { Utf8Value val(env->isolate(), args[0]); // optional arg bool lenient = args[1]->BooleanValue(env->context()).FromJust(); + enum idna_mode mode = lenient ? IDNA_LENIENT : IDNA_DEFAULT; MaybeStackBuffer buf; - int32_t len = ToASCII(&buf, *val, val.length(), lenient); + int32_t len = ToASCII(&buf, *val, val.length(), mode); if (len < 0) { return env->ThrowError("Cannot convert name to ASCII"); diff --git a/src/node_i18n.h b/src/node_i18n.h index cc1f3e6ea53569..adf9feb414df5c 100644 --- a/src/node_i18n.h +++ b/src/node_i18n.h @@ -37,10 +37,26 @@ namespace i18n { bool InitializeICUDirectory(const std::string& path); +enum idna_mode { + // Default mode for maximum compatibility. + IDNA_DEFAULT, + // Ignore all errors in IDNA conversion, if possible. + IDNA_LENIENT, + // Enforce STD3 rules (UseSTD3ASCIIRules) and DNS length restrictions + // (VerifyDnsLength). Corresponds to `beStrict` flag in the "domain to ASCII" + // algorithm. + IDNA_STRICT +}; + +// Implements the WHATWG URL Standard "domain to ASCII" algorithm. +// https://url.spec.whatwg.org/#concept-domain-to-ascii int32_t ToASCII(MaybeStackBuffer* buf, const char* input, size_t length, - bool lenient = false); + enum idna_mode mode = IDNA_DEFAULT); + +// Implements the WHATWG URL Standard "domain to Unicode" algorithm. +// https://url.spec.whatwg.org/#concept-domain-to-unicode int32_t ToUnicode(MaybeStackBuffer* buf, const char* input, size_t length); diff --git a/src/node_version.h b/src/node_version.h index b361e9da66b585..92814947143d4f 100644 --- a/src/node_version.h +++ b/src/node_version.h @@ -23,7 +23,7 @@ #define SRC_NODE_VERSION_H_ #define NODE_MAJOR_VERSION 8 -#define NODE_MINOR_VERSION 0 +#define NODE_MINOR_VERSION 1 #define NODE_PATCH_VERSION 1 #define NODE_VERSION_IS_RELEASE 0 diff --git a/test/abort/test-http-parser-consume.js b/test/abort/test-http-parser-consume.js new file mode 100644 index 00000000000000..4a05a299a8e956 --- /dev/null +++ b/test/abort/test-http-parser-consume.js @@ -0,0 +1,28 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const http = require('http'); +const spawn = require('child_process').spawn; + +if (process.argv[2] === 'child') { + const server = http.createServer(common.mustCall((req, res) => { + res.end('hello'); + })); + + server.listen(0, common.mustCall((s) => { + const rr = http.get( + { port: server.address().port }, + common.mustCall((d) => { + // This bad input (0) should abort the parser and the process + rr.parser.consume(0); + server.close(); + })); + })); +} else { + const child = spawn(process.execPath, [__filename, 'child'], + { stdio: 'inherit' }); + child.on('exit', common.mustCall((code, signal) => { + assert(common.nodeProcessAborted(code, signal), + 'process should have aborted, but did not'); + })); +} diff --git a/test/addons-napi/test_globals/test.js b/test/addons-napi/test_general/testGlobals.js similarity index 96% rename from test/addons-napi/test_globals/test.js rename to test/addons-napi/test_general/testGlobals.js index a6e5f722cb9379..38cf3f3edbccbc 100644 --- a/test/addons-napi/test_globals/test.js +++ b/test/addons-napi/test_general/testGlobals.js @@ -2,7 +2,7 @@ const common = require('../../common'); const assert = require('assert'); -const test_globals = require(`./build/${common.buildType}/test_globals`); +const test_globals = require(`./build/${common.buildType}/test_general`); assert.strictEqual(test_globals.getUndefined(), undefined); assert.strictEqual(test_globals.getNull(), null); diff --git a/test/addons-napi/test_instanceof/test.js b/test/addons-napi/test_general/testInstanceOf.js similarity index 97% rename from test/addons-napi/test_instanceof/test.js rename to test/addons-napi/test_general/testInstanceOf.js index 418149d1909e6f..3279979719dc37 100644 --- a/test/addons-napi/test_instanceof/test.js +++ b/test/addons-napi/test_general/testInstanceOf.js @@ -6,7 +6,7 @@ const assert = require('assert'); // addon is referenced through the eval expression in testFile // eslint-disable-next-line no-unused-vars -const addon = require(`./build/${common.buildType}/test_instanceof`); +const addon = require(`./build/${common.buildType}/test_general`); const path = require('path'); // The following assert functions are referenced by v8's unit tests diff --git a/test/addons-napi/test_napi_status/test.js b/test/addons-napi/test_general/testNapiStatus.js similarity index 73% rename from test/addons-napi/test_napi_status/test.js rename to test/addons-napi/test_general/testNapiStatus.js index 60c4f693b2d951..a588862098f68f 100644 --- a/test/addons-napi/test_napi_status/test.js +++ b/test/addons-napi/test_general/testNapiStatus.js @@ -1,7 +1,7 @@ 'use strict'; const common = require('../../common'); -const addon = require(`./build/${common.buildType}/test_napi_status`); +const addon = require(`./build/${common.buildType}/test_general`); const assert = require('assert'); addon.createNapiError(); diff --git a/test/addons-napi/test_general/test_general.c b/test/addons-napi/test_general/test_general.c index 585a3bf2b3ff0d..0b69cc41e29fb5 100644 --- a/test/addons-napi/test_general/test_general.c +++ b/test/addons-napi/test_general/test_general.c @@ -33,11 +33,73 @@ napi_value testGetVersion(napi_env env, napi_callback_info info) { return result; } +napi_value doInstanceOf(napi_env env, napi_callback_info info) { + size_t argc = 2; + napi_value args[2]; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL)); + + bool instanceof; + NAPI_CALL(env, napi_instanceof(env, args[0], args[1], &instanceof)); + + napi_value result; + NAPI_CALL(env, napi_get_boolean(env, instanceof, &result)); + + return result; +} + +napi_value getNull(napi_env env, napi_callback_info info) { + napi_value result; + NAPI_CALL(env, napi_get_null(env, &result)); + return result; +} + +napi_value getUndefined(napi_env env, napi_callback_info info) { + napi_value result; + NAPI_CALL(env, napi_get_undefined(env, &result)); + return result; +} + +napi_value createNapiError(napi_env env, napi_callback_info info) { + napi_value value; + NAPI_CALL(env, napi_create_string_utf8(env, "xyz", 3, &value)); + + double double_value; + napi_status status = napi_get_value_double(env, value, &double_value); + + NAPI_ASSERT(env, status != napi_ok, "Failed to produce error condition"); + + const napi_extended_error_info *error_info = 0; + NAPI_CALL(env, napi_get_last_error_info(env, &error_info)); + + NAPI_ASSERT(env, error_info->error_code == status, + "Last error info code should match last status"); + NAPI_ASSERT(env, error_info->error_message, + "Last error info message should not be null"); + + return NULL; +} + +napi_value testNapiErrorCleanup(napi_env env, napi_callback_info info) { + const napi_extended_error_info *error_info = 0; + NAPI_CALL(env, napi_get_last_error_info(env, &error_info)); + + napi_value result; + bool is_ok = error_info->error_code == napi_ok; + NAPI_CALL(env, napi_get_boolean(env, is_ok, &result)); + + return result; +} + void Init(napi_env env, napi_value exports, napi_value module, void* priv) { napi_property_descriptor descriptors[] = { DECLARE_NAPI_PROPERTY("testStrictEquals", testStrictEquals), DECLARE_NAPI_PROPERTY("testGetPrototype", testGetPrototype), DECLARE_NAPI_PROPERTY("testGetVersion", testGetVersion), + DECLARE_NAPI_PROPERTY("doInstanceOf", doInstanceOf), + DECLARE_NAPI_PROPERTY("getUndefined", getUndefined), + DECLARE_NAPI_PROPERTY("getNull", getNull), + DECLARE_NAPI_PROPERTY("createNapiError", createNapiError), + DECLARE_NAPI_PROPERTY("testNapiErrorCleanup", testNapiErrorCleanup), }; NAPI_CALL_RETURN_VOID(env, napi_define_properties( diff --git a/test/addons-napi/test_globals/binding.gyp b/test/addons-napi/test_globals/binding.gyp deleted file mode 100644 index 0160dc72e18017..00000000000000 --- a/test/addons-napi/test_globals/binding.gyp +++ /dev/null @@ -1,8 +0,0 @@ -{ - "targets": [ - { - "target_name": "test_globals", - "sources": [ "test_globals.c" ] - } - ] -} diff --git a/test/addons-napi/test_globals/test_globals.c b/test/addons-napi/test_globals/test_globals.c deleted file mode 100644 index 709e42a2e0e6c8..00000000000000 --- a/test/addons-napi/test_globals/test_globals.c +++ /dev/null @@ -1,26 +0,0 @@ -#include -#include "../common.h" - -napi_value getNull(napi_env env, napi_callback_info info) { - napi_value result; - NAPI_CALL(env, napi_get_null(env, &result)); - return result; -} - -napi_value getUndefined(napi_env env, napi_callback_info info) { - napi_value result; - NAPI_CALL(env, napi_get_undefined(env, &result)); - return result; -} - -void Init(napi_env env, napi_value exports, napi_value module, void* priv) { - napi_property_descriptor descriptors[] = { - DECLARE_NAPI_PROPERTY("getUndefined", getUndefined), - DECLARE_NAPI_PROPERTY("getNull", getNull), - }; - - NAPI_CALL_RETURN_VOID(env, napi_define_properties( - env, exports, sizeof(descriptors) / sizeof(*descriptors), descriptors)); -} - -NAPI_MODULE(addon, Init) diff --git a/test/addons-napi/test_instanceof/binding.gyp b/test/addons-napi/test_instanceof/binding.gyp deleted file mode 100644 index 7fca7e0736d410..00000000000000 --- a/test/addons-napi/test_instanceof/binding.gyp +++ /dev/null @@ -1,8 +0,0 @@ -{ - "targets": [ - { - "target_name": "test_instanceof", - "sources": [ "test_instanceof.c" ] - } - ] -} diff --git a/test/addons-napi/test_instanceof/test_instanceof.c b/test/addons-napi/test_instanceof/test_instanceof.c deleted file mode 100644 index 76a6542830959d..00000000000000 --- a/test/addons-napi/test_instanceof/test_instanceof.c +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include -#include "../common.h" - -napi_value doInstanceOf(napi_env env, napi_callback_info info) { - size_t argc = 2; - napi_value args[2]; - NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL)); - - bool instanceof; - NAPI_CALL(env, napi_instanceof(env, args[0], args[1], &instanceof)); - - napi_value result; - NAPI_CALL(env, napi_get_boolean(env, instanceof, &result)); - - return result; -} - -void Init(napi_env env, napi_value exports, napi_value module, void* priv) { - napi_property_descriptor descriptors[] = { - DECLARE_NAPI_PROPERTY("doInstanceOf", doInstanceOf), - }; - - NAPI_CALL_RETURN_VOID(env, napi_define_properties( - env, exports, sizeof(descriptors) / sizeof(*descriptors), descriptors)); -} - -NAPI_MODULE(addon, Init) diff --git a/test/addons-napi/test_napi_status/binding.gyp b/test/addons-napi/test_napi_status/binding.gyp deleted file mode 100644 index 01ace540a99781..00000000000000 --- a/test/addons-napi/test_napi_status/binding.gyp +++ /dev/null @@ -1,8 +0,0 @@ -{ - "targets": [ - { - "target_name": "test_napi_status", - "sources": [ "test_napi_status.cc" ] - } - ] -} diff --git a/test/addons-napi/test_napi_status/test_napi_status.cc b/test/addons-napi/test_napi_status/test_napi_status.cc deleted file mode 100644 index 9e340aa46e106c..00000000000000 --- a/test/addons-napi/test_napi_status/test_napi_status.cc +++ /dev/null @@ -1,45 +0,0 @@ -#include -#include "../common.h" - -napi_value createNapiError(napi_env env, napi_callback_info info) { - napi_value value; - NAPI_CALL(env, napi_create_string_utf8(env, "xyz", 3, &value)); - - double double_value; - napi_status status = napi_get_value_double(env, value, &double_value); - - NAPI_ASSERT(env, status != napi_ok, "Failed to produce error condition"); - - const napi_extended_error_info *error_info = 0; - NAPI_CALL(env, napi_get_last_error_info(env, &error_info)); - - NAPI_ASSERT(env, error_info->error_code == status, - "Last error info code should match last status"); - NAPI_ASSERT(env, error_info->error_message, - "Last error info message should not be null"); - - return nullptr; -} - -napi_value testNapiErrorCleanup(napi_env env, napi_callback_info info) { - const napi_extended_error_info *error_info = 0; - NAPI_CALL(env, napi_get_last_error_info(env, &error_info)); - - napi_value result; - bool is_ok = error_info->error_code == napi_ok; - NAPI_CALL(env, napi_get_boolean(env, is_ok, &result)); - - return result; -} - -void Init(napi_env env, napi_value exports, napi_value module, void* priv) { - napi_property_descriptor descriptors[] = { - DECLARE_NAPI_PROPERTY("createNapiError", createNapiError), - DECLARE_NAPI_PROPERTY("testNapiErrorCleanup", testNapiErrorCleanup), - }; - - NAPI_CALL_RETURN_VOID(env, napi_define_properties( - env, exports, sizeof(descriptors) / sizeof(*descriptors), descriptors)); -} - -NAPI_MODULE(addon, Init) diff --git a/test/addons-napi/test_object/test.js b/test/addons-napi/test_object/test.js index d14a15421feef6..4b64fa4b381af5 100644 --- a/test/addons-napi/test_object/test.js +++ b/test/addons-napi/test_object/test.js @@ -31,35 +31,73 @@ assert(test_object.Has(newObject, 'test_number')); assert.strictEqual(newObject.test_number, 987654321); assert.strictEqual(newObject.test_string, 'test string'); -// test_object.Inflate increases all properties by 1 -const cube = { - x: 10, - y: 10, - z: 10 -}; +{ + // test_object.Inflate increases all properties by 1 + const cube = { + x: 10, + y: 10, + z: 10 + }; -assert.deepStrictEqual(test_object.Inflate(cube), {x: 11, y: 11, z: 11}); -assert.deepStrictEqual(test_object.Inflate(cube), {x: 12, y: 12, z: 12}); -assert.deepStrictEqual(test_object.Inflate(cube), {x: 13, y: 13, z: 13}); -cube.t = 13; -assert.deepStrictEqual(test_object.Inflate(cube), {x: 14, y: 14, z: 14, t: 14}); - -const sym1 = Symbol('1'); -const sym2 = Symbol('2'); -const sym3 = Symbol('3'); -const sym4 = Symbol('4'); -const object2 = { - [sym1]: '@@iterator', - [sym2]: sym3 -}; + assert.deepStrictEqual(test_object.Inflate(cube), {x: 11, y: 11, z: 11}); + assert.deepStrictEqual(test_object.Inflate(cube), {x: 12, y: 12, z: 12}); + assert.deepStrictEqual(test_object.Inflate(cube), {x: 13, y: 13, z: 13}); + cube.t = 13; + assert.deepStrictEqual( + test_object.Inflate(cube), {x: 14, y: 14, z: 14, t: 14}); + + const sym1 = Symbol('1'); + const sym2 = Symbol('2'); + const sym3 = Symbol('3'); + const sym4 = Symbol('4'); + const object2 = { + [sym1]: '@@iterator', + [sym2]: sym3 + }; + + assert(test_object.Has(object2, sym1)); + assert(test_object.Has(object2, sym2)); + assert.strictEqual(test_object.Get(object2, sym1), '@@iterator'); + assert.strictEqual(test_object.Get(object2, sym2), sym3); + assert(test_object.Set(object2, 'string', 'value')); + assert(test_object.Set(object2, sym4, 123)); + assert(test_object.Has(object2, 'string')); + assert(test_object.Has(object2, sym4)); + assert.strictEqual(test_object.Get(object2, 'string'), 'value'); + assert.strictEqual(test_object.Get(object2, sym4), 123); +} + +{ + // Wrap a pointer in a JS object, then verify the pointer can be unwrapped. + const wrapper = {}; + test_object.Wrap(wrapper); + + assert(test_object.Unwrap(wrapper)); +} + +{ + // Verify that wrapping doesn't break an object's prototype chain. + const wrapper = {}; + const protoA = { protoA: true }; + Object.setPrototypeOf(wrapper, protoA); + test_object.Wrap(wrapper); + + assert(test_object.Unwrap(wrapper)); + assert(wrapper.protoA); +} + +{ + // Verify the pointer can be unwrapped after inserting in the prototype chain. + const wrapper = {}; + const protoA = { protoA: true }; + Object.setPrototypeOf(wrapper, protoA); + test_object.Wrap(wrapper); + + const protoB = { protoB: true }; + Object.setPrototypeOf(protoB, Object.getPrototypeOf(wrapper)); + Object.setPrototypeOf(wrapper, protoB); -assert(test_object.Has(object2, sym1)); -assert(test_object.Has(object2, sym2)); -assert.strictEqual(test_object.Get(object2, sym1), '@@iterator'); -assert.strictEqual(test_object.Get(object2, sym2), sym3); -assert(test_object.Set(object2, 'string', 'value')); -assert(test_object.Set(object2, sym4, 123)); -assert(test_object.Has(object2, 'string')); -assert(test_object.Has(object2, sym4)); -assert.strictEqual(test_object.Get(object2, 'string'), 'value'); -assert.strictEqual(test_object.Get(object2, sym4), 123); + assert(test_object.Unwrap(wrapper)); + assert(wrapper.protoA, true); + assert(wrapper.protoB, true); +} diff --git a/test/addons-napi/test_object/test_object.c b/test/addons-napi/test_object/test_object.c index 9e02c1d0bb7197..383fe46342a340 100644 --- a/test/addons-napi/test_object/test_object.c +++ b/test/addons-napi/test_object/test_object.c @@ -1,6 +1,9 @@ #include #include "../common.h" #include +#include + +static int test_value = 3; napi_value Get(napi_env env, napi_callback_info info) { size_t argc = 2; @@ -138,6 +141,31 @@ napi_value Inflate(napi_env env, napi_callback_info info) { return obj; } +napi_value Wrap(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value arg; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &arg, NULL, NULL)); + + int32_t* data = malloc(sizeof(int32_t)); + *data = test_value; + NAPI_CALL(env, napi_wrap(env, arg, data, NULL, NULL, NULL)); + return NULL; +} + +napi_value Unwrap(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value arg; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &arg, NULL, NULL)); + + void* data; + NAPI_CALL(env, napi_unwrap(env, arg, &data)); + + bool is_expected = (data != NULL && *(int*)data == 3); + napi_value result; + NAPI_CALL(env, napi_get_boolean(env, is_expected, &result)); + return result; +} + void Init(napi_env env, napi_value exports, napi_value module, void* priv) { napi_property_descriptor descriptors[] = { DECLARE_NAPI_PROPERTY("Get", Get), @@ -145,6 +173,8 @@ void Init(napi_env env, napi_value exports, napi_value module, void* priv) { DECLARE_NAPI_PROPERTY("Has", Has), DECLARE_NAPI_PROPERTY("New", New), DECLARE_NAPI_PROPERTY("Inflate", Inflate), + DECLARE_NAPI_PROPERTY("Wrap", Wrap), + DECLARE_NAPI_PROPERTY("Unwrap", Unwrap), }; NAPI_CALL_RETURN_VOID(env, napi_define_properties( diff --git a/test/addons-napi/test_reference/test.js b/test/addons-napi/test_reference/test.js index 30effe7eec0922..aaf5531f39e1f3 100644 --- a/test/addons-napi/test_reference/test.js +++ b/test/addons-napi/test_reference/test.js @@ -11,80 +11,110 @@ const test_reference = require(`./build/${common.buildType}/test_reference`); // of a finalizer callback increments the finalizeCount property. assert.strictEqual(test_reference.finalizeCount, 0); -{ - // External value without a finalizer - let value = test_reference.createExternal(); - assert.strictEqual(test_reference.finalizeCount, 0); - assert.strictEqual(typeof value, 'object'); - test_reference.checkExternal(value); - value = null; - global.gc(); - assert.strictEqual(test_reference.finalizeCount, 0); +// Run each test function in sequence, +// with an async delay and GC call between each. +function runTests(i, title, tests) { + if (tests[i]) { + if (typeof tests[i] === 'string') { + title = tests[i]; + runTests(i + 1, title, tests); + } else { + try { + tests[i](); + } catch (e) { + console.error('Test failed: ' + title); + throw e; + } + setImmediate(() => { + global.gc(); + runTests(i + 1, title, tests); + }); + } + } } +runTests(0, undefined, [ -{ - // External value with a finalizer - let value = test_reference.createExternalWithFinalize(); - assert.strictEqual(test_reference.finalizeCount, 0); - assert.strictEqual(typeof value, 'object'); - test_reference.checkExternal(value); - value = null; - global.gc(); - assert.strictEqual(test_reference.finalizeCount, 1); -} - -{ - // Strong reference - let value = test_reference.createExternalWithFinalize(); - assert.strictEqual(test_reference.finalizeCount, 0); - test_reference.createReference(value, 1); - assert.strictEqual(test_reference.referenceValue, value); - value = null; - global.gc(); // Value should NOT be GC'd because there is a strong ref - assert.strictEqual(test_reference.finalizeCount, 0); - test_reference.deleteReference(); - global.gc(); // Value should be GC'd because the strong ref was deleted - assert.strictEqual(test_reference.finalizeCount, 1); -} - -{ - // Strong reference, increment then decrement to weak reference - let value = test_reference.createExternalWithFinalize(); - assert.strictEqual(test_reference.finalizeCount, 0); - test_reference.createReference(value, 1); - value = null; - global.gc(); // Value should NOT be GC'd because there is a strong ref - assert.strictEqual(test_reference.finalizeCount, 0); + 'External value without a finalizer', + () => { + const value = test_reference.createExternal(); + assert.strictEqual(test_reference.finalizeCount, 0); + assert.strictEqual(typeof value, 'object'); + test_reference.checkExternal(value); + }, + () => { + assert.strictEqual(test_reference.finalizeCount, 0); + }, - assert.strictEqual(test_reference.incrementRefcount(), 2); - global.gc(); // Value should NOT be GC'd because there is a strong ref - assert.strictEqual(test_reference.finalizeCount, 0); - - assert.strictEqual(test_reference.decrementRefcount(), 1); - global.gc(); // Value should NOT be GC'd because there is a strong ref - assert.strictEqual(test_reference.finalizeCount, 0); + 'External value with a finalizer', + () => { + const value = test_reference.createExternalWithFinalize(); + assert.strictEqual(test_reference.finalizeCount, 0); + assert.strictEqual(typeof value, 'object'); + test_reference.checkExternal(value); + }, + () => { + assert.strictEqual(test_reference.finalizeCount, 1); + }, - assert.strictEqual(test_reference.decrementRefcount(), 0); - global.gc(); // Value should be GC'd because the ref is now weak! - assert.strictEqual(test_reference.finalizeCount, 1); + 'Weak reference', + () => { + const value = test_reference.createExternalWithFinalize(); + assert.strictEqual(test_reference.finalizeCount, 0); + test_reference.createReference(value, 0); + assert.strictEqual(test_reference.referenceValue, value); + }, + () => { + // Value should be GC'd because there is only a weak ref + assert.strictEqual(test_reference.referenceValue, undefined); + assert.strictEqual(test_reference.finalizeCount, 1); + test_reference.deleteReference(); + }, - test_reference.deleteReference(); - global.gc(); // Value was already GC'd - assert.strictEqual(test_reference.finalizeCount, 1); -} + 'Strong reference', + () => { + const value = test_reference.createExternalWithFinalize(); + assert.strictEqual(test_reference.finalizeCount, 0); + test_reference.createReference(value, 1); + assert.strictEqual(test_reference.referenceValue, value); + }, + () => { + // Value should NOT be GC'd because there is a strong ref + assert.strictEqual(test_reference.finalizeCount, 0); + test_reference.deleteReference(); + }, + () => { + // Value should be GC'd because the strong ref was deleted + assert.strictEqual(test_reference.finalizeCount, 1); + }, -{ - // Weak reference - let value = test_reference.createExternalWithFinalize(); - assert.strictEqual(test_reference.finalizeCount, 0); - test_reference.createReference(value, 0); - assert.strictEqual(test_reference.referenceValue, value); - value = null; - setImmediate(common.mustCall(() => { - // This test only works if gc() is called from an immediate callback. - global.gc(); // Value should be GC'd because there is only a weak ref - assert.strictEqual(test_reference.referenceValue, undefined); + 'Strong reference, increment then decrement to weak reference', + () => { + const value = test_reference.createExternalWithFinalize(); + assert.strictEqual(test_reference.finalizeCount, 0); + test_reference.createReference(value, 1); + }, + () => { + // Value should NOT be GC'd because there is a strong ref + assert.strictEqual(test_reference.finalizeCount, 0); + assert.strictEqual(test_reference.incrementRefcount(), 2); + }, + () => { + // Value should NOT be GC'd because there is a strong ref + assert.strictEqual(test_reference.finalizeCount, 0); + assert.strictEqual(test_reference.decrementRefcount(), 1); + }, + () => { + // Value should NOT be GC'd because there is a strong ref + assert.strictEqual(test_reference.finalizeCount, 0); + assert.strictEqual(test_reference.decrementRefcount(), 0); + }, + () => { + // Value should be GC'd because the ref is now weak! assert.strictEqual(test_reference.finalizeCount, 1); test_reference.deleteReference(); - })); -} + }, + () => { + // Value was already GC'd + assert.strictEqual(test_reference.finalizeCount, 1); + }, +]); diff --git a/test/addons-napi/test_typedarray/test.js b/test/addons-napi/test_typedarray/test.js index cc1fcbe3566da3..dcb7d76442f608 100644 --- a/test/addons-napi/test_typedarray/test.js +++ b/test/addons-napi/test_typedarray/test.js @@ -37,3 +37,23 @@ assert.strictEqual(externalResult.length, 3); assert.strictEqual(externalResult[0], 0); assert.strictEqual(externalResult[1], 1); assert.strictEqual(externalResult[2], 2); + +// validate creation of all kinds of TypedArrays +const buffer = new ArrayBuffer(128); +const arrayTypes = [ Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, + Uint16Array, Int32Array, Uint32Array, Float32Array, + Float64Array ]; + +arrayTypes.forEach((currentType, key) => { + const template = Reflect.construct(currentType, buffer); + const theArray = test_typedarray.CreateTypedArray(template, buffer); + + assert.ok(theArray instanceof currentType, + 'Type of new array should match that of the template'); + assert.notStrictEqual(theArray, + template, + 'the new array should not be a copy of the template'); + assert.strictEqual(theArray.buffer, + buffer, + 'Buffer for array should match the one passed in'); +}); diff --git a/test/addons-napi/test_typedarray/test_typedarray.c b/test/addons-napi/test_typedarray/test_typedarray.c index d77945486518a2..4194492cae8b3a 100644 --- a/test/addons-napi/test_typedarray/test_typedarray.c +++ b/test/addons-napi/test_typedarray/test_typedarray.c @@ -95,10 +95,58 @@ napi_value External(napi_env env, napi_callback_info info) { return output_array; } +napi_value CreateTypedArray(napi_env env, napi_callback_info info) { + size_t argc = 2; + napi_value args[2]; + NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL)); + + NAPI_ASSERT(env, argc == 2, "Wrong number of arguments"); + + napi_value input_array = args[0]; + napi_valuetype valuetype0; + NAPI_CALL(env, napi_typeof(env, input_array, &valuetype0)); + + NAPI_ASSERT(env, valuetype0 == napi_object, + "Wrong type of argments. Expects a typed array as first argument."); + + bool is_typedarray; + NAPI_CALL(env, napi_is_typedarray(env, input_array, &is_typedarray)); + + NAPI_ASSERT(env, is_typedarray, + "Wrong type of argments. Expects a typed array as first argument."); + + napi_valuetype valuetype1; + napi_value input_buffer = args[1]; + NAPI_CALL(env, napi_typeof(env, input_buffer, &valuetype1)); + + NAPI_ASSERT(env, valuetype1 == napi_object, + "Wrong type of argments. Expects an array buffer as second argument."); + + bool is_arraybuffer; + NAPI_CALL(env, napi_is_arraybuffer(env, input_buffer, &is_arraybuffer)); + + NAPI_ASSERT(env, is_arraybuffer, + "Wrong type of argments. Expects an array buffer as second argument."); + + napi_typedarray_type type; + napi_value in_array_buffer; + size_t byte_offset; + size_t length; + NAPI_CALL(env, napi_get_typedarray_info( + env, input_array, &type, &length, NULL, &in_array_buffer, &byte_offset)); + + napi_value output_array; + NAPI_CALL(env, napi_create_typedarray( + env, type, length, input_buffer, byte_offset, &output_array)); + + return output_array; +} + void Init(napi_env env, napi_value exports, napi_value module, void* priv) { napi_property_descriptor descriptors[] = { DECLARE_NAPI_PROPERTY("Multiply", Multiply), DECLARE_NAPI_PROPERTY("External", External), + DECLARE_NAPI_PROPERTY("CreateTypedArray", CreateTypedArray), }; NAPI_CALL_RETURN_VOID(env, napi_define_properties( diff --git a/test/async-hooks/init-hooks.js b/test/async-hooks/init-hooks.js index 6b8c2f4be44747..90758e5335d508 100644 --- a/test/async-hooks/init-hooks.js +++ b/test/async-hooks/init-hooks.js @@ -1,11 +1,11 @@ 'use strict'; // Flags: --expose-gc +require('../common'); const assert = require('assert'); const async_hooks = require('async_hooks'); const util = require('util'); const print = process._rawDebug; -require('../common'); if (typeof global.gc === 'function') { (function exity(cntr) { @@ -109,7 +109,7 @@ class ActivityCollector { } if (violations.length) { console.error(violations.join('\n')); - assert.fail(violations.length, 0, 'Failed sanity check'); + assert.fail(violations.length, 0, `Failed sanity checks: ${violations}`); } } @@ -151,8 +151,8 @@ class ActivityCollector { this._activities.set(uid, stub); return stub; } else { - const err = new Error('Found a handle who\'s ' + hook + - ' hook was invoked but not it\'s init hook'); + const err = new Error(`Found a handle whose ${hook}` + + ' hook was invoked but not its init hook'); // Don't throw if we see invocations due to an assertion in a test // failing since we want to list the assertion failure instead if (/process\._fatalException/.test(err.stack)) return null; diff --git a/test/async-hooks/test-callback-error.js b/test/async-hooks/test-callback-error.js new file mode 100644 index 00000000000000..8fe0177449e4ff --- /dev/null +++ b/test/async-hooks/test-callback-error.js @@ -0,0 +1,56 @@ +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const spawnSync = require('child_process').spawnSync; +const async_hooks = require('async_hooks'); +const initHooks = require('./init-hooks'); + +switch (process.argv[2]) { + case 'test_init_callback': + initHooks({ + oninit: common.mustCall(() => { throw new Error('test_init_callback'); }) + }).enable(); + + async_hooks.emitInit(async_hooks.currentId(), 'test_init_callback_type', + async_hooks.triggerId()); + break; + case 'test_callback': + initHooks({ + onbefore: common.mustCall(() => { throw new Error('test_callback'); }) + }).enable(); + + async_hooks.emitInit(async_hooks.currentId(), 'test_callback_type', + async_hooks.triggerId()); + async_hooks.emitBefore(async_hooks.currentId()); + break; +} + +if (process.execArgv.includes('--abort-on-uncaught-exception')) { + initHooks({ + oninit: common.mustCall(() => { throw new Error('test_callback_abort'); }) + }).enable(); + + async_hooks.emitInit(async_hooks.currentId(), 'test_callback_abort', + async_hooks.triggerId()); +} + +const c1 = spawnSync(`${process.execPath}`, [__filename, 'test_init_callback']); +assert.strictEqual(c1.stderr.toString().split('\n')[0], + 'Error: test_init_callback'); +assert.strictEqual(c1.status, 1); + +const c2 = spawnSync(`${process.execPath}`, [__filename, 'test_callback']); +assert.strictEqual(c2.stderr.toString().split('\n')[0], 'Error: test_callback'); +assert.strictEqual(c2.status, 1); + +const c3 = spawnSync(`${process.execPath}`, ['--abort-on-uncaught-exception', + __filename, + 'test_callback_abort']); +assert.strictEqual(c3.stdout.toString(), ''); + +const stderrOutput = c3.stderr.toString() + .trim() + .split('\n') + .map((s) => s.trim()); +assert.strictEqual(stderrOutput[0], 'Error: test_callback_abort'); diff --git a/test/async-hooks/test-connection.ssl.js b/test/async-hooks/test-connection.ssl.js index 13a2967e0df74b..d331ee1d0c4463 100644 --- a/test/async-hooks/test-connection.ssl.js +++ b/test/async-hooks/test-connection.ssl.js @@ -38,24 +38,22 @@ function createServerConnection( const sc1 = createServerConnection(common.mustCall(onfirstHandShake)); let as = hooks.activitiesOfTypes('SSLCONNECTION'); -assert.strictEqual(as.length, 1, - 'one CONNECTION after first connection created'); +assert.strictEqual(as.length, 1); const f1 = as[0]; -assert.strictEqual(f1.type, 'SSLCONNECTION', 'connection'); -assert.strictEqual(typeof f1.uid, 'number', 'uid is a number'); -assert.strictEqual(typeof f1.triggerId, 'number', 'triggerId is a number'); +assert.strictEqual(f1.type, 'SSLCONNECTION'); +assert.strictEqual(typeof f1.uid, 'number'); +assert.strictEqual(typeof f1.triggerId, 'number'); checkInvocations(f1, { init: 1 }, 'first connection, when first created'); // creating second server connection const sc2 = createServerConnection(common.mustCall(onsecondHandShake)); as = hooks.activitiesOfTypes('SSLCONNECTION'); -assert.strictEqual(as.length, 2, - 'two SSLCONNECTIONs after second connection created'); +assert.strictEqual(as.length, 2); const f2 = as[1]; -assert.strictEqual(f2.type, 'SSLCONNECTION', 'connection'); -assert.strictEqual(typeof f2.uid, 'number', 'uid is a number'); -assert.strictEqual(typeof f2.triggerId, 'number', 'triggerId is a number'); +assert.strictEqual(f2.type, 'SSLCONNECTION'); +assert.strictEqual(typeof f2.uid, 'number'); +assert.strictEqual(typeof f2.triggerId, 'number'); checkInvocations(f1, { init: 1 }, 'first connection, when second created'); checkInvocations(f2, { init: 1 }, 'second connection, when second created'); diff --git a/test/async-hooks/test-crypto-pbkdf2.js b/test/async-hooks/test-crypto-pbkdf2.js index 938a14c16f5e52..c3940a3a5f412e 100644 --- a/test/async-hooks/test-crypto-pbkdf2.js +++ b/test/async-hooks/test-crypto-pbkdf2.js @@ -31,12 +31,12 @@ function onexit() { hooks.sanityCheck('PBKDF2REQUEST'); const as = hooks.activitiesOfTypes('PBKDF2REQUEST'); - assert.strictEqual(as.length, 1, 'one activity'); + assert.strictEqual(as.length, 1); const a = as[0]; - assert.strictEqual(a.type, 'PBKDF2REQUEST', 'random byte request'); - assert.strictEqual(typeof a.uid, 'number', 'uid is a number'); - assert.strictEqual(a.triggerId, 1, 'parent uid 1'); + assert.strictEqual(a.type, 'PBKDF2REQUEST'); + assert.strictEqual(typeof a.uid, 'number'); + assert.strictEqual(a.triggerId, 1); checkInvocations(a, { init: 1, before: 1, after: 1, destroy: 1 }, 'when process exits'); } diff --git a/test/async-hooks/test-crypto-randomBytes.js b/test/async-hooks/test-crypto-randomBytes.js index 7748db482bc7bb..b7af1393693ad1 100644 --- a/test/async-hooks/test-crypto-randomBytes.js +++ b/test/async-hooks/test-crypto-randomBytes.js @@ -32,12 +32,12 @@ function onexit() { hooks.sanityCheck('RANDOMBYTESREQUEST'); const as = hooks.activitiesOfTypes('RANDOMBYTESREQUEST'); - assert.strictEqual(as.length, 1, 'one activity'); + assert.strictEqual(as.length, 1); const a = as[0]; - assert.strictEqual(a.type, 'RANDOMBYTESREQUEST', 'random byte request'); - assert.strictEqual(typeof a.uid, 'number', 'uid is a number'); - assert.strictEqual(a.triggerId, 1, 'parent uid 1'); + assert.strictEqual(a.type, 'RANDOMBYTESREQUEST'); + assert.strictEqual(typeof a.uid, 'number'); + assert.strictEqual(a.triggerId, 1); checkInvocations(a, { init: 1, before: 1, after: 1, destroy: 1 }, 'when process exits'); } diff --git a/test/async-hooks/test-embedder.api.async-event.after-on-destroyed.js b/test/async-hooks/test-embedder.api.async-resource.after-on-destroyed.js similarity index 89% rename from test/async-hooks/test-embedder.api.async-event.after-on-destroyed.js rename to test/async-hooks/test-embedder.api.async-resource.after-on-destroyed.js index eb4772d5f6e26b..8672f943ca7887 100644 --- a/test/async-hooks/test-embedder.api.async-event.after-on-destroyed.js +++ b/test/async-hooks/test-embedder.api.async-resource.after-on-destroyed.js @@ -39,10 +39,12 @@ if (process.argv[2] === 'child') { child.stdout.on('data', (d) => { outData = Buffer.concat([ outData, d ]); }); child.on('close', common.mustCall((code) => { - assert.strictEqual(code, 1, 'exit code 1'); + assert.strictEqual(code, 1); assert.ok(heartbeatMsg.test(outData.toString()), - 'did not crash until we reached offending line of code'); + 'did not crash until we reached offending line of code ' + + `(found ${outData})`); assert.ok(corruptedMsg.test(errData.toString()), - 'printed error contains corrupted message'); + 'printed error contains corrupted message ' + + `(found ${errData})`); })); } diff --git a/test/async-hooks/test-embedder.api.async-event.before-on-destroyed.js b/test/async-hooks/test-embedder.api.async-resource.before-on-destroyed.js similarity index 89% rename from test/async-hooks/test-embedder.api.async-event.before-on-destroyed.js rename to test/async-hooks/test-embedder.api.async-resource.before-on-destroyed.js index 3466e63777711d..0a5d0a61f2b11c 100644 --- a/test/async-hooks/test-embedder.api.async-event.before-on-destroyed.js +++ b/test/async-hooks/test-embedder.api.async-resource.before-on-destroyed.js @@ -39,10 +39,12 @@ if (process.argv[2] === 'child') { child.stdout.on('data', (d) => { outData = Buffer.concat([ outData, d ]); }); child.on('close', common.mustCall((code) => { - assert.strictEqual(code, 1, 'exit code 1'); + assert.strictEqual(code, 1); assert.ok(heartbeatMsg.test(outData.toString()), - 'did not crash until we reached offending line of code'); + 'did not crash until we reached offending line of code ' + + `(found ${outData})`); assert.ok(corruptedMsg.test(errData.toString()), - 'printed error contains corrupted message'); + 'printed error contains corrupted message ' + + `(found ${errData})`); })); } diff --git a/test/async-hooks/test-embedder.api.async-event.improper-order.js b/test/async-hooks/test-embedder.api.async-resource.improper-order.js similarity index 89% rename from test/async-hooks/test-embedder.api.async-event.improper-order.js rename to test/async-hooks/test-embedder.api.async-resource.improper-order.js index 1d3b8c6b899c4d..5f6ba89e6e0f31 100644 --- a/test/async-hooks/test-embedder.api.async-event.improper-order.js +++ b/test/async-hooks/test-embedder.api.async-resource.improper-order.js @@ -37,10 +37,12 @@ if (process.argv[2] === 'child') { child.stdout.on('data', (d) => { outData = Buffer.concat([ outData, d ]); }); child.on('close', common.mustCall((code) => { - assert.strictEqual(code, 1, 'exit code 1'); + assert.strictEqual(code, 1); assert.ok(heartbeatMsg.test(outData.toString()), - 'did not crash until we reached offending line of code'); + 'did not crash until we reached offending line of code ' + + `(found ${outData})`); assert.ok(corruptedMsg.test(errData.toString()), - 'printed error contains corrupted message'); + 'printed error contains corrupted message ' + + `(found ${errData})`); })); } diff --git a/test/async-hooks/test-embedder.api.async-event.improper-unwind.js b/test/async-hooks/test-embedder.api.async-resource.improper-unwind.js similarity index 90% rename from test/async-hooks/test-embedder.api.async-event.improper-unwind.js rename to test/async-hooks/test-embedder.api.async-resource.improper-unwind.js index 1e50cea4244a99..9e0c132dba99f9 100644 --- a/test/async-hooks/test-embedder.api.async-event.improper-unwind.js +++ b/test/async-hooks/test-embedder.api.async-resource.improper-unwind.js @@ -46,10 +46,12 @@ if (process.argv[2] === 'child') { child.stdout.on('data', (d) => { outData = Buffer.concat([ outData, d ]); }); child.on('close', common.mustCall((code) => { - assert.strictEqual(code, 1, 'exit code 1'); + assert.strictEqual(code, 1); assert.ok(heartbeatMsg.test(outData.toString()), - 'did not crash until we reached offending line of code'); + 'did not crash until we reached offending line of code ' + + `(found ${outData})`); assert.ok(corruptedMsg.test(errData.toString()), - 'printed error contains corrupted message'); + 'printed error contains corrupted message ' + + `(found ${errData})`); })); } diff --git a/test/async-hooks/test-embedder.api.async-event.js b/test/async-hooks/test-embedder.api.async-resource.js similarity index 74% rename from test/async-hooks/test-embedder.api.async-event.js rename to test/async-hooks/test-embedder.api.async-resource.js index ea9cd8bbb8df38..ec3d265e58cb0f 100644 --- a/test/async-hooks/test-embedder.api.async-event.js +++ b/test/async-hooks/test-embedder.api.async-resource.js @@ -12,6 +12,14 @@ const { checkInvocations } = require('./hook-checks'); const hooks = initHooks(); hooks.enable(); +assert.throws(() => new AsyncResource(), + /^TypeError: type must be a string with length > 0$/); +assert.throws(() => new AsyncResource('invalid_trigger_id', null), + /^RangeError: triggerId must be an unsigned integer$/); + +assert.strictEqual(typeof new AsyncResource('default_trigger_id').triggerId(), + 'number'); + // create first custom event 'alcazares' with triggerId derived // from async_hooks currentId const alcaTriggerId = async_hooks.currentId(); @@ -19,15 +27,17 @@ const alcaEvent = new AsyncResource('alcazares', alcaTriggerId); const alcazaresActivities = hooks.activitiesOfTypes([ 'alcazares' ]); // alcazares event was constructed and thus only has an `init` call -assert.strictEqual(alcazaresActivities.length, 1, - 'one alcazares activity after one was constructed'); +assert.strictEqual(alcazaresActivities.length, 1); const alcazares = alcazaresActivities[0]; -assert.strictEqual(alcazares.type, 'alcazares', 'alcazares'); -assert.strictEqual(typeof alcazares.uid, 'number', 'uid is a number'); -assert.strictEqual(alcazares.triggerId, alcaTriggerId, - 'triggerId is the one supplied'); +assert.strictEqual(alcazares.type, 'alcazares'); +assert.strictEqual(typeof alcazares.uid, 'number'); +assert.strictEqual(alcazares.triggerId, alcaTriggerId); checkInvocations(alcazares, { init: 1 }, 'alcazares constructed'); +assert.strictEqual(typeof alcaEvent.asyncId(), 'number'); +assert.notStrictEqual(alcaEvent.asyncId(), alcaTriggerId); +assert.strictEqual(alcaEvent.triggerId(), alcaTriggerId); + alcaEvent.emitBefore(); checkInvocations(alcazares, { init: 1, before: 1 }, 'alcazares emitted before'); @@ -52,10 +62,9 @@ function tick1() { const pobEvent = new AsyncResource('poblado', pobTriggerId); const pobladoActivities = hooks.activitiesOfTypes([ 'poblado' ]); const poblado = pobladoActivities[0]; - assert.strictEqual(poblado.type, 'poblado', 'poblado'); - assert.strictEqual(typeof poblado.uid, 'number', 'uid is a number'); - assert.strictEqual(poblado.triggerId, pobTriggerId, - 'triggerId is the one supplied'); + assert.strictEqual(poblado.type, 'poblado'); + assert.strictEqual(typeof poblado.uid, 'number'); + assert.strictEqual(poblado.triggerId, pobTriggerId); checkInvocations(poblado, { init: 1 }, 'poblado constructed'); pobEvent.emitBefore(); checkInvocations(poblado, { init: 1, before: 1 }, diff --git a/test/async-hooks/test-emit-before-after.js b/test/async-hooks/test-emit-before-after.js new file mode 100644 index 00000000000000..fb16bda22aff92 --- /dev/null +++ b/test/async-hooks/test-emit-before-after.js @@ -0,0 +1,46 @@ +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const spawnSync = require('child_process').spawnSync; +const async_hooks = require('async_hooks'); +const initHooks = require('./init-hooks'); + +switch (process.argv[2]) { + case 'test_invalid_async_id': + async_hooks.emitBefore(-1); + break; + case 'test_invalid_trigger_id': + async_hooks.emitBefore(1, -1); + break; +} + +const c1 = spawnSync(process.execPath, [__filename, 'test_invalid_async_id']); +assert.strictEqual(c1.stderr.toString().split('\n')[0], + 'Error: before(): asyncId or triggerId is less than zero ' + + '(asyncId: -1, triggerId: -1)'); +assert.strictEqual(c1.status, 1); + +const c2 = spawnSync(process.execPath, [__filename, 'test_invalid_trigger_id']); +assert.strictEqual(c2.stderr.toString().split('\n')[0], + 'Error: before(): asyncId or triggerId is less than zero ' + + '(asyncId: 1, triggerId: -1)'); +assert.strictEqual(c2.status, 1); + +const expectedId = async_hooks.newUid(); +const expectedTriggerId = async_hooks.newUid(); +const expectedType = 'test_emit_before_after_type'; + +// Verify that if there is no registered hook, then nothing will happen. +async_hooks.emitBefore(expectedId); +async_hooks.emitAfter(expectedId); + +initHooks({ + onbefore: common.mustCall((id) => assert.strictEqual(id, expectedId)), + onafter: common.mustCall((id) => assert.strictEqual(id, expectedId)), + allowNoInit: true +}).enable(); + +async_hooks.emitInit(expectedId, expectedType, expectedTriggerId); +async_hooks.emitBefore(expectedId); +async_hooks.emitAfter(expectedId); diff --git a/test/async-hooks/test-emit-init.js b/test/async-hooks/test-emit-init.js new file mode 100644 index 00000000000000..59476f2d44e7c5 --- /dev/null +++ b/test/async-hooks/test-emit-init.js @@ -0,0 +1,49 @@ +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const async_hooks = require('async_hooks'); +const initHooks = require('./init-hooks'); + +// Verify that if there is no registered hook, then those invalid parameters +// won't be checked. +assert.doesNotThrow(() => async_hooks.emitInit()); + +const expectedId = async_hooks.newUid(); +const expectedTriggerId = async_hooks.newUid(); +const expectedType = 'test_emit_init_type'; +const expectedResource = { key: 'test_emit_init_resource' }; + +const hooks1 = initHooks({ + oninit: common.mustCall((id, type, triggerId, resource) => { + assert.strictEqual(id, expectedId); + assert.strictEqual(type, expectedType); + assert.strictEqual(triggerId, expectedTriggerId); + assert.strictEqual(resource.key, expectedResource.key); + }) +}); + +hooks1.enable(); + +assert.throws(() => async_hooks.emitInit(), + /^RangeError: asyncId must be an unsigned integer$/); +assert.throws(() => async_hooks.emitInit(expectedId), + /^TypeError: type must be a string with length > 0$/); +assert.throws(() => async_hooks.emitInit(expectedId, expectedType, -1), + /^RangeError: triggerId must be an unsigned integer$/); + +async_hooks.emitInit(expectedId, expectedType, expectedTriggerId, + expectedResource); + +hooks1.disable(); + +initHooks({ + oninit: common.mustCall((id, type, triggerId, resource) => { + assert.strictEqual(id, expectedId); + assert.strictEqual(type, expectedType); + assert.notStrictEqual(triggerId, expectedTriggerId); + assert.strictEqual(resource.key, expectedResource.key); + }) +}).enable(); + +async_hooks.emitInit(expectedId, expectedType, expectedResource); diff --git a/test/async-hooks/test-enable-disable.js b/test/async-hooks/test-enable-disable.js index 555baf3fcf82cb..6cd584878a7e0f 100644 --- a/test/async-hooks/test-enable-disable.js +++ b/test/async-hooks/test-enable-disable.js @@ -103,6 +103,8 @@ const hook3 = initHooks({ onbefore: onhook3Before, onafter: onhook3After }); // Enabling hook1 and hook3 only, hook2 is still disabled // hook1.enable(); +// Verify that the hook is enabled even if .enable() is called twice. +hook1.enable(); hook3.enable(); // @@ -122,6 +124,8 @@ let disabledHook3 = false; function onhook2Before() { if (disabledHook3) return; hook1.disable(); + // Verify that the hook is disabled even if .disable() is called twice. + hook1.disable(); disabledHook3 = true; } @@ -145,22 +149,17 @@ function onfirstImmediate() { const as1 = hook1.activitiesOfTypes(types); const as2 = hook2.activitiesOfTypes(types); const as3 = hook3.activitiesOfTypes(types); - assert.strictEqual(as1.length, 1, - 'hook1 captured one immediate on first callback'); + assert.strictEqual(as1.length, 1); // hook2 was not enabled yet .. it is enabled after hook3's "before" completed - assert.strictEqual(as2.length, 0, - 'hook2 captured no immediate on first callback'); - assert.strictEqual(as3.length, 1, - 'hook3 captured one immediate on first callback'); + assert.strictEqual(as2.length, 0); + assert.strictEqual(as3.length, 1); // Check that hook1 and hook3 captured the same Immediate and that it is valid const firstImmediate = as1[0]; - assert.strictEqual(as3[0].uid, as1[0].uid, - 'hook1 and hook3 captured same first immediate'); - assert.strictEqual(firstImmediate.type, 'Immediate', 'immediate'); - assert.strictEqual(typeof firstImmediate.uid, 'number', 'uid is a number'); - assert.strictEqual(typeof firstImmediate.triggerId, - 'number', 'triggerId is a number'); + assert.strictEqual(as3[0].uid, as1[0].uid); + assert.strictEqual(firstImmediate.type, 'Immediate'); + assert.strictEqual(typeof firstImmediate.uid, 'number'); + assert.strictEqual(typeof firstImmediate.triggerId, 'number'); checkInvocations(as1[0], { init: 1, before: 1 }, 'hook1[0]: on first immediate'); checkInvocations(as3[0], { init: 1, before: 1 }, @@ -187,15 +186,9 @@ function onsecondImmediate() { const as1 = hook1.activitiesOfTypes(types); const as2 = hook2.activitiesOfTypes(types); const as3 = hook3.activitiesOfTypes(types); - assert.strictEqual( - as1.length, 2, - 'hook1 captured first and second immediate on second callback'); - assert.strictEqual( - as2.length, 2, - 'hook2 captured first and second immediate on second callback'); - assert.strictEqual( - as3.length, 2, - 'hook3 captured first and second immediate on second callback'); + assert.strictEqual(as1.length, 2); + assert.strictEqual(as2.length, 2); + assert.strictEqual(as3.length, 2); // Assign the info collected by each hook for each immediate for easier // reference. @@ -210,14 +203,11 @@ function onsecondImmediate() { // Check that all hooks captured the same Immediate and that it is valid const secondImmediate = hook1Second; - assert.strictEqual(hook2Second.uid, hook3Second.uid, - 'hook2 and hook3 captured same second immediate'); - assert.strictEqual(hook1Second.uid, hook3Second.uid, - 'hook1 and hook3 captured same second immediate'); - assert.strictEqual(secondImmediate.type, 'Immediate', 'immediate'); - assert.strictEqual(typeof secondImmediate.uid, 'number', 'uid is a number'); - assert.strictEqual(typeof secondImmediate.triggerId, 'number', - 'triggerId is a number'); + assert.strictEqual(hook2Second.uid, hook3Second.uid); + assert.strictEqual(hook1Second.uid, hook3Second.uid); + assert.strictEqual(secondImmediate.type, 'Immediate'); + assert.strictEqual(typeof secondImmediate.uid, 'number'); + assert.strictEqual(typeof secondImmediate.triggerId, 'number'); checkInvocations(hook1First, { init: 1, before: 1, after: 1, destroy: 1 }, 'hook1First: on second immediate'); diff --git a/test/async-hooks/test-fseventwrap.js b/test/async-hooks/test-fseventwrap.js index 39e055005729dc..2eb1abad6573a8 100644 --- a/test/async-hooks/test-fseventwrap.js +++ b/test/async-hooks/test-fseventwrap.js @@ -23,11 +23,11 @@ function onexit() { hooks.sanityCheck('FSEVENTWRAP'); const as = hooks.activitiesOfTypes('FSEVENTWRAP'); - assert.strictEqual(as.length, 1, 'one activity'); + assert.strictEqual(as.length, 1); const a = as[0]; - assert.strictEqual(a.type, 'FSEVENTWRAP', 'fs event wrap'); - assert.strictEqual(typeof a.uid, 'number', 'uid is a number'); - assert.strictEqual(a.triggerId, 1, 'parent uid 1'); + assert.strictEqual(a.type, 'FSEVENTWRAP'); + assert.strictEqual(typeof a.uid, 'number'); + assert.strictEqual(a.triggerId, 1); checkInvocations(a, { init: 1, destroy: 1 }, 'when process exits'); } diff --git a/test/async-hooks/test-fsreqwrap-access.js b/test/async-hooks/test-fsreqwrap-access.js index 5e4c3806c2be8d..2b31f2512d6b9c 100644 --- a/test/async-hooks/test-fsreqwrap-access.js +++ b/test/async-hooks/test-fsreqwrap-access.js @@ -27,11 +27,11 @@ function onexit() { hooks.sanityCheck('FSREQWRAP'); const as = hooks.activitiesOfTypes('FSREQWRAP'); - assert.strictEqual(as.length, 1, 'one activity'); + assert.strictEqual(as.length, 1); const a = as[0]; - assert.strictEqual(a.type, 'FSREQWRAP', 'fs req wrap'); - assert.strictEqual(typeof a.uid, 'number', 'uid is a number'); + assert.strictEqual(a.type, 'FSREQWRAP'); + assert.strictEqual(typeof a.uid, 'number'); checkInvocations(a, { init: 1, before: 1, after: 1, destroy: 1 }, 'when process exits'); } diff --git a/test/async-hooks/test-fsreqwrap-readFile.js b/test/async-hooks/test-fsreqwrap-readFile.js index 653de1493bc96f..20a57a5dd6c490 100644 --- a/test/async-hooks/test-fsreqwrap-readFile.js +++ b/test/async-hooks/test-fsreqwrap-readFile.js @@ -17,9 +17,9 @@ function onread() { let lastParent = 1; for (let i = 0; i < as.length; i++) { const a = as[i]; - assert.strictEqual(a.type, 'FSREQWRAP', 'fs req wrap'); - assert.strictEqual(typeof a.uid, 'number', 'uid is a number'); - assert.strictEqual(a.triggerId, lastParent, 'parent uid 1'); + assert.strictEqual(a.type, 'FSREQWRAP'); + assert.strictEqual(typeof a.uid, 'number'); + assert.strictEqual(a.triggerId, lastParent); lastParent = a.uid; } checkInvocations(as[0], { init: 1, before: 1, after: 1, destroy: 1 }, diff --git a/test/async-hooks/test-getaddrinforeqwrap.js b/test/async-hooks/test-getaddrinforeqwrap.js index 0bbe89f3270a16..b99ba2832bd9d7 100644 --- a/test/async-hooks/test-getaddrinforeqwrap.js +++ b/test/async-hooks/test-getaddrinforeqwrap.js @@ -16,12 +16,12 @@ function onlookup(err_, ip, family) { // tests to run offline (lookup will fail in that case and the err be set); const as = hooks.activitiesOfTypes('GETADDRINFOREQWRAP'); - assert.strictEqual(as.length, 1, 'one activity'); + assert.strictEqual(as.length, 1); const a = as[0]; - assert.strictEqual(a.type, 'GETADDRINFOREQWRAP', 'getaddrinforeq wrap'); - assert.strictEqual(typeof a.uid, 'number', 'uid is a number'); - assert.strictEqual(a.triggerId, 1, 'parent uid 1'); + assert.strictEqual(a.type, 'GETADDRINFOREQWRAP'); + assert.strictEqual(typeof a.uid, 'number'); + assert.strictEqual(a.triggerId, 1); checkInvocations(a, { init: 1, before: 1 }, 'while in onlookup callback'); tick(2); } diff --git a/test/async-hooks/test-getnameinforeqwrap.js b/test/async-hooks/test-getnameinforeqwrap.js index eca1e8457bcc16..e7b9a4aca844fc 100644 --- a/test/async-hooks/test-getnameinforeqwrap.js +++ b/test/async-hooks/test-getnameinforeqwrap.js @@ -16,12 +16,12 @@ function onlookupService(err_, ip, family) { // tests to run offline (lookup will fail in that case and the err be set) const as = hooks.activitiesOfTypes('GETNAMEINFOREQWRAP'); - assert.strictEqual(as.length, 1, 'one activity'); + assert.strictEqual(as.length, 1); const a = as[0]; - assert.strictEqual(a.type, 'GETNAMEINFOREQWRAP', 'getnameinforeq wrap'); - assert.strictEqual(typeof a.uid, 'number', 'uid is a number'); - assert.strictEqual(a.triggerId, 1, 'parent uid 1'); + assert.strictEqual(a.type, 'GETNAMEINFOREQWRAP'); + assert.strictEqual(typeof a.uid, 'number'); + assert.strictEqual(a.triggerId, 1); checkInvocations(a, { init: 1, before: 1 }, 'while in onlookupService callback'); tick(2); diff --git a/test/async-hooks/test-httpparser.request.js b/test/async-hooks/test-httpparser.request.js index b6f594a1597e3d..ebac57b6aba014 100644 --- a/test/async-hooks/test-httpparser.request.js +++ b/test/async-hooks/test-httpparser.request.js @@ -26,12 +26,9 @@ const parser = new HTTPParser(REQUEST); const as = hooks.activitiesOfTypes('HTTPPARSER'); const httpparser = as[0]; -assert.strictEqual( - as.length, 1, - '1 httpparser created synchronously when creating new httpparser'); -assert.strictEqual(typeof httpparser.uid, 'number', 'uid is a number'); -assert.strictEqual(typeof httpparser.triggerId, - 'number', 'triggerId is a number'); +assert.strictEqual(as.length, 1); +assert.strictEqual(typeof httpparser.uid, 'number'); +assert.strictEqual(typeof httpparser.triggerId, 'number'); checkInvocations(httpparser, { init: 1 }, 'when created new Httphttpparser'); parser[kOnHeadersComplete] = common.mustCall(onheadersComplete); diff --git a/test/async-hooks/test-httpparser.response.js b/test/async-hooks/test-httpparser.response.js index e7930ea2bcfc5c..a87de0674fa72a 100644 --- a/test/async-hooks/test-httpparser.response.js +++ b/test/async-hooks/test-httpparser.response.js @@ -30,12 +30,9 @@ const parser = new HTTPParser(RESPONSE); const as = hooks.activitiesOfTypes('HTTPPARSER'); const httpparser = as[0]; -assert.strictEqual( - as.length, 1, - '1 httpparser created synchronously when creating new httpparser'); -assert.strictEqual(typeof httpparser.uid, 'number', 'uid is a number'); -assert.strictEqual(typeof httpparser.triggerId, - 'number', 'triggerId is a number'); +assert.strictEqual(as.length, 1); +assert.strictEqual(typeof httpparser.uid, 'number'); +assert.strictEqual(typeof httpparser.triggerId, 'number'); checkInvocations(httpparser, { init: 1 }, 'when created new Httphttpparser'); parser[kOnHeadersComplete] = common.mustCall(onheadersComplete); diff --git a/test/async-hooks/test-immediate.js b/test/async-hooks/test-immediate.js index 2434d98003bef1..e5bce88de9b257 100644 --- a/test/async-hooks/test-immediate.js +++ b/test/async-hooks/test-immediate.js @@ -13,12 +13,11 @@ hooks.enable(); setImmediate(common.mustCall(onimmediate)); const as = hooks.activitiesOfTypes('Immediate'); -assert.strictEqual(as.length, 1, - 'one immediate when first set immediate installed'); +assert.strictEqual(as.length, 1); const imd1 = as[0]; -assert.strictEqual(imd1.type, 'Immediate', 'immediate'); -assert.strictEqual(typeof imd1.uid, 'number', 'uid is a number'); -assert.strictEqual(typeof imd1.triggerId, 'number', 'triggerId is a number'); +assert.strictEqual(imd1.type, 'Immediate'); +assert.strictEqual(typeof imd1.uid, 'number'); +assert.strictEqual(typeof imd1.triggerId, 'number'); checkInvocations(imd1, { init: 1 }, 'imd1: when first set immediate installed'); @@ -26,20 +25,18 @@ let imd2; function onimmediate() { let as = hooks.activitiesOfTypes('Immediate'); - assert.strictEqual(as.length, 1, - 'one immediate when first set immediate triggered'); + assert.strictEqual(as.length, 1); checkInvocations(imd1, { init: 1, before: 1 }, 'imd1: when first set immediate triggered'); // install second immediate setImmediate(common.mustCall(onimmediateTwo)); as = hooks.activitiesOfTypes('Immediate'); - assert.strictEqual(as.length, 2, - 'two immediates when second set immediate installed'); + assert.strictEqual(as.length, 2); imd2 = as[1]; - assert.strictEqual(imd2.type, 'Immediate', 'immediate'); - assert.strictEqual(typeof imd2.uid, 'number', 'uid is a number'); - assert.strictEqual(typeof imd2.triggerId, 'number', 'triggerId is a number'); + assert.strictEqual(imd2.type, 'Immediate'); + assert.strictEqual(typeof imd2.uid, 'number'); + assert.strictEqual(typeof imd2.triggerId, 'number'); checkInvocations(imd1, { init: 1, before: 1 }, 'imd1: when second set immediate installed'); checkInvocations(imd2, { init: 1 }, diff --git a/test/async-hooks/test-pipeconnectwrap.js b/test/async-hooks/test-pipeconnectwrap.js index 781d4ed2a69221..fa38185f1ee4f1 100644 --- a/test/async-hooks/test-pipeconnectwrap.js +++ b/test/async-hooks/test-pipeconnectwrap.js @@ -24,36 +24,27 @@ net.createServer(common.mustCall(function(c) { function onlisten() { let pipes = hooks.activitiesOfTypes('PIPEWRAP'); let pipeconnects = hooks.activitiesOfTypes('PIPECONNECTWRAP'); - assert.strictEqual( - pipes.length, 1, - 'one pipe wrap created when net server is listening'); - assert.strictEqual( - pipeconnects.length, 0, - 'no pipeconnect wrap created when net server is listening'); + assert.strictEqual(pipes.length, 1); + assert.strictEqual(pipeconnects.length, 0); net.connect(common.PIPE, common.mustCall(maybeOnconnect.bind(null, 'client'))); pipes = hooks.activitiesOfTypes('PIPEWRAP'); pipeconnects = hooks.activitiesOfTypes('PIPECONNECTWRAP'); - assert.strictEqual(pipes.length, 2, - '2 pipe wraps created when connecting client'); - assert.strictEqual(pipeconnects.length, 1, - '1 connectwrap created when connecting client'); + assert.strictEqual(pipes.length, 2); + assert.strictEqual(pipeconnects.length, 1); pipe1 = pipes[0]; pipe2 = pipes[1]; pipeconnect = pipeconnects[0]; - assert.strictEqual(pipe1.type, 'PIPEWRAP', 'first is pipe wrap'); - assert.strictEqual(pipe2.type, 'PIPEWRAP', 'second is pipe wrap'); - assert.strictEqual(pipeconnect.type, 'PIPECONNECTWRAP', - 'third is pipeconnect wrap'); - [ pipe1, pipe2, pipeconnect ].forEach(check); - - function check(a) { - assert.strictEqual(typeof a.uid, 'number', 'uid is a number'); - assert.strictEqual(typeof a.triggerId, 'number', 'triggerId is a number'); + assert.strictEqual(pipe1.type, 'PIPEWRAP'); + assert.strictEqual(pipe2.type, 'PIPEWRAP'); + assert.strictEqual(pipeconnect.type, 'PIPECONNECTWRAP'); + for (const a of [ pipe1, pipe2, pipeconnect ]) { + assert.strictEqual(typeof a.uid, 'number'); + assert.strictEqual(typeof a.triggerId, 'number'); checkInvocations(a, { init: 1 }, 'after net.connect'); } } @@ -69,13 +60,11 @@ function maybeOnconnect(source) { const pipes = hooks.activitiesOfTypes('PIPEWRAP'); const pipeconnects = hooks.activitiesOfTypes('PIPECONNECTWRAP'); - assert.strictEqual(pipes.length, 3, - '3 pipe wraps created when client connected'); - assert.strictEqual(pipeconnects.length, 1, - '1 connectwrap created when client connected'); + assert.strictEqual(pipes.length, 3); + assert.strictEqual(pipeconnects.length, 1); pipe3 = pipes[2]; - assert.strictEqual(typeof pipe3.uid, 'number', 'uid is a number'); - assert.strictEqual(typeof pipe3.triggerId, 'number', 'triggerId is a number'); + assert.strictEqual(typeof pipe3.uid, 'number'); + assert.strictEqual(typeof pipe3.triggerId, 'number'); checkInvocations(pipe1, { init: 1, before: 1, after: 1 }, 'pipe1, client connected'); diff --git a/test/async-hooks/test-pipewrap.js b/test/async-hooks/test-pipewrap.js index a34bca579555e5..4e4236b46d953b 100644 --- a/test/async-hooks/test-pipewrap.js +++ b/test/async-hooks/test-pipewrap.js @@ -23,24 +23,22 @@ nodeVersionSpawn // synchronously const processes = hooks.activitiesOfTypes('PROCESSWRAP'); const pipes = hooks.activitiesOfTypes('PIPEWRAP'); -assert.strictEqual(processes.length, 1, - '1 processwrap created when process created'); -assert.strictEqual(pipes.length, 3, - '3 pipe wraps created when process created'); +assert.strictEqual(processes.length, 1); +assert.strictEqual(pipes.length, 3); const processwrap = processes[0]; const pipe1 = pipes[0]; const pipe2 = pipes[1]; const pipe3 = pipes[2]; -assert.strictEqual(processwrap.type, 'PROCESSWRAP', 'process wrap type'); -assert.strictEqual(processwrap.triggerId, 1, 'processwrap triggerId is 1'); +assert.strictEqual(processwrap.type, 'PROCESSWRAP'); +assert.strictEqual(processwrap.triggerId, 1); checkInvocations(processwrap, { init: 1 }, 'processwrap when sleep.spawn was called'); [ pipe1, pipe2, pipe3 ].forEach((x) => { - assert(x.type, 'PIPEWRAP', 'pipe wrap type'); - assert.strictEqual(x.triggerId, 1, 'pipe wrap triggerId is 1'); + assert.strictEqual(x.type, 'PIPEWRAP'); + assert.strictEqual(x.triggerId, 1); checkInvocations(x, { init: 1 }, 'pipe wrap when sleep.spawn was called'); }); @@ -71,14 +69,14 @@ function onexit() { 'processwrap while in onsleepClose callback'); [ pipe1, pipe2, pipe3 ].forEach((x) => { - assert(x.type, 'PIPEWRAP', 'pipe wrap type'); - assert.strictEqual(x.triggerId, 1, 'pipe wrap triggerId is 1'); + assert.strictEqual(x.type, 'PIPEWRAP'); + assert.strictEqual(x.triggerId, 1); }); const ioEvents = Math.min(pipe2.before.length, pipe2.after.length); // 2 events without any IO and at least one more for the node version data. // Usually it is just one event, but it can be more. - assert.ok(ioEvents >= 3, 'at least 3 stdout io events.'); + assert.ok(ioEvents >= 3, `at least 3 stdout io events, got ${ioEvents}`); checkInvocations(pipe1, { init: 1, before: 2, after: 2 }, 'pipe wrap when sleep.spawn was called'); diff --git a/test/async-hooks/test-promise.chain-promise-before-init-hooks.js b/test/async-hooks/test-promise.chain-promise-before-init-hooks.js new file mode 100644 index 00000000000000..2bbc8d773b2336 --- /dev/null +++ b/test/async-hooks/test-promise.chain-promise-before-init-hooks.js @@ -0,0 +1,38 @@ +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const initHooks = require('./init-hooks'); +const { checkInvocations } = require('./hook-checks'); + +const p = new Promise(common.mustCall(function executor(resolve, reject) { + resolve(5); +})); + +p.then(function afterresolution(val) { + assert.strictEqual(val, 5); + return val; +}); + +// init hooks after chained promise is created +const hooks = initHooks(); +hooks._allowNoInit = true; +hooks.enable(); + + +process.on('exit', function onexit() { + hooks.disable(); + hooks.sanityCheck('PROMISE'); + + // Because the init event was never emitted the hooks listener doesn't + // know what the type was. Thus check for Unknown rather than PROMISE. + const as = hooks.activitiesOfTypes('PROMISE'); + const unknown = hooks.activitiesOfTypes('Unknown'); + assert.strictEqual(as.length, 0); + assert.strictEqual(unknown.length, 1); + + const a0 = unknown[0]; + assert.strictEqual(a0.type, 'Unknown'); + assert.strictEqual(typeof a0.uid, 'number'); + checkInvocations(a0, { before: 1, after: 1 }, 'when process exits'); +}); diff --git a/test/async-hooks/test-promise.js b/test/async-hooks/test-promise.js index 30cf94d28b15ab..bded7e3aaccb07 100644 --- a/test/async-hooks/test-promise.js +++ b/test/async-hooks/test-promise.js @@ -14,7 +14,7 @@ p.then(afterresolution); function executor(resolve, reject) { const as = hooks.activitiesOfTypes('PROMISE'); - assert.strictEqual(as.length, 1, 'one activities'); + assert.strictEqual(as.length, 1); const a = as[0]; checkInvocations(a, { init: 1 }, 'while in promise executor'); resolve(5); @@ -23,7 +23,7 @@ function executor(resolve, reject) { function afterresolution(val) { assert.strictEqual(val, 5); const as = hooks.activitiesOfTypes('PROMISE'); - assert.strictEqual(as.length, 2, 'two activities'); + assert.strictEqual(as.length, 2); checkInvocations(as[0], { init: 1 }, 'after resolution parent promise'); checkInvocations(as[1], { init: 1, before: 1 }, 'after resolution child promise'); @@ -35,18 +35,18 @@ function onexit() { hooks.sanityCheck('PROMISE'); const as = hooks.activitiesOfTypes('PROMISE'); - assert.strictEqual(as.length, 2, 'two activities'); + assert.strictEqual(as.length, 2); const a0 = as[0]; - assert.strictEqual(a0.type, 'PROMISE', 'promise request'); - assert.strictEqual(typeof a0.uid, 'number', 'uid is a number'); - assert.strictEqual(a0.triggerId, 1, 'parent uid 1'); + assert.strictEqual(a0.type, 'PROMISE'); + assert.strictEqual(typeof a0.uid, 'number'); + assert.strictEqual(a0.triggerId, 1); checkInvocations(a0, { init: 1 }, 'when process exits'); const a1 = as[1]; - assert.strictEqual(a1.type, 'PROMISE', 'promise request'); - assert.strictEqual(typeof a1.uid, 'number', 'uid is a number'); - assert.strictEqual(a1.triggerId, 1, 'parent uid 1'); + assert.strictEqual(a1.type, 'PROMISE'); + assert.strictEqual(typeof a1.uid, 'number'); + assert.strictEqual(a1.triggerId, a0.uid); // We expect a destroy hook as well but we cannot guarentee predictable gc. checkInvocations(a1, { init: 1, before: 1, after: 1 }, 'when process exits'); } diff --git a/test/async-hooks/test-promise.promise-before-init-hooks.js b/test/async-hooks/test-promise.promise-before-init-hooks.js new file mode 100644 index 00000000000000..123e5e2da947a0 --- /dev/null +++ b/test/async-hooks/test-promise.promise-before-init-hooks.js @@ -0,0 +1,42 @@ +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const initHooks = require('./init-hooks'); +const { checkInvocations } = require('./hook-checks'); + +const p = new Promise(common.mustCall(function executor(resolve, reject) { + resolve(5); +})); + +// init hooks after promise was created +const hooks = initHooks({allowNoInit: true}); +hooks.enable(); + +p.then(function afterresolution(val) { + assert.strictEqual(val, 5); + const as = hooks.activitiesOfTypes('PROMISE'); + assert.strictEqual(as.length, 1, 'one activity'); + checkInvocations(as[0], { init: 1, before: 1 }, + 'after resolution child promise'); + return val; +}); + +process.on('exit', function onexit() { + hooks.disable(); + hooks.sanityCheck('PROMISE'); + + const as = hooks.activitiesOfTypes('PROMISE'); + assert.strictEqual(as.length, 1); + + const a0 = as[0]; + assert.strictEqual(a0.type, 'PROMISE'); + assert.strictEqual(typeof a0.uid, 'number'); + // we can't get the asyncId from the parent dynamically, since init was + // never called. However, it is known that the parent promise was created + // immediately before the child promise, thus there should only be one + // difference in id. + assert.strictEqual(a0.triggerId, a0.uid - 1); + // We expect a destroy hook as well but we cannot guarentee predictable gc. + checkInvocations(a0, { init: 1, before: 1, after: 1 }, 'when process exits'); +}); diff --git a/test/async-hooks/test-querywrap.js b/test/async-hooks/test-querywrap.js index 7aaa4ce3b40766..9ab219ecf58128 100644 --- a/test/async-hooks/test-querywrap.js +++ b/test/async-hooks/test-querywrap.js @@ -17,7 +17,7 @@ dns.resolve('localhost', common.mustCall(onresolved)); function onresolved() { const as = hooks.activitiesOfTypes('QUERYWRAP'); const a = as[0]; - assert.strictEqual(as.length, 1, 'one activity in onresolved callback'); + assert.strictEqual(as.length, 1); checkInvocations(a, { init: 1, before: 1 }, 'while in onresolved callback'); tick(1E4); } @@ -29,12 +29,12 @@ function onexit() { hooks.sanityCheck('QUERYWRAP'); const as = hooks.activitiesOfTypes('QUERYWRAP'); - assert.strictEqual(as.length, 1, 'one activity on process exit'); + assert.strictEqual(as.length, 1); const a = as[0]; - assert.strictEqual(a.type, 'QUERYWRAP', 'query wrap'); - assert.strictEqual(typeof a.uid, 'number', 'uid is a number'); - assert.strictEqual(typeof a.triggerId, 'number', 'triggerId is a number'); + assert.strictEqual(a.type, 'QUERYWRAP'); + assert.strictEqual(typeof a.uid, 'number'); + assert.strictEqual(typeof a.triggerId, 'number'); checkInvocations(a, { init: 1, before: 1, after: 1, destroy: 1 }, 'when process exits'); } diff --git a/test/async-hooks/test-shutdownwrap.js b/test/async-hooks/test-shutdownwrap.js index 8ce2aae27514ef..c3d9936c540034 100644 --- a/test/async-hooks/test-shutdownwrap.js +++ b/test/async-hooks/test-shutdownwrap.js @@ -22,29 +22,21 @@ function onlistening() { // Therefore we track here if we ended the connection already or not. let endedConnection = false; function onconnection(c) { - assert.strictEqual(hooks.activitiesOfTypes('SHUTDOWNWRAP').length, 0, - 'no shutdown wrap before ending the client connection'); + assert.strictEqual(hooks.activitiesOfTypes('SHUTDOWNWRAP').length, 0); c.end(); endedConnection = true; const as = hooks.activitiesOfTypes('SHUTDOWNWRAP'); - assert.strictEqual( - as.length, 1, - 'one shutdown wrap created sync after ending the client connection'); + assert.strictEqual(as.length, 1); checkInvocations(as[0], { init: 1 }, 'after ending client connection'); this.close(onserverClosed); } function onconnected() { if (endedConnection) { - assert.strictEqual( - hooks.activitiesOfTypes('SHUTDOWNWRAP').length, 1, - 'one shutdown wrap when client connected but server ended connection'); + assert.strictEqual(hooks.activitiesOfTypes('SHUTDOWNWRAP').length, 1); } else { - assert.strictEqual( - hooks.activitiesOfTypes('SHUTDOWNWRAP').length, 0, - 'no shutdown wrap when client connected and server did not end connection' - ); + assert.strictEqual(hooks.activitiesOfTypes('SHUTDOWNWRAP').length, 0); } } @@ -61,9 +53,9 @@ function onexit() { hooks.sanityCheck('SHUTDOWNWRAP'); const as = hooks.activitiesOfTypes('SHUTDOWNWRAP'); const a = as[0]; - assert.strictEqual(a.type, 'SHUTDOWNWRAP', 'shutdown wrap'); - assert.strictEqual(typeof a.uid, 'number', 'uid is a number'); - assert.strictEqual(typeof a.triggerId, 'number', 'triggerId is a number'); + assert.strictEqual(a.type, 'SHUTDOWNWRAP'); + assert.strictEqual(typeof a.uid, 'number'); + assert.strictEqual(typeof a.triggerId, 'number'); checkInvocations(as[0], { init: 1, before: 1, after: 1, destroy: 1 }, 'when process exits'); } diff --git a/test/async-hooks/test-signalwrap.js b/test/async-hooks/test-signalwrap.js index 1065616032663e..3b1cffbb8c8259 100644 --- a/test/async-hooks/test-signalwrap.js +++ b/test/async-hooks/test-signalwrap.js @@ -12,12 +12,11 @@ hooks.enable(); process.on('SIGUSR2', common.mustCall(onsigusr2, 2)); const as = hooks.activitiesOfTypes('SIGNALWRAP'); -assert.strictEqual(as.length, 1, - 'one signal wrap when SIGUSR2 handler is set up'); +assert.strictEqual(as.length, 1); const signal1 = as[0]; -assert.strictEqual(signal1.type, 'SIGNALWRAP', 'signal wrap'); -assert.strictEqual(typeof signal1.uid, 'number', 'uid is a number'); -assert.strictEqual(typeof signal1.triggerId, 'number', 'triggerId is a number'); +assert.strictEqual(signal1.type, 'SIGNALWRAP'); +assert.strictEqual(typeof signal1.uid, 'number'); +assert.strictEqual(typeof signal1.triggerId, 'number'); checkInvocations(signal1, { init: 1 }, 'when SIGUSR2 handler is set up'); let count = 0; @@ -47,14 +46,11 @@ function onsigusr2() { process.on('SIGUSR2', common.mustCall(onsigusr2Again)); const as = hooks.activitiesOfTypes('SIGNALWRAP'); - assert.strictEqual( - as.length, 2, - 'two signal wraps when second SIGUSR2 handler is set up'); + assert.strictEqual(as.length, 2); signal2 = as[1]; - assert.strictEqual(signal2.type, 'SIGNALWRAP', 'signal wrap'); - assert.strictEqual(typeof signal2.uid, 'number', 'uid is a number'); - assert.strictEqual(typeof signal2.triggerId, 'number', - 'triggerId is a number'); + assert.strictEqual(signal2.type, 'SIGNALWRAP'); + assert.strictEqual(typeof signal2.uid, 'number'); + assert.strictEqual(typeof signal2.triggerId, 'number'); checkInvocations( signal1, { init: 1, before: 2, after: 1 }, diff --git a/test/async-hooks/test-statwatcher.js b/test/async-hooks/test-statwatcher.js index fe2a97c06f43bf..a4814842ae416a 100644 --- a/test/async-hooks/test-statwatcher.js +++ b/test/async-hooks/test-statwatcher.js @@ -15,24 +15,24 @@ function onchange() {} fs.watchFile(__filename, onchange); let as = hooks.activitiesOfTypes('STATWATCHER'); -assert.strictEqual(as.length, 1, 'one stat watcher when watching one file'); +assert.strictEqual(as.length, 1); const statwatcher1 = as[0]; -assert.strictEqual(statwatcher1.type, 'STATWATCHER', 'stat watcher'); -assert.strictEqual(typeof statwatcher1.uid, 'number', 'uid is a number'); -assert.strictEqual(statwatcher1.triggerId, 1, 'parent uid 1'); +assert.strictEqual(statwatcher1.type, 'STATWATCHER'); +assert.strictEqual(typeof statwatcher1.uid, 'number'); +assert.strictEqual(statwatcher1.triggerId, 1); checkInvocations(statwatcher1, { init: 1 }, 'watcher1: when started to watch file'); // install second file watcher fs.watchFile(commonPath, onchange); as = hooks.activitiesOfTypes('STATWATCHER'); -assert.strictEqual(as.length, 2, 'two stat watchers when watching two files'); +assert.strictEqual(as.length, 2); const statwatcher2 = as[1]; -assert.strictEqual(statwatcher2.type, 'STATWATCHER', 'stat watcher'); -assert.strictEqual(typeof statwatcher2.uid, 'number', 'uid is a number'); -assert.strictEqual(statwatcher2.triggerId, 1, 'parent uid 1'); +assert.strictEqual(statwatcher2.type, 'STATWATCHER'); +assert.strictEqual(typeof statwatcher2.uid, 'number'); +assert.strictEqual(statwatcher2.triggerId, 1); checkInvocations(statwatcher1, { init: 1 }, 'watcher1: when started to watch second file'); checkInvocations(statwatcher2, { init: 1 }, @@ -41,14 +41,14 @@ checkInvocations(statwatcher2, { init: 1 }, // remove first file watcher fs.unwatchFile(__filename); checkInvocations(statwatcher1, { init: 1, before: 1, after: 1 }, - 'watcher:1 when unwatched first file'); + 'watcher1: when unwatched first file'); checkInvocations(statwatcher2, { init: 1 }, 'watcher2: when unwatched first file'); // remove second file watcher fs.unwatchFile(commonPath); checkInvocations(statwatcher1, { init: 1, before: 1, after: 1 }, - 'watcher:1 when unwatched second file'); + 'watcher1: when unwatched second file'); checkInvocations(statwatcher2, { init: 1, before: 1, after: 1 }, 'watcher2: when unwatched second file'); @@ -58,7 +58,7 @@ function onexit() { hooks.disable(); hooks.sanityCheck('STATWATCHER'); checkInvocations(statwatcher1, { init: 1, before: 1, after: 1 }, - 'watcher:1 when process exits'); + 'watcher1: when process exits'); checkInvocations(statwatcher2, { init: 1, before: 1, after: 1 }, 'watcher2: when process exits'); } diff --git a/test/async-hooks/test-tcpwrap.js b/test/async-hooks/test-tcpwrap.js index 0827779229297b..bdb45b47a36029 100644 --- a/test/async-hooks/test-tcpwrap.js +++ b/test/async-hooks/test-tcpwrap.js @@ -29,16 +29,12 @@ const server = net server.listen(common.PORT); const tcps = hooks.activitiesOfTypes('TCPWRAP'); const tcpconnects = hooks.activitiesOfTypes('TCPCONNECTWRAP'); - assert.strictEqual( - tcps.length, 1, - 'one TCPWRAP created synchronously when calling server.listen'); - assert.strictEqual( - tcpconnects.length, 0, - 'no TCPCONNECTWRAP created synchronously when calling server.listen'); + assert.strictEqual(tcps.length, 1); + assert.strictEqual(tcpconnects.length, 0); tcp1 = tcps[0]; - assert.strictEqual(tcp1.type, 'TCPWRAP', 'tcp wrap'); - assert.strictEqual(typeof tcp1.uid, 'number', 'uid is a number'); - assert.strictEqual(typeof tcp1.triggerId, 'number', 'triggerId is a number'); + assert.strictEqual(tcp1.type, 'TCPWRAP'); + assert.strictEqual(typeof tcp1.uid, 'number'); + assert.strictEqual(typeof tcp1.triggerId, 'number'); checkInvocations(tcp1, { init: 1 }, 'when calling server.listen'); } @@ -48,30 +44,24 @@ const server = net { port: server.address().port, host: server.address().address }, common.mustCall(onconnected)); const tcps = hooks.activitiesOfTypes('TCPWRAP'); - assert.strictEqual( - tcps.length, 2, - '2 TCPWRAPs present when client is connecting'); + assert.strictEqual(tcps.length, 2); process.nextTick(() => { const tcpconnects = hooks.activitiesOfTypes('TCPCONNECTWRAP'); - assert.strictEqual( - tcpconnects.length, 1, - '1 TCPCONNECTWRAP present when client is connecting'); + assert.strictEqual(tcpconnects.length, 1); }); tcp2 = tcps[1]; - assert.strictEqual(tcps.length, 2, - '2 TCPWRAP present when client is connecting'); - assert.strictEqual(tcp2.type, 'TCPWRAP', 'tcp wrap'); - assert.strictEqual(typeof tcp2.uid, 'number', 'uid is a number'); - assert.strictEqual(typeof tcp2.triggerId, 'number', 'triggerId is a number'); + assert.strictEqual(tcps.length, 2); + assert.strictEqual(tcp2.type, 'TCPWRAP'); + assert.strictEqual(typeof tcp2.uid, 'number'); + assert.strictEqual(typeof tcp2.triggerId, 'number'); checkInvocations(tcp1, { init: 1 }, 'tcp1 when client is connecting'); checkInvocations(tcp2, { init: 1 }, 'tcp2 when client is connecting'); } function onlistening() { - assert.strictEqual(hooks.activitiesOfTypes('TCPWRAP').length, 2, - 'two TCPWRAPs when server is listening'); + assert.strictEqual(hooks.activitiesOfTypes('TCPWRAP').length, 2); } // Depending on timing we see client: onconnected or server: onconnection first @@ -92,14 +82,11 @@ function ontcpConnection(serverConnection) { // only focusing on TCPCONNECTWRAP here const tcpconnects = hooks.activitiesOfTypes('TCPCONNECTWRAP'); - assert.strictEqual( - tcpconnects.length, 1, - 'one TCPCONNECTWRAP present on tcp connection'); + assert.strictEqual(tcpconnects.length, 1); tcpconnect = tcpconnects[0]; - assert.strictEqual(tcpconnect.type, 'TCPCONNECTWRAP', 'tcpconnect wrap'); - assert.strictEqual(typeof tcpconnect.uid, 'number', 'uid is a number'); - assert.strictEqual(typeof tcpconnect.triggerId, - 'number', 'triggerId is a number'); + assert.strictEqual(tcpconnect.type, 'TCPCONNECTWRAP'); + assert.strictEqual(typeof tcpconnect.uid, 'number'); + assert.strictEqual(typeof tcpconnect.triggerId, 'number'); // When client receives connection first ('onconnected'), we 'before' has // been invoked at this point already, otherwise it only was 'init'ed const expected = serverConnection ? { init: 1 } : { init: 1, before: 1 }; @@ -125,16 +112,12 @@ function onconnection(c) { const tcps = hooks.activitiesOfTypes([ 'TCPWRAP' ]); const tcpconnects = hooks.activitiesOfTypes('TCPCONNECTWRAP'); - assert.strictEqual( - tcps.length, 3, - '3 TCPWRAPs present when server receives connection'); - assert.strictEqual( - tcpconnects.length, 1, - 'one TCPCONNECTWRAP present when server receives connection'); + assert.strictEqual(tcps.length, 3); + assert.strictEqual(tcpconnects.length, 1); tcp3 = tcps[2]; - assert.strictEqual(tcp3.type, 'TCPWRAP', 'tcp wrap'); - assert.strictEqual(typeof tcp3.uid, 'number', 'uid is a number'); - assert.strictEqual(typeof tcp3.triggerId, 'number', 'triggerId is a number'); + assert.strictEqual(tcp3.type, 'TCPWRAP'); + assert.strictEqual(typeof tcp3.uid, 'number'); + assert.strictEqual(typeof tcp3.triggerId, 'number'); checkInvocations(tcp1, { init: 1, before: 1 }, 'tcp1 when server receives connection'); diff --git a/test/async-hooks/test-timerwrap.setInterval.js b/test/async-hooks/test-timerwrap.setInterval.js index 8e8b11a7e76bdb..02cd2740dfe071 100644 --- a/test/async-hooks/test-timerwrap.setInterval.js +++ b/test/async-hooks/test-timerwrap.setInterval.js @@ -14,16 +14,16 @@ let count = 0; const iv = setInterval(common.mustCall(oninterval, 3), TIMEOUT); const as = hooks.activitiesOfTypes('TIMERWRAP'); -assert.strictEqual(as.length, 1, 'one timer wrap when interval installed'); +assert.strictEqual(as.length, 1); const t = as[0]; -assert.strictEqual(t.type, 'TIMERWRAP', 'timer wrap'); -assert.strictEqual(typeof t.uid, 'number', 'uid is a number'); -assert.strictEqual(typeof t.triggerId, 'number', 'triggerId is a number'); +assert.strictEqual(t.type, 'TIMERWRAP'); +assert.strictEqual(typeof t.uid, 'number'); +assert.strictEqual(typeof t.triggerId, 'number'); checkInvocations(t, { init: 1 }, 't: when first timer installed'); function oninterval() { count++; - assert.strictEqual(as.length, 1, 'one timer wrap when timer is triggered'); + assert.strictEqual(as.length, 1); switch (count) { case 1: { checkInvocations(t, { init: 1, before: 1 }, diff --git a/test/async-hooks/test-timerwrap.setTimeout.js b/test/async-hooks/test-timerwrap.setTimeout.js index 5f0ee5897d36dd..c95d116a249f7c 100644 --- a/test/async-hooks/test-timerwrap.setTimeout.js +++ b/test/async-hooks/test-timerwrap.setTimeout.js @@ -13,11 +13,11 @@ hooks.enable(); // install first timeout setTimeout(common.mustCall(ontimeout), TIMEOUT); const as = hooks.activitiesOfTypes('TIMERWRAP'); -assert.strictEqual(as.length, 1, 'one timer wrap when first timeout installed'); +assert.strictEqual(as.length, 1); const t1 = as[0]; -assert.strictEqual(t1.type, 'TIMERWRAP', 'timer wrap'); -assert.strictEqual(typeof t1.uid, 'number', 'uid is a number'); -assert.strictEqual(typeof t1.triggerId, 'number', 'triggerId is a number'); +assert.strictEqual(t1.type, 'TIMERWRAP'); +assert.strictEqual(typeof t1.uid, 'number'); +assert.strictEqual(typeof t1.triggerId, 'number'); checkInvocations(t1, { init: 1 }, 't1: when first timer installed'); function ontimeout() { @@ -26,8 +26,7 @@ function ontimeout() { // install second timeout with same TIMEOUT to see timer wrap being reused setTimeout(onsecondTimeout, TIMEOUT); const as = hooks.activitiesOfTypes('TIMERWRAP'); - assert.strictEqual(as.length, 1, - 'one timer wrap when second timer installed'); + assert.strictEqual(as.length, 1); checkInvocations(t1, { init: 1, before: 1 }, 't1: when second timer installed'); } @@ -38,19 +37,18 @@ let t2; function onsecondTimeout() { let as = hooks.activitiesOfTypes('TIMERWRAP'); - assert.strictEqual(as.length, 1, 'one timer wrap when second timer fired'); + assert.strictEqual(as.length, 1); checkInvocations(t1, { init: 1, before: 2, after: 1 }, 't1: when second timer fired'); // install third timeout with different TIMEOUT setTimeout(onthirdTimeout, TIMEOUT + 1); as = hooks.activitiesOfTypes('TIMERWRAP'); - assert.strictEqual(as.length, 2, - 'two timer wraps when third timer installed'); + assert.strictEqual(as.length, 2); t2 = as[1]; - assert.strictEqual(t2.type, 'TIMERWRAP', 'timer wrap'); - assert.strictEqual(typeof t2.uid, 'number', 'uid is a number'); - assert.strictEqual(typeof t2.triggerId, 'number', 'triggerId is a number'); + assert.strictEqual(t2.type, 'TIMERWRAP'); + assert.strictEqual(typeof t2.uid, 'number'); + assert.strictEqual(typeof t2.triggerId, 'number'); checkInvocations(t1, { init: 1, before: 2, after: 1 }, 't1: when third timer installed'); checkInvocations(t2, { init: 1 }, diff --git a/test/async-hooks/test-tlswrap.js b/test/async-hooks/test-tlswrap.js index 39e2cf100a623c..7429a54f10fbdf 100644 --- a/test/async-hooks/test-tlswrap.js +++ b/test/async-hooks/test-tlswrap.js @@ -38,12 +38,12 @@ function onlistening() { .on('secureConnect', common.mustCall(onsecureConnect)); const as = hooks.activitiesOfTypes('TLSWRAP'); - assert.strictEqual(as.length, 1, 'one TLSWRAP when client connecting'); + assert.strictEqual(as.length, 1); svr = as[0]; - assert.strictEqual(svr.type, 'TLSWRAP', 'tls wrap'); - assert.strictEqual(typeof svr.uid, 'number', 'uid is a number'); - assert.strictEqual(typeof svr.triggerId, 'number', 'triggerId is a number'); + assert.strictEqual(svr.type, 'TLSWRAP'); + assert.strictEqual(typeof svr.uid, 'number'); + assert.strictEqual(typeof svr.triggerId, 'number'); checkInvocations(svr, { init: 1 }, 'server: when client connecting'); } @@ -52,13 +52,11 @@ function onsecureConnection() { // Server received client connection // const as = hooks.activitiesOfTypes('TLSWRAP'); - assert.strictEqual(as.length, 2, - 'two TLSWRAPs when server has secure connection'); + assert.strictEqual(as.length, 2); client = as[1]; - assert.strictEqual(client.type, 'TLSWRAP', 'tls wrap'); - assert.strictEqual(typeof client.uid, 'number', 'uid is a number'); - assert.strictEqual(typeof client.triggerId, 'number', - 'triggerId is a number'); + assert.strictEqual(client.type, 'TLSWRAP'); + assert.strictEqual(typeof client.uid, 'number'); + assert.strictEqual(typeof client.triggerId, 'number'); // TODO(thlorenz) which callback did the server wrap execute that already // finished as well? diff --git a/test/async-hooks/test-ttywrap.readstream.js b/test/async-hooks/test-ttywrap.readstream.js index 017fb3142a7324..96f078ab1482d4 100644 --- a/test/async-hooks/test-ttywrap.readstream.js +++ b/test/async-hooks/test-ttywrap.readstream.js @@ -13,11 +13,11 @@ const ReadStream = require('tty').ReadStream; const ttyStream = new ReadStream(0); const as = hooks.activitiesOfTypes('TTYWRAP'); -assert.strictEqual(as.length, 1, 'one TTYWRAP when tty created'); +assert.strictEqual(as.length, 1); const tty = as[0]; -assert.strictEqual(tty.type, 'TTYWRAP', 'tty wrap'); -assert.strictEqual(typeof tty.uid, 'number', 'uid is a number'); -assert.strictEqual(typeof tty.triggerId, 'number', 'triggerId is a number'); +assert.strictEqual(tty.type, 'TTYWRAP'); +assert.strictEqual(typeof tty.uid, 'number'); +assert.strictEqual(typeof tty.triggerId, 'number'); checkInvocations(tty, { init: 1 }, 'when tty created'); ttyStream.end(common.mustCall(onend)); diff --git a/test/async-hooks/test-ttywrap.writestream.js b/test/async-hooks/test-ttywrap.writestream.js index c6dd6e5f145361..ad0148191f806c 100644 --- a/test/async-hooks/test-ttywrap.writestream.js +++ b/test/async-hooks/test-ttywrap.writestream.js @@ -23,18 +23,18 @@ const hooks = initHooks(); hooks.enable(); const as = hooks.activitiesOfTypes('TTYWRAP'); -assert.strictEqual(as.length, 1, 'one TTYWRAP when tty created'); +assert.strictEqual(as.length, 1); const tty = as[0]; -assert.strictEqual(tty.type, 'TTYWRAP', 'tty wrap'); -assert.strictEqual(typeof tty.uid, 'number', 'uid is a number'); -assert.strictEqual(typeof tty.triggerId, 'number', 'triggerId is a number'); +assert.strictEqual(tty.type, 'TTYWRAP'); +assert.strictEqual(typeof tty.uid, 'number'); +assert.strictEqual(typeof tty.triggerId, 'number'); checkInvocations(tty, { init: 1 }, 'when tty created'); ttyStream .on('finish', common.mustCall(onfinish)) .end(common.mustCall(onend)); -checkInvocations(tty, { init: 1}, 'when tty.end() was invoked '); +checkInvocations(tty, { init: 1 }, 'when tty.end() was invoked '); function onend() { tick(2, common.mustCall(() => diff --git a/test/async-hooks/test-udpsendwrap.js b/test/async-hooks/test-udpsendwrap.js index 72b12c1e217cc1..07fb8790fae114 100644 --- a/test/async-hooks/test-udpsendwrap.js +++ b/test/async-hooks/test-udpsendwrap.js @@ -25,20 +25,17 @@ function onlistening() { // callback in a next tick even if no lookup is needed // TODO (trevnorris) submit patch to fix creation of tick objects and instead // create the send wrap synchronously. - assert.strictEqual( - hooks.activitiesOfTypes('UDPSENDWRAP').length, 0, - 'no udpsendwrap after sock connected and sock.send called'); + assert.strictEqual(hooks.activitiesOfTypes('UDPSENDWRAP').length, 0); } function onsent() { const as = hooks.activitiesOfTypes('UDPSENDWRAP'); send = as[0]; - assert.strictEqual(as.length, 1, - 'one UDPSENDWRAP created synchronously when message sent'); - assert.strictEqual(send.type, 'UDPSENDWRAP', 'send wrap'); - assert.strictEqual(typeof send.uid, 'number', 'uid is a number'); - assert.strictEqual(typeof send.triggerId, 'number', 'triggerId is a number'); + assert.strictEqual(as.length, 1); + assert.strictEqual(send.type, 'UDPSENDWRAP'); + assert.strictEqual(typeof send.uid, 'number'); + assert.strictEqual(typeof send.triggerId, 'number'); checkInvocations(send, { init: 1, before: 1 }, 'when message sent'); sock.close(common.mustCall(onsockClosed)); diff --git a/test/async-hooks/test-udpwrap.js b/test/async-hooks/test-udpwrap.js index db81db8339eb3e..66142911de0f4e 100644 --- a/test/async-hooks/test-udpwrap.js +++ b/test/async-hooks/test-udpwrap.js @@ -14,11 +14,10 @@ const sock = dgram.createSocket('udp4'); const as = hooks.activitiesOfTypes('UDPWRAP'); const udpwrap = as[0]; -assert.strictEqual(as.length, 1, - 'one UDPWRAP handle after dgram.createSocket call'); -assert.strictEqual(udpwrap.type, 'UDPWRAP', 'udp wrap'); -assert.strictEqual(typeof udpwrap.uid, 'number', 'uid is a number'); -assert.strictEqual(typeof udpwrap.triggerId, 'number', 'triggerId is a number'); +assert.strictEqual(as.length, 1); +assert.strictEqual(udpwrap.type, 'UDPWRAP'); +assert.strictEqual(typeof udpwrap.uid, 'number'); +assert.strictEqual(typeof udpwrap.triggerId, 'number'); checkInvocations(udpwrap, { init: 1 }, 'after dgram.createSocket call'); sock.close(common.mustCall(onsockClosed)); diff --git a/test/async-hooks/test-writewrap.js b/test/async-hooks/test-writewrap.js index fecceaf13c5cad..eabb61847ff166 100644 --- a/test/async-hooks/test-writewrap.js +++ b/test/async-hooks/test-writewrap.js @@ -27,12 +27,10 @@ const server = tls .on('secureConnection', common.mustCall(onsecureConnection)) .listen(common.PORT); -assert.strictEqual(hooks.activitiesOfTypes('WRITEWRAP').length, 0, - 'no WRITEWRAP when server created'); +assert.strictEqual(hooks.activitiesOfTypes('WRITEWRAP').length, 0); function onlistening() { - assert.strictEqual(hooks.activitiesOfTypes('WRITEWRAP').length, 0, - 'no WRITEWRAP when server is listening'); + assert.strictEqual(hooks.activitiesOfTypes('WRITEWRAP').length, 0); // // Creating client and connecting it to server // @@ -40,20 +38,19 @@ function onlistening() { .connect(common.PORT, { rejectUnauthorized: false }) .on('secureConnect', common.mustCall(onsecureConnect)); - assert.strictEqual(hooks.activitiesOfTypes('WRITEWRAP').length, 0, - 'no WRITEWRAP when client created'); + assert.strictEqual(hooks.activitiesOfTypes('WRITEWRAP').length, 0); } function checkDestroyedWriteWraps(n, stage) { const as = hooks.activitiesOfTypes('WRITEWRAP'); - assert.strictEqual(as.length, n, n + ' WRITEWRAPs when ' + stage); + assert.strictEqual(as.length, n, `${n} WRITEWRAPs when ${stage}`); function checkValidWriteWrap(w) { - assert.strictEqual(w.type, 'WRITEWRAP', 'write wrap'); - assert.strictEqual(typeof w.uid, 'number', 'uid is a number'); - assert.strictEqual(typeof w.triggerId, 'number', 'triggerId is a number'); + assert.strictEqual(w.type, 'WRITEWRAP'); + assert.strictEqual(typeof w.uid, 'number'); + assert.strictEqual(typeof w.triggerId, 'number'); - checkInvocations(w, { init: 1, destroy: 1 }, 'when ' + stage); + checkInvocations(w, { init: 1 }, `when ${stage}`); } as.forEach(checkValidWriteWrap); } diff --git a/test/async-hooks/test-zlib.zlib-binding.deflate.js b/test/async-hooks/test-zlib.zlib-binding.deflate.js index 715d1652b94444..bf991cfbabb73f 100644 --- a/test/async-hooks/test-zlib.zlib-binding.deflate.js +++ b/test/async-hooks/test-zlib.zlib-binding.deflate.js @@ -14,11 +14,11 @@ const constants = process.binding('constants').zlib; const handle = new Zlib(constants.DEFLATE); const as = hooks.activitiesOfTypes('ZLIB'); -assert.strictEqual(as.length, 1, 'one zlib on when created handle'); +assert.strictEqual(as.length, 1); const hdl = as[0]; -assert.strictEqual(hdl.type, 'ZLIB', 'zlib'); -assert.strictEqual(typeof hdl.uid, 'number', 'uid is a number'); -assert.strictEqual(typeof hdl.triggerId, 'number', 'triggerId is a number'); +assert.strictEqual(hdl.type, 'ZLIB'); +assert.strictEqual(typeof hdl.uid, 'number'); +assert.strictEqual(typeof hdl.triggerId, 'number'); checkInvocations(hdl, { init: 1 }, 'when created handle'); handle.init( diff --git a/test/async-hooks/verify-graph.js b/test/async-hooks/verify-graph.js index e87dd5596c31cb..1f4cacd2a770e2 100644 --- a/test/async-hooks/verify-graph.js +++ b/test/async-hooks/verify-graph.js @@ -1,6 +1,7 @@ 'use strict'; const assert = require('assert'); +const util = require('util'); require('../common'); function findInGraph(graph, type, n) { @@ -85,14 +86,14 @@ module.exports = function verifyGraph(hooks, graph) { ) ); } - assert.strictEqual(errors.length, 0, 'Found errors while verifying graph.'); + assert.strictEqual(errors.length, 0); }; // // Helper to generate the input to the verifyGraph tests // function inspect(obj, depth) { - console.error(require('util').inspect(obj, false, depth || 5, true)); + console.error(util.inspect(obj, false, depth || 5, true)); } module.exports.printGraph = function printGraph(hooks) { diff --git a/test/cctest/test_inspector_socket.cc b/test/cctest/test_inspector_socket.cc index 609053a6cd0803..181ab6e017a32d 100644 --- a/test/cctest/test_inspector_socket.cc +++ b/test/cctest/test_inspector_socket.cc @@ -335,8 +335,8 @@ static void really_close(uv_handle_t* handle) { // Called when the test leaves inspector socket in active state static void manual_inspector_socket_cleanup() { EXPECT_EQ(0, uv_is_active( - reinterpret_cast(&inspector.client))); - really_close(reinterpret_cast(&inspector.client)); + reinterpret_cast(&inspector.tcp))); + really_close(reinterpret_cast(&inspector.tcp)); delete inspector.ws_state; inspector.ws_state = nullptr; delete inspector.http_parsing_state; @@ -346,7 +346,7 @@ static void manual_inspector_socket_cleanup() { static void assert_both_sockets_closed() { SPIN_WHILE(uv_is_active(reinterpret_cast(&client_socket))); - SPIN_WHILE(uv_is_active(reinterpret_cast(&inspector.client))); + SPIN_WHILE(uv_is_active(reinterpret_cast(&inspector.tcp))); } static void on_connection(uv_connect_t* connect, int status) { diff --git a/test/cctest/test_inspector_socket_server.cc b/test/cctest/test_inspector_socket_server.cc index 4e292691c10550..7224ad9e31b3a1 100644 --- a/test/cctest/test_inspector_socket_server.cc +++ b/test/cctest/test_inspector_socket_server.cc @@ -306,9 +306,9 @@ class SocketWrapper { class ServerHolder { public: template - ServerHolder(Delegate* delegate, int port, FILE* out = NULL) + ServerHolder(Delegate* delegate, uv_loop_t* loop, int port, FILE* out = NULL) : closed(false), paused(false), - server_(delegate, HOST, port, out) { + server_(delegate, loop, HOST, port, out) { delegate->Connect(&server_); } @@ -387,8 +387,8 @@ static const std::string WsHandshakeRequest(const std::string& target_id) { TEST_F(InspectorSocketServerTest, InspectorSessions) { TestInspectorServerDelegate delegate; - ServerHolder server(&delegate, 0); - ASSERT_TRUE(server->Start(&loop)); + ServerHolder server(&delegate, &loop, 0); + ASSERT_TRUE(server->Start()); SocketWrapper well_behaved_socket(&loop); // Regular connection @@ -474,8 +474,8 @@ TEST_F(InspectorSocketServerTest, InspectorSessions) { TEST_F(InspectorSocketServerTest, ServerDoesNothing) { TestInspectorServerDelegate delegate; - ServerHolder server(&delegate, 0); - ASSERT_TRUE(server->Start(&loop)); + ServerHolder server(&delegate, &loop, 0); + ASSERT_TRUE(server->Start()); server->Stop(ServerHolder::CloseCallback); server->TerminateConnections(); @@ -485,8 +485,8 @@ TEST_F(InspectorSocketServerTest, ServerDoesNothing) { TEST_F(InspectorSocketServerTest, ServerWithoutTargets) { ServerDelegateNoTargets delegate; - ServerHolder server(&delegate, 0); - ASSERT_TRUE(server->Start(&loop)); + ServerHolder server(&delegate, &loop, 0); + ASSERT_TRUE(server->Start()); TestHttpRequest(server.port(), "/json/list", "[ ]"); TestHttpRequest(server.port(), "/json", "[ ]"); @@ -503,10 +503,10 @@ TEST_F(InspectorSocketServerTest, ServerWithoutTargets) { TEST_F(InspectorSocketServerTest, ServerCannotStart) { ServerDelegateNoTargets delegate1, delegate2; - ServerHolder server1(&delegate1, 0); - ASSERT_TRUE(server1->Start(&loop)); - ServerHolder server2(&delegate2, server1.port()); - ASSERT_FALSE(server2->Start(&loop)); + ServerHolder server1(&delegate1, &loop, 0); + ASSERT_TRUE(server1->Start()); + ServerHolder server2(&delegate2, &loop, server1.port()); + ASSERT_FALSE(server2->Start()); server1->Stop(ServerHolder::CloseCallback); server1->TerminateConnections(); SPIN_WHILE(!server1.closed); @@ -515,8 +515,8 @@ TEST_F(InspectorSocketServerTest, ServerCannotStart) { TEST_F(InspectorSocketServerTest, StoppingServerDoesNotKillConnections) { ServerDelegateNoTargets delegate; - ServerHolder server(&delegate, 0); - ASSERT_TRUE(server->Start(&loop)); + ServerHolder server(&delegate, &loop, 0); + ASSERT_TRUE(server->Start()); SocketWrapper socket1(&loop); socket1.Connect(HOST, server.port()); socket1.TestHttpRequest("/json/list", "[ ]"); @@ -530,8 +530,8 @@ TEST_F(InspectorSocketServerTest, StoppingServerDoesNotKillConnections) { TEST_F(InspectorSocketServerTest, ClosingConnectionReportsDone) { ServerDelegateNoTargets delegate; - ServerHolder server(&delegate, 0); - ASSERT_TRUE(server->Start(&loop)); + ServerHolder server(&delegate, &loop, 0); + ASSERT_TRUE(server->Start()); SocketWrapper socket1(&loop); socket1.Connect(HOST, server.port()); socket1.TestHttpRequest("/json/list", "[ ]"); @@ -545,8 +545,8 @@ TEST_F(InspectorSocketServerTest, ClosingConnectionReportsDone) { TEST_F(InspectorSocketServerTest, ClosingSocketReportsDone) { TestInspectorServerDelegate delegate; - ServerHolder server(&delegate, 0); - ASSERT_TRUE(server->Start(&loop)); + ServerHolder server(&delegate, &loop, 0); + ASSERT_TRUE(server->Start()); SocketWrapper socket1(&loop); socket1.Connect(HOST, server.port()); socket1.Write(WsHandshakeRequest(MAIN_TARGET_ID)); @@ -560,8 +560,8 @@ TEST_F(InspectorSocketServerTest, ClosingSocketReportsDone) { TEST_F(InspectorSocketServerTest, TerminatingSessionReportsDone) { TestInspectorServerDelegate delegate; - ServerHolder server(&delegate, 0); - ASSERT_TRUE(server->Start(&loop)); + ServerHolder server(&delegate, &loop, 0); + ASSERT_TRUE(server->Start()); SocketWrapper socket1(&loop); socket1.Connect(HOST, server.port()); socket1.Write(WsHandshakeRequest(MAIN_TARGET_ID)); diff --git a/test/common/README.md b/test/common/README.md index 492b5acdea586c..01d19116bdac29 100644 --- a/test/common/README.md +++ b/test/common/README.md @@ -204,6 +204,12 @@ fail. If `fn` is not provided, `common.noop` will be used. +### mustNotCall([msg]) +* `msg` [<String>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type) default = 'function should not have been called' +* return [<Function>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function) + +Returns a function that triggers an `AssertionError` if it is invoked. `msg` is used as the error message for the `AssertionError`. + ### nodeProcessAborted(exitCode, signal) * `exitCode` [<Number>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type) * `signal` [<String>](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type) diff --git a/test/fixtures/url-idna.js b/test/fixtures/url-idna.js index cbfe702e9372bf..4b8f5a48cc9646 100644 --- a/test/fixtures/url-idna.js +++ b/test/fixtures/url-idna.js @@ -1,223 +1,215 @@ 'use strict'; // Credit for list: http://www.i18nguy.com/markup/idna-examples.html -module.exports = { - valid: [ - { ascii: 'xn--mgbaal8b0b9b2b.icom.museum', - unicode: 'افغانستا.icom.museum' - }, - { - ascii: 'xn--lgbbat1ad8j.icom.museum', - unicode: 'الجزائر.icom.museum' - }, - { - ascii: 'xn--sterreich-z7a.icom.museum', - unicode: 'österreich.icom.museum' - }, - { - ascii: 'xn--54b6eqazv8bc7e.icom.museum', - unicode: 'বাংলাদেশ.icom.museum' - }, - { - ascii: 'xn--80abmy0agn7e.icom.museum', - unicode: 'беларусь.icom.museum' - }, - { - ascii: 'xn--belgi-rsa.icom.museum', - unicode: 'belgië.icom.museum' - }, - { - ascii: 'xn--80abgvm6a7d2b.icom.museum', - unicode: 'българия.icom.museum' - }, - { - ascii: 'xn--mgbfqim.icom.museum', - unicode: 'تشادر.icom.museum' - }, - { - ascii: 'xn--fiqs8s.icom.museum', - unicode: '中国.icom.museum' - }, - { - ascii: 'xn--mgbu4chg.icom.museum', - unicode: 'القمر.icom.museum' - }, - { - ascii: 'xn--vxakcego.icom.museum', - unicode: 'κυπρος.icom.museum' - }, - { - ascii: 'xn--eskrepublika-ebb62d.icom.museum', - unicode: 'českárepublika.icom.museum' - }, - { - ascii: 'xn--wgbh1c.icom.museum', - unicode: 'مصر.icom.museum' - }, - { - ascii: 'xn--hxakic4aa.icom.museum', - unicode: 'ελλάδα.icom.museum' - }, - { - ascii: 'xn--magyarorszg-t7a.icom.museum', - unicode: 'magyarország.icom.museum' - }, - { - ascii: 'xn--sland-ysa.icom.museum', - unicode: 'ísland.icom.museum' - }, - { - ascii: 'xn--h2brj9c.icom.museum', - unicode: 'भारत.icom.museum' - }, - { - ascii: 'xn--mgba3a4fra.icom.museum', - unicode: 'ايران.icom.museum' - }, - { - ascii: 'xn--ire-9la.icom.museum', - unicode: 'éire.icom.museum' - }, - { - ascii: 'xn--4dbklr2c8d.xn--4dbrk0ce.museum', - unicode: 'איקו״ם.ישראל.museum' - }, - { - ascii: 'xn--wgv71a.icom.museum', - unicode: '日本.icom.museum' - }, - { - ascii: 'xn--igbhzh7gpa.icom.museum', - unicode: 'الأردن.icom.museum' - }, - { - ascii: 'xn--80aaa0a6awh12ed.icom.museum', - unicode: 'қазақстан.icom.museum' - }, - { - ascii: 'xn--3e0b707e.icom.museum', - unicode: '한국.icom.museum' - }, - { - ascii: 'xn--80afmksoji0fc.icom.museum', - unicode: 'кыргызстан.icom.museum' - }, - { - ascii: 'xn--q7ce6a.icom.museum', - unicode: 'ລາວ.icom.museum' - }, - { - ascii: 'xn--mgbb7fjb.icom.museum', - unicode: 'لبنان.icom.museum' - }, - { - ascii: 'xn--80aaldqjmmi6x.icom.museum', - unicode: 'македонија.icom.museum' - }, - { - ascii: 'xn--mgbah1a3hjkrd.icom.museum', - unicode: 'موريتانيا.icom.museum' - }, - { - ascii: 'xn--mxico-bsa.icom.museum', - unicode: 'méxico.icom.museum' - }, - { - ascii: 'xn--c1aqabffc0aq.icom.museum', - unicode: 'монголулс.icom.museum' - }, - { - ascii: 'xn--mgbc0a9azcg.icom.museum', - unicode: 'المغرب.icom.museum' - }, - { - ascii: 'xn--l2bey1c2b.icom.museum', - unicode: 'नेपाल.icom.museum' - }, - { - ascii: 'xn--mgb9awbf.icom.museum', - unicode: 'عمان.icom.museum' - }, - { - ascii: 'xn--wgbl6a.icom.museum', - unicode: 'قطر.icom.museum' - }, - { - ascii: 'xn--romnia-yta.icom.museum', - unicode: 'românia.icom.museum' - }, - { - ascii: 'xn--h1alffa9f.xn--h1aegh.museum', - unicode: 'россия.иком.museum' - }, - { - ascii: 'xn--80aaabm1ab4blmeec9e7n.xn--h1aegh.museum', - unicode: 'србијаицрнагора.иком.museum' - }, - { - ascii: 'xn--xkc2al3hye2a.icom.museum', - unicode: 'இலங்கை.icom.museum' - }, - { - ascii: 'xn--espaa-rta.icom.museum', - unicode: 'españa.icom.museum' - }, - { - ascii: 'xn--o3cw4h.icom.museum', - unicode: 'ไทย.icom.museum' - }, - { - ascii: 'xn--pgbs0dh.icom.museum', - unicode: 'تونس.icom.museum' - }, - { - ascii: 'xn--trkiye-3ya.icom.museum', - unicode: 'türkiye.icom.museum' - }, - { - ascii: 'xn--80aaxgrpt.icom.museum', - unicode: 'украина.icom.museum' - }, - { - ascii: 'xn--vitnam-jk8b.icom.museum', - unicode: 'việtnam.icom.museum' - }, - // long label - { - ascii: `${'a'.repeat(64)}.com`, - unicode: `${'a'.repeat(64)}.com`, - }, - // long URL - { - ascii: `${`${'a'.repeat(64)}.`.repeat(4)}com`, - unicode: `${`${'a'.repeat(64)}.`.repeat(4)}com` - }, - // URLs with hyphen - { - ascii: 'r4---sn-a5mlrn7s.gevideo.com', - unicode: 'r4---sn-a5mlrn7s.gevideo.com' - }, - { - ascii: '-sn-a5mlrn7s.gevideo.com', - unicode: '-sn-a5mlrn7s.gevideo.com' - }, - { - ascii: 'sn-a5mlrn7s-.gevideo.com', - unicode: 'sn-a5mlrn7s-.gevideo.com' - }, - { - ascii: '-sn-a5mlrn7s-.gevideo.com', - unicode: '-sn-a5mlrn7s-.gevideo.com' - }, - { - ascii: '-sn--a5mlrn7s-.gevideo.com', - unicode: '-sn--a5mlrn7s-.gevideo.com' - } - ], - invalid: [ - // invalid character - '\ufffd.com', - // invalid bi-directional character - 'تشادرlatin.icom.museum' - ] -} +module.exports = [ + { ascii: 'xn--mgbaal8b0b9b2b.icom.museum', + unicode: 'افغانستا.icom.museum' + }, + { + ascii: 'xn--lgbbat1ad8j.icom.museum', + unicode: 'الجزائر.icom.museum' + }, + { + ascii: 'xn--sterreich-z7a.icom.museum', + unicode: 'österreich.icom.museum' + }, + { + ascii: 'xn--54b6eqazv8bc7e.icom.museum', + unicode: 'বাংলাদেশ.icom.museum' + }, + { + ascii: 'xn--80abmy0agn7e.icom.museum', + unicode: 'беларусь.icom.museum' + }, + { + ascii: 'xn--belgi-rsa.icom.museum', + unicode: 'belgië.icom.museum' + }, + { + ascii: 'xn--80abgvm6a7d2b.icom.museum', + unicode: 'българия.icom.museum' + }, + { + ascii: 'xn--mgbfqim.icom.museum', + unicode: 'تشادر.icom.museum' + }, + { + ascii: 'xn--fiqs8s.icom.museum', + unicode: '中国.icom.museum' + }, + { + ascii: 'xn--mgbu4chg.icom.museum', + unicode: 'القمر.icom.museum' + }, + { + ascii: 'xn--vxakcego.icom.museum', + unicode: 'κυπρος.icom.museum' + }, + { + ascii: 'xn--eskrepublika-ebb62d.icom.museum', + unicode: 'českárepublika.icom.museum' + }, + { + ascii: 'xn--wgbh1c.icom.museum', + unicode: 'مصر.icom.museum' + }, + { + ascii: 'xn--hxakic4aa.icom.museum', + unicode: 'ελλάδα.icom.museum' + }, + { + ascii: 'xn--magyarorszg-t7a.icom.museum', + unicode: 'magyarország.icom.museum' + }, + { + ascii: 'xn--sland-ysa.icom.museum', + unicode: 'ísland.icom.museum' + }, + { + ascii: 'xn--h2brj9c.icom.museum', + unicode: 'भारत.icom.museum' + }, + { + ascii: 'xn--mgba3a4fra.icom.museum', + unicode: 'ايران.icom.museum' + }, + { + ascii: 'xn--ire-9la.icom.museum', + unicode: 'éire.icom.museum' + }, + { + ascii: 'xn--4dbklr2c8d.xn--4dbrk0ce.museum', + unicode: 'איקו״ם.ישראל.museum' + }, + { + ascii: 'xn--wgv71a.icom.museum', + unicode: '日本.icom.museum' + }, + { + ascii: 'xn--igbhzh7gpa.icom.museum', + unicode: 'الأردن.icom.museum' + }, + { + ascii: 'xn--80aaa0a6awh12ed.icom.museum', + unicode: 'қазақстан.icom.museum' + }, + { + ascii: 'xn--3e0b707e.icom.museum', + unicode: '한국.icom.museum' + }, + { + ascii: 'xn--80afmksoji0fc.icom.museum', + unicode: 'кыргызстан.icom.museum' + }, + { + ascii: 'xn--q7ce6a.icom.museum', + unicode: 'ລາວ.icom.museum' + }, + { + ascii: 'xn--mgbb7fjb.icom.museum', + unicode: 'لبنان.icom.museum' + }, + { + ascii: 'xn--80aaldqjmmi6x.icom.museum', + unicode: 'македонија.icom.museum' + }, + { + ascii: 'xn--mgbah1a3hjkrd.icom.museum', + unicode: 'موريتانيا.icom.museum' + }, + { + ascii: 'xn--mxico-bsa.icom.museum', + unicode: 'méxico.icom.museum' + }, + { + ascii: 'xn--c1aqabffc0aq.icom.museum', + unicode: 'монголулс.icom.museum' + }, + { + ascii: 'xn--mgbc0a9azcg.icom.museum', + unicode: 'المغرب.icom.museum' + }, + { + ascii: 'xn--l2bey1c2b.icom.museum', + unicode: 'नेपाल.icom.museum' + }, + { + ascii: 'xn--mgb9awbf.icom.museum', + unicode: 'عمان.icom.museum' + }, + { + ascii: 'xn--wgbl6a.icom.museum', + unicode: 'قطر.icom.museum' + }, + { + ascii: 'xn--romnia-yta.icom.museum', + unicode: 'românia.icom.museum' + }, + { + ascii: 'xn--h1alffa9f.xn--h1aegh.museum', + unicode: 'россия.иком.museum' + }, + { + ascii: 'xn--80aaabm1ab4blmeec9e7n.xn--h1aegh.museum', + unicode: 'србијаицрнагора.иком.museum' + }, + { + ascii: 'xn--xkc2al3hye2a.icom.museum', + unicode: 'இலங்கை.icom.museum' + }, + { + ascii: 'xn--espaa-rta.icom.museum', + unicode: 'españa.icom.museum' + }, + { + ascii: 'xn--o3cw4h.icom.museum', + unicode: 'ไทย.icom.museum' + }, + { + ascii: 'xn--pgbs0dh.icom.museum', + unicode: 'تونس.icom.museum' + }, + { + ascii: 'xn--trkiye-3ya.icom.museum', + unicode: 'türkiye.icom.museum' + }, + { + ascii: 'xn--80aaxgrpt.icom.museum', + unicode: 'украина.icom.museum' + }, + { + ascii: 'xn--vitnam-jk8b.icom.museum', + unicode: 'việtnam.icom.museum' + }, + // long label + { + ascii: `${'a'.repeat(64)}.com`, + unicode: `${'a'.repeat(64)}.com`, + }, + // long URL + { + ascii: `${`${'a'.repeat(64)}.`.repeat(4)}com`, + unicode: `${`${'a'.repeat(64)}.`.repeat(4)}com` + }, + // URLs with hyphen + { + ascii: 'r4---sn-a5mlrn7s.gevideo.com', + unicode: 'r4---sn-a5mlrn7s.gevideo.com' + }, + { + ascii: '-sn-a5mlrn7s.gevideo.com', + unicode: '-sn-a5mlrn7s.gevideo.com' + }, + { + ascii: 'sn-a5mlrn7s-.gevideo.com', + unicode: 'sn-a5mlrn7s-.gevideo.com' + }, + { + ascii: '-sn-a5mlrn7s-.gevideo.com', + unicode: '-sn-a5mlrn7s-.gevideo.com' + }, + { + ascii: '-sn--a5mlrn7s-.gevideo.com', + unicode: '-sn--a5mlrn7s-.gevideo.com' + } +]; diff --git a/test/fixtures/url-toascii.js b/test/fixtures/url-toascii.js new file mode 100644 index 00000000000000..ea5e0f22ba1b5f --- /dev/null +++ b/test/fixtures/url-toascii.js @@ -0,0 +1,156 @@ +'use strict'; + +/* WPT Refs: + https://github.com/w3c/web-platform-tests/blob/4839a0a804/url/toascii.json + License: http://www.w3.org/Consortium/Legal/2008/04-testsuite-copyright.html +*/ +module.exports = +[ + "This resource is focused on highlighting issues with UTS #46 ToASCII", + { + "comment": "Label with hyphens in 3rd and 4th position", + "input": "aa--", + "output": "aa--" + }, + { + "input": "a†--", + "output": "xn--a---kp0a" + }, + { + "input": "ab--c", + "output": "ab--c" + }, + { + "comment": "Label with leading hyphen", + "input": "-x", + "output": "-x" + }, + { + "input": "-†", + "output": "xn----xhn" + }, + { + "input": "-x.xn--nxa", + "output": "-x.xn--nxa" + }, + { + "input": "-x.β", + "output": "-x.xn--nxa" + }, + { + "comment": "Label with trailing hyphen", + "input": "x-.xn--nxa", + "output": "x-.xn--nxa" + }, + { + "input": "x-.β", + "output": "x-.xn--nxa" + }, + { + "comment": "Empty labels", + "input": "x..xn--nxa", + "output": "x..xn--nxa" + }, + { + "input": "x..β", + "output": "x..xn--nxa" + }, + { + "comment": "Invalid Punycode", + "input": "xn--a", + "output": null + }, + { + "input": "xn--a.xn--nxa", + "output": null + }, + { + "input": "xn--a.β", + "output": null + }, + { + "comment": "Valid Punycode", + "input": "xn--nxa.xn--nxa", + "output": "xn--nxa.xn--nxa" + }, + { + "comment": "Mixed", + "input": "xn--nxa.β", + "output": "xn--nxa.xn--nxa" + }, + { + "input": "ab--c.xn--nxa", + "output": "ab--c.xn--nxa" + }, + { + "input": "ab--c.β", + "output": "ab--c.xn--nxa" + }, + { + "comment": "CheckJoiners is true", + "input": "\u200D.example", + "output": null + }, + { + "input": "xn--1ug.example", + "output": null + }, + { + "comment": "CheckBidi is true", + "input": "يa", + "output": null + }, + { + "input": "xn--a-yoc", + "output": null + }, + { + "comment": "processing_option is Nontransitional_Processing", + "input": "ශ්‍රී", + "output": "xn--10cl1a0b660p" + }, + { + "input": "نامه‌ای", + "output": "xn--mgba3gch31f060k" + }, + { + "comment": "U+FFFD", + "input": "\uFFFD.com", + "output": null + }, + { + "comment": "U+FFFD character encoded in Punycode", + "input": "xn--zn7c.com", + "output": null + }, + { + "comment": "Label longer than 63 code points", + "input": "x01234567890123456789012345678901234567890123456789012345678901x", + "output": "x01234567890123456789012345678901234567890123456789012345678901x" + }, + { + "input": "x01234567890123456789012345678901234567890123456789012345678901†", + "output": "xn--x01234567890123456789012345678901234567890123456789012345678901-6963b" + }, + { + "input": "x01234567890123456789012345678901234567890123456789012345678901x.xn--nxa", + "output": "x01234567890123456789012345678901234567890123456789012345678901x.xn--nxa" + }, + { + "input": "x01234567890123456789012345678901234567890123456789012345678901x.β", + "output": "x01234567890123456789012345678901234567890123456789012345678901x.xn--nxa" + }, + { + "comment": "Domain excluding TLD longer than 253 code points", + "input": "01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.x", + "output": "01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.x" + }, + { + "input": "01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.xn--nxa", + "output": "01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.xn--nxa" + }, + { + "input": "01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.β", + "output": "01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.01234567890123456789012345678901234567890123456789.0123456789012345678901234567890123456789012345678.xn--nxa" + } +] diff --git a/test/inspector/global-function.js b/test/inspector/global-function.js new file mode 100644 index 00000000000000..d72bacd7ca9b36 --- /dev/null +++ b/test/inspector/global-function.js @@ -0,0 +1,13 @@ +'use strict'; // eslint-disable-line required-modules +let invocations = 0; +const interval = setInterval(() => {}, 1000); + +global.sum = function() { + const a = 1; + const b = 2; + const c = a + b; + clearInterval(interval); + console.log(invocations++, c); +}; + +console.log('Ready!'); diff --git a/test/inspector/inspector-helper.js b/test/inspector/inspector-helper.js index 755c357077752d..faf932f495367a 100644 --- a/test/inspector/inspector-helper.js +++ b/test/inspector/inspector-helper.js @@ -10,6 +10,7 @@ const url = require('url'); const DEBUG = false; const TIMEOUT = 15 * 1000; const EXPECT_ALIVE_SYMBOL = Symbol('isAlive'); +const DONT_EXPECT_RESPONSE_SYMBOL = Symbol('dontExpectResponse'); const mainScript = path.join(common.fixturesDir, 'loop.js'); function send(socket, message, id, callback) { @@ -183,7 +184,6 @@ TestSession.prototype.processMessage_ = function(message) { this.messagefilter_ && this.messagefilter_(message); const id = message['id']; if (id) { - assert.strictEqual(id, this.expectedId_); this.expectedId_++; if (this.responseCheckers_[id]) { const messageJSON = JSON.stringify(message); @@ -207,16 +207,21 @@ TestSession.prototype.sendAll_ = function(commands, callback) { if (!commands.length) { callback(); } else { - this.lastId_++; + let id = ++this.lastId_; let command = commands[0]; if (command instanceof Array) { - this.responseCheckers_[this.lastId_] = command[1]; + this.responseCheckers_[id] = command[1]; command = command[0]; } if (command instanceof Function) command = command(); - this.messages_[this.lastId_] = command; - send(this.socket_, command, this.lastId_, + if (!command[DONT_EXPECT_RESPONSE_SYMBOL]) { + this.messages_[id] = command; + } else { + id += 100000; + this.lastId_--; + } + send(this.socket_, command, id, () => this.sendAll_(commands.slice(1), callback)); } }; @@ -497,12 +502,13 @@ Harness.prototype.kill = function() { exports.startNodeForInspectorTest = function(callback, inspectorFlags = ['--inspect-brk'], - opt_script_contents) { + scriptContents = '', + scriptFile = mainScript) { const args = [].concat(inspectorFlags); - if (opt_script_contents) { - args.push('-e', opt_script_contents); + if (scriptContents) { + args.push('-e', scriptContents); } else { - args.push(mainScript); + args.push(scriptFile); } const child = spawn(process.execPath, args); @@ -534,3 +540,7 @@ exports.startNodeForInspectorTest = function(callback, exports.mainScriptSource = function() { return fs.readFileSync(mainScript, 'utf8'); }; + +exports.markMessageNoResponse = function(message) { + message[DONT_EXPECT_RESPONSE_SYMBOL] = true; +}; diff --git a/test/inspector/inspector.status b/test/inspector/inspector.status index ed6a782b9031a7..070d817b2c3ab2 100644 --- a/test/inspector/inspector.status +++ b/test/inspector/inspector.status @@ -5,5 +5,6 @@ prefix inspector # sample-test : PASS,FLAKY [true] # This section applies to all platforms +test-inspector-port-zero-cluster : PASS,FLAKY [$system==win32] diff --git a/test/inspector/test-inspector-break-when-eval.js b/test/inspector/test-inspector-break-when-eval.js new file mode 100644 index 00000000000000..388edf6f5c21a7 --- /dev/null +++ b/test/inspector/test-inspector-break-when-eval.js @@ -0,0 +1,128 @@ +'use strict'; +const common = require('../common'); +common.skipIfInspectorDisabled(); +const assert = require('assert'); +const helper = require('./inspector-helper.js'); +const path = require('path'); + +const script = path.join(path.dirname(module.filename), 'global-function.js'); + + +function setupExpectBreakOnLine(line, url, session) { + return function(message) { + if ('Debugger.paused' === message['method']) { + const callFrame = message['params']['callFrames'][0]; + const location = callFrame['location']; + assert.strictEqual(url, session.scriptUrlForId(location['scriptId'])); + assert.strictEqual(line, location['lineNumber']); + return true; + } + }; +} + +function setupExpectConsoleOutputAndBreak(type, values) { + if (!(values instanceof Array)) + values = [ values ]; + let consoleLog = false; + function matchConsoleLog(message) { + if ('Runtime.consoleAPICalled' === message['method']) { + const params = message['params']; + if (params['type'] === type) { + let i = 0; + for (const value of params['args']) { + if (value['value'] !== values[i++]) + return false; + } + return i === values.length; + } + } + } + + return function(message) { + if (consoleLog) + return message['method'] === 'Debugger.paused'; + consoleLog = matchConsoleLog(message); + return false; + }; +} + +function setupExpectContextDestroyed(id) { + return function(message) { + if ('Runtime.executionContextDestroyed' === message['method']) + return message['params']['executionContextId'] === id; + }; +} + +function setupDebugger(session) { + console.log('[test]', 'Setting up a debugger'); + const commands = [ + { 'method': 'Runtime.enable' }, + { 'method': 'Debugger.enable' }, + { 'method': 'Debugger.setAsyncCallStackDepth', + 'params': {'maxDepth': 0} }, + { 'method': 'Runtime.runIfWaitingForDebugger' }, + ]; + + session + .sendInspectorCommands(commands) + .expectMessages((message) => 'Runtime.consoleAPICalled' === message.method); +} + +function breakOnLine(session) { + console.log('[test]', 'Breaking in the code'); + const commands = [ + { 'method': 'Debugger.setBreakpointByUrl', + 'params': { 'lineNumber': 9, + 'url': script, + 'columnNumber': 0, + 'condition': '' + } + }, + { 'method': 'Runtime.evaluate', + 'params': { 'expression': 'sum()', + 'objectGroup': 'console', + 'includeCommandLineAPI': true, + 'silent': false, + 'contextId': 1, + 'returnByValue': false, + 'generatePreview': true, + 'userGesture': true, + 'awaitPromise': false + } + } + ]; + helper.markMessageNoResponse(commands[1]); + session + .sendInspectorCommands(commands) + .expectMessages(setupExpectBreakOnLine(9, script, session)); +} + +function stepOverConsoleStatement(session) { + console.log('[test]', 'Step over console statement and test output'); + session + .sendInspectorCommands({ 'method': 'Debugger.stepOver' }) + .expectMessages(setupExpectConsoleOutputAndBreak('log', [0, 3])); +} + +function testWaitsForFrontendDisconnect(session, harness) { + console.log('[test]', 'Verify node waits for the frontend to disconnect'); + session.sendInspectorCommands({ 'method': 'Debugger.resume'}) + .expectMessages(setupExpectContextDestroyed(1)) + .expectStderrOutput('Waiting for the debugger to disconnect...') + .disconnect(true); +} + +function runTests(harness) { + harness + .runFrontendSession([ + setupDebugger, + breakOnLine, + stepOverConsoleStatement, + testWaitsForFrontendDisconnect + ]).expectShutDown(0); +} + +helper.startNodeForInspectorTest(runTests, + ['--inspect'], + undefined, + script); diff --git a/test/inspector/test-inspector-debug-brk.js b/test/inspector/test-inspector-debug-brk.js index a5cb77250de439..27c9c5fdbc328d 100644 --- a/test/inspector/test-inspector-debug-brk.js +++ b/test/inspector/test-inspector-debug-brk.js @@ -1,6 +1,8 @@ 'use strict'; const common = require('../common'); + common.skipIfInspectorDisabled(); + const assert = require('assert'); const helper = require('./inspector-helper.js'); diff --git a/test/inspector/test-inspector-ip-detection.js b/test/inspector/test-inspector-ip-detection.js index d2d60411894ca8..ad51c631645e4a 100644 --- a/test/inspector/test-inspector-ip-detection.js +++ b/test/inspector/test-inspector-ip-detection.js @@ -1,5 +1,6 @@ 'use strict'; const common = require('../common'); + common.skipIfInspectorDisabled(); const assert = require('assert'); diff --git a/test/inspector/test-inspector-port-zero-cluster.js b/test/inspector/test-inspector-port-zero-cluster.js new file mode 100644 index 00000000000000..4582b4bb38657b --- /dev/null +++ b/test/inspector/test-inspector-port-zero-cluster.js @@ -0,0 +1,34 @@ +// Flags: --inspect=0 +'use strict'; +const common = require('../common'); + +common.skipIfInspectorDisabled(); + +const assert = require('assert'); +const cluster = require('cluster'); + +if (cluster.isMaster) { + const ports = []; + for (const worker of [cluster.fork(), + cluster.fork(), + cluster.fork()]) { + worker.on('message', common.mustCall((message) => { + ports.push(message.debugPort); + worker.kill(); + })); + worker.send('debugPort'); + } + process.on('exit', () => { + ports.sort(); + assert.strictEqual(ports.length, 3); + assert(ports.every((port) => port > 0)); + assert(ports.every((port) => port < 65536)); + assert.strictEqual(ports[0] + 1, ports[1]); // Ports should be consecutive. + assert.strictEqual(ports[1] + 1, ports[2]); + }); +} else { + process.on('message', (message) => { + if (message === 'debugPort') + process.send({ debugPort: process.debugPort }); + }); +} diff --git a/test/inspector/test-inspector-port-zero.js b/test/inspector/test-inspector-port-zero.js new file mode 100644 index 00000000000000..0776c8226530e9 --- /dev/null +++ b/test/inspector/test-inspector-port-zero.js @@ -0,0 +1,48 @@ +'use strict'; +const { mustCall, skipIfInspectorDisabled } = require('../common'); + +skipIfInspectorDisabled(); + +const assert = require('assert'); +const { URL } = require('url'); +const { spawn } = require('child_process'); + +function test(arg) { + const args = [arg, '-p', 'process.debugPort']; + const proc = spawn(process.execPath, args); + proc.stdout.setEncoding('utf8'); + proc.stderr.setEncoding('utf8'); + let stdout = ''; + let stderr = ''; + proc.stdout.on('data', (data) => stdout += data); + proc.stderr.on('data', (data) => stderr += data); + proc.stdout.on('close', assert.ifError); + proc.stderr.on('close', assert.ifError); + let port = ''; + proc.stderr.on('data', () => { + if (!stderr.includes('\n')) return; + assert(/Debugger listening on (.+)/.test(stderr)); + port = new URL(RegExp.$1).port; + assert(+port > 0); + }); + if (/inspect-brk/.test(arg)) { + proc.stderr.on('data', () => { + if (stderr.includes('\n') && !proc.killed) proc.kill(); + }); + } else { + let onclose = () => { + onclose = () => assert.strictEqual(port, stdout.trim()); + }; + proc.stdout.on('close', mustCall(() => onclose())); + proc.stderr.on('close', mustCall(() => onclose())); + proc.on('exit', mustCall((exitCode) => assert.strictEqual(exitCode, 0))); + } +} + +test('--inspect=0'); +test('--inspect=127.0.0.1:0'); +test('--inspect=localhost:0'); + +test('--inspect-brk=0'); +test('--inspect-brk=127.0.0.1:0'); +test('--inspect-brk=localhost:0'); diff --git a/test/inspector/test-inspector-stops-no-file.js b/test/inspector/test-inspector-stops-no-file.js index d0f3a753464096..772063b279f5af 100644 --- a/test/inspector/test-inspector-stops-no-file.js +++ b/test/inspector/test-inspector-stops-no-file.js @@ -1,5 +1,6 @@ 'use strict'; require('../common'); + const spawn = require('child_process').spawn; const child = spawn(process.execPath, diff --git a/test/inspector/test-inspector.js b/test/inspector/test-inspector.js index 9d6bb563e1190a..19eb3601f0fbc7 100644 --- a/test/inspector/test-inspector.js +++ b/test/inspector/test-inspector.js @@ -1,6 +1,8 @@ 'use strict'; const common = require('../common'); + common.skipIfInspectorDisabled(); + const assert = require('assert'); const helper = require('./inspector-helper.js'); diff --git a/test/internet/test-dns.js b/test/internet/test-dns.js index fc001ff96533fc..3096fda5b1ee75 100644 --- a/test/internet/test-dns.js +++ b/test/internet/test-dns.js @@ -492,11 +492,12 @@ TEST(function test_lookupservice_invalid(done) { TEST(function test_reverse_failure(done) { - const req = dns.reverse('0.0.0.0', function(err) { + // 203.0.113.0/24 are addresses reserved for (RFC) documentation use only + const req = dns.reverse('203.0.113.0', function(err) { assert(err instanceof Error); assert.strictEqual(err.code, 'ENOTFOUND'); // Silly error code... - assert.strictEqual(err.hostname, '0.0.0.0'); - assert.ok(/0\.0\.0\.0/.test(err.message)); + assert.strictEqual(err.hostname, '203.0.113.0'); + assert.ok(/203\.0\.113\.0/.test(err.message)); done(); }); diff --git a/test/known_issues/test-http-path-contains-unicode.js b/test/known_issues/test-http-path-contains-unicode.js new file mode 100644 index 00000000000000..8f90a0d57f07b4 --- /dev/null +++ b/test/known_issues/test-http-path-contains-unicode.js @@ -0,0 +1,41 @@ +'use strict'; +const common = require('../common'); + +// This test ensures that Unicode characters in the URL get handled correctly +// by `http` +// Refs: https://github.com/nodejs/node/issues/13296 + +const assert = require('assert'); +const http = require('http'); + +const expected = '/café🐶'; + +assert.strictEqual( + expected, + '/caf\u{e9}\u{1f436}', + 'Sanity check that string literal produced the expected string' +); + +const server = http.createServer(common.mustCall(function(req, res) { + assert.strictEqual(req.url, expected); + req.on('data', common.mustCall(function() { + })).on('end', common.mustCall(function() { + server.close(); + res.writeHead(200); + res.end('hello world\n'); + })); + +})); + +server.listen(0, function() { + http.request({ + port: this.address().port, + path: expected, + method: 'GET' + }, common.mustCall(function(res) { + res.resume(); + })).on('error', function(e) { + console.log(e.message); + process.exit(1); + }).end(); +}); diff --git a/test/parallel/test-assert-deep.js b/test/parallel/test-assert-deep.js index e54377bdbbfeb7..fecb5c89dbe3e7 100644 --- a/test/parallel/test-assert-deep.js +++ b/test/parallel/test-assert-deep.js @@ -158,6 +158,16 @@ assertNotDeepOrStrict(new Set([1, 2, 3, 4]), new Set([1, 2, 3])); assertDeepAndStrictEqual(new Set(['1', '2', '3']), new Set(['1', '2', '3'])); assertDeepAndStrictEqual(new Set([[1, 2], [3, 4]]), new Set([[3, 4], [1, 2]])); +const a = [ 1, 2 ]; +const b = [ 3, 4 ]; +const c = [ 1, 2 ]; +const d = [ 3, 4 ]; + +assertDeepAndStrictEqual( + { a: a, b: b, s: new Set([a, b]) }, + { a: c, b: d, s: new Set([d, c]) } +); + assertDeepAndStrictEqual(new Map([[1, 1], [2, 2]]), new Map([[1, 1], [2, 2]])); assertDeepAndStrictEqual(new Map([[1, 1], [2, 2]]), new Map([[2, 2], [1, 1]])); assertNotDeepOrStrict(new Map([[1, 1], [2, 2]]), new Map([[1, 2], [2, 1]])); @@ -177,6 +187,28 @@ assertOnlyDeepEqual(new Map([['a', '1']]), new Map([['a', 1]])); assertDeepAndStrictEqual(new Set([{}]), new Set([{}])); +// Ref: https://github.com/nodejs/node/issues/13347 +assertNotDeepOrStrict( + new Set([{a: 1}, {a: 1}]), + new Set([{a: 1}, {a: 2}]) +); +assertNotDeepOrStrict( + new Set([{a: 1}, {a: 1}, {a: 2}]), + new Set([{a: 1}, {a: 2}, {a: 2}]) +); +assertNotDeepOrStrict( + new Map([[{x: 1}, 5], [{x: 1}, 5]]), + new Map([[{x: 1}, 5], [{x: 2}, 5]]) +); + +assertNotDeepOrStrict(new Set([3, '3']), new Set([3, 4])); +assertNotDeepOrStrict(new Map([[3, 0], ['3', 0]]), new Map([[3, 0], [4, 0]])); + +assertNotDeepOrStrict( + new Set([{a: 1}, {a: 1}, {a: 2}]), + new Set([{a: 1}, {a: 2}, {a: 2}]) +); + // This is an awful case, where a map contains multiple equivalent keys: assertOnlyDeepEqual( new Map([[1, 'a'], ['1', 'b']]), diff --git a/test/parallel/test-assert.js b/test/parallel/test-assert.js index 4489773a40ea1b..7b492374f0518b 100644 --- a/test/parallel/test-assert.js +++ b/test/parallel/test-assert.js @@ -535,6 +535,18 @@ a.throws(makeBlock(thrower, TypeError), function(err) { a.throws(makeBlock(a.deepEqual, d, e), /AssertionError/); a.throws(makeBlock(a.deepStrictEqual, d, e), /AssertionError/); + + // https://github.com/nodejs/node/issues/13314 + const f = {}; + f.ref = f; + + const g = {}; + g.ref = g; + + const h = {ref: g}; + + a.throws(makeBlock(a.deepEqual, f, h), /AssertionError/); + a.throws(makeBlock(a.deepStrictEqual, f, h), /AssertionError/); } // GH-7178. Ensure reflexivity of deepEqual with `arguments` objects. const args = (function() { return arguments; })(); diff --git a/test/parallel/test-async-hooks-close-during-destroy.js b/test/parallel/test-async-hooks-close-during-destroy.js new file mode 100644 index 00000000000000..98e12e77fbcce1 --- /dev/null +++ b/test/parallel/test-async-hooks-close-during-destroy.js @@ -0,0 +1,37 @@ +'use strict'; +// Test that async ids that are added to the destroy queue while running a +// `destroy` callback are handled correctly. + +const common = require('../common'); +const assert = require('assert'); +const async_hooks = require('async_hooks'); + +const initCalls = new Set(); +let destroyResCallCount = 0; +let res2; + +async_hooks.createHook({ + init: common.mustCallAtLeast((id, provider, triggerId) => { + if (provider === 'foobar') + initCalls.add(id); + }, 2), + destroy: common.mustCallAtLeast((id) => { + if (!initCalls.has(id)) return; + + switch (destroyResCallCount++) { + case 0: + // Trigger the second `destroy` call. + res2.emitDestroy(); + break; + case 2: + assert.fail('More than 2 destroy() invocations'); + break; + } + }, 2) +}).enable(); + +const res1 = new async_hooks.AsyncResource('foobar'); +res2 = new async_hooks.AsyncResource('foobar'); +res1.emitDestroy(); + +process.on('exit', () => assert.strictEqual(destroyResCallCount, 2)); diff --git a/test/parallel/test-async-hooks-http-agent.js b/test/parallel/test-async-hooks-http-agent.js new file mode 100644 index 00000000000000..348b97b111658a --- /dev/null +++ b/test/parallel/test-async-hooks-http-agent.js @@ -0,0 +1,79 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const async_id_symbol = process.binding('async_wrap').async_id_symbol; +const http = require('http'); + +// Regression test for https://github.com/nodejs/node/issues/13325 +// Checks that an http.Agent properly asyncReset()s a reused socket handle, and +// re-assigns the fresh async id to the reused `net.Socket` instance. + +// Make sure a single socket is transpartently reused for 2 requests. +const agent = new http.Agent({ + keepAlive: true, + keepAliveMsecs: Infinity, + maxSockets: 1 +}); + +const server = http.createServer(common.mustCall((req, res) => { + req.once('data', common.mustCallAtLeast(() => { + res.writeHead(200, {'Content-Type': 'text/plain'}); + res.write('foo'); + })); + req.on('end', common.mustCall(() => { + res.end('bar'); + })); +}, 2)).listen(0, common.mustCall(() => { + const port = server.address().port; + const payload = 'hello world'; + + // First request. This is useless except for adding a socket to the + // agent’s pool for reuse. + const r1 = http.request({ + agent, port, method: 'POST' + }, common.mustCall((res) => { + // Remember which socket we used. + const socket = res.socket; + const asyncIdAtFirstRequest = socket[async_id_symbol]; + assert.ok(asyncIdAtFirstRequest > 0, `${asyncIdAtFirstRequest} > 0`); + // Check that request and response share their socket. + assert.strictEqual(r1.socket, socket); + + res.on('data', common.mustCallAtLeast(() => {})); + res.on('end', common.mustCall(() => { + // setImmediate() to give the agent time to register the freed socket. + setImmediate(common.mustCall(() => { + // The socket is free for reuse now. + assert.strictEqual(socket[async_id_symbol], -1); + + // Second request. To re-create the exact conditions from the + // referenced issue, we use a POST request without chunked encoding + // (hence the Content-Length header) and call .end() after the + // response header has already been received. + const r2 = http.request({ + agent, port, method: 'POST', headers: { + 'Content-Length': payload.length + } + }, common.mustCall((res) => { + const asyncId = res.socket[async_id_symbol]; + assert.ok(asyncId > 0, `${asyncId} > 0`); + assert.strictEqual(r2.socket, socket); + // Empty payload, to hit the “right” code path. + r2.end(''); + + res.on('data', common.mustCallAtLeast(() => {})); + res.on('end', common.mustCall(() => { + // Clean up to let the event loop stop. + server.close(); + agent.destroy(); + })); + })); + + // Schedule a payload to be written immediately, but do not end the + // request just yet. + r2.write(payload); + })); + })); + })); + r1.end(payload); +})); diff --git a/test/parallel/test-async-hooks-run-in-async-id-scope.js b/test/parallel/test-async-hooks-run-in-async-id-scope.js new file mode 100644 index 00000000000000..a283e9c30924be --- /dev/null +++ b/test/parallel/test-async-hooks-run-in-async-id-scope.js @@ -0,0 +1,13 @@ +'use strict'; + +const common = require('../common'); +const assert = require('assert'); +const async_hooks = require('async_hooks'); + +const asyncId = async_hooks.newUid(); + +assert.notStrictEqual(async_hooks.currentId(), asyncId); + +async_hooks.runInAsyncIdScope(asyncId, common.mustCall(() => { + assert.strictEqual(async_hooks.currentId(), asyncId); +})); diff --git a/test/parallel/test-async-hooks-top-level-clearimmediate.js b/test/parallel/test-async-hooks-top-level-clearimmediate.js new file mode 100644 index 00000000000000..f667c3ca337816 --- /dev/null +++ b/test/parallel/test-async-hooks-top-level-clearimmediate.js @@ -0,0 +1,27 @@ +'use strict'; + +// Regression test for https://github.com/nodejs/node/issues/13262 + +const common = require('../common'); +const assert = require('assert'); +const async_hooks = require('async_hooks'); + +let seenId, seenResource; + +async_hooks.createHook({ + init: common.mustCall((id, provider, triggerId, resource) => { + seenId = id; + seenResource = resource; + assert.strictEqual(provider, 'Immediate'); + assert.strictEqual(triggerId, 1); + }), + before: common.mustNotCall(), + after: common.mustNotCall(), + destroy: common.mustCall((id) => { + assert.strictEqual(seenId, id); + }) +}).enable(); + +const immediate = setImmediate(common.mustNotCall()); +assert.strictEqual(immediate, seenResource); +clearImmediate(immediate); diff --git a/test/parallel/test-async-wrap-trigger-id.js b/test/parallel/test-async-wrap-trigger-id.js new file mode 100644 index 00000000000000..53e84a351eed62 --- /dev/null +++ b/test/parallel/test-async-wrap-trigger-id.js @@ -0,0 +1,28 @@ +'use strict'; +require('../common'); + +const assert = require('assert'); +const async_hooks = require('async_hooks'); +const triggerId = async_hooks.triggerId; + +const triggerId0 = triggerId(); +let triggerId1; + +process.nextTick(() => { + process.nextTick(() => { + triggerId1 = triggerId(); + assert.notStrictEqual( + triggerId0, + triggerId1, + 'Async resources having different causal ancestry ' + + 'should have different triggerIds'); + }); + process.nextTick(() => { + const triggerId2 = triggerId(); + assert.strictEqual( + triggerId1, + triggerId2, + 'Async resources having the same causal ancestry ' + + 'should have the same triggerId'); + }); +}); diff --git a/test/parallel/test-cluster-inspector-debug-port.js b/test/parallel/test-cluster-inspector-debug-port.js index 2b214c4ad26bd8..a049da78be0f70 100644 --- a/test/parallel/test-cluster-inspector-debug-port.js +++ b/test/parallel/test-cluster-inspector-debug-port.js @@ -1,7 +1,9 @@ 'use strict'; // Flags: --inspect={PORT} const common = require('../common'); + common.skipIfInspectorDisabled(); + const assert = require('assert'); const cluster = require('cluster'); const debuggerPort = common.PORT; diff --git a/test/parallel/test-crypto-dh.js b/test/parallel/test-crypto-dh.js index fed392cd9f0ba3..285f35b830a2f6 100644 --- a/test/parallel/test-crypto-dh.js +++ b/test/parallel/test-crypto-dh.js @@ -172,6 +172,7 @@ assert.strictEqual(bad_dh.verifyError, DH_NOT_SUITABLE_GENERATOR); const availableCurves = new Set(crypto.getCurves()); +const availableHashes = new Set(crypto.getHashes()); // Oakley curves do not clean up ERR stack, it was causing unexpected failure // when accessing other OpenSSL APIs afterwards. @@ -307,6 +308,28 @@ if (availableCurves.has('prime256v1') && availableCurves.has('secp256k1')) { }); } +// Use of invalid keys was not cleaning up ERR stack, and was causing +// unexpected failure in subsequent signing operations. +if (availableCurves.has('prime256v1') && availableHashes.has('sha256')) { + const curve = crypto.createECDH('prime256v1'); + const invalidKey = Buffer.alloc(65); + invalidKey.fill('\0'); + curve.generateKeys(); + assert.throws(() => { + curve.computeSecret(invalidKey); + }, /^Error: Failed to translate Buffer to a EC_POINT$/); + // Check that signing operations are not impacted by the above error. + const ecPrivateKey = + '-----BEGIN EC PRIVATE KEY-----\n' + + 'MHcCAQEEIF+jnWY1D5kbVYDNvxxo/Y+ku2uJPDwS0r/VuPZQrjjVoAoGCCqGSM49\n' + + 'AwEHoUQDQgAEurOxfSxmqIRYzJVagdZfMMSjRNNhB8i3mXyIMq704m2m52FdfKZ2\n' + + 'pQhByd5eyj3lgZ7m7jbchtdgyOF8Io/1ng==\n' + + '-----END EC PRIVATE KEY-----'; + assert.doesNotThrow(() => { + crypto.createSign('SHA256').sign(ecPrivateKey); + }); +} + // invalid test: curve argument is undefined assert.throws(() => { crypto.createECDH(); diff --git a/test/parallel/test-dgram-oob-buffer.js b/test/parallel/test-dgram-oob-buffer.js index 136d378bbb9a46..1e71815927baca 100644 --- a/test/parallel/test-dgram-oob-buffer.js +++ b/test/parallel/test-dgram-oob-buffer.js @@ -31,14 +31,14 @@ const socket = dgram.createSocket('udp4'); const buf = Buffer.from([1, 2, 3, 4]); const portGetter = dgram.createSocket('udp4') .bind(0, 'localhost', common.mustCall(() => { - const address = portGetter.address(); + const { address, port } = portGetter.address(); portGetter.close(common.mustCall(() => { - socket.send(buf, 0, 0, address.port, address.address, common.noop); - socket.send(buf, 0, 4, address.port, address.address, common.noop); - socket.send(buf, 1, 3, address.port, address.address, common.noop); - socket.send(buf, 3, 1, address.port, address.address, common.noop); + socket.send(buf, 0, 0, port, address, common.mustNotCall()); + socket.send(buf, 0, 4, port, address, common.mustNotCall()); + socket.send(buf, 1, 3, port, address, common.mustNotCall()); + socket.send(buf, 3, 1, port, address, common.mustNotCall()); // Since length of zero means nothing, don't error despite OOB. - socket.send(buf, 4, 0, address.port, address.address, common.noop); + socket.send(buf, 4, 0, port, address, common.mustNotCall()); socket.close(); })); diff --git a/test/parallel/test-fs-promisified.js b/test/parallel/test-fs-promisified.js index 12bd5d6fa1f954..ac6e22f9690821 100644 --- a/test/parallel/test-fs-promisified.js +++ b/test/parallel/test-fs-promisified.js @@ -9,6 +9,7 @@ common.crashOnUnhandledRejection(); const read = promisify(fs.read); const write = promisify(fs.write); +const exists = promisify(fs.exists); { const fd = fs.openSync(__filename, 'r'); @@ -29,3 +30,9 @@ common.refreshTmpDir(); fs.closeSync(fd); })); } + +{ + exists(__filename).then(common.mustCall((x) => { + assert.strictEqual(x, true); + })); +} diff --git a/test/parallel/test-fs-stat.js b/test/parallel/test-fs-stat.js index 6ed27806b9343c..c12af535fa837e 100644 --- a/test/parallel/test-fs-stat.js +++ b/test/parallel/test-fs-stat.js @@ -65,38 +65,55 @@ fs.open('.', 'r', undefined, common.mustCall(function(err, fd) { assert.fail(err); } if (stats) { - console.dir(stats); assert.ok(stats.mtime instanceof Date); } fs.close(fd, assert.ifError); })); -console.log(`stating: ${__filename}`); fs.stat(__filename, common.mustCall(function(err, s) { assert.ifError(err); - - console.dir(s); - - console.log(`isDirectory: ${JSON.stringify(s.isDirectory())}`); assert.strictEqual(false, s.isDirectory()); - - console.log(`isFile: ${JSON.stringify(s.isFile())}`); assert.strictEqual(true, s.isFile()); - - console.log(`isSocket: ${JSON.stringify(s.isSocket())}`); assert.strictEqual(false, s.isSocket()); - - console.log(`isBlockDevice: ${JSON.stringify(s.isBlockDevice())}`); assert.strictEqual(false, s.isBlockDevice()); - - console.log(`isCharacterDevice: ${JSON.stringify(s.isCharacterDevice())}`); assert.strictEqual(false, s.isCharacterDevice()); - - console.log(`isFIFO: ${JSON.stringify(s.isFIFO())}`); assert.strictEqual(false, s.isFIFO()); - - console.log(`isSymbolicLink: ${JSON.stringify(s.isSymbolicLink())}`); assert.strictEqual(false, s.isSymbolicLink()); - - assert.ok(s.mtime instanceof Date); + const keys = [ + 'dev', 'mode', 'nlink', 'uid', + 'gid', 'rdev', 'ino', 'size', + 'atime', 'mtime', 'ctime', 'birthtime', + 'atimeMs', 'mtimeMs', 'ctimeMs', 'birthtimeMs' + ]; + if (!common.isWindows) { + keys.push('blocks', 'blksize'); + } + const numberFields = [ + 'dev', 'mode', 'nlink', 'uid', 'gid', 'rdev', 'ino', 'size', + 'atimeMs', 'mtimeMs', 'ctimeMs', 'birthtimeMs' + ]; + const dateFields = ['atime', 'mtime', 'ctime', 'birthtime']; + keys.forEach(function(k) { + assert.ok(k in s, `${k} should be in Stats`); + assert.notStrictEqual(s[k], undefined, `${k} should not be undefined`); + assert.notStrictEqual(s[k], null, `${k} should not be null`); + }); + numberFields.forEach((k) => { + assert.strictEqual(typeof s[k], 'number', `${k} should be a number`); + }); + dateFields.forEach((k) => { + assert.ok(s[k] instanceof Date, `${k} should be a Date`); + }); + const jsonString = JSON.stringify(s); + const parsed = JSON.parse(jsonString); + keys.forEach(function(k) { + assert.notStrictEqual(parsed[k], undefined, `${k} should not be undefined`); + assert.notStrictEqual(parsed[k], null, `${k} should not be null`); + }); + numberFields.forEach((k) => { + assert.strictEqual(typeof parsed[k], 'number', `${k} should be a number`); + }); + dateFields.forEach((k) => { + assert.strictEqual(typeof parsed[k], 'string', `${k} should be a string`); + }); })); diff --git a/test/parallel/test-fs-watch.js b/test/parallel/test-fs-watch.js new file mode 100644 index 00000000000000..6edb141129975c --- /dev/null +++ b/test/parallel/test-fs-watch.js @@ -0,0 +1,77 @@ +'use strict'; +const common = require('../common'); + +// tests if `filename` is provided to watcher on supported platforms + +const fs = require('fs'); +const assert = require('assert'); +const { join } = require('path'); + +class WatchTestCase { + constructor(shouldInclude, dirName, fileName, field) { + this.dirName = dirName; + this.fileName = fileName; + this.field = field; + this.shouldSkip = !shouldInclude; + } + get dirPath() { return join(common.tmpDir, this.dirName); } + get filePath() { return join(this.dirPath, this.fileName); } +} + +const cases = [ + // Watch on a directory should callback with a filename on supported systems + new WatchTestCase( + common.isLinux || common.isOSX || common.isWindows || common.isAix, + 'watch1', + 'foo', + 'filePath' + ), + // Watch on a file should callback with a filename on supported systems + new WatchTestCase( + common.isLinux || common.isOSX || common.isWindows, + 'watch2', + 'bar', + 'dirPath' + ) +]; + +common.refreshTmpDir(); + +for (const testCase of cases) { + if (testCase.shouldSkip) continue; + fs.mkdirSync(testCase.dirPath); + // long content so it's actually flushed. + const content1 = Date.now() + testCase.fileName.toLowerCase().repeat(1e4); + fs.writeFileSync(testCase.filePath, content1); + + let interval; + const watcher = fs.watch(testCase[testCase.field]); + watcher.on('error', (err) => { + if (interval) { + clearInterval(interval); + interval = null; + } + assert.fail(err); + }); + watcher.on('change', common.mustCall(function(eventType, argFilename) { + if (interval) { + clearInterval(interval); + interval = null; + } + if (common.isOSX) + assert.strictEqual(['rename', 'change'].includes(eventType), true); + else + assert.strictEqual(eventType, 'change'); + assert.strictEqual(argFilename, testCase.fileName); + + // end of test case + watcher.close(); + })); + + // long content so it's actually flushed. toUpperCase so there's real change. + const content2 = Date.now() + testCase.fileName.toUpperCase().repeat(1e4); + interval = setInterval(() => { + fs.writeFileSync(testCase.filePath, ''); + fs.writeFileSync(testCase.filePath, content2); + }, 100); +} diff --git a/test/parallel/test-fs-watchfile.js b/test/parallel/test-fs-watchfile.js index fe22f93a10e044..fb87b1ee87a0fb 100644 --- a/test/parallel/test-fs-watchfile.js +++ b/test/parallel/test-fs-watchfile.js @@ -64,20 +64,24 @@ fs.watchFile(enoentFile, {interval: 0}, common.mustCall(function(curr, prev) { } }, 2)); -// Watch events should callback with a filename on supported systems -if (common.isLinux || common.isOSX || common.isWindows || common.isAix) { +// Watch events should callback with a filename on supported systems. +// Omitting AIX. It works but not reliably. +if (common.isLinux || common.isOSX || common.isWindows) { const dir = common.tmpDir + '/watch'; fs.mkdir(dir, common.mustCall(function(err) { if (err) assert.fail(err); fs.watch(dir, common.mustCall(function(eventType, filename) { + clearInterval(interval); this._handle.close(); assert.strictEqual(filename, 'foo.txt'); })); - fs.writeFile(`${dir}/foo.txt`, 'foo', common.mustCall(function(err) { - if (err) assert.fail(err); - })); + const interval = setInterval(() => { + fs.writeFile(`${dir}/foo.txt`, 'foo', common.mustCall(function(err) { + if (err) assert.fail(err); + })); + }, 1); })); } diff --git a/test/disabled/test-http-abort-stream-end.js b/test/parallel/test-http-abort-stream-end.js similarity index 84% rename from test/disabled/test-http-abort-stream-end.js rename to test/parallel/test-http-abort-stream-end.js index f754e60300ff62..8f89aeffff2cd0 100644 --- a/test/disabled/test-http-abort-stream-end.js +++ b/test/parallel/test-http-abort-stream-end.js @@ -20,27 +20,27 @@ // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; -const common = require('../common'); +require('../common'); const assert = require('assert'); const http = require('http'); -var maxSize = 1024; -var size = 0; +const maxSize = 1024; +let size = 0; -var s = http.createServer(function(req, res) { +const s = http.createServer(function(req, res) { this.close(); res.writeHead(200, {'Content-Type': 'text/plain'}); - for (var i = 0; i < maxSize; i++) { + for (let i = 0; i < maxSize; i++) { res.write('x' + i); } res.end(); }); -var aborted = false; -s.listen(common.PORT, function() { - var req = http.get('http://localhost:' + common.PORT, function(res) { +let aborted = false; +s.listen(0, function() { + const req = http.get('http://localhost:' + s.address().port, function(res) { res.on('data', function(chunk) { size += chunk.length; assert(!aborted, 'got data after abort'); @@ -51,8 +51,6 @@ s.listen(common.PORT, function() { } }); }); - - req.end(); }); process.on('exit', function() { diff --git a/test/parallel/test-http-keepalive-override.js b/test/parallel/test-http-keepalive-override.js new file mode 100644 index 00000000000000..d25fc319747ad2 --- /dev/null +++ b/test/parallel/test-http-keepalive-override.js @@ -0,0 +1,67 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); + +const http = require('http'); + +const server = http.createServer((req, res) => { + res.end('ok'); +}).listen(0, common.mustCall(() => { + const agent = http.Agent({ + keepAlive: true, + maxSockets: 5, + maxFreeSockets: 2 + }); + + const keepSocketAlive = agent.keepSocketAlive; + const reuseSocket = agent.reuseSocket; + + let called = 0; + let expectedSocket; + agent.keepSocketAlive = common.mustCall((socket) => { + assert(socket); + + called++; + if (called === 1) { + return false; + } else if (called === 2) { + expectedSocket = socket; + return keepSocketAlive.call(agent, socket); + } + + assert.strictEqual(socket, expectedSocket); + return false; + }, 3); + + agent.reuseSocket = common.mustCall((socket, req) => { + assert.strictEqual(socket, expectedSocket); + assert(req); + + return reuseSocket.call(agent, socket, req); + }, 1); + + function req(callback) { + http.request({ + method: 'GET', + path: '/', + agent, + port: server.address().port + }, common.mustCall((res) => { + res.resume(); + res.once('end', common.mustCall(() => { + setImmediate(callback); + })); + })).end(); + } + + // Should destroy socket instead of keeping it alive + req(common.mustCall(() => { + // Should keep socket alive + req(common.mustCall(() => { + // Should reuse the socket + req(common.mustCall(() => { + server.close(); + })); + })); + })); +})); diff --git a/test/parallel/test-https-server-keep-alive-timeout.js b/test/parallel/test-https-server-keep-alive-timeout.js index 87ce973ac6d09a..d1e9ed67889ac6 100644 --- a/test/parallel/test-https-server-keep-alive-timeout.js +++ b/test/parallel/test-https-server-keep-alive-timeout.js @@ -1,6 +1,10 @@ 'use strict'; const common = require('../common'); +if (!common.hasCrypto) { + common.skip('missing crypto'); + return; +} const assert = require('assert'); const https = require('https'); const tls = require('tls'); @@ -26,24 +30,20 @@ function run() { } test(function serverKeepAliveTimeoutWithPipeline(cb) { - let socket; - let destroyedSockets = 0; - let timeoutCount = 0; let requestCount = 0; process.on('exit', function() { - assert.strictEqual(timeoutCount, 1); assert.strictEqual(requestCount, 3); - assert.strictEqual(destroyedSockets, 1); }); const server = https.createServer(serverOptions, (req, res) => { - socket = req.socket; requestCount++; res.end(); }); - server.setTimeout(200, (socket) => { - timeoutCount++; + server.setTimeout(500, common.mustCall((socket) => { + // End this test and call `run()` for the next test (if any). socket.destroy(); - }); + server.close(); + cb(); + })); server.keepAliveTimeout = 50; server.listen(0, common.mustCall(() => { const options = { @@ -56,32 +56,23 @@ test(function serverKeepAliveTimeoutWithPipeline(cb) { c.write('GET /2 HTTP/1.1\r\nHost: localhost\r\n\r\n'); c.write('GET /3 HTTP/1.1\r\nHost: localhost\r\n\r\n'); }); - setTimeout(() => { - server.close(); - if (socket.destroyed) destroyedSockets++; - cb(); - }, 1000); })); }); test(function serverNoEndKeepAliveTimeoutWithPipeline(cb) { - let socket; - let destroyedSockets = 0; - let timeoutCount = 0; let requestCount = 0; process.on('exit', () => { - assert.strictEqual(timeoutCount, 1); assert.strictEqual(requestCount, 3); - assert.strictEqual(destroyedSockets, 1); }); const server = https.createServer(serverOptions, (req, res) => { - socket = req.socket; requestCount++; }); - server.setTimeout(200, (socket) => { - timeoutCount++; + server.setTimeout(500, common.mustCall((socket) => { + // End this test and call `run()` for the next test (if any). socket.destroy(); - }); + server.close(); + cb(); + })); server.keepAliveTimeout = 50; server.listen(0, common.mustCall(() => { const options = { @@ -94,10 +85,5 @@ test(function serverNoEndKeepAliveTimeoutWithPipeline(cb) { c.write('GET /2 HTTP/1.1\r\nHost: localhost\r\n\r\n'); c.write('GET /3 HTTP/1.1\r\nHost: localhost\r\n\r\n'); }); - setTimeout(() => { - server.close(); - if (socket && socket.destroyed) destroyedSockets++; - cb(); - }, 1000); })); }); diff --git a/test/parallel/test-icu-punycode.js b/test/parallel/test-icu-punycode.js index ba2014bdc85a2f..13db2dd7bacede 100644 --- a/test/parallel/test-icu-punycode.js +++ b/test/parallel/test-icu-punycode.js @@ -10,9 +10,10 @@ const icu = process.binding('icu'); const assert = require('assert'); const tests = require('../fixtures/url-idna.js'); +const wptToASCIITests = require('../fixtures/url-toascii.js'); { - for (const [i, { ascii, unicode }] of tests.valid.entries()) { + for (const [i, { ascii, unicode }] of tests.entries()) { assert.strictEqual(ascii, icu.toASCII(unicode), `toASCII(${i + 1})`); assert.strictEqual(unicode, icu.toUnicode(ascii), `toUnicode(${i + 1})`); assert.strictEqual(ascii, icu.toASCII(icu.toUnicode(ascii)), @@ -23,13 +24,24 @@ const tests = require('../fixtures/url-idna.js'); } { - for (const [i, url] of tests.invalid.entries()) { - assert.throws(() => icu.toASCII(url), - /^Error: Cannot convert name to ASCII$/, - `ToASCII invalid case ${i + 1}`); - assert.doesNotThrow(() => icu.toASCII(url, true), - `ToASCII invalid case ${i + 1} in lenient mode`); - assert.doesNotThrow(() => icu.toUnicode(url), - `ToUnicode invalid case ${i + 1}`); + for (const [i, test] of wptToASCIITests.entries()) { + if (typeof test === 'string') + continue; // skip comments + const { comment, input, output } = test; + let caseComment = `case ${i + 1}`; + if (comment) + caseComment += ` (${comment})`; + if (output === null) { + assert.throws(() => icu.toASCII(input), + /^Error: Cannot convert name to ASCII$/, + `ToASCII ${caseComment}`); + assert.doesNotThrow(() => icu.toASCII(input, true), + `ToASCII ${caseComment} in lenient mode`); + } else { + assert.strictEqual(icu.toASCII(input), output, `ToASCII ${caseComment}`); + assert.strictEqual(icu.toASCII(input, true), output, + `ToASCII ${caseComment} in lenient mode`); + } + assert.doesNotThrow(() => icu.toUnicode(input), `ToUnicode ${caseComment}`); } } diff --git a/test/parallel/test-inspector-invalid-args.js b/test/parallel/test-inspector-invalid-args.js index 6e249470230abb..80473a568cacd8 100644 --- a/test/parallel/test-inspector-invalid-args.js +++ b/test/parallel/test-inspector-invalid-args.js @@ -1,11 +1,12 @@ 'use strict'; +const common = require('../common'); + +common.skipIfInspectorDisabled(); + const assert = require('assert'); const execFile = require('child_process').execFile; const path = require('path'); -const common = require('../common'); -common.skipIfInspectorDisabled(); - const mainScript = path.join(common.fixturesDir, 'loop.js'); const expected = '`node --debug` and `node --debug-brk` are invalid. ' + diff --git a/test/parallel/test-inspector-open.js b/test/parallel/test-inspector-open.js new file mode 100644 index 00000000000000..bc7d15a554aa06 --- /dev/null +++ b/test/parallel/test-inspector-open.js @@ -0,0 +1,104 @@ +'use strict'; +const common = require('../common'); + +// Test inspector open()/close()/url() API. It uses ephemeral ports so can be +// run safely in parallel. + +const assert = require('assert'); +const fork = require('child_process').fork; +const net = require('net'); +const url = require('url'); + +common.skipIfInspectorDisabled(); + +if (process.env.BE_CHILD) + return beChild(); + +const child = fork(__filename, {env: {BE_CHILD: 1}}); + +child.once('message', common.mustCall((msg) => { + assert.strictEqual(msg.cmd, 'started'); + + child.send({cmd: 'open', args: [0]}); + child.once('message', common.mustCall(firstOpen)); +})); + +let firstPort; + +function firstOpen(msg) { + assert.strictEqual(msg.cmd, 'url'); + const port = url.parse(msg.url).port; + ping(port, (err) => { + assert.ifError(err); + // Inspector is already open, and won't be reopened, so args don't matter. + child.send({cmd: 'open', args: []}); + child.once('message', common.mustCall(tryToOpenWhenOpen)); + firstPort = port; + }); +} + +function tryToOpenWhenOpen(msg) { + assert.strictEqual(msg.cmd, 'url'); + const port = url.parse(msg.url).port; + // Reopen didn't do anything, the port was already open, and has not changed. + assert.strictEqual(port, firstPort); + ping(port, (err) => { + assert.ifError(err); + child.send({cmd: 'close'}); + child.once('message', common.mustCall(closeWhenOpen)); + }); +} + +function closeWhenOpen(msg) { + assert.strictEqual(msg.cmd, 'url'); + assert.strictEqual(msg.url, undefined); + ping(firstPort, (err) => { + assert(err); + child.send({cmd: 'close'}); + child.once('message', common.mustCall(tryToCloseWhenClosed)); + }); +} + +function tryToCloseWhenClosed(msg) { + assert.strictEqual(msg.cmd, 'url'); + assert.strictEqual(msg.url, undefined); + child.send({cmd: 'open', args: []}); + child.once('message', common.mustCall(reopenAfterClose)); +} + +function reopenAfterClose(msg) { + assert.strictEqual(msg.cmd, 'url'); + const port = url.parse(msg.url).port; + assert.notStrictEqual(port, firstPort); + ping(port, (err) => { + assert.ifError(err); + process.exit(); + }); +} + +function ping(port, callback) { + net.connect(port) + .on('connect', function() { close(this); }) + .on('error', function(err) { close(this, err); }); + + function close(self, err) { + self.end(); + self.on('close', () => callback(err)); + } +} + +function beChild() { + const inspector = require('inspector'); + + process.send({cmd: 'started'}); + + process.on('message', (msg) => { + if (msg.cmd === 'open') { + inspector.open(...msg.args); + } + if (msg.cmd === 'close') { + inspector.close(); + } + process.send({cmd: 'url', url: inspector.url()}); + }); +} diff --git a/test/parallel/test-module-loading-error.js b/test/parallel/test-module-loading-error.js index fb8ddf5a66b794..5cdf9182608632 100644 --- a/test/parallel/test-module-loading-error.js +++ b/test/parallel/test-module-loading-error.js @@ -22,23 +22,38 @@ 'use strict'; const common = require('../common'); const assert = require('assert'); +const { execSync } = require('child_process'); -const error_desc = { +const errorMessagesByPlatform = { win32: ['%1 is not a valid Win32 application'], linux: ['file too short', 'Exec format error'], sunos: ['unknown file type', 'not an ELF file'], darwin: ['file too short'] }; -const dlerror_msg = error_desc[process.platform]; +// If we don't know a priori what the error would be, we accept anything. +const errorMessages = errorMessagesByPlatform[process.platform] || ['']; + +// On Windows, error messages are MUI dependent +// Ref: https://github.com/nodejs/node/issues/13376 +let localeOk = true; +if (common.isWindows) { + const powerShellFindMUI = + 'powershell -NoProfile -ExecutionPolicy Unrestricted -c ' + + '"(Get-UICulture).TwoLetterISOLanguageName"'; + try { + // If MUI != 'en' we'll ignore the content of the message + localeOk = execSync(powerShellFindMUI).toString('utf8').trim() === 'en'; + } catch (_) { + // It's only a best effort try to find the MUI + } +} assert.throws( () => { require('../fixtures/module-loading-error.node'); }, (e) => { - if (dlerror_msg && !dlerror_msg.some((msg) => e.message.includes(msg))) - return false; - if (e.name !== 'Error') + if (localeOk && !errorMessages.some((msg) => e.message.includes(msg))) return false; - return true; + return e.name === 'Error'; } ); diff --git a/test/parallel/test-net-server-bind.js b/test/parallel/test-net-server-bind.js deleted file mode 100644 index d27644200660df..00000000000000 --- a/test/parallel/test-net-server-bind.js +++ /dev/null @@ -1,86 +0,0 @@ -'use strict'; -const common = require('../common'); -const assert = require('assert'); -const net = require('net'); - - -// With only a callback, server should get a port assigned by the OS - -let address0; -const server0 = net.createServer(common.noop); - -server0.listen(function() { - address0 = server0.address(); - console.log('address0 %j', address0); - server0.close(); -}); - - -// No callback to listen(), assume we can bind in 100 ms - -let address1; -let connectionKey1; -const server1 = net.createServer(common.noop); - -server1.listen(common.PORT); - -setTimeout(function() { - address1 = server1.address(); - connectionKey1 = server1._connectionKey; - console.log('address1 %j', address1); - server1.close(); -}, 100); - - -// Callback to listen() - -let address2; -const server2 = net.createServer(common.noop); - -server2.listen(common.PORT + 1, function() { - address2 = server2.address(); - console.log('address2 %j', address2); - server2.close(); -}); - - -// Backlog argument - -let address3; -const server3 = net.createServer(common.noop); - -server3.listen(common.PORT + 2, '0.0.0.0', 127, function() { - address3 = server3.address(); - console.log('address3 %j', address3); - server3.close(); -}); - - -// Backlog argument without host argument - -let address4; -const server4 = net.createServer(common.noop); - -server4.listen(common.PORT + 3, 127, function() { - address4 = server4.address(); - console.log('address4 %j', address4); - server4.close(); -}); - - -process.on('exit', function() { - assert.ok(address0.port > 100); - assert.strictEqual(common.PORT, address1.port); - - let expectedConnectionKey1; - - if (address1.family === 'IPv6') - expectedConnectionKey1 = `6::::${address1.port}`; - else - expectedConnectionKey1 = `4:0.0.0.0:${address1.port}`; - - assert.strictEqual(connectionKey1, expectedConnectionKey1); - assert.strictEqual(common.PORT + 1, address2.port); - assert.strictEqual(common.PORT + 2, address3.port); - assert.strictEqual(common.PORT + 3, address4.port); -}); diff --git a/test/parallel/test-process-versions.js b/test/parallel/test-process-versions.js index fdbe6e0db2e601..4da16379d5b3fe 100644 --- a/test/parallel/test-process-versions.js +++ b/test/parallel/test-process-versions.js @@ -26,5 +26,5 @@ assert(/^\d+\.\d+\.\d+(-.*)?$/.test(process.versions.http_parser)); assert(/^\d+\.\d+\.\d+(-.*)?$/.test(process.versions.node)); assert(/^\d+\.\d+\.\d+(-.*)?$/.test(process.versions.uv)); assert(/^\d+\.\d+\.\d+(-.*)?$/.test(process.versions.zlib)); -assert(/^\d+\.\d+\.\d+(\.\d+)?$/.test(process.versions.v8)); +assert(/^\d+\.\d+\.\d+(\.\d+)?( \(candidate\))?$/.test(process.versions.v8)); assert(/^\d+$/.test(process.versions.modules)); diff --git a/test/parallel/test-readline-interface.js b/test/parallel/test-readline-interface.js index 86c102c45f1107..6f8849a322618a 100644 --- a/test/parallel/test-readline-interface.js +++ b/test/parallel/test-readline-interface.js @@ -564,7 +564,7 @@ function isWarned(emitter) { }); const rl = readline.createInterface({ - input: new Readable({ read: common.noop }), + input: new Readable({ read: common.mustCall() }), output: output, prompt: '$ ', terminal: terminal diff --git a/test/parallel/test-readline-set-raw-mode.js b/test/parallel/test-readline-set-raw-mode.js index db42a5a9495a9e..ddffd131d0baff 100644 --- a/test/parallel/test-readline-set-raw-mode.js +++ b/test/parallel/test-readline-set-raw-mode.js @@ -74,6 +74,8 @@ assert(!rawModeCalled); assert(resumeCalled); assert(!pauseCalled); +// One data listener for the keypress events. +assert.strictEqual(stream.listeners('data').length, 1); // close() should call setRawMode(false) expectedRawMode = false; @@ -86,5 +88,5 @@ assert(!resumeCalled); assert(pauseCalled); assert.deepStrictEqual(stream.listeners('keypress'), []); -// one data listener for the keypress events. -assert.strictEqual(stream.listeners('data').length, 1); +// Data listener is removed once interface is closed. +assert.strictEqual(stream.listeners('data').length, 0); diff --git a/test/parallel/test-socket-write-after-fin.js b/test/parallel/test-socket-write-after-fin.js index c8ff56871734af..2551d3f54f651f 100644 --- a/test/parallel/test-socket-write-after-fin.js +++ b/test/parallel/test-socket-write-after-fin.js @@ -2,7 +2,7 @@ const common = require('../common'); const assert = require('assert'); const net = require('net'); -const expected = 'hello1hello2hello3\nTHUNDERMUSCLE!'; +const expected = 'hello1hello2hello3\nbye'; const server = net.createServer({ allowHalfOpen: true @@ -35,5 +35,6 @@ server.listen(0, common.mustCall(function() { sock.write('hello1'); sock.write('hello2'); sock.write('hello3\n'); - sock.end('THUNDERMUSCLE!'); + assert.strictEqual(sock.end('bye'), sock); + })); diff --git a/test/parallel/test-stream2-objects.js b/test/parallel/test-stream2-objects.js index 159286a4322257..6894d4b9171411 100644 --- a/test/parallel/test-stream2-objects.js +++ b/test/parallel/test-stream2-objects.js @@ -76,7 +76,7 @@ function toArray(callback) { function fromArray(list) { const r = new Readable({ objectMode: true }); - r._read = common.noop; + r._read = common.mustNotCall(); list.forEach(function(chunk) { r.push(chunk); }); @@ -164,7 +164,7 @@ test('can read strings as objects', function(t) { const r = new Readable({ objectMode: true }); - r._read = common.noop; + r._read = common.mustNotCall(); const list = ['one', 'two', 'three']; list.forEach(function(str) { r.push(str); @@ -182,7 +182,7 @@ test('read(0) for object streams', function(t) { const r = new Readable({ objectMode: true }); - r._read = common.noop; + r._read = common.mustNotCall(); r.push('foobar'); r.push(null); @@ -198,7 +198,7 @@ test('falsey values', function(t) { const r = new Readable({ objectMode: true }); - r._read = common.noop; + r._read = common.mustNotCall(); r.push(false); r.push(0); @@ -249,7 +249,7 @@ test('high watermark push', function(t) { highWaterMark: 6, objectMode: true }); - r._read = common.noop; + r._read = common.mustNotCall(); for (let i = 0; i < 6; i++) { const bool = r.push(i); assert.strictEqual(bool, i !== 5); diff --git a/test/parallel/test-ttywrap-invalid-fd.js b/test/parallel/test-ttywrap-invalid-fd.js index b78bc689b23755..2f3dc778a09668 100644 --- a/test/parallel/test-ttywrap-invalid-fd.js +++ b/test/parallel/test-ttywrap-invalid-fd.js @@ -1,14 +1,17 @@ 'use strict'; - const common = require('../common'); const assert = require('assert'); const fs = require('fs'); const tty = require('tty'); - assert.throws(() => { new tty.WriteStream(-1); -}, /fd must be positive integer:/); +}, common.expectsError({ + code: 'ERR_INVALID_FD', + type: RangeError, + message: '"fd" must be a positive integer: -1' +}) +); const err_regex = common.isWindows ? /^Error: EBADF: bad file descriptor, uv_tty_init$/ : @@ -24,7 +27,12 @@ assert.throws(() => { assert.throws(() => { new tty.ReadStream(-1); -}, /fd must be positive integer:/); +}, common.expectsError({ + code: 'ERR_INVALID_FD', + type: RangeError, + message: '"fd" must be a positive integer: -1' +}) +); assert.throws(() => { let fd = 2; diff --git a/test/parallel/test-util-format.js b/test/parallel/test-util-format.js index c3b2cc95d1c7ba..93998c598a0e1f 100644 --- a/test/parallel/test-util-format.js +++ b/test/parallel/test-util-format.js @@ -106,6 +106,8 @@ assert.strictEqual(util.format('%%s%s', 'foo'), '%sfoo'); assert.strictEqual(util.format('%s:%s'), '%s:%s'); assert.strictEqual(util.format('%s:%s', undefined), 'undefined:%s'); assert.strictEqual(util.format('%s:%s', 'foo'), 'foo:%s'); +assert.strictEqual(util.format('%s:%i', 'foo'), 'foo:%i'); +assert.strictEqual(util.format('%s:%f', 'foo'), 'foo:%f'); assert.strictEqual(util.format('%s:%s', 'foo', 'bar'), 'foo:bar'); assert.strictEqual(util.format('%s:%s', 'foo', 'bar', 'baz'), 'foo:bar baz'); assert.strictEqual(util.format('%%%s%%', 'hi'), '%hi%'); @@ -114,6 +116,12 @@ assert.strictEqual(util.format('%sbc%%def', 'a'), 'abc%def'); assert.strictEqual(util.format('%d:%d', 12, 30), '12:30'); assert.strictEqual(util.format('%d:%d', 12), '12:%d'); assert.strictEqual(util.format('%d:%d'), '%d:%d'); +assert.strictEqual(util.format('%i:%i', 12, 30), '12:30'); +assert.strictEqual(util.format('%i:%i', 12), '12:%i'); +assert.strictEqual(util.format('%i:%i'), '%i:%i'); +assert.strictEqual(util.format('%f:%f', 12, 30), '12:30'); +assert.strictEqual(util.format('%f:%f', 12), '12:%f'); +assert.strictEqual(util.format('%f:%f'), '%f:%f'); assert.strictEqual(util.format('o: %j, a: %j', {}, []), 'o: {}, a: []'); assert.strictEqual(util.format('o: %j, a: %j', {}), 'o: {}, a: %j'); assert.strictEqual(util.format('o: %j, a: %j'), 'o: %j, a: %j'); diff --git a/test/parallel/test-vm-timeout.js b/test/parallel/test-vm-timeout.js index 939f15f9fd37fb..a53883bef7c0b2 100644 --- a/test/parallel/test-vm-timeout.js +++ b/test/parallel/test-vm-timeout.js @@ -32,12 +32,12 @@ assert.throws(function() { // Test 2: Timeout must be >= 0ms assert.throws(function() { vm.runInThisContext('', { timeout: -1 }); -}, RangeError); +}, /^RangeError: timeout must be a positive number$/); // Test 3: Timeout of 0ms assert.throws(function() { vm.runInThisContext('', { timeout: 0 }); -}, RangeError); +}, /^RangeError: timeout must be a positive number$/); // Test 4: Timeout of 1000ms, script finishes first vm.runInThisContext('', { timeout: 1000 }); diff --git a/test/parallel/test-whatwg-url-domainto.js b/test/parallel/test-whatwg-url-domainto.js index 90d9ee4a8c4648..b399f24136e14b 100644 --- a/test/parallel/test-whatwg-url-domainto.js +++ b/test/parallel/test-whatwg-url-domainto.js @@ -11,6 +11,7 @@ const { domainToASCII, domainToUnicode } = require('url'); // Tests below are not from WPT. const tests = require('../fixtures/url-idna.js'); +const wptToASCIITests = require('../fixtures/url-toascii.js'); { const expectedError = common.expectsError( @@ -22,7 +23,7 @@ const tests = require('../fixtures/url-idna.js'); } { - for (const [i, { ascii, unicode }] of tests.valid.entries()) { + for (const [i, { ascii, unicode }] of tests.entries()) { assert.strictEqual(ascii, domainToASCII(unicode), `domainToASCII(${i + 1})`); assert.strictEqual(unicode, domainToUnicode(ascii), @@ -35,8 +36,20 @@ const tests = require('../fixtures/url-idna.js'); } { - for (const [i, url] of tests.invalid.entries()) { - assert.strictEqual(domainToASCII(url), '', `Invalid case ${i + 1}`); - assert.strictEqual(domainToUnicode(url), '', `Invalid case ${i + 1}`); + for (const [i, test] of wptToASCIITests.entries()) { + if (typeof test === 'string') + continue; // skip comments + const { comment, input, output } = test; + let caseComment = `Case ${i + 1}`; + if (comment) + caseComment += ` (${comment})`; + if (output === null) { + assert.strictEqual(domainToASCII(input), '', caseComment); + assert.strictEqual(domainToUnicode(input), '', caseComment); + } else { + assert.strictEqual(domainToASCII(input), output, caseComment); + const roundtripped = domainToASCII(domainToUnicode(input)); + assert.strictEqual(roundtripped, output, caseComment); + } } } diff --git a/test/parallel/test-whatwg-url-searchparams-constructor.js b/test/parallel/test-whatwg-url-searchparams-constructor.js index 643ba3c5f40ffb..03ea62462165df 100644 --- a/test/parallel/test-whatwg-url-searchparams-constructor.js +++ b/test/parallel/test-whatwg-url-searchparams-constructor.js @@ -11,7 +11,7 @@ const { /* eslint-disable */ var params; // Strict mode fix for WPT. /* WPT Refs: - https://github.com/w3c/web-platform-tests/blob/e94c604916/url/urlsearchparams-constructor.html + https://github.com/w3c/web-platform-tests/blob/54c3502d7b/url/urlsearchparams-constructor.html License: http://www.w3.org/Consortium/Legal/2008/04-testsuite-copyright.html */ test(function() { @@ -87,6 +87,17 @@ test(function() { assert_equals(params.get('a b'), 'c'); }, 'Parse +'); +test(function() { + const testValue = '+15555555555'; + const params = new URLSearchParams(); + params.set('query', testValue); + var newParams = new URLSearchParams(params.toString()); + + assert_equals(params.toString(), 'query=%2B15555555555'); + assert_equals(params.get('query'), testValue); + assert_equals(newParams.get('query'), testValue); +}, 'Parse encoded +'); + test(function() { var params = new URLSearchParams('a=b c'); assert_equals(params.get('a'), 'b c'); @@ -156,7 +167,8 @@ test(function() { [ { "input": {"+": "%C2"}, "output": [["+", "%C2"]], "name": "object with +" }, { "input": {c: "x", a: "?"}, "output": [["c", "x"], ["a", "?"]], "name": "object with two keys" }, - { "input": [["c", "x"], ["a", "?"]], "output": [["c", "x"], ["a", "?"]], "name": "array with two keys" } + { "input": [["c", "x"], ["a", "?"]], "output": [["c", "x"], ["a", "?"]], "name": "array with two keys" }, + { "input": {"a\0b": "42", "c\uD83D": "23", "d\u1234": "foo"}, "output": [["a\0b", "42"], ["c\uFFFD", "23"], ["d\u1234", "foo"]], "name": "object with NULL, non-ASCII, and surrogate keys" } ].forEach((val) => { test(() => { let params = new URLSearchParams(val.input), @@ -179,12 +191,12 @@ test(() => { /* eslint-enable */ // Tests below are not from WPT. -{ -// assert.throws(() => { -// new URLSearchParams({ -// toString() { throw new TypeError('Illegal invocation'); } -// }); -// }, TypeError); +function makeIterableFunc(array) { + return Object.assign(() => {}, { + [Symbol.iterator]() { + return array[Symbol.iterator](); + } + }); } { @@ -200,17 +212,25 @@ test(() => { }); let params; - // URLSearchParams constructor, undefined and null as argument params = new URLSearchParams(undefined); assert.strictEqual(params.toString(), ''); params = new URLSearchParams(null); assert.strictEqual(params.toString(), ''); + params = new URLSearchParams( + makeIterableFunc([['key', 'val'], ['key2', 'val2']]) + ); + assert.strictEqual(params.toString(), 'key=val&key2=val2'); + params = new URLSearchParams( + makeIterableFunc([['key', 'val'], ['key2', 'val2']].map(makeIterableFunc)) + ); + assert.strictEqual(params.toString(), 'key=val&key2=val2'); assert.throws(() => new URLSearchParams([[1]]), tupleError); assert.throws(() => new URLSearchParams([[1, 2, 3]]), tupleError); assert.throws(() => new URLSearchParams({ [Symbol.iterator]: 42 }), iterableError); assert.throws(() => new URLSearchParams([{}]), tupleError); assert.throws(() => new URLSearchParams(['a']), tupleError); + assert.throws(() => new URLSearchParams([null]), tupleError); assert.throws(() => new URLSearchParams([{ [Symbol.iterator]: 42 }]), tupleError); } @@ -221,15 +241,14 @@ test(() => { valueOf() { throw new Error('valueOf'); } }; const sym = Symbol(); - - assert.throws(() => new URLSearchParams({ a: obj }), /^Error: toString$/); - assert.throws(() => new URLSearchParams([['a', obj]]), /^Error: toString$/); - assert.throws(() => new URLSearchParams(sym), - /^TypeError: Cannot convert a Symbol value to a string$/); - assert.throws(() => new URLSearchParams({ a: sym }), - /^TypeError: Cannot convert a Symbol value to a string$/); - assert.throws(() => new URLSearchParams([[sym, 'a']]), - /^TypeError: Cannot convert a Symbol value to a string$/); - assert.throws(() => new URLSearchParams([['a', sym]]), - /^TypeError: Cannot convert a Symbol value to a string$/); + const toStringError = /^Error: toString$/; + const symbolError = /^TypeError: Cannot convert a Symbol value to a string$/; + + assert.throws(() => new URLSearchParams({ a: obj }), toStringError); + assert.throws(() => new URLSearchParams([['a', obj]]), toStringError); + assert.throws(() => new URLSearchParams(sym), symbolError); + assert.throws(() => new URLSearchParams({ [sym]: 'a' }), symbolError); + assert.throws(() => new URLSearchParams({ a: sym }), symbolError); + assert.throws(() => new URLSearchParams([[sym, 'a']]), symbolError); + assert.throws(() => new URLSearchParams([['a', sym]]), symbolError); } diff --git a/test/parallel/test-whatwg-url-toascii.js b/test/parallel/test-whatwg-url-toascii.js new file mode 100644 index 00000000000000..bd986c96a47a84 --- /dev/null +++ b/test/parallel/test-whatwg-url-toascii.js @@ -0,0 +1,85 @@ +'use strict'; +const common = require('../common'); +const path = require('path'); +const { URL } = require('url'); +const { test, assert_equals, assert_throws } = require('../common/wpt'); + +if (!common.hasIntl) { + // A handful of the tests fail when ICU is not included. + common.skip('missing Intl'); + return; +} + +const request = { + response: require(path.join(common.fixturesDir, 'url-toascii')) +}; + +/* eslint-disable */ +/* WPT Refs: + https://github.com/w3c/web-platform-tests/blob/4839a0a804/url/toascii.window.js + License: http://www.w3.org/Consortium/Legal/2008/04-testsuite-copyright.html +*/ +// async_test(t => { +// const request = new XMLHttpRequest() +// request.open("GET", "toascii.json") +// request.send() +// request.responseType = "json" +// request.onload = t.step_func_done(() => { + runTests(request.response) +// }) +// }, "Loading data…") + +function makeURL(type, input) { + input = "https://" + input + "/x" + if(type === "url") { + return new URL(input) + } else { + const url = document.createElement(type) + url.href = input + return url + } +} + +function runTests(tests) { + for(var i = 0, l = tests.length; i < l; i++) { + let hostTest = tests[i] + if (typeof hostTest === "string") { + continue // skip comments + } + const typeName = { "url": "URL", "a": "", "area": "" } + // ;["url", "a", "area"].forEach((type) => { + ;["url"].forEach((type) => { + test(() => { + if(hostTest.output !== null) { + const url = makeURL("url", hostTest.input) + assert_equals(url.host, hostTest.output) + assert_equals(url.hostname, hostTest.output) + assert_equals(url.pathname, "/x") + assert_equals(url.href, "https://" + hostTest.output + "/x") + } else { + if(type === "url") { + assert_throws(new TypeError, () => makeURL("url", hostTest.input)) + } else { + const url = makeURL(type, hostTest.input) + assert_equals(url.host, "") + assert_equals(url.hostname, "") + assert_equals(url.pathname, "") + assert_equals(url.href, "https://" + hostTest.input + "/x") + } + } + }, hostTest.input + " (using " + typeName[type] + ")") + ;["host", "hostname"].forEach((val) => { + test(() => { + const url = makeURL(type, "x") + url[val] = hostTest.input + if(hostTest.output !== null) { + assert_equals(url[val], hostTest.output) + } else { + assert_equals(url[val], "x") + } + }, hostTest.input + " (using " + typeName[type] + "." + val + ")") + }) + }) + } +} +/* eslint-enable */ diff --git a/test/parallel/test-zlib-bytes-read.js b/test/parallel/test-zlib-bytes-read.js new file mode 100644 index 00000000000000..701d286817a267 --- /dev/null +++ b/test/parallel/test-zlib-bytes-read.js @@ -0,0 +1,93 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const zlib = require('zlib'); + +const expectStr = 'abcdefghijklmnopqrstuvwxyz'.repeat(2); +const expectBuf = Buffer.from(expectStr); + +function createWriter(target, buffer) { + const writer = { size: 0 }; + const write = () => { + target.write(Buffer.from([buffer[writer.size++]]), () => { + if (writer.size < buffer.length) { + target.flush(write); + } else { + target.end(); + } + }); + }; + write(); + return writer; +} + +for (const method of [ + ['createGzip', 'createGunzip', false], + ['createGzip', 'createUnzip', false], + ['createDeflate', 'createInflate', true], + ['createDeflateRaw', 'createInflateRaw', true] +]) { + let compWriter; + let compData = new Buffer(0); + + const comp = zlib[method[0]](); + comp.on('data', function(d) { + compData = Buffer.concat([compData, d]); + assert.strictEqual(this.bytesRead, compWriter.size, + `Should get write size on ${method[0]} data.`); + }); + comp.on('end', common.mustCall(function() { + assert.strictEqual(this.bytesRead, compWriter.size, + `Should get write size on ${method[0]} end.`); + assert.strictEqual(this.bytesRead, expectStr.length, + `Should get data size on ${method[0]} end.`); + + { + let decompWriter; + let decompData = new Buffer(0); + + const decomp = zlib[method[1]](); + decomp.on('data', function(d) { + decompData = Buffer.concat([decompData, d]); + assert.strictEqual(this.bytesRead, decompWriter.size, + `Should get write size on ${method[0]}/` + + `${method[1]} data.`); + }); + decomp.on('end', common.mustCall(function() { + assert.strictEqual(this.bytesRead, compData.length, + `Should get compressed size on ${method[0]}/` + + `${method[1]} end.`); + assert.strictEqual(decompData.toString(), expectStr, + `Should get original string on ${method[0]}/` + + `${method[1]} end.`); + })); + decompWriter = createWriter(decomp, compData); + } + + // Some methods should allow extra data after the compressed data + if (method[2]) { + const compDataExtra = Buffer.concat([compData, new Buffer('extra')]); + + let decompWriter; + let decompData = new Buffer(0); + + const decomp = zlib[method[1]](); + decomp.on('data', function(d) { + decompData = Buffer.concat([decompData, d]); + assert.strictEqual(this.bytesRead, decompWriter.size, + `Should get write size on ${method[0]}/` + + `${method[1]} data.`); + }); + decomp.on('end', common.mustCall(function() { + assert.strictEqual(this.bytesRead, compData.length, + `Should get compressed size on ${method[0]}/` + + `${method[1]} end.`); + assert.strictEqual(decompData.toString(), expectStr, + `Should get original string on ${method[0]}/` + + `${method[1]} end.`); + })); + decompWriter = createWriter(decomp, compDataExtra); + } + })); + compWriter = createWriter(comp, expectBuf); +} diff --git a/test/parallel/test-zlib-convenience-methods.js b/test/parallel/test-zlib-convenience-methods.js index 5612575d8e7db4..5c1f7395062d9d 100644 --- a/test/parallel/test-zlib-convenience-methods.js +++ b/test/parallel/test-zlib-convenience-methods.js @@ -36,6 +36,10 @@ const opts = { chunkSize: 1024, }; +const optsInfo = { + info: true +}; + for (const [type, expect] of [ ['string', expectStr], ['Buffer', expectBuf], @@ -44,10 +48,10 @@ for (const [type, expect] of [ ) ]) { for (const method of [ - ['gzip', 'gunzip'], - ['gzip', 'unzip'], - ['deflate', 'inflate'], - ['deflateRaw', 'inflateRaw'], + ['gzip', 'gunzip', 'Gzip', 'Gunzip'], + ['gzip', 'unzip', 'Gzip', 'Unzip'], + ['deflate', 'inflate', 'Deflate', 'Inflate'], + ['deflateRaw', 'inflateRaw', 'DeflateRaw', 'InflateRaw'], ]) { zlib[method[0]](expect, opts, common.mustCall((err, result) => { zlib[method[1]](result, opts, common.mustCall((err, result) => { @@ -65,6 +69,22 @@ for (const [type, expect] of [ })); })); + zlib[method[0]](expect, optsInfo, common.mustCall((err, result) => { + assert.ok(result.engine instanceof zlib[method[2]], + `Should get engine ${method[2]} after ${method[0]} ` + + `${type} with info option.`); + + const compressed = result.buffer; + zlib[method[1]](compressed, optsInfo, common.mustCall((err, result) => { + assert.strictEqual(result.buffer.toString(), expectStr, + `Should get original string after ${method[0]}/` + + `${method[1]} ${type} with info option.`); + assert.ok(result.engine instanceof zlib[method[3]], + `Should get engine ${method[3]} after ${method[0]} ` + + `${type} with info option.`); + })); + })); + { const compressed = zlib[`${method[0]}Sync`](expect, opts); const decompressed = zlib[`${method[1]}Sync`](compressed, opts); @@ -81,5 +101,21 @@ for (const [type, expect] of [ `Should get original string after ${method[0]}Sync/` + `${method[1]}Sync ${type} without options.`); } + + + { + const compressed = zlib[`${method[0]}Sync`](expect, optsInfo); + assert.ok(compressed.engine instanceof zlib[method[2]], + `Should get engine ${method[2]} after ${method[0]} ` + + `${type} with info option.`); + const decompressed = zlib[`${method[1]}Sync`](compressed.buffer, + optsInfo); + assert.strictEqual(decompressed.buffer.toString(), expectStr, + `Should get original string after ${method[0]}Sync/` + + `${method[1]}Sync ${type} without options.`); + assert.ok(decompressed.engine instanceof zlib[method[3]], + `Should get engine ${method[3]} after ${method[0]} ` + + `${type} with info option.`); + } } } diff --git a/test/parallel/test-zlib-deflate-raw-inherits.js b/test/parallel/test-zlib-deflate-raw-inherits.js new file mode 100644 index 00000000000000..a24726a3fbe465 --- /dev/null +++ b/test/parallel/test-zlib-deflate-raw-inherits.js @@ -0,0 +1,27 @@ +'use strict'; + +require('../common'); +const { DeflateRaw } = require('zlib'); +const { inherits } = require('util'); +const { Readable } = require('stream'); + +// validates that zlib.DeflateRaw can be inherited +// with util.inherits + +function NotInitialized(options) { + DeflateRaw.call(this, options); + this.prop = true; +} +inherits(NotInitialized, DeflateRaw); + +const dest = new NotInitialized(); + +const read = new Readable({ + read() { + this.push(Buffer.from('a test string')); + this.push(null); + } +}); + +read.pipe(dest); +dest.resume(); diff --git a/test/sequential/test-benchmark-http.js b/test/sequential/test-benchmark-http.js index cbeafcb8e6f19a..ce3d58e5d8d4b8 100644 --- a/test/sequential/test-benchmark-http.js +++ b/test/sequential/test-benchmark-http.js @@ -20,6 +20,9 @@ const path = require('path'); const runjs = path.join(__dirname, '..', '..', 'benchmark', 'run.js'); +const env = Object.assign({}, process.env, + { NODEJS_BENCHMARK_ZERO_ALLOWED: 1 }); + const child = fork(runjs, ['--set', 'benchmarker=test-double', '--set', 'c=1', '--set', 'chunks=0', @@ -28,7 +31,7 @@ const child = fork(runjs, ['--set', 'benchmarker=test-double', '--set', 'len=1', '--set', 'n=1', 'http'], - {env: {NODEJS_BENCHMARK_ZERO_ALLOWED: 1}}); + {env}); child.on('exit', (code, signal) => { assert.strictEqual(code, 0); assert.strictEqual(signal, null); diff --git a/test/sequential/test-net-server-bind.js b/test/sequential/test-net-server-bind.js new file mode 100644 index 00000000000000..56216d0ed60619 --- /dev/null +++ b/test/sequential/test-net-server-bind.js @@ -0,0 +1,64 @@ +'use strict'; +const common = require('../common'); +const assert = require('assert'); +const net = require('net'); + + +// With only a callback, server should get a port assigned by the OS +{ + const server = net.createServer(common.mustNotCall()); + + server.listen(common.mustCall(function() { + assert.ok(server.address().port > 100); + server.close(); + })); +} + +// No callback to listen(), assume we can bind in 100 ms +{ + const server = net.createServer(common.mustNotCall()); + + server.listen(common.PORT); + + setTimeout(function() { + const address = server.address(); + assert.strictEqual(address.port, common.PORT); + + if (address.family === 'IPv6') + assert.strictEqual(server._connectionKey, `6::::${address.port}`); + else + assert.strictEqual(server._connectionKey, `4:0.0.0.0:${address.port}`); + + server.close(); + }, 100); +} + +// Callback to listen() +{ + const server = net.createServer(common.mustNotCall()); + + server.listen(common.PORT + 1, common.mustCall(function() { + assert.strictEqual(server.address().port, common.PORT + 1); + server.close(); + })); +} + +// Backlog argument +{ + const server = net.createServer(common.mustNotCall()); + + server.listen(common.PORT + 2, '0.0.0.0', 127, common.mustCall(function() { + assert.strictEqual(server.address().port, common.PORT + 2); + server.close(); + })); +} + +// Backlog argument without host argument +{ + const server = net.createServer(common.mustNotCall()); + + server.listen(common.PORT + 3, 127, common.mustCall(function() { + assert.strictEqual(server.address().port, common.PORT + 3); + server.close(); + })); +} diff --git a/tools/release.sh b/tools/release.sh index 1151b6dd68d510..988a2c19b6d39d 100755 --- a/tools/release.sh +++ b/tools/release.sh @@ -20,7 +20,7 @@ signcmd=dist-sign echo "# Selecting GPG key ..." -gpgkey=$(gpg --list-secret-keys | awk -F'( +|/)' '/^(sec|ssb)/{print $3}') +gpgkey=$(gpg --list-secret-keys --keyid-format SHORT | awk -F'( +|/)' '/^(sec|ssb)/{print $3}') keycount=$(echo $gpgkey | wc -w) if [ $keycount -eq 0 ]; then diff --git a/tools/test-npm-package.js b/tools/test-npm-package.js index 951ec5c306ecc7..4acad2067f0484 100755 --- a/tools/test-npm-package.js +++ b/tools/test-npm-package.js @@ -24,7 +24,7 @@ const path = require('path'); const common = require('../test/common'); const projectDir = path.resolve(__dirname, '..'); -const npmBin = path.join(projectDir, 'deps', 'npm', 'cli.js'); +const npmBin = path.join(projectDir, 'deps', 'npm', 'bin', 'npm-cli.js'); const nodePath = path.dirname(process.execPath); function spawnCopyDeepSync(source, destination) { @@ -82,6 +82,7 @@ function runNPMPackageTests({ srcDir, install, rebuild, testArgs, logfile }) { npmBin, 'install', '--ignore-scripts', + '--no-save', ], npmOptions); } diff --git a/tools/test.py b/tools/test.py index 8ba5ef6aafa635..d45b4f0de94275 100755 --- a/tools/test.py +++ b/tools/test.py @@ -817,6 +817,10 @@ def GetConfiguration(self, context): (file, pathname, description) = imp.find_module('testcfg', [ self.path ]) module = imp.load_module('testcfg', file, pathname, description) self.config = module.GetConfiguration(context, self.path) + if hasattr(self.config, 'additional_flags'): + self.config.additional_flags += context.node_args + else: + self.config.additional_flags = context.node_args finally: if file: file.close() diff --git a/vcbuild.bat b/vcbuild.bat index ac2bf7f72ab53b..ae2c50e1c6c49f 100644 --- a/vcbuild.bat +++ b/vcbuild.bat @@ -157,7 +157,7 @@ if _%PROCESSOR_ARCHITECTURE%_==_AMD64_ set msvs_host_arch=amd64 if _%PROCESSOR_ARCHITEW6432%_==_AMD64_ set msvs_host_arch=amd64 @rem usualy vcvarsall takes an argument: host + '_' + target set vcvarsall_arg=%msvs_host_arch%_%target_arch% -@rem unless both host and taget are x64 +@rem unless both host and target are x64 if %target_arch%==x64 if %msvs_host_arch%==amd64 set vcvarsall_arg=amd64 @rem Look for Visual Studio 2017