diff --git a/.eslintrc.yaml b/.eslintrc.yaml index b2201aa41ff2..9167f21c5dd0 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 b4ba0e2983f1..dea969504a90 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 5cac93621c15..a00b00a5f8bc 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 80110b956593..2339e11e484f 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 5c9beb48c94b..da37eab45500 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 e2c4a1586241..e014085c69e5 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 000000000000..ebe9d05695ef --- /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 dbf67611c454..95255d8d8072 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 64d9c2d0616c..7357c4a1bd5b 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 e2a8004b8d9b..03b7e29d91e8 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 d808b2dbcca4..7b97e79d626e 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 c8c426f4ada8..e2c013b5df86 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 dad219b4a14d..f6dde3649237 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 193caa924091..1a06ff794b67 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 eb4f72947d74..666842908391 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 f015aacdbc89..4fcfc87ccda4 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 46385d7295f3..905c01acb0d2 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 962a3282d819..131dff4dd2da 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 79e11b018ec6..e73b582a191f 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 ba59bba643ab..99f846f55f2a 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 8f3510f5b8f2..3898c9c0a846 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 fdcf22363880..ff6f6cb556f5 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 18d659ea8377..9322d0a096cd 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 2ef422bd74f9..6d1f6fcc2080 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 d6ff8ce76084..21c85e73b8de 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 6741f7478b7c..5b3e33d42288 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 8fa52c2b33be..1325853d7651 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 530a784ed9c3..7100b563c5fa 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 b75fcc561869..41125d789078 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 8860c492adc4..b4291160b658 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 115d43584cb6..1e5208e496f0 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 a9cb77652bbf..528e70cbab6e 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 bd72e9471ef3..5f2a04a159dc 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 6f053ddb1b52..215fdb40a9e7 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 02866f73743f..83325a828911 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 55eaabcfd33b..b41029e7c99a 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 b279ab4d3a85..54b41d91dcbe 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 3ecde84cc3e4..d3a544534eba 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 af4103febf0d..500ca033e576 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 7b36dc7f5bc9..1c862a8ba7a7 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 aeaa8acb8926..e4cc4d7de89d 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 d40a92437a4c..25982014e359 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 e9a9f97b2001..666ba97c7cef 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 99dacb66606c..30c3172493f5 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 56e8b8ab2933..52b2ba78e4ee 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 9b9cca3cb090..3fca99216934 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 a2a1ad03ab16..7ec9923cb8bb 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 83ec73d5f560..38990dc8e96f 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 c4d3296c251d..6847b24387ce 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 9b115bb0036f..af03619a5d68 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 07e1c514d627..2f61d63aece0 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 02dc30d68e36..cc95846328a2 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 a1809977c592..44388546d8a2 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 8fce9194617a..aacae893619a 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 db7f2e063321..8252aa8f21ae 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 756bc34e6800..8c8dd3bb39d1 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 31c18f4ba250..b55a285de775 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 13fd9474881f..8bf5fdea1ed9 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 798519122a01..e099df218cb6 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 147b6e563e3a..37bb0bd71f77 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 587dad4259c8..36d0d3286161 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 ee1c38dc692c..197aa41870f1 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 00361d5174f5..bc29ed75ac1b 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 9fa968fd636f..70bf31e43597 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 c25ad77e5912..8f84bc8ab62e 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 55495142954b..4e4d97b23507 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 4f9656a922b0..300df680e1af 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 4f9656a922b0..300df680e1af 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 7d6ed1c78a18..e0f2df86f293 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 7f8851781ba0..56bf73fbf86e 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 3498af792170..1437a6807ee6 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 ef6d01b61199..9dd6e18b10c0 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 57423161bd84..ea9439e8418e 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 7d6ed1c78a18..e0f2df86f293 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 75891616b891..9e300e85bf23 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 0048979e908a..081d89f4945c 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 bed7aa07367e..c6fc5cad3cb2 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 d87e8c05fcd4..7d27bd2bc197 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 e5d95529e6be..351539c60b87 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 75956cc368a4..4888d872841e 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 1c769d1495d7..f3aab6e8517a 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 aca3dc550c74..7c6445b4cf4a 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 f15285ba784e..98595501fad1 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 976695a05cc8..ea3ecc321d81 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 8a7a51e4b062..98404d073c88 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 5a8b556bcabc..44c208b217d8 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 5dd243a7953a..c2acc0066235 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 705544fe3cba..2d2dda59fa3e 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 000000000000..d4e2417097fa --- /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 357ba91a5ac7..95ede1bc8724 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 50014fd232eb..1cefb6e64cea 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 df5615e47632..000fa1a5b689 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 5d111b32c8b6..67dcf98b70d7 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 ba38e602f82d..ded2350dff71 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 771a2a939953..5e4333a5b51c 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 70da583df4e4..66bbb44a33de 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 8cb75626bb5d..7ad966ea0a90 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 b993dd6235eb..3e2f2ce8fade 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 dbd8e97150a7..990d8c510985 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 075a672d66f2..4552bbc49898 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 cbc75821708b..4ef025c4bac5 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 5374d1feeca0..b13d42e1df45 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 fa475434ff61..ac0ef0934201 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 649dfac01bd5..43e0f5fb128e 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 ac6cb0f4cca5..0c2fbb6faa24 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 a0004f7ed35d..d2a7a9fa00d1 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 0d2426de56df..64b037402f0d 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 6dd28b8615f4..e6a15a467c33 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 949412ae0c64..860d5299ca08 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 f0f629d3343c..322d8c069e7e 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 ca564836cc17..c8d8f8686b3e 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 cc8b1e2fae49..41d84cba055d 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 e2f0217b7784..11b4d11b1f1d 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 491401e0b1b2..265aff01c6cd 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 19d20cb3ceb0..d0962471d801 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 d8c806dd18fd..2b26e9fc56fe 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 049ad0d868b5..3142da944ff0 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 9ae6826c22d2..c97b912e1843 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 7ef3c91d09e2..787b9d42198c 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 c495f292c483..978a4e54f3e6 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 03986814eecc..d5cf964ecb2a 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 f4512cb7d045..d54f31654222 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 3028ac419596..a102985b9f24 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 99d1bad04ea5..c8ccd94b7b86 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 9b7094591c36..3bdd4c632b95 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 2dca6a4b8fe5..e90cc4f8f40c 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 ae6e6b3b1e98..b5b1d25098f3 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 c594d22fa082..1bb0d25ce53c 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 31cbd387aa69..bf339ee70ca6 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 c43306fcb861..992c359dcbab 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 29a9d54bfc40..9eb713bd666d 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 9e80b63ea9c8..634d3e84094c 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 1df2ee8a520a..e14fa450d972 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 539cce1e6e8d..46d06910454a 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 21695ac1350b..c8051b36e8ed 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 603c79da7f49..5095939be6ad 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 3eac6d27a991..7cb888b260d7 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 18f2a3f69f2c..cf2c9f7f5797 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 95f402d09d4d..7a0c40d0502d 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 8a158479e4e9..fd30fb7cac44 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 7c75d8680d74..eaffbefc0ff5 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 caeab7142f57..89cb716d847a 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 08ce497d2066..d6d12bf16767 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 ed9afb395f1c..a04ce7363e2d 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 ca709693776b..face66764b54 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 9886f0d9a99e..0916970e0d24 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 10fb4a4d0b97..430f3c117f5c 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 2a73f126df6c..b38561f71147 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 e32f30670ae6..ad9fc14d558f 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 aa86ac30ba74..29df8f50f4f2 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 ab85d670a914..c3883a59498f 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 0ebcd400eb6e..14bad07f5fed 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 069e9e45ea24..ae2678a8db61 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 0341f9001d26..0bfedd6b8b9c 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 66d53afa33d4..8fdf66c2fc5b 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 8ce03075f12a..e3771ad9facb 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 d3757535db3f..194e6bcc02d4 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 d3757535db3f..194e6bcc02d4 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 a8c4be85a0b5..89eefefcf681 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 d751dc556615..4d6a28519294 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 deb06a7244cd..400e23b20adb 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 70b824a7d9cc..a80fdca666fe 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 fb86d4d0c56e..09dc0d760040 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 a8c4be85a0b5..89eefefcf681 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 3ab6f30cbec6..6a788d870c22 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 67e8880659a0..7af1f90f7cb8 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 52bf3c9144b7..da88a0df013c 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 7c4f2462f9b6..8de6d02da89a 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 8ec9c1597698..689e6b91ad96 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 c8873a0122fc..4c37567e1579 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 26806666babf..483f36010c03 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 14243684d999..5331efae4921 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 f57a4c221fef..c58a1ef95449 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 789a9e3516a4..f2bd986225fa 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 d534638e02a7..88ed4a079912 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 a9d38222a7de..79e865924d78 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 bc6ed1f17bfe..4f8c1fc7d853 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 ba6cb1385de0..e3a85f406627 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", "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/move-concurrently/copy-concurrently", "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/move-concurrently/run-queue", "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/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": "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/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 8235212ade49..802257622eab 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 422c8294e340..e12e98188c42 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 26b8e826f216..b55c3ba6897b 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", "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/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 e727128350b4..70aca6bc9e2c 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 d5443080dd0c..a5c1325c7122 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 142290039022..f2f6a7925e4e 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 a41a354f61c4..87e0a9c9bbab 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 5253109857bd..0445fb6452ca 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 4bad1bffd11c..1351576d12e8 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 89eaf9be3612..0d177f1c93e4 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 9a3664d910c4..ce58e31b95ff 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 339ef8793a93..000000000000 --- 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 a94c54abbd7f..e359958a3818 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 d8ef6979cbd5..b8afefc57720 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", "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/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": "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/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 39747c08b4dc..000000000000 --- 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 6ff074b74880..000000000000 --- 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 3a645ec9329a..9250ce33a4ab 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 d6e30bd54551..df646cd0559a 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": "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/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": "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/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 1060a9354d6c..000000000000 --- 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 d57401da0b5d..000000000000 --- 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 aa0e6b33def6..000000000000 --- 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 55c0cda6861a..7f7eac282da1 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 d8af7693642c..9da6a6438a42 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 46a926a1a15b..1c6c8e8d6e2c 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 dc189b54189a..fc3d158fa7c7 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 dd8aa518dc52..a2692836a3ad 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 854388027b06..54d88f339186 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 0100498947e2..a3c910eb9340 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 85a50123c63e..20b794051c9a 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 0ceef6c13f70..2191a9e80147 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 4005ebc0efb9..7ea91f886cba 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 0e296ced06eb..f74df4fcb787 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": "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/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": "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/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 f87d308f8e65..7d8dee66ce90 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 85a50123c63e..20b794051c9a 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 0ceef6c13f70..2191a9e80147 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 4005ebc0efb9..7ea91f886cba 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 b57e81b1b464..9dedd7231d81 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": "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/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": "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/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 f87d308f8e65..7d8dee66ce90 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 85a50123c63e..20b794051c9a 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 0ceef6c13f70..2191a9e80147 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 4005ebc0efb9..7ea91f886cba 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 81950940bbdd..e20413153712 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": "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/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": "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/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 f87d308f8e65..7d8dee66ce90 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 8b8e2cd878d5..37607223547a 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": "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/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 c27683d0d207..44e5b7eca0ab 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 b3cda81f7fdc..d2248f82b55a 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 f9fa36224131..55513a939470 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": "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/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 8a6a89b085a9..96f152012090 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 76b4b0cfcb07..0c5d2bc262d3 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 8b6e5d39bd39..3024d77c6956 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 b19b2088b957..a01012e3cfbb 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 15db0386836c..e9701f500727 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 e4bfcf02dc8b..82598c852179 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 1cab4c05e1ac..000000000000 --- 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 01cfaefe2fca..000000000000 --- 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 8e4af6603bb2..000000000000 --- 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": "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/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", - "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/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": "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/calvinmetcalf/buffer-shims/issues" - }, - "bundleDependencies": false, - "dependencies": {}, - "deprecated": false, - "description": "some shims for node buffers", - "devDependencies": { - "tape": "^4.5.1" - }, - "files": [ - "index.js" - ], - "homepage": "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/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 7ea6475e284e..000000000000 --- 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 13d827d8947e..dc3a2d2160b9 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 696d7ab6136a..26fb94c349ac 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 fb2958ba2cfc..cb5868ecedc4 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": "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/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": "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/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 d1bf299d055b..5308555f4963 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", "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/mississippi/concat-stream", @@ -34,12 +38,10 @@ "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/tap/tap-mocha-reporter", "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/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 96eb387aa085..e9a81afd0406 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 0bd12027d30f..000000000000 --- 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 74a7358ee82a..ea87b099d83d 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 d866dd9580b6..8bce3da12596 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", + "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/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": "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/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 7da8ad761ee7..4925059c5c59 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 46a0093e00c3..c03bb4174eff 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 f01986fa51b1..6ec0d73df6ba 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 fae62d7c5296..b004400f3801 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", "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/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 3bb9001de010..ba61cdda81ef 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 18bfe5f22aa0..c71455a2480c 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 399fd0f93b42..fb430af21018 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 449e7a442e87..b21ed7078b19 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 880422486853..c7c53e8771e1 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 139ebe3615c4..70eed05b00c1 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 0e81a290e3ec..06d11dc9c8e9 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 c7606aec49a9..cdce52cd0a23 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 89faf46249a9..40e75bfedb6d 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 ef623d596771..909270ecae31 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 7403dc3ee6ba..5a2c8e0eb52b 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 4fe9772a0f5e..d697869bb25b 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 c767b91f9a7c..6cb8077b9da0 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 80a4d1a5183a..08369b42391d 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 3db70b61139e..c3e9fd6dbaf0 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 b4462fc2aa72..d53b6a44d895 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 449e7a442e87..b21ed7078b19 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 d4ed2047c6db..84c5dced020b 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 0e81a290e3ec..06d11dc9c8e9 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 015db5faa7fa..8cd95238b020 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 ef623d596771..909270ecae31 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 bfc5fa17b4aa..dbad8c5e233d 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 c767b91f9a7c..6cb8077b9da0 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 80a4d1a5183a..08369b42391d 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 3db70b61139e..c3e9fd6dbaf0 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 b4462fc2aa72..d53b6a44d895 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 0b5a4da2199b..c647b9485aa6 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 0cca4cae21dd..b7632639d750 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 e0d62da24e14..8d7bda716a4b 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 3f7202d25427..bec911036c26 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 e0d0f8fa6134..32759db4742f 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 dbb034867982..c4865e0b623c 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 106701864c0e..fc229f197577 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 95aabc64d054..307b2ed5e312 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 5da7cadbf332..fd7988e2b3d9 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 fb03713dd111..bdfd985a691b 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 0b894ff47f30..a3d30318f917 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 402333e809e5..ea0d92e4d7db 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 61a329b4f20f..f51f0a756c3e 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 be4a266bac13..fd49cedeba4c 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 615d0c6a5dc8..4c357d9a836d 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 4cea3cb7b1ce..f90f033baed3 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 1210adb104d9..bd91234abd66 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 8c8f1ef0f90b..66145b3be770 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 f54631b50d81..a8eed9af5c18 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 7c62d1c8709b..19f2e5d9cf9f 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 133167f2d4d1..d8f764a3d7f1 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 fb498fd20c27..d5c0039bd69d 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 fa6258cf5e13..73498e3d6efa 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 cdea1f611194..ede1d32cae62 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 cdea5ff8d857..ffb8ffc5af20 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 b561cf3a362b..d75871386928 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 37341a5d20ed..ce01a24f2a78 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 8695359488d8..8c38feae6d95 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 bba370c4f3f1..21534e00ba4a 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 e825c140194f..05e4a0149ed8 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 8c84260856e1..7a30e893fbe6 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 72f44ecf6253..588ade64ee52 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 83343e2de1af..70b3f9656f4f 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 f906188b114b..c429342e03d4 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 7cbc4751cd81..57a04f768ca0 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 fa76dcac91f3..85118137859f 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 2d2303d8599e..99ffe7378735 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 fcb2d565cdd0..0eeb79cd428c 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 724a10be4ed6..0344482cc247 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 94cd54dbeedd..527f1d8f87b3 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 2bdc78d74491..e6ed7f1e770b 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 d25402730b8b..d49a5d5792a4 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 b0c73beeb578..54f459d1ed9c 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 3aed44a3ddf7..aecb95069de7 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 26378fdb2a02..1fb7ad1cbf88 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 987fe068c6de..eb3ab759349c 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 d3e860686c3c..f96294bb4304 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 a6e3b3ac0130..0cf67e5b770b 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 c4c640951759..20e8ef0a28d7 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 b8fb1e8a25dc..d8662878006e 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 8177fd294772..e911e157859a 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 5cf0de169e04..489af8b424ca 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 3fafb6f3e90a..6bede65e1dd4 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 f121fb6e9a08..f85a6550a54e 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 e9aabbd166a2..41919613eec5 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 8d926d5d8268..fe49113080b7 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 68c77cec7d8b..75e309aaca81 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 bb5e2fe25215..b0b6896f837e 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 8b5166ca9ff5..89156ba5ce2d 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 8fd8fe14bb63..d9c5e7fcb3bb 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 a5bd9016aae8..a228c7a7a4c3 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 d089af7a2830..2c41c6e7a9f1 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 33abf61f4441..b0cd3e1788dc 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 23b8c3089b2f..24ca67a6ef1e 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 df9b37a750d6..176ec1f17308 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 2a2b95ce837e..af59471c4771 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 52dc9a5ddd87..0b1fcfc1f1a5 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 585aa8ba3df9..f42365620db0 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 7c62d327a1f6..b45b364466ac 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 6dfd590a4a2c..d114710e98ec 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 46c9d033895b..917ae0751dee 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 0e910d6d8085..ab8126e5c9cf 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 0e40f09f2f91..be577bac767f 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 d06686290459..b7b7bdcd0290 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 f96a51781ab0..108a1959eacf 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 0ffff79cc450..0a59a01cf0e8 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 000000000000..34bd8b78b4f9 --- /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 000000000000..7a52dd1f1a11 --- /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 f5240da74cd7..9942cb4e37a6 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 06c3960cc6c0..dd4c9ce9e0b8 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 a7863d98be2f..2528f4a1b9ca 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 f9dbed871127..fb3b2fd8e437 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 b99e5990b4e4..04d805d9a96d 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 645dd0793f32..825a330abc88 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 79cd2d4f65b1..d19195ea06a8 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 cbf34da05ada..b1f7381a6fb5 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 74af4732b5fa..60566b1a5f52 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 bd76e23e3deb..29e465b07524 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 7434ff737e66..a495324cc6b5 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 ac583bf60b01..8896e2e97714 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 41bc0844e48e..2c3fd73b0996 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 de6cdde58a9c..8b8f8b285f1c 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 a8ec52a4dadc..c8bc7a94b26c 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 f9b42ac6e588..ed02efc26183 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 3cc067c3b7ee..643ae593439a 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 50120a4d70c6..b7424809fdbb 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 7f1e71dd1a42..a0351faf1119 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 d97f6226b9ee..b99269e7f839 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 e052a34b940a..7064c725d98d 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 845be673b799..96e629a9301f 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 d208d02392e9..a3d6f438f91e 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 e95f6274f5e0..90ed196c09cd 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 000000000000..e69de29bb2d1 diff --git a/deps/openssl/openssl/doc/apps/ciphers.pod b/deps/openssl/openssl/doc/apps/ciphers.pod index 9224557255ed..35d40bbf27ae 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 e12591528c0c..3f607d3b5fc8 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 3dc9870f34b9..f4ed9593ae26 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 30653e509357..1682ba5143dd 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 29675dd213f4..b45acbc5e3e4 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 fa17488d9173..1fe93ddfbebb 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 d9513338d8aa..0c0a30c1ffa0 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 746a80c79ea0..3e1f895c5ad8 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 ab0fe3b2cd1c..0541f348b3e2 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 eb38b0a10905..1aee11726863 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 e1add56b5e81..339617aab024 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 000000000000..3b0a50956d9b --- /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 8d926d5d8268..fe49113080b7 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 a5bd9016aae8..a228c7a7a4c3 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 585aa8ba3df9..f42365620db0 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 645dd0793f32..825a330abc88 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 7bbcdf69a431..add18a4b37c2 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 9bc61536101b..e6bc761e8bf2 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 7e2f5c2830b5..76451a346d86 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 7a02459f2b78..10586fee5408 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 bc875b53c9a0..8502b242e51c 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 6850dc0c6704..b80d1fd8ce6e 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 470bd3d94f29..d3f6db15ccee 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 32f2f1aeed2b..5b8b2da59f54 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 fbc954d43c70..1eee9d9b21cf 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 0385e039c8d4..1014a3fce16f 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 6ece87d0628c..0290c991d810 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 ea56f9ca8150..ba17f1b56281 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 1be6fb0032e2..155728d03772 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 2ad8f4392236..40021329a936 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 f8054dae6b6b..24be376c9fdf 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 d50edd18c916..aeffc0063471 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 f679801a297c..af03d45c2e9a 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 c3369a44aea7..f50f5142126f 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 890e47685350..b75cac61fbdc 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 79ed946a5142..0f4aba0226b4 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 e60c88bd5b27..6587e8bb685c 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 8f272ef99d5e..a324eeb39ac3 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 000000000000..3e3a27d41d7d 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 a6f9fa770b36..d7dda6e9a5af 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 75f0c8ae01ee..e40b37ed6e7a 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 000000000000..09a0c3aa326f 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 000000000000..35378a8ff9ae 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 bc2a85f7dd50..5a92559c9b7a 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 7a3ae11f7865..490a034e4037 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 8acf8fecd140..618274c0d2e2 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 4719d2368aec..ab4e099f1673 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 da4c3b13f14e..71b210f44bdd 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 000000000000..53883b1c7add --- /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 27a3523ea455..d85deb0066b1 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 036464e71ecc..404674baf211 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 8139138fccf6..3acf9e14a9ea 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 284dfb47c3d9..e5d94faf0fa3 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 bff1050d6331..3a000c5dd25e 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 e8e79f051e89..c542e34b9911 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 68e3bde39305..9782718a2326 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 470b73385d83..94e760030335 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 360652198e5a..8ac06f7fc8c8 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 000000000000..22f0640f549e --- /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 3f8689d2e5c6..c9b4ea38c310 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 34c3cff68e54..487d08ba6255 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 192ecc7056de..3f766e393f2f 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 c08ade2ef597..2af3e9802bd0 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 4efb2440e0ba..2912bad9349a 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 000000000000..126e08082c22 --- /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 14aec51fff16..a0f3d05fdb1b 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 fa89c4bffe58..5ec2beb511cb 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 1f504cb391f1..02543171de48 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 71934694623d..9d7c3617e864 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 dc1223b90ac5..5b3b352bdd25 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 18949507e750..93bd236d35e9 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 000000000000..32840c2696a1 --- /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 000000000000..9a96634db0e3 --- /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 3030f719a271..d7754509b1e2 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 cf0004879094..34d4a43f9e5f 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 31f09f0f6af3..f076094ccdc2 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 ae9913a1c6e1..aa2a91c9a12e 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 2c5152b42008..108934112c58 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 1d2cd4a80e97..388c9cca9707 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 393cdebd4ea3..45c088ea1b39 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 000000000000..414789451ab3 --- /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 1ec549cccb5c..8276c6041329 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 000000000000..5a887dd4c2d0 --- /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 cf95da21693b..df6dd1c61bbc 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 cba44a3e0b07..e52ae99dbe90 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 d331a1317267..643e233cfe9e 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 1188e8fe7099..2e3afa6c8568 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 fffd4626f175..6bc60bbe4688 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 58dd813ddf13..2866e938545c 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 4708c051d3b5..5934c5d8cb06 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 bd63c2f9d1d2..bcd49242cea2 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 4a9e6cbc17c7..9b5546b7e695 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 000000000000..38fb6ab0bb2c --- /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 000000000000..a5c19fbff58d --- /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 909288cc8888..56f0af15c3ef 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 2bf3b73815a5..7edf2358d43a 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 be325a923091..2ba5abf35490 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 b73994cb8de3..4a812955b0d1 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 000000000000..323dfc203924 --- /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 000000000000..3fba96e1bf15 --- /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 000000000000..5fdb61155056 --- /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 dbd8f86448d7..cb09ead50a4c 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 7059df16a69a..7b23d16ecf14 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 a43f7f1b1c02..2dc02ae457cd 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 000000000000..ebad0e89db59 --- /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 000000000000..23b4fc6e914a --- /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 1cd49257865d..c556325de018 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 27902fdf8645..781a8559dc84 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 ad240ab89724..0b636ed1e913 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 61e006026c18..6d8126f6921b 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 e84186d4ecc8..9ed4e824c6e9 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 a12179f7981d..72dfb7a17717 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 03e4adc058f9..95f843ad08ed 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 6902d4f1a694..2d72cdc70fe7 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 c13bfec350f2..baab838898a6 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 66b64b883248..9f10cd2a5a14 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 72b49d979045..39150702ddcd 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 b8cfde90e81f..444327d647f2 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 2442be7301eb..edf300212179 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 d479e521efe2..a648ba711d56 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 bdf88d2cdd94..d14160160785 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 b5e502eef552..f2513b7d3e7b 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 af7974c36446..7b42dd99280a 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 b7a3c11958c2..bf12148afe16 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 a2466e5e9db8..13cbfdcb9e6e 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 0709696ff9af..972539f4df49 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 1b7adf64ffcb..a6f583956fe6 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 9bf1453e536d..2fd15cfa9a64 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 050058afaa9a..d2e7f772ce29 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 1fa179b5724e..aa5d719fbea1 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 d2e667e9f754..e86d76b131ca 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 1b4a569aef54..0f1b56e777c6 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 65a1132e4986..67eb98049268 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 000000000000..641050e675ff --- /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 000000000000..3716a3ad975c --- /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 df8dc4c2f700..fba6b5440b0f 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 030245eadc53..c482ab5c71c0 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 000000000000..5229804b5694 --- /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 869b099e0fcc..156fccde39de 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 133ae9014937..160c235078b9 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 f018c2d4d49b..a2fda2458546 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 3a1e82a91918..3571aa230839 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 c074178541b0..bdc967151ed8 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 38b57db6991f..9cf93165e413 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 3de5a9a0bf4e..0a60d4a96424 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 4b4ceccc45ce..d1628a67d5d0 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 f6d893b44943..3bf427f8aa06 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 1dcdfffaf7cb..ea9977dd843e 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 b89550801047..72c176edc459 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 6c1f98b7eff5..7cfc159a2b3d 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 5d5ede9d6029..886f83a7d30f 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 39f4b0fc7391..05728c83365b 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 75c054354995..d7aae89914da 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 158129919bd7..11193dcf50b2 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 c0424c60a099..9a881510c721 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 53a036969b62..52fc7f6cc5e9 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 1a508e474aa7..b87e7324184b 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 d50289c3c26f..5119be6d3309 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 917f5f475160..dd13d8ae4bf1 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 6fc2c95c9859..e761822fa349 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 3f3027404700..f7e46abc98da 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 a65f09e0c6d7..54b364da9ebc 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 000000000000..6253ff7a4134 --- /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 0999f6b34252..215f72257233 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 6ff48d44c881..29a82a5c3740 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 000000000000..7a19d3e1151f --- /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 49d5d22f9678..a3a42787b37b 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 b4fbf847be7a..5b7ea75de5ce 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 29fffbc59fc1..4865334ec02b 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 a4741e64274c..7122fe96fa01 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 3eb95f0ba29c..1a040a927bc7 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 000000000000..709a12d3869f --- /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 0d98a2f1c1b5..5de805b6e983 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 4800d5bc9302..2120e36f4be3 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 606e13e60180..3411d3ce0afb 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 9ee328e65232..fc3e5d95665b 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 cd66a2063b22..b19ffb6d8e1f 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 0f42366a7052..f4000335a007 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 f90b823b78f5..3336874b9492 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 e98233215a9c..668e3fab18f8 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 6b94b6bc3fb8..5757ba6e2b34 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 6fabd83d9ce3..6229c7a79fae 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 06a5618949bf..b6a6173fe488 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 6e35185d024c..839bdadf76e1 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 aa36319ac20f..288dcaf9e383 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 b7b9170b784a..462103bd6428 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 f608dbd624c2..148082de4b6b 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 4d15f73ae839..688e13a3237d 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 a9f4885501e5..3f174843397b 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 eafc906026d6..f1f82fdb9816 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 d791a961c76f..9f0efe82d143 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 7707fa74cf78..3c6950794ac9 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 9151836ad835..6e5aff1cc9c1 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 03fbd47f9741..9143fa1fc46b 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 0f0f3f165aee..bd36c9a16d1b 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 d5d5407b1de1..aec73ed770f0 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 49cd9c929415..99f920bd208f 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 1609d66192e3..742b629d87fc 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 e1b34326e48f..6273c975c120 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 1edc9fc3beeb..e4c401a9951d 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 1ca0f59d793b..153cf45bbbba 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 033005e6ed6c..3208fb098d0a 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 bb33f75b0901..14c22e4ff467 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 07344ea7c779..67c231ef2560 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 60864f40afdb..6a1ed150d72c 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 d467c8278104..1d6cc5c68866 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 d73b12dcfd59..56a8ff68c822 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 c1cc0a2c54f0..a25901ac6ef1 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 0ea6c64a8be5..0f5c800f40d9 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 e2a58761fd02..cf7304c98dba 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 034625b37544..0bf4b573aafd 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 c8c8232cc07f..7179a6081cc4 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 5daef2e1ba9f..948719ed702c 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 2bc65f766402..80967212cd7a 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 6dcc1e0fdd3e..69eed62ab472 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 dc7e148252a0..6ef2ea54c474 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 495cb3b3aa3e..85984b7fa11a 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 558d87bcb76b..7cd8254fb3f4 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 1e1d0ff56766..f3e56b6ceb53 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 8c8e2aaade93..4c606ee77a15 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 60fba9ad2fa5..68f134ffe99b 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 719ceacb4bdb..0c8abd0998e7 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 85d05a25061a..8c2121687600 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 3f1a2e56e899..d82e92170a93 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 6fdd30384fc3..99364f40989f 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 40e106cd46fd..a339043bdca5 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 dc50f9995a69..f35bf2685592 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 cc1f3e6ea535..adf9feb414df 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 b361e9da66b5..92814947143d 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 000000000000..4a05a299a8e9 --- /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 a6e5f722cb93..38cf3f3edbcc 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 418149d1909e..3279979719dc 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 60c4f693b2d9..a588862098f6 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 585a3bf2b3ff..0b69cc41e29f 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 0160dc72e180..000000000000 --- 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 709e42a2e0e6..000000000000 --- 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 7fca7e0736d4..000000000000 --- 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 76a654283095..000000000000 --- 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 01ace540a997..000000000000 --- 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 9e340aa46e10..000000000000 --- 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 d14a15421fee..4b64fa4b381a 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 9e02c1d0bb71..383fe46342a3 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 30effe7eec09..aaf5531f39e1 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 cc1fcbe3566d..dcb7d76442f6 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 d77945486518..4194492cae8b 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 6b8c2f4be447..90758e5335d5 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 000000000000..8fe0177449e4 --- /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 13a2967e0df7..d331ee1d0c44 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 938a14c16f5e..c3940a3a5f41 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 7748db482bc7..b7af1393693a 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 eb4772d5f6e2..8672f943ca78 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 3466e6377771..0a5d0a61f2b1 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 1d3b8c6b899c..5f6ba89e6e0f 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 1e50cea4244a..9e0c132dba99 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 ea9cd8bbb8df..ec3d265e58cb 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 000000000000..fb16bda22aff --- /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 000000000000..59476f2d44e7 --- /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 555baf3fcf82..6cd584878a7e 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 39e055005729..2eb1abad6573 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 5e4c3806c2be..2b31f2512d6b 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 653de1493bc9..20a57a5dd6c4 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 0bbe89f3270a..b99ba2832bd9 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 eca1e8457bcc..e7b9a4aca844 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 b6f594a1597e..ebac57b6aba0 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 e7930ea2bcfc..a87de0674fa7 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 2434d98003be..e5bce88de9b2 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 781d4ed2a692..fa38185f1ee4 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 a34bca579555..4e4236b46d95 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 000000000000..2bbc8d773b23 --- /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 30cf94d28b15..bded7e3aaccb 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 000000000000..123e5e2da947 --- /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 7aaa4ce3b407..9ab219ecf581 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 8ce2aae27514..c3d9936c5400 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 106561603266..3b1cffbb8c82 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 fe2a97c06f43..a4814842ae41 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 082777922929..bdb45b47a360 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 8e8b11a7e76b..02cd2740dfe0 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 5f0ee5897d36..c95d116a249f 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 39e2cf100a62..7429a54f10fb 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 017fb3142a73..96f078ab1482 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 c6dd6e5f1453..ad0148191f80 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 72b12c1e217c..07fb8790fae1 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 db81db8339eb..66142911de0f 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 fecceaf13c5c..eabb61847ff1 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 715d1652b944..bf991cfbabb7 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 e87dd5596c31..1f4cacd2a770 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 609053a6cd08..181ab6e017a3 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 4e292691c105..7224ad9e31b3 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(), "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/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("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/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("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/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 492b5acdea58..01d19116bdac 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 cbfe702e9372..4b8f5a48cc96 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 000000000000..ea5e0f22ba1b --- /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 000000000000..d72bacd7ca9b --- /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 755c35707775..faf932f49536 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 ed6a782b9031..070d817b2c3a 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 000000000000..388edf6f5c21 --- /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 a5cb77250de4..27c9c5fdbc32 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 d2d60411894c..ad51c631645e 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 000000000000..4582b4bb3865 --- /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 000000000000..0776c8226530 --- /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 d0f3a7534640..772063b279f5 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 9d6bb563e119..19eb3601f0fb 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 fc001ff96533..3096fda5b1ee 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 000000000000..8f90a0d57f07 --- /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 e54377bdbbfe..fecb5c89dbe3 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 4489773a40ea..7b492374f051 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 000000000000..98e12e77fbcc --- /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 000000000000..348b97b11165 --- /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 000000000000..a283e9c30924 --- /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 000000000000..f667c3ca3378 --- /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 000000000000..53e84a351eed --- /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 2b214c4ad26b..a049da78be0f 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 fed392cd9f0b..285f35b830a2 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 136d378bbb9a..1e71815927ba 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 12bd5d6fa1f9..ac6e22f96908 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 6ed27806b934..c12af535fa83 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 000000000000..6edb14112997 --- /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 fe22f93a10e0..fb87b1ee87a0 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 f754e60300ff..8f89aeffff2c 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 000000000000..d25fc319747a --- /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 87ce973ac6d0..d1e9ed67889a 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 ba2014bdc85a..13db2dd7bace 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 6e249470230a..80473a568cac 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 000000000000..bc7d15a554aa --- /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 fb8ddf5a66b7..5cdf91826086 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 d27644200660..000000000000 --- 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 fdbe6e0db2e6..4da16379d5b3 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 86c102c45f11..6f8849a32261 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 db42a5a9495a..ddffd131d0ba 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 c8ff56871734..2551d3f54f65 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 159286a43222..6894d4b91714 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 b78bc689b237..2f3dc778a096 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 c3b2cc95d1c7..93998c598a0e 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 939f15f9fd37..a53883bef7c0 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 90d9ee4a8c46..b399f24136e1 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 643ba3c5f40f..03ea62462165 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 000000000000..bd986c96a47a --- /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 000000000000..701d286817a2 --- /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 5612575d8e7d..5c1f7395062d 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 000000000000..a24726a3fbe4 --- /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 cbeafcb8e6f1..ce3d58e5d8d4 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 000000000000..56216d0ed606 --- /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 1151b6dd68d5..988a2c19b6d3 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 951ec5c306ec..4acad2067f04 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 8ba5ef6aafa6..d45b4f0de942 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 ac2bf7f72ab5..ae2c50e1c6c4 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