diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..00022d9c --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +test/fixtures/files/** text eol=lf diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..f0bc5b36 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,45 @@ +name: CI + +on: [push, pull_request] + +jobs: + build: + strategy: + matrix: + node-version: [10.x, 12.x, 14.x] + platform: + - os: ubuntu-latest + shell: bash + - os: macos-latest + shell: bash + - os: windows-latest + shell: powershell + + fail-fast: false + + runs-on: ${{ matrix.platform.os }} + defaults: + run: + shell: ${{ matrix.platform.shell }} + + steps: + # there are files here that make windows unhappy by default + - name: Support longpaths + run: git config --global core.longpaths true + + - name: Checkout Repository + uses: actions/checkout@v1.1.0 + + - name: Use Nodejs ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + + - name: use latest npm + run: npm i -g npm@latest + + - name: Install dependencies + run: npm install + + - name: Run Tap Tests + run: npm test -- -c -t0 diff --git a/.travis.yml b/.travis.yml index 85318e47..09263d7a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,18 @@ language: node_js sudo: false + node_js: + - node + - 12 + - 10 - 8 - - 6 - - 4 -notifications: - email: false + +os: + - linux + cache: directories: - $HOME/.npm + +notifications: + email: false diff --git a/README.md b/README.md index fc55bc36..034e4865 100644 --- a/README.md +++ b/README.md @@ -108,7 +108,7 @@ tar.c( // or tar.create gzip: }, ['some', 'files', 'and', 'folders'] -).pipe(fs.createWriteStream('my-tarball.tgz') +).pipe(fs.createWriteStream('my-tarball.tgz')) ``` To replicate `tar xf my-tarball.tgz` you'd do: @@ -230,6 +230,9 @@ The following options are supported: Note that this prevents using other mtime-based features like `tar.update` or the `keepNewer` option with the resulting tar archive. [Alias: `m`, `no-mtime`] +- `mtime` Set to a `Date` object to force a specific `mtime` for + everything added to the archive. Overridden by `noMtime`. + The following options are mostly internal, but can be modified in some advanced use cases, such as re-using caches between runs. diff --git a/benchmarks/node_modules/balanced-match/index.js b/benchmarks/node_modules/balanced-match/index.js index e8d85870..1685a762 100644 --- a/benchmarks/node_modules/balanced-match/index.js +++ b/benchmarks/node_modules/balanced-match/index.js @@ -1,3 +1,4 @@ +'use strict'; module.exports = balanced; function balanced(a, b, str) { if (a instanceof RegExp) a = maybeMatch(a, str); diff --git a/benchmarks/node_modules/balanced-match/package.json b/benchmarks/node_modules/balanced-match/package.json index 8ec4c8c5..dc208685 100644 --- a/benchmarks/node_modules/balanced-match/package.json +++ b/benchmarks/node_modules/balanced-match/package.json @@ -1,33 +1,32 @@ { - "_from": "balanced-match@^0.4.1", - "_id": "balanced-match@0.4.2", - "_integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "_from": "balanced-match@^1.0.0", + "_id": "balanced-match@1.0.0", + "_inBundle": false, + "_integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "_location": "/balanced-match", "_phantomChildren": {}, "_requested": { "type": "range", "registry": true, - "raw": "balanced-match@^0.4.1", + "raw": "balanced-match@^1.0.0", "name": "balanced-match", "escapedName": "balanced-match", - "rawSpec": "^0.4.1", + "rawSpec": "^1.0.0", "saveSpec": null, - "fetchSpec": "^0.4.1" + "fetchSpec": "^1.0.0" }, "_requiredBy": [ "/brace-expansion" ], - "_resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", - "_shasum": "cb3f3e3c732dc0f01ee70b403f302e61d7709838", - "_shrinkwrap": null, - "_spec": "balanced-match@^0.4.1", + "_resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "_shasum": "89b4d199ab2bee49de164ea02b89ce462d71b767", + "_spec": "balanced-match@^1.0.0", "_where": "/Users/isaacs/dev/js/tar/benchmarks/node_modules/brace-expansion", "author": { "name": "Julian Gruber", "email": "mail@juliangruber.com", "url": "http://juliangruber.com" }, - "bin": null, "bugs": { "url": "https://github.com/juliangruber/balanced-match/issues" }, @@ -36,6 +35,7 @@ "deprecated": false, "description": "Match balanced character pairs, like \"{\" and \"}\"", "devDependencies": { + "matcha": "^0.7.0", "tape": "^4.6.0" }, "homepage": "https://github.com/juliangruber/balanced-match", @@ -49,13 +49,12 @@ "license": "MIT", "main": "index.js", "name": "balanced-match", - "optionalDependencies": {}, - "peerDependencies": {}, "repository": { "type": "git", "url": "git://github.com/juliangruber/balanced-match.git" }, "scripts": { + "bench": "make bench", "test": "make test" }, "testling": { @@ -74,5 +73,5 @@ "android-browser/4.2..latest" ] }, - "version": "0.4.2" + "version": "1.0.0" } diff --git a/benchmarks/node_modules/brace-expansion/README.md b/benchmarks/node_modules/brace-expansion/README.md index ed2ec1fd..6b4e0e16 100644 --- a/benchmarks/node_modules/brace-expansion/README.md +++ b/benchmarks/node_modules/brace-expansion/README.md @@ -63,7 +63,7 @@ Valid expansions are: // {a,b,...} ``` -A comma seperated list of options, like `{a,b}` or `{a,{b,c}}` or `{,a,}`. +A comma separated list of options, like `{a,b}` or `{a,{b,c}}` or `{,a,}`. ```js /^-?\d+\.\.-?\d+(\.\.-?\d+)?$/ @@ -98,6 +98,12 @@ npm install brace-expansion - [Julian Gruber](https://github.com/juliangruber) - [Isaac Z. Schlueter](https://github.com/isaacs) +## Sponsors + +This module is proudly supported by my [Sponsors](https://github.com/juliangruber/sponsors)! + +Do you want to support modules like this to improve their quality, stability and weigh in on new features? Then please consider donating to my [Patreon](https://www.patreon.com/juliangruber). Not sure how much of my modules you're using? Try [feross/thanks](https://github.com/feross/thanks)! + ## License (MIT) diff --git a/benchmarks/node_modules/brace-expansion/package.json b/benchmarks/node_modules/brace-expansion/package.json index 52b2baef..26587e47 100644 --- a/benchmarks/node_modules/brace-expansion/package.json +++ b/benchmarks/node_modules/brace-expansion/package.json @@ -1,39 +1,38 @@ { - "_from": "brace-expansion@^1.0.0", - "_id": "brace-expansion@1.1.7", - "_integrity": "sha1-Pv/DxQ4ABTH7cg6v+A8K6O8jz1k=", + "_from": "brace-expansion@^1.1.7", + "_id": "brace-expansion@1.1.11", + "_inBundle": false, + "_integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "_location": "/brace-expansion", "_phantomChildren": {}, "_requested": { "type": "range", "registry": true, - "raw": "brace-expansion@^1.0.0", + "raw": "brace-expansion@^1.1.7", "name": "brace-expansion", "escapedName": "brace-expansion", - "rawSpec": "^1.0.0", + "rawSpec": "^1.1.7", "saveSpec": null, - "fetchSpec": "^1.0.0" + "fetchSpec": "^1.1.7" }, "_requiredBy": [ "/minimatch" ], - "_resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz", - "_shasum": "3effc3c50e000531fb720eaff80f0ae8ef23cf59", - "_shrinkwrap": null, - "_spec": "brace-expansion@^1.0.0", + "_resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "_shasum": "3c7fcbf529d87226f3d2f52b966ff5271eb441dd", + "_spec": "brace-expansion@^1.1.7", "_where": "/Users/isaacs/dev/js/tar/benchmarks/node_modules/minimatch", "author": { "name": "Julian Gruber", "email": "mail@juliangruber.com", "url": "http://juliangruber.com" }, - "bin": null, "bugs": { "url": "https://github.com/juliangruber/brace-expansion/issues" }, "bundleDependencies": false, "dependencies": { - "balanced-match": "^0.4.1", + "balanced-match": "^1.0.0", "concat-map": "0.0.1" }, "deprecated": false, @@ -47,8 +46,6 @@ "license": "MIT", "main": "index.js", "name": "brace-expansion", - "optionalDependencies": {}, - "peerDependencies": {}, "repository": { "type": "git", "url": "git://github.com/juliangruber/brace-expansion.git" @@ -74,5 +71,5 @@ "android-browser/4.2..latest" ] }, - "version": "1.1.7" + "version": "1.1.11" } diff --git a/benchmarks/node_modules/fstream/.npmignore b/benchmarks/node_modules/fstream/.npmignore deleted file mode 100644 index 494272a8..00000000 --- a/benchmarks/node_modules/fstream/.npmignore +++ /dev/null @@ -1,5 +0,0 @@ -.*.swp -node_modules/ -examples/deep-copy/ -examples/path/ -examples/filter-copy/ diff --git a/benchmarks/node_modules/fstream/lib/writer.js b/benchmarks/node_modules/fstream/lib/writer.js index 140e449e..3f105478 100644 --- a/benchmarks/node_modules/fstream/lib/writer.js +++ b/benchmarks/node_modules/fstream/lib/writer.js @@ -147,7 +147,7 @@ Writer.prototype._stat = function (current) { // if it's a type change, then we need to clobber or error. // if it's not a type change, then let the impl take care of it. - if (currentType !== self.type) { + if (currentType !== self.type || self.type === 'File' && current.nlink > 1) { return rimraf(self._path, function (er) { if (er) return self.error(er) self._old = null diff --git a/benchmarks/node_modules/fstream/package.json b/benchmarks/node_modules/fstream/package.json index 63fc2fff..fb48fdc2 100644 --- a/benchmarks/node_modules/fstream/package.json +++ b/benchmarks/node_modules/fstream/package.json @@ -1,33 +1,32 @@ { - "_from": "fstream@^1.0.2", - "_id": "fstream@1.0.11", - "_integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", + "_from": "fstream@^1.0.12", + "_id": "fstream@1.0.12", + "_inBundle": false, + "_integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", "_location": "/fstream", "_phantomChildren": {}, "_requested": { "type": "range", "registry": true, - "raw": "fstream@^1.0.2", + "raw": "fstream@^1.0.12", "name": "fstream", "escapedName": "fstream", - "rawSpec": "^1.0.2", + "rawSpec": "^1.0.12", "saveSpec": null, - "fetchSpec": "^1.0.2" + "fetchSpec": "^1.0.12" }, "_requiredBy": [ "/tar" ], - "_resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", - "_shasum": "5c1fb1f117477114f0632a0eb4b71b3cb0fd3171", - "_shrinkwrap": null, - "_spec": "fstream@^1.0.2", + "_resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "_shasum": "4e8ba8ee2d48be4f7d0de505455548eae5932045", + "_spec": "fstream@^1.0.12", "_where": "/Users/isaacs/dev/js/tar/benchmarks/node_modules/tar", "author": { "name": "Isaac Z. Schlueter", "email": "i@izs.me", "url": "http://blog.izs.me/" }, - "bin": null, "bugs": { "url": "https://github.com/npm/fstream/issues" }, @@ -51,8 +50,6 @@ "license": "ISC", "main": "fstream.js", "name": "fstream", - "optionalDependencies": {}, - "peerDependencies": {}, "repository": { "type": "git", "url": "git+https://github.com/npm/fstream.git" @@ -60,5 +57,5 @@ "scripts": { "test": "standard && tap examples/*.js" }, - "version": "1.0.11" + "version": "1.0.12" } diff --git a/benchmarks/node_modules/glob/LICENSE b/benchmarks/node_modules/glob/LICENSE index 19129e31..42ca266d 100644 --- a/benchmarks/node_modules/glob/LICENSE +++ b/benchmarks/node_modules/glob/LICENSE @@ -13,3 +13,9 @@ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +## Glob Logo + +Glob's logo created by Tanya Brassie , licensed +under a Creative Commons Attribution-ShareAlike 4.0 International License +https://creativecommons.org/licenses/by-sa/4.0/ diff --git a/benchmarks/node_modules/glob/README.md b/benchmarks/node_modules/glob/README.md index baa1d1ba..e71b967e 100644 --- a/benchmarks/node_modules/glob/README.md +++ b/benchmarks/node_modules/glob/README.md @@ -7,7 +7,7 @@ Match files using the patterns the shell uses, like stars and stuff. This is a glob implementation in JavaScript. It uses the `minimatch` library to do its matching. -![](oh-my-glob.gif) +![](logo/glob.png) ## Usage @@ -347,6 +347,11 @@ Users are thus advised not to use a glob result as a guarantee of filesystem state in the face of rapid changes. For the vast majority of operations, this is never a problem. +## Glob Logo +Glob's logo was created by [Tanya Brassie](http://tanyabrassie.com/). Logo files can be found [here](https://github.com/isaacs/node-glob/tree/master/logo). + +The logo is licensed under a [Creative Commons Attribution-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/). + ## Contributing Any change to behavior (including bugfixes) must come with a test. diff --git a/benchmarks/node_modules/glob/glob.js b/benchmarks/node_modules/glob/glob.js index bfdd7a11..58dec0f6 100644 --- a/benchmarks/node_modules/glob/glob.js +++ b/benchmarks/node_modules/glob/glob.js @@ -153,9 +153,7 @@ function Glob (pattern, options, cb) { } var self = this - var n = this.minimatch.set.length this._processing = 0 - this.matches = new Array(n) this._emitQueue = [] this._processQueue = [] diff --git a/benchmarks/node_modules/glob/package.json b/benchmarks/node_modules/glob/package.json index e1dc4e02..1df6c1c2 100644 --- a/benchmarks/node_modules/glob/package.json +++ b/benchmarks/node_modules/glob/package.json @@ -1,33 +1,32 @@ { - "_from": "glob@^7.0.5", - "_id": "glob@7.1.1", - "_integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", + "_from": "glob@^7.1.3", + "_id": "glob@7.1.4", + "_inBundle": false, + "_integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", "_location": "/glob", "_phantomChildren": {}, "_requested": { "type": "range", "registry": true, - "raw": "glob@^7.0.5", + "raw": "glob@^7.1.3", "name": "glob", "escapedName": "glob", - "rawSpec": "^7.0.5", + "rawSpec": "^7.1.3", "saveSpec": null, - "fetchSpec": "^7.0.5" + "fetchSpec": "^7.1.3" }, "_requiredBy": [ "/rimraf" ], - "_resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", - "_shasum": "805211df04faaf1c63a3600306cdf5ade50b2ec8", - "_shrinkwrap": null, - "_spec": "glob@^7.0.5", + "_resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "_shasum": "aa608a2f6c577ad357e1ae5a5c26d9a8d1969255", + "_spec": "glob@^7.1.3", "_where": "/Users/isaacs/dev/js/tar/benchmarks/node_modules/rimraf", "author": { "name": "Isaac Z. Schlueter", "email": "i@izs.me", "url": "http://blog.izs.me/" }, - "bin": null, "bugs": { "url": "https://github.com/isaacs/node-glob/issues" }, @@ -36,7 +35,7 @@ "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.2", + "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" }, @@ -45,7 +44,7 @@ "devDependencies": { "mkdirp": "0", "rimraf": "^2.2.8", - "tap": "^7.1.2", + "tap": "^12.0.1", "tick": "0.0.6" }, "engines": { @@ -60,8 +59,6 @@ "license": "ISC", "main": "glob.js", "name": "glob", - "optionalDependencies": {}, - "peerDependencies": {}, "repository": { "type": "git", "url": "git://github.com/isaacs/node-glob.git" @@ -75,5 +72,5 @@ "test": "tap test/*.js --cov", "test-regen": "npm run profclean && TEST_REGEN=1 node test/00-setup.js" }, - "version": "7.1.1" + "version": "7.1.4" } diff --git a/benchmarks/node_modules/graceful-fs/fs.js b/benchmarks/node_modules/graceful-fs/fs.js deleted file mode 100644 index 8ad4a383..00000000 --- a/benchmarks/node_modules/graceful-fs/fs.js +++ /dev/null @@ -1,21 +0,0 @@ -'use strict' - -var fs = require('fs') - -module.exports = clone(fs) - -function clone (obj) { - if (obj === null || typeof obj !== 'object') - return obj - - if (obj instanceof Object) - var copy = { __proto__: obj.__proto__ } - else - var copy = Object.create(null) - - Object.getOwnPropertyNames(obj).forEach(function (key) { - Object.defineProperty(copy, key, Object.getOwnPropertyDescriptor(obj, key)) - }) - - return copy -} diff --git a/benchmarks/node_modules/graceful-fs/graceful-fs.js b/benchmarks/node_modules/graceful-fs/graceful-fs.js index 33b30d2e..ac206757 100644 --- a/benchmarks/node_modules/graceful-fs/graceful-fs.js +++ b/benchmarks/node_modules/graceful-fs/graceful-fs.js @@ -1,6 +1,8 @@ var fs = require('fs') var polyfills = require('./polyfills.js') var legacy = require('./legacy-streams.js') +var clone = require('./clone.js') + var queue = [] var util = require('util') @@ -24,17 +26,17 @@ if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) { }) } -module.exports = patch(require('./fs.js')) -if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH) { - module.exports = patch(fs) +module.exports = patch(clone(fs)) +if (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH && !fs.__patched) { + module.exports = patch(fs) + fs.__patched = true; } // Always patch fs.close/closeSync, because we want to // retry() whenever a close happens *anywhere* in the program. // This is essential when multiple graceful-fs instances are // in play at the same time. -module.exports.close = -fs.close = (function (fs$close) { return function (fd, cb) { +module.exports.close = (function (fs$close) { return function (fd, cb) { return fs$close.call(fs, fd, function (err) { if (!err) retry() @@ -44,8 +46,7 @@ fs.close = (function (fs$close) { return function (fd, cb) { }) }})(fs.close) -module.exports.closeSync = -fs.closeSync = (function (fs$closeSync) { return function (fd) { +module.exports.closeSync = (function (fs$closeSync) { return function (fd) { // Note that graceful-fs also retries when fs.closeSync() fails. // Looks like a bug to me, although it's probably a harmless one. var rval = fs$closeSync.apply(fs, arguments) @@ -53,6 +54,17 @@ fs.closeSync = (function (fs$closeSync) { return function (fd) { return rval }})(fs.closeSync) +// Only patch fs once, otherwise we'll run into a memory leak if +// graceful-fs is loaded multiple times, such as in test environments that +// reset the loaded modules between tests. +// We look for the string `graceful-fs` from the comment above. This +// way we are not adding any extra properties and it will detect if older +// versions of graceful-fs are installed. +if (!/\bgraceful-fs\b/.test(fs.closeSync.toString())) { + fs.closeSync = module.exports.closeSync; + fs.close = module.exports.close; +} + function patch (fs) { // Everything that references the open() function needs to be in here polyfills(fs) @@ -144,6 +156,7 @@ function patch (fs) { if (err && (err.code === 'EMFILE' || err.code === 'ENFILE')) enqueue([go$readdir, [args]]) + else { if (typeof cb === 'function') cb.apply(this, arguments) @@ -163,12 +176,16 @@ function patch (fs) { } var fs$ReadStream = fs.ReadStream - ReadStream.prototype = Object.create(fs$ReadStream.prototype) - ReadStream.prototype.open = ReadStream$open + if (fs$ReadStream) { + ReadStream.prototype = Object.create(fs$ReadStream.prototype) + ReadStream.prototype.open = ReadStream$open + } var fs$WriteStream = fs.WriteStream - WriteStream.prototype = Object.create(fs$WriteStream.prototype) - WriteStream.prototype.open = WriteStream$open + if (fs$WriteStream) { + WriteStream.prototype = Object.create(fs$WriteStream.prototype) + WriteStream.prototype.open = WriteStream$open + } fs.ReadStream = ReadStream fs.WriteStream = WriteStream diff --git a/benchmarks/node_modules/graceful-fs/package.json b/benchmarks/node_modules/graceful-fs/package.json index b81becf6..abe85bec 100644 --- a/benchmarks/node_modules/graceful-fs/package.json +++ b/benchmarks/node_modules/graceful-fs/package.json @@ -1,7 +1,8 @@ { "_from": "graceful-fs@^4.1.2", - "_id": "graceful-fs@4.1.11", - "_integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "_id": "graceful-fs@4.1.15", + "_inBundle": false, + "_integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", "_location": "/graceful-fs", "_phantomChildren": {}, "_requested": { @@ -17,35 +18,31 @@ "_requiredBy": [ "/fstream" ], - "_resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "_shasum": "0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658", - "_shrinkwrap": null, + "_resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "_shasum": "ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00", "_spec": "graceful-fs@^4.1.2", "_where": "/Users/isaacs/dev/js/tar/benchmarks/node_modules/fstream", - "bin": null, "bugs": { "url": "https://github.com/isaacs/node-graceful-fs/issues" }, "bundleDependencies": false, - "dependencies": {}, "deprecated": false, "description": "A drop-in replacement for fs, making various improvements.", "devDependencies": { + "import-fresh": "^2.0.0", "mkdirp": "^0.5.0", "rimraf": "^2.2.8", - "tap": "^5.4.2" + "tap": "^12.0.1" }, "directories": { "test": "test" }, - "engines": { - "node": ">=0.4.0" - }, "files": [ "fs.js", "graceful-fs.js", "legacy-streams.js", - "polyfills.js" + "polyfills.js", + "clone.js" ], "homepage": "https://github.com/isaacs/node-graceful-fs#readme", "keywords": [ @@ -67,14 +64,15 @@ "license": "ISC", "main": "graceful-fs.js", "name": "graceful-fs", - "optionalDependencies": {}, - "peerDependencies": {}, "repository": { "type": "git", "url": "git+https://github.com/isaacs/node-graceful-fs.git" }, "scripts": { + "postpublish": "git push origin --all; git push origin --tags", + "postversion": "npm publish", + "preversion": "npm test", "test": "node test.js | tap -" }, - "version": "4.1.11" + "version": "4.1.15" } diff --git a/benchmarks/node_modules/graceful-fs/polyfills.js b/benchmarks/node_modules/graceful-fs/polyfills.js index 4c6aca78..b964ed08 100644 --- a/benchmarks/node_modules/graceful-fs/polyfills.js +++ b/benchmarks/node_modules/graceful-fs/polyfills.js @@ -1,4 +1,3 @@ -var fs = require('./fs.js') var constants = require('constants') var origCwd = process.cwd @@ -145,73 +144,36 @@ function patch (fs) { } } }})(fs.readSync) -} - -function patchLchmod (fs) { - fs.lchmod = function (path, mode, callback) { - fs.open( path - , constants.O_WRONLY | constants.O_SYMLINK - , mode - , function (err, fd) { - if (err) { - if (callback) callback(err) - return - } - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - fs.fchmod(fd, mode, function (err) { - fs.close(fd, function(err2) { - if (callback) callback(err || err2) - }) - }) - }) - } - - fs.lchmodSync = function (path, mode) { - var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode) - - // prefer to return the chmod error, if one occurs, - // but still try to close, and report closing errors if they occur. - var threw = true - var ret - try { - ret = fs.fchmodSync(fd, mode) - threw = false - } finally { - if (threw) { - try { - fs.closeSync(fd) - } catch (er) {} - } else { - fs.closeSync(fd) - } - } - return ret - } -} -function patchLutimes (fs) { - if (constants.hasOwnProperty("O_SYMLINK")) { - fs.lutimes = function (path, at, mt, cb) { - fs.open(path, constants.O_SYMLINK, function (er, fd) { - if (er) { - if (cb) cb(er) + function patchLchmod (fs) { + fs.lchmod = function (path, mode, callback) { + fs.open( path + , constants.O_WRONLY | constants.O_SYMLINK + , mode + , function (err, fd) { + if (err) { + if (callback) callback(err) return } - fs.futimes(fd, at, mt, function (er) { - fs.close(fd, function (er2) { - if (cb) cb(er || er2) + // prefer to return the chmod error, if one occurs, + // but still try to close, and report closing errors if they occur. + fs.fchmod(fd, mode, function (err) { + fs.close(fd, function(err2) { + if (callback) callback(err || err2) }) }) }) } - fs.lutimesSync = function (path, at, mt) { - var fd = fs.openSync(path, constants.O_SYMLINK) - var ret + fs.lchmodSync = function (path, mode) { + var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode) + + // prefer to return the chmod error, if one occurs, + // but still try to close, and report closing errors if they occur. var threw = true + var ret try { - ret = fs.futimesSync(fd, at, mt) + ret = fs.fchmodSync(fd, mode) threw = false } finally { if (threw) { @@ -224,107 +186,144 @@ function patchLutimes (fs) { } return ret } + } + + function patchLutimes (fs) { + if (constants.hasOwnProperty("O_SYMLINK")) { + fs.lutimes = function (path, at, mt, cb) { + fs.open(path, constants.O_SYMLINK, function (er, fd) { + if (er) { + if (cb) cb(er) + return + } + fs.futimes(fd, at, mt, function (er) { + fs.close(fd, function (er2) { + if (cb) cb(er || er2) + }) + }) + }) + } + + fs.lutimesSync = function (path, at, mt) { + var fd = fs.openSync(path, constants.O_SYMLINK) + var ret + var threw = true + try { + ret = fs.futimesSync(fd, at, mt) + threw = false + } finally { + if (threw) { + try { + fs.closeSync(fd) + } catch (er) {} + } else { + fs.closeSync(fd) + } + } + return ret + } - } else { - fs.lutimes = function (_a, _b, _c, cb) { if (cb) process.nextTick(cb) } - fs.lutimesSync = function () {} + } else { + fs.lutimes = function (_a, _b, _c, cb) { if (cb) process.nextTick(cb) } + fs.lutimesSync = function () {} + } } -} -function chmodFix (orig) { - if (!orig) return orig - return function (target, mode, cb) { - return orig.call(fs, target, mode, function (er) { - if (chownErOk(er)) er = null - if (cb) cb.apply(this, arguments) - }) + function chmodFix (orig) { + if (!orig) return orig + return function (target, mode, cb) { + return orig.call(fs, target, mode, function (er) { + if (chownErOk(er)) er = null + if (cb) cb.apply(this, arguments) + }) + } } -} -function chmodFixSync (orig) { - if (!orig) return orig - return function (target, mode) { - try { - return orig.call(fs, target, mode) - } catch (er) { - if (!chownErOk(er)) throw er + function chmodFixSync (orig) { + if (!orig) return orig + return function (target, mode) { + try { + return orig.call(fs, target, mode) + } catch (er) { + if (!chownErOk(er)) throw er + } } } -} -function chownFix (orig) { - if (!orig) return orig - return function (target, uid, gid, cb) { - return orig.call(fs, target, uid, gid, function (er) { - if (chownErOk(er)) er = null - if (cb) cb.apply(this, arguments) - }) + function chownFix (orig) { + if (!orig) return orig + return function (target, uid, gid, cb) { + return orig.call(fs, target, uid, gid, function (er) { + if (chownErOk(er)) er = null + if (cb) cb.apply(this, arguments) + }) + } } -} -function chownFixSync (orig) { - if (!orig) return orig - return function (target, uid, gid) { - try { - return orig.call(fs, target, uid, gid) - } catch (er) { - if (!chownErOk(er)) throw er + function chownFixSync (orig) { + if (!orig) return orig + return function (target, uid, gid) { + try { + return orig.call(fs, target, uid, gid) + } catch (er) { + if (!chownErOk(er)) throw er + } } } -} -function statFix (orig) { - if (!orig) return orig - // Older versions of Node erroneously returned signed integers for - // uid + gid. - return function (target, cb) { - return orig.call(fs, target, function (er, stats) { - if (!stats) return cb.apply(this, arguments) + function statFix (orig) { + if (!orig) return orig + // Older versions of Node erroneously returned signed integers for + // uid + gid. + return function (target, cb) { + return orig.call(fs, target, function (er, stats) { + if (!stats) return cb.apply(this, arguments) + if (stats.uid < 0) stats.uid += 0x100000000 + if (stats.gid < 0) stats.gid += 0x100000000 + if (cb) cb.apply(this, arguments) + }) + } + } + + function statFixSync (orig) { + if (!orig) return orig + // Older versions of Node erroneously returned signed integers for + // uid + gid. + return function (target) { + var stats = orig.call(fs, target) if (stats.uid < 0) stats.uid += 0x100000000 if (stats.gid < 0) stats.gid += 0x100000000 - if (cb) cb.apply(this, arguments) - }) + return stats; + } } -} -function statFixSync (orig) { - if (!orig) return orig - // Older versions of Node erroneously returned signed integers for - // uid + gid. - return function (target) { - var stats = orig.call(fs, target) - if (stats.uid < 0) stats.uid += 0x100000000 - if (stats.gid < 0) stats.gid += 0x100000000 - return stats; - } -} + // ENOSYS means that the fs doesn't support the op. Just ignore + // that, because it doesn't matter. + // + // if there's no getuid, or if getuid() is something other + // than 0, and the error is EINVAL or EPERM, then just ignore + // it. + // + // This specific case is a silent failure in cp, install, tar, + // and most other unix tools that manage permissions. + // + // When running as root, or if other types of errors are + // encountered, then it's strict. + function chownErOk (er) { + if (!er) + return true -// ENOSYS means that the fs doesn't support the op. Just ignore -// that, because it doesn't matter. -// -// if there's no getuid, or if getuid() is something other -// than 0, and the error is EINVAL or EPERM, then just ignore -// it. -// -// This specific case is a silent failure in cp, install, tar, -// and most other unix tools that manage permissions. -// -// When running as root, or if other types of errors are -// encountered, then it's strict. -function chownErOk (er) { - if (!er) - return true - - if (er.code === "ENOSYS") - return true - - var nonroot = !process.getuid || process.getuid() !== 0 - if (nonroot) { - if (er.code === "EINVAL" || er.code === "EPERM") + if (er.code === "ENOSYS") return true - } - return false + var nonroot = !process.getuid || process.getuid() !== 0 + if (nonroot) { + if (er.code === "EINVAL" || er.code === "EPERM") + return true + } + + return false + } } diff --git a/benchmarks/node_modules/minimatch/package.json b/benchmarks/node_modules/minimatch/package.json index f8a4ef30..4f29eb4d 100644 --- a/benchmarks/node_modules/minimatch/package.json +++ b/benchmarks/node_modules/minimatch/package.json @@ -1,45 +1,43 @@ { - "_from": "minimatch@^3.0.2", - "_id": "minimatch@3.0.3", - "_integrity": "sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q=", + "_from": "minimatch@^3.0.4", + "_id": "minimatch@3.0.4", + "_inBundle": false, + "_integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "_location": "/minimatch", "_phantomChildren": {}, "_requested": { "type": "range", "registry": true, - "raw": "minimatch@^3.0.2", + "raw": "minimatch@^3.0.4", "name": "minimatch", "escapedName": "minimatch", - "rawSpec": "^3.0.2", + "rawSpec": "^3.0.4", "saveSpec": null, - "fetchSpec": "^3.0.2" + "fetchSpec": "^3.0.4" }, "_requiredBy": [ "/glob" ], - "_resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz", - "_shasum": "2a4e4090b96b2db06a9d7df01055a62a77c9b774", - "_shrinkwrap": null, - "_spec": "minimatch@^3.0.2", + "_resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "_shasum": "5166e286457f03306064be5497e8dbb0c3d32083", + "_spec": "minimatch@^3.0.4", "_where": "/Users/isaacs/dev/js/tar/benchmarks/node_modules/glob", "author": { "name": "Isaac Z. Schlueter", "email": "i@izs.me", "url": "http://blog.izs.me" }, - "bin": null, "bugs": { "url": "https://github.com/isaacs/minimatch/issues" }, "bundleDependencies": false, "dependencies": { - "brace-expansion": "^1.0.0" + "brace-expansion": "^1.1.7" }, "deprecated": false, "description": "a glob matcher in javascript", "devDependencies": { - "standard": "^3.7.2", - "tap": "^5.6.0" + "tap": "^10.3.2" }, "engines": { "node": "*" @@ -51,15 +49,15 @@ "license": "ISC", "main": "minimatch.js", "name": "minimatch", - "optionalDependencies": {}, - "peerDependencies": {}, "repository": { "type": "git", "url": "git://github.com/isaacs/minimatch.git" }, "scripts": { - "posttest": "standard minimatch.js test/*.js", - "test": "tap test/*.js" + "postpublish": "git push origin --all; git push origin --tags", + "postversion": "npm publish", + "preversion": "npm test", + "test": "tap test/*.js --cov" }, - "version": "3.0.3" + "version": "3.0.4" } diff --git a/benchmarks/node_modules/rimraf/package.json b/benchmarks/node_modules/rimraf/package.json index 551aa27b..1eef864a 100644 --- a/benchmarks/node_modules/rimraf/package.json +++ b/benchmarks/node_modules/rimraf/package.json @@ -1,7 +1,8 @@ { "_from": "rimraf@2", - "_id": "rimraf@2.6.1", - "_integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", + "_id": "rimraf@2.6.3", + "_inBundle": false, + "_integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "_location": "/rimraf", "_phantomChildren": {}, "_requested": { @@ -17,9 +18,8 @@ "_requiredBy": [ "/fstream" ], - "_resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", - "_shasum": "c2338ec643df7a1b7fe5c54fa86f57428a55f33d", - "_shrinkwrap": null, + "_resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "_shasum": "b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab", "_spec": "rimraf@2", "_where": "/Users/isaacs/dev/js/tar/benchmarks/node_modules/fstream", "author": { @@ -35,13 +35,13 @@ }, "bundleDependencies": false, "dependencies": { - "glob": "^7.0.5" + "glob": "^7.1.3" }, "deprecated": false, "description": "A deep deletion module for node (like `rm -rf`)", "devDependencies": { "mkdirp": "^0.5.1", - "tap": "^10.1.2" + "tap": "^12.1.1" }, "files": [ "LICENSE", @@ -53,14 +53,15 @@ "license": "ISC", "main": "rimraf.js", "name": "rimraf", - "optionalDependencies": {}, - "peerDependencies": {}, "repository": { "type": "git", "url": "git://github.com/isaacs/rimraf.git" }, "scripts": { + "postpublish": "git push origin --all; git push origin --tags", + "postversion": "npm publish", + "preversion": "npm test", "test": "tap test/*.js" }, - "version": "2.6.1" + "version": "2.6.3" } diff --git a/benchmarks/node_modules/rimraf/rimraf.js b/benchmarks/node_modules/rimraf/rimraf.js index c2633126..e80dd106 100644 --- a/benchmarks/node_modules/rimraf/rimraf.js +++ b/benchmarks/node_modules/rimraf/rimraf.js @@ -5,6 +5,7 @@ var assert = require("assert") var path = require("path") var fs = require("fs") var glob = require("glob") +var _0666 = parseInt('666', 8) var defaultGlobOpts = { nosort: true, @@ -165,7 +166,7 @@ function fixWinEPERM (p, options, er, cb) { if (er) assert(er instanceof Error) - options.chmod(p, 666, function (er2) { + options.chmod(p, _0666, function (er2) { if (er2) cb(er2.code === "ENOENT" ? null : er) else @@ -187,7 +188,7 @@ function fixWinEPERMSync (p, options, er) { assert(er instanceof Error) try { - options.chmodSync(p, 666) + options.chmodSync(p, _0666) } catch (er2) { if (er2.code === "ENOENT") return diff --git a/benchmarks/node_modules/tar/.npmignore b/benchmarks/node_modules/tar/.npmignore deleted file mode 100644 index c167ad5b..00000000 --- a/benchmarks/node_modules/tar/.npmignore +++ /dev/null @@ -1,5 +0,0 @@ -.*.swp -node_modules -examples/extract/ -test/tmp/ -test/fixtures/ diff --git a/benchmarks/node_modules/tar/lib/parse.js b/benchmarks/node_modules/tar/lib/parse.js index 600ad782..1c66ebda 100644 --- a/benchmarks/node_modules/tar/lib/parse.js +++ b/benchmarks/node_modules/tar/lib/parse.js @@ -38,6 +38,7 @@ function Parse () { me._stream = new BlockStream(512) me.position = 0 me._ended = false + me._hardLinks = {} me._stream.on("error", function (e) { me.emit("error", e) @@ -251,6 +252,11 @@ Parse.prototype._startEntry = function (c) { if (onend) entry.on("end", onend) this._entry = entry + + if (entry.type === "Link") { + this._hardLinks[entry.path] = entry + } + var me = this entry.on("pause", function () { diff --git a/benchmarks/node_modules/tar/package.json b/benchmarks/node_modules/tar/package.json index 0d8d0982..c9c694c0 100644 --- a/benchmarks/node_modules/tar/package.json +++ b/benchmarks/node_modules/tar/package.json @@ -1,41 +1,40 @@ { - "_from": "tar@latest", - "_id": "tar@2.2.1", - "_integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "_from": "tar@2.2.2", + "_id": "tar@2.2.2", + "_inBundle": false, + "_integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", "_location": "/tar", "_phantomChildren": {}, "_requested": { - "type": "tag", + "type": "version", "registry": true, - "raw": "tar@latest", + "raw": "tar@2.2.2", "name": "tar", "escapedName": "tar", - "rawSpec": "latest", + "rawSpec": "2.2.2", "saveSpec": null, - "fetchSpec": "latest" + "fetchSpec": "2.2.2" }, "_requiredBy": [ "#USER", "/" ], - "_resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "_shasum": "8e4d2a256c0e2185c6b18ad694aec968b83cb1d1", - "_shrinkwrap": null, - "_spec": "tar@latest", + "_resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "_shasum": "0ca8848562c7299b8b446ff6a4d60cdbb23edc40", + "_spec": "tar@2.2.2", "_where": "/Users/isaacs/dev/js/tar/benchmarks", "author": { "name": "Isaac Z. Schlueter", "email": "i@izs.me", "url": "http://blog.izs.me/" }, - "bin": null, "bugs": { "url": "https://github.com/isaacs/node-tar/issues" }, "bundleDependencies": false, "dependencies": { "block-stream": "*", - "fstream": "^1.0.2", + "fstream": "^1.0.12", "inherits": "2" }, "deprecated": false, @@ -50,8 +49,6 @@ "license": "ISC", "main": "tar.js", "name": "tar", - "optionalDependencies": {}, - "peerDependencies": {}, "repository": { "type": "git", "url": "git://github.com/isaacs/node-tar.git" @@ -59,5 +56,5 @@ "scripts": { "test": "tap test/*.js" }, - "version": "2.2.1" + "version": "2.2.2" } diff --git a/benchmarks/package-lock.json b/benchmarks/package-lock.json index b1f88c0f..f24ac944 100644 --- a/benchmarks/package-lock.json +++ b/benchmarks/package-lock.json @@ -1,19 +1,30 @@ { + "name": "benchmarks", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, "dependencies": { "balanced-match": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", - "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "block-stream": { "version": "0.0.9", "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", - "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=" + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "requires": { + "inherits": "~2.0.0" + } }, "brace-expansion": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz", - "integrity": "sha1-Pv/DxQ4ABTH7cg6v+A8K6O8jz1k=" + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } }, "concat-map": { "version": "0.0.1", @@ -26,24 +37,42 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fstream": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", - "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=" + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } }, "glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", - "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=" + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } }, "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=" + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } }, "inherits": { "version": "2.0.3", @@ -51,9 +80,12 @@ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q=" + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } }, "minimist": { "version": "0.0.8", @@ -63,12 +95,18 @@ "mkdirp": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=" + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=" + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } }, "path-is-absolute": { "version": "1.0.1", @@ -76,14 +114,22 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "rimraf": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", - "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=" + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "requires": { + "glob": "^7.1.3" + } }, "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=" + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz", + "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==", + "requires": { + "block-stream": "*", + "fstream": "^1.0.12", + "inherits": "2" + } }, "wrappy": { "version": "1.0.2", diff --git a/benchmarks/package.json b/benchmarks/package.json new file mode 100644 index 00000000..78dfdbc8 --- /dev/null +++ b/benchmarks/package.json @@ -0,0 +1,7 @@ +{ + "name": "benchmarks", + "version": "1.0.0", + "dependencies": { + "tar": "^2.2.2" + } +} diff --git a/lib/extract.js b/lib/extract.js index cbb458a0..6d032016 100644 --- a/lib/extract.js +++ b/lib/extract.js @@ -6,6 +6,7 @@ const Unpack = require('./unpack.js') const fs = require('fs') const fsm = require('fs-minipass') const path = require('path') +const stripSlash = require('./strip-trailing-slashes.js') const x = module.exports = (opt_, files, cb) => { if (typeof opt_ === 'function') @@ -41,7 +42,7 @@ const x = module.exports = (opt_, files, cb) => { // construct a filter that limits the file entries listed // include child entries if a dir is included const filesFilter = (opt, files) => { - const map = new Map(files.map(f => [f.replace(/\/+$/, ''), true])) + const map = new Map(files.map(f => [stripSlash(f), true])) const filter = opt.filter const mapHas = (file, r) => { @@ -55,8 +56,8 @@ const filesFilter = (opt, files) => { } opt.filter = filter - ? (file, entry) => filter(file, entry) && mapHas(file.replace(/\/+$/, '')) - : file => mapHas(file.replace(/\/+$/, '')) + ? (file, entry) => filter(file, entry) && mapHas(stripSlash(file)) + : file => mapHas(stripSlash(file)) } const extractFileSync = opt => { diff --git a/lib/header.js b/lib/header.js index cad4aec2..d29c3b99 100644 --- a/lib/header.js +++ b/lib/header.js @@ -9,10 +9,11 @@ const types = require('./types.js') const pathModule = require('path').posix const large = require('./large-numbers.js') +const SLURP = Symbol('slurp') const TYPE = Symbol('type') class Header { - constructor (data, off) { + constructor (data, off, ex, gex) { this.cksumValid = false this.needPax = false this.nullBlock = false @@ -35,12 +36,12 @@ class Header { this.ctime = null if (Buffer.isBuffer(data)) - this.decode(data, off || 0) + this.decode(data, off || 0, ex, gex) else if (data) this.set(data) } - decode (buf, off) { + decode (buf, off, ex, gex) { if (!off) off = 0 @@ -55,6 +56,11 @@ class Header { this.mtime = decDate(buf, off + 136, 12) this.cksum = decNumber(buf, off + 148, 12) + // if we have extended or global extended headers, apply them now + // See https://github.com/npm/node-tar/pull/187 + this[SLURP](ex) + this[SLURP](gex, true) + // old tar versions marked dirs as a file with a trailing / this[TYPE] = decString(buf, off + 156, 1) if (this[TYPE] === '') @@ -101,6 +107,16 @@ class Header { this.nullBlock = true } + [SLURP] (ex, global) { + for (let k in ex) { + // we slurp in everything except for the path attribute in + // a global extended header, because that's weird. + if (ex[k] !== null && ex[k] !== undefined && + !(global && k === 'path')) + this[k] = ex[k] + } + } + encode (buf, off) { if (!buf) { buf = this.block = Buffer.alloc(512) diff --git a/lib/large-numbers.js b/lib/large-numbers.js index ff499926..3e5c9925 100644 --- a/lib/large-numbers.js +++ b/lib/large-numbers.js @@ -1,12 +1,13 @@ 'use strict' // Tar can encode large and negative numbers using a leading byte of -// 0xff for negative, and 0x80 for positive. The trailing byte in the -// section will always be 0x20, or in some implementations 0x00. -// this module encodes and decodes these things. +// 0xff for negative, and 0x80 for positive. const encode = exports.encode = (num, buf) => { - buf[buf.length - 1] = 0x20 - if (num < 0) + if (!Number.isSafeInteger(num)) + // The number is so large that javascript cannot represent it with integer + // precision. + throw TypeError('cannot encode number outside of javascript safe integer range') + else if (num < 0) encodeNegative(num, buf) else encodePositive(num, buf) @@ -15,13 +16,10 @@ const encode = exports.encode = (num, buf) => { const encodePositive = (num, buf) => { buf[0] = 0x80 - for (var i = buf.length - 2; i > 0; i--) { - if (num === 0) - buf[i] = 0 - else { - buf[i] = num % 0x100 - num = Math.floor(num / 0x100) - } + + for (var i = buf.length; i > 1; i--) { + buf[i-1] = num & 0xff + num = Math.floor(num / 0x100) } } @@ -29,21 +27,16 @@ const encodeNegative = (num, buf) => { buf[0] = 0xff var flipped = false num = num * -1 - for (var i = buf.length - 2; i > 0; i--) { - var byte - if (num === 0) - byte = 0 - else { - byte = num % 0x100 - num = Math.floor(num / 0x100) - } + for (var i = buf.length; i > 1; i--) { + var byte = num & 0xff + num = Math.floor(num / 0x100) if (flipped) - buf[i] = onesComp(byte) + buf[i-1] = onesComp(byte) else if (byte === 0) - buf[i] = 0 + buf[i-1] = 0 else { flipped = true - buf[i] = twosComp(byte) + buf[i-1] = twosComp(byte) } } } @@ -51,8 +44,20 @@ const encodeNegative = (num, buf) => { const parse = exports.parse = (buf) => { var post = buf[buf.length - 1] var pre = buf[0] - return pre === 0x80 ? pos(buf.slice(1, buf.length - 1)) - : twos(buf.slice(1, buf.length - 1)) + var value; + if (pre === 0x80) + value = pos(buf.slice(1, buf.length)) + else if (pre === 0xff) + value = twos(buf) + else + throw TypeError('invalid base256 encoding') + + if (!Number.isSafeInteger(value)) + // The number is so large that javascript cannot represent it with integer + // precision. + throw TypeError('parsed number outside of javascript safe integer range') + + return value } const twos = (buf) => { @@ -71,9 +76,9 @@ const twos = (buf) => { f = twosComp(byte) } if (f !== 0) - sum += f * Math.pow(256, len - i - 1) + sum -= f * Math.pow(256, len - i - 1) } - return sum * -1 + return sum } const pos = (buf) => { diff --git a/lib/list.js b/lib/list.js index 250ebe00..5a5023bb 100644 --- a/lib/list.js +++ b/lib/list.js @@ -11,6 +11,7 @@ const Parser = require('./parse.js') const fs = require('fs') const fsm = require('fs-minipass') const path = require('path') +const stripSlash = require('./strip-trailing-slashes.js') const t = module.exports = (opt_, files, cb) => { if (typeof opt_ === 'function') @@ -56,7 +57,7 @@ const onentryFunction = opt => { // construct a filter that limits the file entries listed // include child entries if a dir is included const filesFilter = (opt, files) => { - const map = new Map(files.map(f => [f.replace(/\/+$/, ''), true])) + const map = new Map(files.map(f => [stripSlash(f), true])) const filter = opt.filter const mapHas = (file, r) => { @@ -70,8 +71,8 @@ const filesFilter = (opt, files) => { } opt.filter = filter - ? (file, entry) => filter(file, entry) && mapHas(file.replace(/\/+$/, '')) - : file => mapHas(file.replace(/\/+$/, '')) + ? (file, entry) => filter(file, entry) && mapHas(stripSlash(file)) + : file => mapHas(stripSlash(file)) } const listFileSync = opt => { diff --git a/lib/mkdir.js b/lib/mkdir.js index 382329ef..69e8c083 100644 --- a/lib/mkdir.js +++ b/lib/mkdir.js @@ -8,6 +8,7 @@ const mkdirp = require('mkdirp') const fs = require('fs') const path = require('path') const chownr = require('chownr') +const normPath = require('./normalize-windows-path.js') class SymlinkError extends Error { constructor (symlink, path) { @@ -33,7 +34,20 @@ class CwdError extends Error { } } -const mkdir = module.exports = (dir, opt, cb) => { +const cGet = (cache, key) => cache.get(normPath(key)) +const cSet = (cache, key, val) => cache.set(normPath(key), val) + +const checkCwd = (dir, cb) => { + fs.stat(dir, (er, st) => { + if (er || !st.isDirectory()) + er = new CwdError(dir, er && er.code || 'ENOTDIR') + cb(er) + }) +} + +module.exports = (dir, opt, cb) => { + dir = normPath(dir) + // if there's any overlap between mask and mode, // then we'll need an explicit chmod const umask = opt.umask @@ -49,13 +63,13 @@ const mkdir = module.exports = (dir, opt, cb) => { const preserve = opt.preserve const unlink = opt.unlink const cache = opt.cache - const cwd = opt.cwd + const cwd = normPath(opt.cwd) const done = (er, created) => { if (er) cb(er) else { - cache.set(dir, true) + cSet(cache, dir, true) if (created && doChown) chownr(created, uid, gid, er => done(er)) else if (needChmod) @@ -65,21 +79,17 @@ const mkdir = module.exports = (dir, opt, cb) => { } } - if (cache && cache.get(dir) === true) + if (cache && cGet(cache, dir) === true) return done() if (dir === cwd) - return fs.lstat(dir, (er, st) => { - if (er || !st.isDirectory()) - er = new CwdError(dir, er && er.code || 'ENOTDIR') - done(er) - }) + return checkCwd(dir, done) if (preserve) return mkdirp(dir, mode, done) - const sub = path.relative(cwd, dir) - const parts = sub.split(/\/|\\/) + const sub = normPath(path.relative(cwd, dir)) + const parts = sub.split('/') mkdir_(cwd, parts, mode, cache, unlink, cwd, null, done) } @@ -87,22 +97,19 @@ const mkdir_ = (base, parts, mode, cache, unlink, cwd, created, cb) => { if (!parts.length) return cb(null, created) const p = parts.shift() - const part = base + '/' + p - if (cache.get(part)) + const part = normPath(path.resolve(base + '/' + p)) + if (cGet(cache, part)) return mkdir_(part, parts, mode, cache, unlink, cwd, created, cb) fs.mkdir(part, mode, onmkdir(part, parts, mode, cache, unlink, cwd, created, cb)) } const onmkdir = (part, parts, mode, cache, unlink, cwd, created, cb) => er => { if (er) { - if (er.path && path.dirname(er.path) === cwd && - (er.code === 'ENOTDIR' || er.code === 'ENOENT')) - return cb(new CwdError(cwd, er.code)) - fs.lstat(part, (statEr, st) => { - if (statEr) + if (statEr) { + statEr.path = statEr.path && normPath(statEr.path) cb(statEr) - else if (st.isDirectory()) + } else if (st.isDirectory()) mkdir_(part, parts, mode, cache, unlink, cwd, created, cb) else if (unlink) fs.unlink(part, er => { @@ -121,7 +128,21 @@ const onmkdir = (part, parts, mode, cache, unlink, cwd, created, cb) => er => { } } -const mkdirSync = module.exports.sync = (dir, opt) => { +const checkCwdSync = dir => { + let ok = false + let code = 'ENOTDIR' + try { + ok = fs.statSync(dir).isDirectory() + } catch (er) { + code = er.code + } finally { + if (!ok) + throw new CwdError(dir, code) + } +} + +module.exports.sync = (dir, opt) => { + dir = normPath(dir) // if there's any overlap between mask and mode, // then we'll need an explicit chmod const umask = opt.umask @@ -137,65 +158,51 @@ const mkdirSync = module.exports.sync = (dir, opt) => { const preserve = opt.preserve const unlink = opt.unlink const cache = opt.cache - const cwd = opt.cwd + const cwd = normPath(opt.cwd) const done = (created) => { - cache.set(dir, true) + cSet(cache, dir, true) if (created && doChown) chownr.sync(created, uid, gid) if (needChmod) fs.chmodSync(dir, mode) } - if (cache && cache.get(dir) === true) + if (cache && cGet(cache, dir) === true) return done() if (dir === cwd) { - let ok = false - let code = 'ENOTDIR' - try { - ok = fs.lstatSync(dir).isDirectory() - } catch (er) { - code = er.code - } finally { - if (!ok) - throw new CwdError(dir, code) - } - done() - return + checkCwdSync(cwd) + return done() } if (preserve) return done(mkdirp.sync(dir, mode)) - const sub = path.relative(cwd, dir) - const parts = sub.split(/\/|\\/) + const sub = normPath(path.relative(cwd, dir)) + const parts = sub.split('/') let created = null for (let p = parts.shift(), part = cwd; - p && (part += '/' + p); - p = parts.shift()) { - - if (cache.get(part)) + p && (part += '/' + p); + p = parts.shift()) { + part = normPath(path.resolve(part)) + if (cGet(cache, part)) continue try { fs.mkdirSync(part, mode) created = created || part - cache.set(part, true) + cSet(cache, part, true) } catch (er) { - if (er.path && path.dirname(er.path) === cwd && - (er.code === 'ENOTDIR' || er.code === 'ENOENT')) - return new CwdError(cwd, er.code) - const st = fs.lstatSync(part) if (st.isDirectory()) { - cache.set(part, true) + cSet(cache, part, true) continue } else if (unlink) { fs.unlinkSync(part) fs.mkdirSync(part, mode) created = created || part - cache.set(part, true) + cSet(cache, part, true) continue } else if (st.isSymbolicLink()) return new SymlinkError(part, part + '/' + parts.join('/')) diff --git a/lib/normalize-windows-path.js b/lib/normalize-windows-path.js new file mode 100644 index 00000000..eb13ba01 --- /dev/null +++ b/lib/normalize-windows-path.js @@ -0,0 +1,8 @@ +// on windows, either \ or / are valid directory separators. +// on unix, \ is a valid character in filenames. +// so, on windows, and only on windows, we replace all \ chars with /, +// so that we can use / as our one and only directory separator char. + +const platform = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform +module.exports = platform !== 'win32' ? p => p + : p => p && p.replace(/\\/g, '/') diff --git a/lib/pack.js b/lib/pack.js index 857cea91..102a3d51 100644 --- a/lib/pack.js +++ b/lib/pack.js @@ -56,6 +56,7 @@ const ONDRAIN = Symbol('ondrain') const fs = require('fs') const path = require('path') const warner = require('./warn-mixin.js') +const normPath = require('./normalize-windows-path.js') const Pack = warner(class Pack extends MiniPass { constructor (opt) { @@ -67,7 +68,7 @@ const Pack = warner(class Pack extends MiniPass { this.preservePaths = !!opt.preservePaths this.strict = !!opt.strict this.noPax = !!opt.noPax - this.prefix = (opt.prefix || '').replace(/(\\|\/)+$/, '') + this.prefix = normPath(opt.prefix || '') this.linkCache = opt.linkCache || new Map() this.statCache = opt.statCache || new Map() this.readdirCache = opt.readdirCache || new Map() @@ -132,10 +133,7 @@ const Pack = warner(class Pack extends MiniPass { } [ADDTARENTRY] (p) { - const absolute = path.resolve(this.cwd, p.path) - if (this.prefix) - p.path = this.prefix + '/' + p.path.replace(/^\.(\/+|$)/, '') - + const absolute = normPath(path.resolve(this.cwd, p.path)) // in this case, we don't have to wait for the stat if (!this.filter(p.path, p)) p.resume() @@ -151,10 +149,7 @@ const Pack = warner(class Pack extends MiniPass { } [ADDFSENTRY] (p) { - const absolute = path.resolve(this.cwd, p) - if (this.prefix) - p = this.prefix + '/' + p.replace(/^\.(\/+|$)/, '') - + const absolute = normPath(path.resolve(this.cwd, p)) this[QUEUE].push(new PackJob(p, absolute)) this[PROCESS]() } @@ -298,7 +293,8 @@ const Pack = warner(class Pack extends MiniPass { linkCache: this.linkCache, statCache: this.statCache, noMtime: this.noMtime, - mtime: this.mtime + mtime: this.mtime, + prefix: this.prefix, } } @@ -324,10 +320,7 @@ const Pack = warner(class Pack extends MiniPass { if (job.readdir) job.readdir.forEach(entry => { - const p = this.prefix ? - job.path.slice(this.prefix.length + 1) || './' - : job.path - + const p = job.path const base = p === './' ? '' : p.replace(/\/*$/, '/') this[ADDFSENTRY](base + entry) }) @@ -380,10 +373,7 @@ class PackSync extends Pack { if (job.readdir) job.readdir.forEach(entry => { - const p = this.prefix ? - job.path.slice(this.prefix.length + 1) || './' - : job.path - + const p = job.path const base = p === './' ? '' : p.replace(/\/*$/, '/') this[ADDFSENTRY](base + entry) }) diff --git a/lib/parse.js b/lib/parse.js index 2a73b2bb..43d4383d 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -29,6 +29,7 @@ const maxMetaEntrySize = 1024 * 1024 const Entry = require('./read-entry.js') const Pax = require('./pax.js') const zlib = require('minizlib') +const Buffer = require('./buffer.js') const gzipHeader = Buffer.from([0x1f, 0x8b]) const STATE = Symbol('state') @@ -101,7 +102,12 @@ module.exports = warner(class Parser extends EE { } [CONSUMEHEADER] (chunk, position) { - const header = new Header(chunk, position) + let header + try { + header = new Header(chunk, position, this[EX], this[GEX]) + } catch (er) { + return this.warn('invalid entry', er) + } if (header.nullBlock) this[EMIT]('nullBlock') diff --git a/lib/path-reservations.js b/lib/path-reservations.js new file mode 100644 index 00000000..b7f6c916 --- /dev/null +++ b/lib/path-reservations.js @@ -0,0 +1,149 @@ +// A path exclusive reservation system +// reserve([list, of, paths], fn) +// When the fn is first in line for all its paths, it +// is called with a cb that clears the reservation. +// +// Used by async unpack to avoid clobbering paths in use, +// while still allowing maximal safe parallelization. + +const assert = require('assert') +const normPath = require('./normalize-windows-path.js') +const stripSlashes = require('./strip-trailing-slashes.js') +const { join } = require('path') + +const platform = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform +const isWindows = platform === 'win32' + +module.exports = () => { + // path => [function or Set] + // A Set object means a directory reservation + // A fn is a direct reservation on that path + const queues = new Map() + + // fn => {paths:[path,...], dirs:[path, ...]} + const reservations = new Map() + + // return a set of parent dirs for a given path + // '/a/b/c/d' -> ['/', '/a', '/a/b', '/a/b/c', '/a/b/c/d'] + const getDirs = path => { + const dirs = path.split('/').slice(0, -1).reduce((set, path) => { + if (set.length) + path = normPath(join(set[set.length - 1], path)) + set.push(path || '/') + return set + }, []) + return dirs + } + + // functions currently running + const running = new Set() + + // return the queues for each path the function cares about + // fn => {paths, dirs} + const getQueues = fn => { + const res = reservations.get(fn) + /* istanbul ignore if - unpossible */ + if (!res) + throw new Error('function does not have any path reservations') + return { + paths: res.paths.map(path => queues.get(path)), + dirs: [...res.dirs].map(path => queues.get(path)), + } + } + + // check if fn is first in line for all its paths, and is + // included in the first set for all its dir queues + const check = fn => { + const {paths, dirs} = getQueues(fn) + return paths.every(q => q[0] === fn) && + dirs.every(q => q[0] instanceof Set && q[0].has(fn)) + } + + // run the function if it's first in line and not already running + const run = fn => { + if (running.has(fn) || !check(fn)) + return false + running.add(fn) + fn(() => clear(fn)) + return true + } + + const clear = fn => { + if (!running.has(fn)) + return false + + const { paths, dirs } = reservations.get(fn) + const next = new Set() + + paths.forEach(path => { + const q = queues.get(path) + assert.equal(q[0], fn) + if (q.length === 1) + queues.delete(path) + else { + q.shift() + if (typeof q[0] === 'function') + next.add(q[0]) + else + q[0].forEach(fn => next.add(fn)) + } + }) + + dirs.forEach(dir => { + const q = queues.get(dir) + assert(q[0] instanceof Set) + if (q[0].size === 1 && q.length === 1) { + queues.delete(dir) + } else if (q[0].size === 1) { + q.shift() + + // must be a function or else the Set would've been reused + next.add(q[0]) + } else + q[0].delete(fn) + }) + running.delete(fn) + + next.forEach(fn => run(fn)) + return true + } + + const reserve = (paths, fn) => { + // collide on matches across case and unicode normalization + // On windows, thanks to the magic of 8.3 shortnames, it is fundamentally + // impossible to determine whether two paths refer to the same thing on + // disk, without asking the kernel for a shortname. + // So, we just pretend that every path matches every other path here, + // effectively removing all parallelization on windows. + paths = isWindows ? ['win32 parallelization disabled'] : paths.map(p => { + return stripSlashes(normPath(join(p))) + .normalize('NFKD') + .toLowerCase() + }) + + const dirs = new Set( + paths.map(path => getDirs(path)).reduce((a, b) => a.concat(b)) + ) + reservations.set(fn, {dirs, paths}) + paths.forEach(path => { + const q = queues.get(path) + if (!q) + queues.set(path, [fn]) + else + q.push(fn) + }) + dirs.forEach(dir => { + const q = queues.get(dir) + if (!q) + queues.set(dir, [new Set([fn])]) + else if (q[q.length-1] instanceof Set) + q[q.length-1].add(fn) + else + q.push(new Set([fn])) + }) + + return run(fn) + } + + return { check, reserve } +} diff --git a/lib/read-entry.js b/lib/read-entry.js index aa369c74..6ea3135c 100644 --- a/lib/read-entry.js +++ b/lib/read-entry.js @@ -1,11 +1,16 @@ 'use strict' const types = require('./types.js') const MiniPass = require('minipass') +const normPath = require('./normalize-windows-path.js') const SLURP = Symbol('slurp') module.exports = class ReadEntry extends MiniPass { constructor (header, ex, gex) { super() + // read entries always start life paused. this is to avoid the + // situation where Minipass's auto-ending empty streams results + // in an entry ending before we're ready for it. + this.pause() this.extended = ex this.globalExtended = gex this.header = header @@ -43,7 +48,7 @@ module.exports = class ReadEntry extends MiniPass { this.ignore = true } - this.path = header.path + this.path = normPath(header.path) this.mode = header.mode if (this.mode) this.mode = this.mode & 0o7777 @@ -55,7 +60,7 @@ module.exports = class ReadEntry extends MiniPass { this.mtime = header.mtime this.atime = header.atime this.ctime = header.ctime - this.linkpath = header.linkpath + this.linkpath = normPath(header.linkpath) this.uname = header.uname this.gname = header.gname @@ -88,7 +93,7 @@ module.exports = class ReadEntry extends MiniPass { // a global extended header, because that's weird. if (ex[k] !== null && ex[k] !== undefined && !(global && k === 'path')) - this[k] = ex[k] + this[k] = k === 'path' || k === 'linkpath' ? normPath(ex[k]) : ex[k] } } } diff --git a/lib/replace.js b/lib/replace.js index 571cee94..68d83a47 100644 --- a/lib/replace.js +++ b/lib/replace.js @@ -168,7 +168,8 @@ const replace = (opt, files, cb) => { fs.fstat(fd, (er, st) => { if (er) - return reject(er) + return fs.close(fd, () => reject(er)) + getPos(fd, st.size, (er, position) => { if (er) return reject(er) diff --git a/lib/strip-absolute-path.js b/lib/strip-absolute-path.js new file mode 100644 index 00000000..1aa2d2ae --- /dev/null +++ b/lib/strip-absolute-path.js @@ -0,0 +1,24 @@ +// unix absolute paths are also absolute on win32, so we use this for both +const { isAbsolute, parse } = require('path').win32 + +// returns [root, stripped] +// Note that windows will think that //x/y/z/a has a "root" of //x/y, and in +// those cases, we want to sanitize it to x/y/z/a, not z/a, so we strip / +// explicitly if it's the first character. +// drive-specific relative paths on Windows get their root stripped off even +// though they are not absolute, so `c:../foo` becomes ['c:', '../foo'] +module.exports = path => { + let r = '' + + let parsed = parse(path) + while (isAbsolute(path) || parsed.root) { + // windows will think that //x/y/z has a "root" of //x/y/ + // but strip the //?/C:/ off of //?/C:/path + const root = path.charAt(0) === '/' && path.slice(0, 4) !== '//?/' ? '/' + : parsed.root + path = path.substr(root.length) + r += root + parsed = parse(path) + } + return [r, path] +} diff --git a/lib/strip-trailing-slashes.js b/lib/strip-trailing-slashes.js new file mode 100644 index 00000000..f702ed5a --- /dev/null +++ b/lib/strip-trailing-slashes.js @@ -0,0 +1,24 @@ +// this is the only approach that was significantly faster than using +// str.replace(/\/+$/, '') for strings ending with a lot of / chars and +// containing multiple / chars. +const batchStrings = [ + '/'.repeat(1024), + '/'.repeat(512), + '/'.repeat(256), + '/'.repeat(128), + '/'.repeat(64), + '/'.repeat(32), + '/'.repeat(16), + '/'.repeat(8), + '/'.repeat(4), + '/'.repeat(2), + '/', +] + +module.exports = str => { + for (const s of batchStrings) { + while (str.length >= s.length && str.slice(-1 * s.length) === s) + str = str.slice(0, -1 * s.length) + } + return str +} diff --git a/lib/unpack.js b/lib/unpack.js index 5b79cda0..726c4576 100644 --- a/lib/unpack.js +++ b/lib/unpack.js @@ -1,5 +1,11 @@ 'use strict' +// the PEND/UNPEND stuff tracks whether we're ready to emit end/close yet. +// but the path reservations are required to avoid race conditions where +// parallelized unpack ops may mess with one another, due to dependencies +// (like a Link depending on its target) or destructive operations (like +// clobbering an fs object to create one of a different type.) + const assert = require('assert') const EE = require('events').EventEmitter const Parser = require('./parse.js') @@ -9,9 +15,15 @@ const path = require('path') const mkdir = require('./mkdir.js') const mkdirSync = mkdir.sync const wc = require('./winchars.js') +const stripAbsolutePath = require('./strip-absolute-path.js') +const pathReservations = require('./path-reservations.js') +const normPath = require('./normalize-windows-path.js') +const stripSlash = require('./strip-trailing-slashes.js') const ONENTRY = Symbol('onEntry') const CHECKFS = Symbol('checkFs') +const CHECKFS2 = Symbol('checkFs2') +const PRUNECACHE = Symbol('pruneCache') const ISREUSABLE = Symbol('isReusable') const MAKEFS = Symbol('makeFs') const FILE = Symbol('file') @@ -33,7 +45,10 @@ const SKIP = Symbol('skip') const DOCHOWN = Symbol('doChown') const UID = Symbol('uid') const GID = Symbol('gid') +const CHECKED_CWD = Symbol('checkedCwd') const crypto = require('crypto') +const platform = process.env.TESTING_TAR_FAKE_PLATFORM || process.platform +const isWindows = platform === 'win32' // Unlinks on Windows are not atomic. // @@ -52,7 +67,7 @@ const crypto = require('crypto') // See: https://github.com/npm/node-tar/issues/183 /* istanbul ignore next */ const unlinkFile = (path, cb) => { - if (process.platform !== 'win32') + if (!isWindows) return fs.unlink(path, cb) const name = path + '.DELETE.' + crypto.randomBytes(16).toString('hex') @@ -65,7 +80,7 @@ const unlinkFile = (path, cb) => { /* istanbul ignore next */ const unlinkFileSync = path => { - if (process.platform !== 'win32') + if (!isWindows) return fs.unlinkSync(path) const name = path + '.DELETE.' + crypto.randomBytes(16).toString('hex') @@ -79,6 +94,33 @@ const uint32 = (a, b, c) => : b === b >>> 0 ? b : c +// clear the cache if it's a case-insensitive unicode-squashing match. +// we can't know if the current file system is case-sensitive or supports +// unicode fully, so we check for similarity on the maximally compatible +// representation. Err on the side of pruning, since all it's doing is +// preventing lstats, and it's not the end of the world if we get a false +// positive. +// Note that on windows, we always drop the entire cache whenever a +// symbolic link is encountered, because 8.3 filenames are impossible +// to reason about, and collisions are hazards rather than just failures. +const cacheKeyNormalize = path => stripSlash(normPath(path)) + .normalize('NFKD') + .toLowerCase() + +const pruneCache = (cache, abs) => { + abs = cacheKeyNormalize(abs) + for (const path of cache.keys()) { + const pnorm = cacheKeyNormalize(path) + if (pnorm === abs || pnorm.indexOf(abs + '/') === 0) + cache.delete(path) + } +} + +const dropCache = cache => { + for (const key of cache.keys()) + cache.delete(key) +} + class Unpack extends Parser { constructor (opt) { if (!opt) @@ -91,6 +133,10 @@ class Unpack extends Parser { super(opt) + this[CHECKED_CWD] = false + + this.reservations = pathReservations() + this.transform = typeof opt.transform === 'function' ? opt.transform : null this.writable = true @@ -133,7 +179,7 @@ class Unpack extends Parser { this.forceChown = opt.forceChown === true // turn >= this.strip) + entry.linkpath = linkparts.slice(this.strip).join('/') + else + return false + } } if (!this.preservePaths) { - const p = entry.path - if (p.match(/(^|\/|\\)\.\.(\\|\/|$)/)) { - this.warn('path contains \'..\'', p) + const p = normPath(entry.path) + const parts = p.split('/') + if (parts.includes('..') || isWindows && /^[a-z]:\.\.$/i.test(parts[0])) { + this.warn(`path contains '..'`, p) return false } - // absolutes on posix are also absolutes on win32 - // so we only need to test this one to get both - if (path.win32.isAbsolute(p)) { - const parsed = path.win32.parse(p) - this.warn('stripping ' + parsed.root + ' from absolute path', p) - entry.path = p.substr(parsed.root.length) + // strip off the root + const s = stripAbsolutePath(p) + if (s[0]) { + entry.path = s[1] + this.warn(`stripping ${s[0]} from absolute path`, p) } } + if (path.isAbsolute(entry.path)) + entry.absolute = normPath(path.resolve(entry.path)) + else + entry.absolute = normPath(path.resolve(this.cwd, entry.path)) + + // if we somehow ended up with a path that escapes the cwd, and we are + // not in preservePaths mode, then something is fishy! This should have + // been prevented above, so ignore this for coverage. + /* istanbul ignore if - defense in depth */ + if (!this.preservePaths && + entry.absolute.indexOf(this.cwd + '/') !== 0 && + entry.absolute !== this.cwd) { + this.warn('TAR_ENTRY_ERROR', 'path escaped extraction target', { + entry, + path: normPath(entry.path), + resolvedPath: entry.absolute, + cwd: this.cwd, + }) + return false + } + + // an archive can set properties on the extraction directory, but it + // may not replace the cwd with a different kind of thing entirely. + if (entry.absolute === this.cwd && + entry.type !== 'Directory' && + entry.type !== 'GNUDumpDir') + return false + // only encode : chars that aren't drive letter indicators if (this.win32) { - const parsed = path.win32.parse(entry.path) - entry.path = parsed.root === '' ? wc.encode(entry.path) - : parsed.root + wc.encode(entry.path.substr(parsed.root.length)) + const { root: aRoot } = path.win32.parse(entry.absolute) + entry.absolute = aRoot + wc.encode(entry.absolute.substr(aRoot.length)) + const { root: pRoot } = path.win32.parse(entry.path) + entry.path = pRoot + wc.encode(entry.path.substr(pRoot.length)) } - if (path.isAbsolute(entry.path)) - entry.absolute = entry.path - else - entry.absolute = path.resolve(this.cwd, entry.path) - return true } @@ -251,7 +329,7 @@ class Unpack extends Parser { } [MKDIR] (dir, mode, cb) { - mkdir(dir, { + mkdir(normPath(dir), { uid: this.uid, gid: this.gid, processUid: this.processUid, @@ -285,21 +363,44 @@ class Unpack extends Parser { return uint32(this.gid, entry.gid, this.processGid) } - [FILE] (entry) { + [FILE] (entry, fullyDone) { const mode = entry.mode & 0o7777 || this.fmode const stream = new fsm.WriteStream(entry.absolute, { mode: mode, autoClose: false }) - stream.on('error', er => this[ONERROR](er, entry)) + stream.on('error', er => { + if (stream.fd) + fs.close(stream.fd, () => {}) + + // flush all the data out so that we aren't left hanging + // if the error wasn't actually fatal. otherwise the parse + // is blocked, and we never proceed. + /* istanbul ignore next */ + stream.write = () => true + this[ONERROR](er, entry) + fullyDone() + }) let actions = 1 const done = er => { - if (er) - return this[ONERROR](er, entry) + if (er) { + /* istanbul ignore else - we should always have a fd by now */ + if (stream.fd) + fs.close(stream.fd, () => {}) - if (--actions === 0) - fs.close(stream.fd, _ => this[UNPEND]()) + this[ONERROR](er, entry) + fullyDone() + return + } + + if (--actions === 0) { + fs.close(stream.fd, er => { + fullyDone() + /* istanbul ignore next */ + er ? this[ONERROR](er, entry) : this[UNPEND]() + }) + } } stream.on('finish', _ => { @@ -331,20 +432,25 @@ class Unpack extends Parser { }) const tx = this.transform ? this.transform(entry) || entry : entry - if (tx !== entry) + if (tx !== entry) { + tx.on('error', er => this[ONERROR](er, entry)) entry.pipe(tx) + } tx.pipe(stream) } - [DIRECTORY] (entry) { + [DIRECTORY] (entry, fullyDone) { const mode = entry.mode & 0o7777 || this.dmode this[MKDIR](entry.absolute, mode, er => { - if (er) + if (er) { + fullyDone() return this[ONERROR](er, entry) + } let actions = 1 const done = _ => { if (--actions === 0) { + fullyDone() this[UNPEND]() entry.resume() } @@ -369,12 +475,13 @@ class Unpack extends Parser { entry.resume() } - [SYMLINK] (entry) { - this[LINK](entry, entry.linkpath, 'symlink') + [SYMLINK] (entry, done) { + this[LINK](entry, entry.linkpath, 'symlink', done) } - [HARDLINK] (entry) { - this[LINK](entry, path.resolve(this.cwd, entry.linkpath), 'link') + [HARDLINK] (entry, done) { + const linkpath = normPath(path.resolve(this.cwd, entry.linkpath)) + this[LINK](entry, linkpath, 'link', done) } [PEND] () { @@ -399,35 +506,122 @@ class Unpack extends Parser { !this.unlink && st.isFile() && st.nlink <= 1 && - process.platform !== 'win32' + !isWindows } // check if a thing is there, and if so, try to clobber it [CHECKFS] (entry) { this[PEND]() - this[MKDIR](path.dirname(entry.absolute), this.dmode, er => { - if (er) - return this[ONERROR](er, entry) - fs.lstat(entry.absolute, (er, st) => { - if (st && (this.keep || this.newer && st.mtime > entry.mtime)) + const paths = [entry.path] + if (entry.linkpath) + paths.push(entry.linkpath) + this.reservations.reserve(paths, done => this[CHECKFS2](entry, done)) + } + + [PRUNECACHE] (entry) { + // if we are not creating a directory, and the path is in the dirCache, + // then that means we are about to delete the directory we created + // previously, and it is no longer going to be a directory, and neither + // is any of its children. + // If a symbolic link is encountered, all bets are off. There is no + // reasonable way to sanitize the cache in such a way we will be able to + // avoid having filesystem collisions. If this happens with a non-symlink + // entry, it'll just fail to unpack, but a symlink to a directory, using an + // 8.3 shortname or certain unicode attacks, can evade detection and lead + // to arbitrary writes to anywhere on the system. + if (entry.type === 'SymbolicLink') + dropCache(this.dirCache) + else if (entry.type !== 'Directory') + pruneCache(this.dirCache, entry.absolute) + } + + [CHECKFS2] (entry, fullyDone) { + this[PRUNECACHE](entry) + + const done = er => { + this[PRUNECACHE](entry) + fullyDone(er) + } + + const checkCwd = () => { + this[MKDIR](this.cwd, this.dmode, er => { + if (er) { + this[ONERROR](er, entry) + done() + return + } + this[CHECKED_CWD] = true + start() + }) + } + + const start = () => { + if (entry.absolute !== this.cwd) { + const parent = normPath(path.dirname(entry.absolute)) + if (parent !== this.cwd) { + return this[MKDIR](parent, this.dmode, er => { + if (er) { + this[ONERROR](er, entry) + done() + return + } + afterMakeParent() + }) + } + } + afterMakeParent() + } + + const afterMakeParent = () => { + fs.lstat(entry.absolute, (lstatEr, st) => { + if (st && (this.keep || this.newer && st.mtime > entry.mtime)) { this[SKIP](entry) - else if (er || this[ISREUSABLE](entry, st)) - this[MAKEFS](null, entry) - else if (st.isDirectory()) { + done() + return + } + if (lstatEr || this[ISREUSABLE](entry, st)) + return this[MAKEFS](null, entry, done) + + if (st.isDirectory()) { if (entry.type === 'Directory') { - if (!entry.mode || (st.mode & 0o7777) === entry.mode) - this[MAKEFS](null, entry) - else - fs.chmod(entry.absolute, entry.mode, er => this[MAKEFS](er, entry)) - } else - fs.rmdir(entry.absolute, er => this[MAKEFS](er, entry)) - } else - unlinkFile(entry.absolute, er => this[MAKEFS](er, entry)) + const needChmod = !this.noChmod && + entry.mode && + (st.mode & 0o7777) !== entry.mode + const afterChmod = er => this[MAKEFS](er, entry, done) + if (!needChmod) + return afterChmod() + return fs.chmod(entry.absolute, entry.mode, afterChmod) + } + // Not a dir entry, have to remove it. + // NB: the only way to end up with an entry that is the cwd + // itself, in such a way that == does not detect, is a + // tricky windows absolute path with UNC or 8.3 parts (and + // preservePaths:true, or else it will have been stripped). + // In that case, the user has opted out of path protections + // explicitly, so if they blow away the cwd, c'est la vie. + if (entry.absolute !== this.cwd) { + return fs.rmdir(entry.absolute, er => + this[MAKEFS](er, entry, done)) + } + } + + // not a dir, and not reusable + // don't remove if the cwd, we want that error + if (entry.absolute === this.cwd) + return this[MAKEFS](null, entry, done) + + unlinkFile(entry.absolute, er => + this[MAKEFS](er, entry, done)) }) - }) + } + + if (this[CHECKED_CWD]) + start() + else + checkCwd() } - [MAKEFS] (er, entry) { + [MAKEFS] (er, entry, done) { if (er) return this[ONERROR](er, entry) @@ -435,73 +629,107 @@ class Unpack extends Parser { case 'File': case 'OldFile': case 'ContiguousFile': - return this[FILE](entry) + return this[FILE](entry, done) case 'Link': - return this[HARDLINK](entry) + return this[HARDLINK](entry, done) case 'SymbolicLink': - return this[SYMLINK](entry) + return this[SYMLINK](entry, done) case 'Directory': case 'GNUDumpDir': - return this[DIRECTORY](entry) + return this[DIRECTORY](entry, done) } } - [LINK] (entry, linkpath, link) { - // XXX: get the type ('file' or 'dir') for windows + [LINK] (entry, linkpath, link, done) { + // XXX: get the type ('symlink' or 'junction') for windows fs[link](linkpath, entry.absolute, er => { if (er) return this[ONERROR](er, entry) + done() this[UNPEND]() entry.resume() }) } } +const callSync = fn => { + try { + return [null, fn()] + } catch (er) { + return [er, null] + } +} class UnpackSync extends Unpack { - constructor (opt) { - super(opt) + [MAKEFS] (er, entry) { + return super[MAKEFS](er, entry, /* istanbul ignore next */ () => {}) } [CHECKFS] (entry) { - const er = this[MKDIR](path.dirname(entry.absolute), this.dmode) - if (er) - return this[ONERROR](er, entry) - try { - const st = fs.lstatSync(entry.absolute) - if (this.keep || this.newer && st.mtime > entry.mtime) - return this[SKIP](entry) - else if (this[ISREUSABLE](entry, st)) - return this[MAKEFS](null, entry) - else { - try { - if (st.isDirectory()) { - if (entry.type === 'Directory') { - if (entry.mode && (st.mode & 0o7777) !== entry.mode) - fs.chmodSync(entry.absolute, entry.mode) - } else - fs.rmdirSync(entry.absolute) - } else - unlinkFileSync(entry.absolute) - return this[MAKEFS](null, entry) - } catch (er) { - return this[ONERROR](er, entry) - } + this[PRUNECACHE](entry) + + if (!this[CHECKED_CWD]) { + const er = this[MKDIR](this.cwd, this.dmode) + if (er) + return this[ONERROR](er, entry) + this[CHECKED_CWD] = true + } + + // don't bother to make the parent if the current entry is the cwd, + // we've already checked it. + if (entry.absolute !== this.cwd) { + const parent = normPath(path.dirname(entry.absolute)) + if (parent !== this.cwd) { + const mkParent = this[MKDIR](parent, this.dmode) + if (mkParent) + return this[ONERROR](mkParent, entry) } - } catch (er) { + } + + const [lstatEr, st] = callSync(() => fs.lstatSync(entry.absolute)) + if (st && (this.keep || this.newer && st.mtime > entry.mtime)) + return this[SKIP](entry) + + if (lstatEr || this[ISREUSABLE](entry, st)) return this[MAKEFS](null, entry) + + if (st.isDirectory()) { + if (entry.type === 'Directory') { + const needChmod = !this.noChmod && + entry.mode && + (st.mode & 0o7777) !== entry.mode + const [er] = needChmod ? callSync(() => { + fs.chmodSync(entry.absolute, entry.mode) + }) : [] + return this[MAKEFS](er, entry) + } + // not a dir entry, have to remove it + const [er] = callSync(() => fs.rmdirSync(entry.absolute)) + this[MAKEFS](er, entry) } + + // not a dir, and not reusable. + // don't remove if it's the cwd, since we want that error. + const [er] = entry.absolute === this.cwd ? [] + : callSync(() => unlinkFileSync(entry.absolute)) + this[MAKEFS](er, entry) } - [FILE] (entry) { + [FILE] (entry, done) { const mode = entry.mode & 0o7777 || this.fmode const oner = er => { - try { fs.closeSync(fd) } catch (_) {} - if (er) - this[ONERROR](er, entry) + let closeError + try { + fs.closeSync(fd) + } catch (e) { + closeError = e + } + if (er || closeError) + this[ONERROR](er || closeError, entry) + done() } let stream @@ -512,8 +740,10 @@ class UnpackSync extends Unpack { return oner(er) } const tx = this.transform ? this.transform(entry) || entry : entry - if (tx !== entry) + if (tx !== entry) { + tx.on('error', er => this[ONERROR](er, entry)) entry.pipe(tx) + } tx.on('data', chunk => { try { @@ -560,11 +790,14 @@ class UnpackSync extends Unpack { }) } - [DIRECTORY] (entry) { + [DIRECTORY] (entry, done) { const mode = entry.mode & 0o7777 || this.dmode const er = this[MKDIR](entry.absolute, mode) - if (er) - return this[ONERROR](er, entry) + if (er) { + this[ONERROR](er, entry) + done() + return + } if (entry.mtime && !this.noMtime) { try { fs.utimesSync(entry.absolute, entry.atime || new Date(), entry.mtime) @@ -575,12 +808,13 @@ class UnpackSync extends Unpack { fs.chownSync(entry.absolute, this[UID](entry), this[GID](entry)) } catch (er) {} } + done() entry.resume() } [MKDIR] (dir, mode) { try { - return mkdir.sync(dir, { + return mkdir.sync(normPath(dir), { uid: this.uid, gid: this.gid, processUid: this.processUid, @@ -597,9 +831,10 @@ class UnpackSync extends Unpack { } } - [LINK] (entry, linkpath, link) { + [LINK] (entry, linkpath, link, done) { try { fs[link + 'Sync'](linkpath, entry.absolute) + done() entry.resume() } catch (er) { return this[ONERROR](er, entry) diff --git a/lib/write-entry.js b/lib/write-entry.js index 3a4c99b9..239e4233 100644 --- a/lib/write-entry.js +++ b/lib/write-entry.js @@ -6,8 +6,16 @@ const Header = require('./header.js') const ReadEntry = require('./read-entry.js') const fs = require('fs') const path = require('path') +const normPath = require('./normalize-windows-path.js') +const stripSlash = require('./strip-trailing-slashes.js') + +const prefixPath = (path, prefix) => { + if (!prefix) + return path + path = normPath(path).replace(/^\.(\/|$)/, '') + return stripSlash(prefix) + '/' + path +} -const types = require('./types.js') const maxReadSize = 16 * 1024 * 1024 const PROCESS = Symbol('process') const FILE = Symbol('file') @@ -24,8 +32,13 @@ const OPENFILE = Symbol('openfile') const ONOPENFILE = Symbol('onopenfile') const CLOSE = Symbol('close') const MODE = Symbol('mode') +const AWAITDRAIN = Symbol('awaitDrain') +const ONDRAIN = Symbol('ondrain') +const PREFIX = Symbol('prefix') +const HAD_ERROR = Symbol('hadError') const warner = require('./warn-mixin.js') const winchars = require('./winchars.js') +const stripAbsolutePath = require('./strip-absolute-path.js') const modeFix = require('./mode-fix.js') @@ -35,40 +48,52 @@ const WriteEntry = warner(class WriteEntry extends MiniPass { super(opt) if (typeof p !== 'string') throw new TypeError('path is required') - this.path = p + this.path = normPath(p) // suppress atime, ctime, uid, gid, uname, gname this.portable = !!opt.portable // until node has builtin pwnam functions, this'll have to do - this.myuid = process.getuid && process.getuid() + this.myuid = process.getuid && process.getuid() || 0 this.myuser = process.env.USER || '' this.maxReadSize = opt.maxReadSize || maxReadSize this.linkCache = opt.linkCache || new Map() this.statCache = opt.statCache || new Map() this.preservePaths = !!opt.preservePaths - this.cwd = opt.cwd || process.cwd() + this.cwd = normPath(opt.cwd || process.cwd()) this.strict = !!opt.strict this.noPax = !!opt.noPax this.noMtime = !!opt.noMtime this.mtime = opt.mtime || null + this.prefix = opt.prefix ? normPath(opt.prefix) : null + + this.fd = null + this.blockLen = null + this.blockRemain = null + this.buf = null + this.offset = null + this.length = null + this.pos = null + this.remain = null if (typeof opt.onwarn === 'function') this.on('warn', opt.onwarn) - if (!this.preservePaths && path.win32.isAbsolute(p)) { - // absolutes on posix are also absolutes on win32 - // so we only need to test this one to get both - const parsed = path.win32.parse(p) - this.warn('stripping ' + parsed.root + ' from absolute path', p) - this.path = p.substr(parsed.root.length) + if (!this.preservePaths) { + const s = stripAbsolutePath(this.path) + if (s[0]) { + this.warn('stripping ' + s[0] + ' from absolute path', this.path) + this.path = s[1] + } } this.win32 = !!opt.win32 || process.platform === 'win32' if (this.win32) { + // force the \ to / normalization, since we might not *actually* + // be on windows, but want \ to be considered a path separator. this.path = winchars.decode(this.path.replace(/\\/g, '/')) p = p.replace(/\\/g, '/') } - this.absolute = opt.absolute || path.resolve(this.cwd, p) + this.absolute = normPath(opt.absolute || path.resolve(this.cwd, p)) if (this.path === '') this.path = './' @@ -79,6 +104,12 @@ const WriteEntry = warner(class WriteEntry extends MiniPass { this[LSTAT]() } + emit (ev, ...data) { + if (ev === 'error') + this[HAD_ERROR] = true + return super.emit(ev, ...data) + } + [LSTAT] () { fs.lstat(this.absolute, (er, stat) => { if (er) @@ -111,13 +142,19 @@ const WriteEntry = warner(class WriteEntry extends MiniPass { return modeFix(mode, this.type === 'Directory') } + [PREFIX] (path) { + return prefixPath(path, this.prefix) + } + [HEADER] () { if (this.type === 'Directory' && this.portable) this.noMtime = true this.header = new Header({ - path: this.path, - linkpath: this.linkpath, + path: this[PREFIX](this.path), + // only apply the prefix to hard links. + linkpath: this.type === 'Link' ? this[PREFIX](this.linkpath) + : this.linkpath, // only the permissions and setuid/setgid/sticky bitflags // not the higher-order bits that specify file type mode: this[MODE](this.stat.mode), @@ -132,14 +169,15 @@ const WriteEntry = warner(class WriteEntry extends MiniPass { ctime: this.portable ? null : this.stat.ctime }) - if (this.header.encode() && !this.noPax) - this.write(new Pax({ + if (this.header.encode() && !this.noPax) { + super.write(new Pax({ atime: this.portable ? null : this.header.atime, ctime: this.portable ? null : this.header.ctime, gid: this.portable ? null : this.header.gid, mtime: this.noMtime ? null : this.mtime || this.header.mtime, - path: this.path, - linkpath: this.linkpath, + path: this[PREFIX](this.path), + linkpath: this.type === 'Link' ? this[PREFIX](this.linkpath) + : this.linkpath, size: this.header.size, uid: this.portable ? null : this.header.uid, uname: this.portable ? null : this.header.uname, @@ -147,7 +185,8 @@ const WriteEntry = warner(class WriteEntry extends MiniPass { ino: this.portable ? null : this.stat.ino, nlink: this.portable ? null : this.stat.nlink }).encode()) - this.write(this.header.block) + } + super.write(this.header.block) } [DIRECTORY] () { @@ -167,14 +206,14 @@ const WriteEntry = warner(class WriteEntry extends MiniPass { } [ONREADLINK] (linkpath) { - this.linkpath = linkpath + this.linkpath = normPath(linkpath) this[HEADER]() this.end() } [HARDLINK] (linkpath) { this.type = 'Link' - this.linkpath = path.relative(this.cwd, linkpath) + this.linkpath = normPath(path.relative(this.cwd, linkpath)) this.stat.size = 0 this[HEADER]() this.end() @@ -207,65 +246,111 @@ const WriteEntry = warner(class WriteEntry extends MiniPass { } [ONOPENFILE] (fd) { - const blockLen = 512 * Math.ceil(this.stat.size / 512) - const bufLen = Math.min(blockLen, this.maxReadSize) - const buf = Buffer.allocUnsafe(bufLen) - this[READ](fd, buf, 0, buf.length, 0, this.stat.size, blockLen) + this.fd = fd + if (this[HAD_ERROR]) + return this[CLOSE]() + + this.blockLen = 512 * Math.ceil(this.stat.size / 512) + this.blockRemain = this.blockLen + const bufLen = Math.min(this.blockLen, this.maxReadSize) + this.buf = Buffer.allocUnsafe(bufLen) + this.offset = 0 + this.pos = 0 + this.remain = this.stat.size + this.length = this.buf.length + this[READ]() } - [READ] (fd, buf, offset, length, pos, remain, blockRemain) { + [READ] () { + const { fd, buf, offset, length, pos } = this fs.read(fd, buf, offset, length, pos, (er, bytesRead) => { - if (er) - return this[CLOSE](fd, _ => this.emit('error', er)) - this[ONREAD](fd, buf, offset, length, pos, remain, blockRemain, bytesRead) + if (er) { + // ignoring the error from close(2) is a bad practice, but at + // this point we already have an error, don't need another one + return this[CLOSE](() => this.emit('error', er)) + } + this[ONREAD](bytesRead) }) } - [CLOSE] (fd, cb) { - fs.close(fd, cb) + [CLOSE] (cb) { + fs.close(this.fd, cb) } - [ONREAD] (fd, buf, offset, length, pos, remain, blockRemain, bytesRead) { - if (bytesRead <= 0 && remain > 0) { - const er = new Error('unexpected EOF') + [ONREAD] (bytesRead) { + if (bytesRead <= 0 && this.remain > 0) { + const er = new Error('encountered unexpected EOF') + er.path = this.absolute + er.syscall = 'read' + er.code = 'EOF' + return this[CLOSE](() => this.emit('error', er)) + } + + if (bytesRead > this.remain) { + const er = new Error('did not encounter expected EOF') er.path = this.absolute er.syscall = 'read' er.code = 'EOF' - this.emit('error', er) + return this[CLOSE](() => this.emit('error', er)) } // null out the rest of the buffer, if we could fit the block padding - if (bytesRead === remain) { - for (let i = bytesRead; i < length && bytesRead < blockRemain; i++) { - buf[i + offset] = 0 - bytesRead ++ - remain ++ + // at the end of this loop, we've incremented bytesRead and this.remain + // to be incremented up to the blockRemain level, as if we had expected + // to get a null-padded file, and read it until the end. then we will + // decrement both remain and blockRemain by bytesRead, and know that we + // reached the expected EOF, without any null buffer to append. + if (bytesRead === this.remain) { + for (let i = bytesRead; i < this.length && bytesRead < this.blockRemain; i++) { + this.buf[i + this.offset] = 0 + bytesRead++ + this.remain++ } } - const writeBuf = offset === 0 && bytesRead === buf.length ? - buf : buf.slice(offset, offset + bytesRead) - remain -= bytesRead - blockRemain -= bytesRead - pos += bytesRead - offset += bytesRead - - this.write(writeBuf) - - if (!remain) { - if (blockRemain) - this.write(Buffer.alloc(blockRemain)) - this.end() - this[CLOSE](fd, _ => _) - return + const writeBuf = this.offset === 0 && bytesRead === this.buf.length ? + this.buf : this.buf.slice(this.offset, this.offset + bytesRead) + + const flushed = this.write(writeBuf) + if (!flushed) + this[AWAITDRAIN](() => this[ONDRAIN]()) + else + this[ONDRAIN]() + } + + [AWAITDRAIN] (cb) { + this.once('drain', cb) + } + + write (writeBuf) { + if (this.blockRemain < writeBuf.length) { + const er = new Error('writing more data than expected') + er.path = this.absolute + return this.emit('error', er) } + this.remain -= writeBuf.length + this.blockRemain -= writeBuf.length + this.pos += writeBuf.length + this.offset += writeBuf.length + return super.write(writeBuf) + } - if (offset >= length) { - buf = Buffer.allocUnsafe(length) - offset = 0 + [ONDRAIN] () { + if (!this.remain) { + if (this.blockRemain) + super.write(Buffer.alloc(this.blockRemain)) + return this[CLOSE](/* istanbul ignore next - legacy */ + er => er ? this.emit('error', er) : this.end()) } - length = buf.length - offset - this[READ](fd, buf, offset, length, pos, remain, blockRemain) + + if (this.offset >= this.length) { + // if we only have a smaller bit left to read, alloc a smaller buffer + // otherwise, keep it the same length it was before. + this.buf = Buffer.allocUnsafe(Math.min(this.blockRemain, this.buf.length)) + this.offset = 0 + } + this.length = this.buf.length - this.offset + this[READ]() } }) @@ -286,20 +371,31 @@ class WriteEntrySync extends WriteEntry { this[ONOPENFILE](fs.openSync(this.absolute, 'r')) } - [READ] (fd, buf, offset, length, pos, remain, blockRemain) { + [READ] () { let threw = true try { + const { fd, buf, offset, length, pos } = this const bytesRead = fs.readSync(fd, buf, offset, length, pos) - this[ONREAD](fd, buf, offset, length, pos, remain, blockRemain, bytesRead) + this[ONREAD](bytesRead) threw = false } finally { - if (threw) - try { this[CLOSE](fd) } catch (er) {} + // ignoring the error from close(2) is a bad practice, but at + // this point we already have an error, don't need another one + if (threw) { + try { + this[CLOSE](() => {}) + } catch (er) {} + } } } - [CLOSE] (fd) { - fs.closeSync(fd) + [AWAITDRAIN] (cb) { + cb() + } + + [CLOSE] (cb) { + fs.closeSync(this.fd) + cb() } } @@ -318,7 +414,9 @@ const WriteEntryTar = warner(class WriteEntryTar extends MiniPass { if (this.type === 'Directory' && this.portable) this.noMtime = true - this.path = readEntry.path + this.prefix = opt.prefix || null + + this.path = normPath(readEntry.path) this.mode = this[MODE](readEntry.mode) this.uid = this.portable ? null : readEntry.uid this.gid = this.portable ? null : readEntry.gid @@ -328,26 +426,29 @@ const WriteEntryTar = warner(class WriteEntryTar extends MiniPass { this.mtime = this.noMtime ? null : opt.mtime || readEntry.mtime this.atime = this.portable ? null : readEntry.atime this.ctime = this.portable ? null : readEntry.ctime - this.linkpath = readEntry.linkpath + this.linkpath = normPath(readEntry.linkpath) if (typeof opt.onwarn === 'function') this.on('warn', opt.onwarn) - if (path.isAbsolute(this.path) && !this.preservePaths) { - const parsed = path.parse(this.path) - this.warn( - 'stripping ' + parsed.root + ' from absolute path', - this.path - ) - this.path = this.path.substr(parsed.root.length) + if (!this.preservePaths) { + const s = stripAbsolutePath(this.path) + if (s[0]) { + this.warn( + 'stripping ' + s[0] + ' from absolute path', + this.path + ) + this.path = s[1] + } } this.remain = readEntry.size this.blockRemain = readEntry.startBlockSize this.header = new Header({ - path: this.path, - linkpath: this.linkpath, + path: this[PREFIX](this.path), + linkpath: this.type === 'Link' ? this[PREFIX](this.linkpath) + : this.linkpath, // only the permissions and setuid/setgid/sticky bitflags // not the higher-order bits that specify file type mode: this.mode, @@ -367,8 +468,9 @@ const WriteEntryTar = warner(class WriteEntryTar extends MiniPass { ctime: this.portable ? null : this.ctime, gid: this.portable ? null : this.gid, mtime: this.noMtime ? null : this.mtime, - path: this.path, - linkpath: this.linkpath, + path: this[PREFIX](this.path), + linkpath: this.type === 'Link' ? this[PREFIX](this.linkpath) + : this.linkpath, size: this.size, uid: this.portable ? null : this.uid, uname: this.portable ? null : this.uname, @@ -381,6 +483,10 @@ const WriteEntryTar = warner(class WriteEntryTar extends MiniPass { readEntry.pipe(this) } + [PREFIX] (path) { + return prefixPath(path, this.prefix) + } + [MODE] (mode) { return modeFix(mode, this.type === 'Directory') } @@ -395,7 +501,7 @@ const WriteEntryTar = warner(class WriteEntryTar extends MiniPass { end () { if (this.blockRemain) - this.write(Buffer.alloc(this.blockRemain)) + super.write(Buffer.alloc(this.blockRemain)) return super.end() } }) diff --git a/map.js b/map.js new file mode 100644 index 00000000..adeceef6 --- /dev/null +++ b/map.js @@ -0,0 +1,9 @@ +const {basename} = require('path') + +const map = test => + test === 'index.js' || test === 'map.js' ? test + : test === 'unpack.js' ? ['lib/unpack.js', 'lib/mkdir.js'] + : test === 'load-all.js' ? [] + : `lib/${test}` + +module.exports = test => map(basename(test)) diff --git a/package-lock.json b/package-lock.json index a498a844..6268f47c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,25 +1,192 @@ { "name": "tar", - "version": "4.4.4", + "version": "4.4.19", "lockfileVersion": 1, "requires": true, "dependencies": { + "@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.14.5" + } + }, + "@babel/generator": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.0.tgz", + "integrity": "sha512-eKl4XdMrbpYvuB505KTta4AV9g+wWzmVBW69tX0H2NwKVKd2YJbKgyK6M8j/rgLbmHOYJn6rUklV677nOyJrEQ==", + "dev": true, + "requires": { + "@babel/types": "^7.15.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/helper-function-name": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", + "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", + "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz", + "integrity": "sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", + "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.14.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz", + "integrity": "sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==", + "dev": true + }, + "@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.15.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.2.tgz", + "integrity": "sha512-bMJXql1Ss8lFnvr11TZDH4ArtwlAS5NG9qBmdiFW2UHHm6MVoR+GDc5XE2b9K938cyjc9O6/+vjjcffLDtfuDg==", + "dev": true + }, + "@babel/template": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", + "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5" + } + }, + "@babel/traverse": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.0.tgz", + "integrity": "sha512-392d8BN0C9eVxVWd8H6x9WfipgVH5IaIoLp23334Sc1vbKKWINnvwRpb4us0xtPaCumlwbTtIYNA0Dv/32sVFw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.15.0", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-hoist-variables": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/parser": "^7.15.0", + "@babel/types": "^7.15.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.0.tgz", + "integrity": "sha512-OBvfqnllOIdX4ojTHpwZbpvz4j3EWyjkZEdmjH0/cgsd6QOdSgU8rLSk6ard/pcW7rlmjdVSX/AWOaORR1uNOQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.9", + "to-fast-properties": "^2.0.0" + } + }, "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", + "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "append-transform": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", + "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", + "dev": true, + "requires": { + "default-require-extensions": "^2.0.0" + } + }, + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "dev": true + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "dev": true }, "argparse": { @@ -32,10 +199,13 @@ } }, "asn1": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", - "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", - "dev": true + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } }, "assert-plus": { "version": "1.0.0", @@ -43,6 +213,15 @@ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true }, + "async-hook-domain": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/async-hook-domain/-/async-hook-domain-1.1.3.tgz", + "integrity": "sha512-ZovMxSbADV3+biB7oR1GL5lGyptI24alp0LWHlmz1OFc5oL47pz3EiIF6nXOkDW7yLqih4NtsiYduzdDW0i+Wg==", + "dev": true, + "requires": { + "source-map-support": "^0.5.11" + } + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -56,31 +235,36 @@ "dev": true }, "aws4": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz", - "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", "dev": true }, "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, "bcrypt-pbkdf": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", - "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", "dev": true, - "optional": true, "requires": { "tweetnacl": "^0.14.3" } }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, "bind-obj-methods": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/bind-obj-methods/-/bind-obj-methods-2.0.0.tgz", - "integrity": "sha512-3/qRXczDi2Cdbz6jE+W3IflJOutRVica8frpBn14de1mBOkzDo+6tY33kNhvkw54Kn3PzRRD2VnGbGPcTAk4sw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bind-obj-methods/-/bind-obj-methods-2.0.2.tgz", + "integrity": "sha512-bUkRdEOppT1Xg/jG0+bp0JSjUD9U0r7skxb/42WeBUjfBpW6COQTIgQmKX5J2Z3aMXcORKgN2N+d7IQwTK3pag==", "dev": true }, "bl": { @@ -93,48 +277,94 @@ "safe-buffer": "^5.1.1" } }, - "bluebird": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", - "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", - "dev": true - }, "brace-expansion": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", - "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", + "dev": true + }, "buffer-alloc": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.1.0.tgz", - "integrity": "sha1-BVFNM78WVtNUDGhPZbEgLpDsowM=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", "dev": true, "requires": { - "buffer-alloc-unsafe": "^0.1.0", - "buffer-fill": "^0.1.0" + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" } }, "buffer-alloc-unsafe": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-0.1.1.tgz", - "integrity": "sha1-/+H2dVHdBVc33iUzN7/oU9+rGmo=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", "dev": true }, "buffer-fill": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-0.1.1.tgz", - "integrity": "sha512-YgBMBzdRLEfgxJIGu2wrvI2E03tMCFU1p7d1KhB4BOoMN0VxmTFjSyN5JtKt9z8Z9JajMHruI6SE25W96wNv7Q==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", "dev": true }, "buffer-from": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.0.0.tgz", - "integrity": "sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "caching-transform": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-3.0.2.tgz", + "integrity": "sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w==", + "dev": true, + "requires": { + "hasha": "^3.0.0", + "make-dir": "^2.0.0", + "package-hash": "^3.0.0", + "write-file-atomic": "^2.4.2" + }, + "dependencies": { + "write-file-atomic": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", + "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + } + } + }, + "caller": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/caller/-/caller-1.0.1.tgz", + "integrity": "sha1-uFGGD3Dhlds9J3OVqhp+I+ow7PU=", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, "caseless": { @@ -143,27 +373,74 @@ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "dev": true }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, "chmodr": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chmodr/-/chmodr-1.0.2.tgz", - "integrity": "sha1-BGYrky0PAuxm3qorDqQoEZaOPrk=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/chmodr/-/chmodr-1.2.0.tgz", + "integrity": "sha512-Y5uI7Iq/Az6HgJEL6pdw7THVd7jbVOTPwsmcPOBjQL8e3N+pz872kzK5QxYGEy21iRys+iHWV0UZQXDFJo1hyA==", "dev": true }, + "chokidar": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", + "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, "chownr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", - "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=" + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + } }, - "clean-yaml-object": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/clean-yaml-object/-/clean-yaml-object-0.1.0.tgz", - "integrity": "sha1-Y/sRDcLOGoTcIfbZM0h20BCui2g=", + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, "color-support": { @@ -173,20 +450,43 @@ "dev": true }, "combined-stream": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", - "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, "requires": { "delayed-stream": "~1.0.0" } }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -194,24 +494,29 @@ "dev": true }, "coveralls": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.1.tgz", - "integrity": "sha512-FAzXwiDOYLGDWH+zgoIA+8GbWv50hlx+kpEJyvzLKOdnIBv9uWoVl4DhqGgyUHpiRjAlF8KYZSipWXYtllWH6Q==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.1.1.tgz", + "integrity": "sha512-+dxnG2NHncSD1NrqbSM3dn/lE57O6Qf/koe9+I7c+wzkqRmEvcp0kgJdxKInzYzkICKkFMZsX3Vct3++tsF9ww==", "dev": true, "requires": { - "js-yaml": "^3.6.1", - "lcov-parse": "^0.0.10", - "log-driver": "^1.2.5", - "minimist": "^1.2.0", - "request": "^2.79.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } + "js-yaml": "^3.13.1", + "lcov-parse": "^1.0.0", + "log-driver": "^1.2.7", + "minimist": "^1.2.5", + "request": "^2.88.2" + } + }, + "cp-file": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-6.2.0.tgz", + "integrity": "sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "make-dir": "^2.0.0", + "nested-error-stacks": "^2.0.0", + "pify": "^4.0.1", + "safe-buffer": "^5.0.1" } }, "cross-spawn": { @@ -222,6 +527,17 @@ "requires": { "lru-cache": "^4.0.1", "which": "^1.2.9" + }, + "dependencies": { + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } } }, "dashdash": { @@ -234,12 +550,27 @@ } }, "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "default-require-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", + "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", "dev": true, "requires": { - "ms": "2.0.0" + "strip-bom": "^3.0.0" } }, "delayed-stream": { @@ -249,40 +580,73 @@ "dev": true }, "diff": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz", - "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "diff-frag": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/diff-frag/-/diff-frag-1.1.1.tgz", + "integrity": "sha512-y0YLhUGviNXaypPimkzmOCaZf8ruocRb+dpOL/lfoicxBua2gkExddlbWxIP56Z5BpSg4gL5sAWhBN2iQm4HVQ==", "dev": true }, "ecc-jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", - "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", "dev": true, - "optional": true, "requires": { - "jsbn": "~0.1.0" + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" } }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dev": true, "requires": { "once": "^1.4.0" } }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, + "esm": { + "version": "3.2.25", + "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", + "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", + "dev": true + }, "esprima": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, "events-to-array": { @@ -292,9 +656,9 @@ "dev": true }, "extend": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", - "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true }, "extsprintf": { @@ -304,17 +668,69 @@ "dev": true }, "fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "findit": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "resolved": "https://registry.npmjs.org/findit/-/findit-2.0.0.tgz", + "integrity": "sha1-ZQnwEmr0wXhVHPqZOU4DLhOk1W4=", + "dev": true + }, + "flow-parser": { + "version": "0.157.0", + "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.157.0.tgz", + "integrity": "sha512-p0vdtrM8oAMlscIXpX0e/eGWll5NPteVChNtlQncbIbivH+BdiwXHN5QO6myAfmebd027r9RiQKdUPsFAiEVgQ==", "dev": true }, + "flow-remove-types": { + "version": "2.157.0", + "resolved": "https://registry.npmjs.org/flow-remove-types/-/flow-remove-types-2.157.0.tgz", + "integrity": "sha512-nqK4QAi3cMC4xDGeOJZgj2EXtb81p8s4r2WgHP3vMnGxmBW2qKYfsPm+dMX0GTHezNF39/O00AteldLQeSQLQw==", + "dev": true, + "requires": { + "flow-parser": "^0.157.0", + "pirates": "^3.0.2", + "vlq": "^0.2.1" + } + }, "foreground-child": { "version": "1.5.6", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", @@ -332,13 +748,13 @@ "dev": true }, "form-data": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", - "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", "dev": true, "requires": { "asynckit": "^0.4.0", - "combined-stream": "1.0.6", + "combined-stream": "^1.0.6", "mime-types": "^2.1.12" } }, @@ -355,11 +771,11 @@ "dev": true }, "fs-minipass": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz", - "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", "requires": { - "minipass": "^2.2.1" + "minipass": "^2.6.0" } }, "fs.realpath": { @@ -368,10 +784,29 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, "function-loop": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/function-loop/-/function-loop-1.0.1.tgz", - "integrity": "sha1-gHa7MF6OajzO7ikgdl8zDRkPNAw=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/function-loop/-/function-loop-1.0.2.tgz", + "integrity": "sha512-Iw4MzMfS3udk/rqxTiDDCllhGwlOrsr50zViTOO/W6lS/9y6B1J0BD2VZzrnWUYBJsl3aeqjgR5v7bWWhZSYbA==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, "getpass": { @@ -384,9 +819,9 @@ } }, "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -397,10 +832,25 @@ "path-is-absolute": "^1.0.0" } }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", "dev": true }, "har-schema": { @@ -410,18 +860,54 @@ "dev": true }, "har-validator": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", - "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", "dev": true, "requires": { - "ajv": "^5.1.0", + "ajv": "^6.12.3", "har-schema": "^2.0.0" } }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "hasha": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", + "integrity": "sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk=", + "dev": true, + "requires": { + "is-stream": "^1.0.1" + } + }, + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "dev": true, "requires": { @@ -452,6 +938,63 @@ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-core-module": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.5.0.tgz", + "integrity": "sha512-TXCMSDsEHMEEZ6eCA8rwRDbLu55MRGmrctljsBX/2v1d9/GzqHOxW5c5oPSgrUt2vBFXebu9rGqckXGPWOlYpg==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -476,10 +1019,144 @@ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", "dev": true }, + "istanbul-lib-coverage": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", + "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", + "dev": true + }, + "istanbul-lib-hook": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz", + "integrity": "sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==", + "dev": true, + "requires": { + "append-transform": "^1.0.0" + } + }, + "istanbul-lib-instrument": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", + "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", + "dev": true, + "requires": { + "@babel/generator": "^7.4.0", + "@babel/parser": "^7.4.3", + "@babel/template": "^7.4.0", + "@babel/traverse": "^7.4.3", + "@babel/types": "^7.4.0", + "istanbul-lib-coverage": "^2.0.5", + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "istanbul-lib-processinfo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-1.0.0.tgz", + "integrity": "sha512-FY0cPmWa4WoQNlvB8VOcafiRoB5nB+l2Pz2xGuXHRSy1KM8QFOYfz/rN+bGMCAeejrY3mrpF5oJHcN0s/garCg==", + "dev": true, + "requires": { + "archy": "^1.0.0", + "cross-spawn": "^6.0.5", + "istanbul-lib-coverage": "^2.0.3", + "rimraf": "^2.6.3", + "uuid": "^3.3.2" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "istanbul-lib-report": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", + "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "supports-color": "^6.1.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", + "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "rimraf": "^2.6.3", + "source-map": "^0.6.1" + } + }, + "istanbul-reports": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz", + "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0" + } + }, + "jackspeak": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-1.4.0.tgz", + "integrity": "sha512-VDcSunT+wcccoG46FtzuBAyQKlzhHjli4q31e1fIHGOsRspqNUFjVzGb+7eIFDlTvqLygxapDHPHS0ouT2o/tw==", + "dev": true, + "requires": { + "cliui": "^4.1.0" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, "js-yaml": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz", - "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==", + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, "requires": { "argparse": "^1.0.7", @@ -490,8 +1167,19 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true, - "optional": true + "dev": true + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true }, "json-schema": { "version": "0.2.3", @@ -500,9 +1188,9 @@ "dev": true }, "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, "json-stringify-safe": { @@ -524,9 +1212,45 @@ } }, "lcov-parse": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-0.0.10.tgz", - "integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz", + "integrity": "sha1-6w1GtUER68VhrLTECO+TY73I9+A=", + "dev": true + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", "dev": true }, "log-driver": { @@ -535,10 +1259,19 @@ "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", "dev": true }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, "lru-cache": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", - "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", "dev": true, "requires": { "pseudomap": "^1.0.2", @@ -553,19 +1286,44 @@ } } }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "merge-source-map": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", + "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", + "dev": true, + "requires": { + "source-map": "^0.6.1" + } + }, "mime-db": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", + "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==", "dev": true }, "mime-types": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "version": "2.1.32", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", + "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", "dev": true, "requires": { - "mime-db": "~1.33.0" + "mime-db": "1.49.0" } }, "minimatch": { @@ -578,39 +1336,39 @@ } }, "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, "minipass": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.3.tgz", - "integrity": "sha512-/jAn9/tEX4gnpyRATxgHEOV6xbcyxgT7iUnxo9Y3+OB0zX00TgKIv/2FZCf5brBbICcwbLqVv2ImjvWWrQMSYw==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" } }, "minizlib": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.1.0.tgz", - "integrity": "sha512-4T6Ur/GctZ27nHfpt9THOdRZNgyJ9FZchYO1ceg5S8Q3DNLCKYy44nCZzgCJgcvx2UM8czmqak5BCxJMrq37lA==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", "requires": { - "minipass": "^2.2.1" + "minipass": "^2.9.0" } }, "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "requires": { - "minimist": "0.0.8" + "minimist": "^1.2.5" } }, "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "mutate-fs": { @@ -619,2931 +1377,1884 @@ "integrity": "sha512-WI5pPPUNiWqaK2XdK94AVpxIc8GmZEXYlLfFbWuc4gUtBGHTK92jdPqFdx/lilxgb5Ep7tQ15NqCcJEOeq6wdA==", "dev": true }, + "nested-error-stacks": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz", + "integrity": "sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "dev": true + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, "nyc": { - "version": "11.8.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-11.8.0.tgz", - "integrity": "sha512-PUFq1PSsx5OinSk5g5aaZygcDdI3QQT5XUlbR9QRMihtMS6w0Gm8xj4BxmKeeAlpQXC5M2DIhH16Y+KejceivQ==", + "version": "14.1.1", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-14.1.1.tgz", + "integrity": "sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw==", "dev": true, "requires": { "archy": "^1.0.0", - "arrify": "^1.0.1", - "caching-transform": "^1.0.0", - "convert-source-map": "^1.5.1", - "debug-log": "^1.0.1", - "default-require-extensions": "^1.0.0", - "find-cache-dir": "^0.1.1", - "find-up": "^2.1.0", - "foreground-child": "^1.5.3", - "glob": "^7.0.6", - "istanbul-lib-coverage": "^1.1.2", - "istanbul-lib-hook": "^1.1.0", - "istanbul-lib-instrument": "^1.10.0", - "istanbul-lib-report": "^1.1.3", - "istanbul-lib-source-maps": "^1.2.3", - "istanbul-reports": "^1.4.0", - "md5-hex": "^1.2.0", + "caching-transform": "^3.0.2", + "convert-source-map": "^1.6.0", + "cp-file": "^6.2.0", + "find-cache-dir": "^2.1.0", + "find-up": "^3.0.0", + "foreground-child": "^1.5.6", + "glob": "^7.1.3", + "istanbul-lib-coverage": "^2.0.5", + "istanbul-lib-hook": "^2.0.7", + "istanbul-lib-instrument": "^3.3.0", + "istanbul-lib-report": "^2.0.8", + "istanbul-lib-source-maps": "^3.0.6", + "istanbul-reports": "^2.2.4", + "js-yaml": "^3.13.1", + "make-dir": "^2.1.0", "merge-source-map": "^1.1.0", - "micromatch": "^3.1.10", - "mkdirp": "^0.5.0", - "resolve-from": "^2.0.0", - "rimraf": "^2.6.2", - "signal-exit": "^3.0.1", + "resolve-from": "^4.0.0", + "rimraf": "^2.6.3", + "signal-exit": "^3.0.2", "spawn-wrap": "^1.4.2", - "test-exclude": "^4.2.0", - "yargs": "11.1.0", - "yargs-parser": "^8.0.0" + "test-exclude": "^5.2.3", + "uuid": "^3.3.2", + "yargs": "^13.2.2", + "yargs-parser": "^13.0.0" + } + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "own-or": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/own-or/-/own-or-1.0.0.tgz", + "integrity": "sha1-Tod/vtqaLsgAD7wLyuOWRe6L+Nw=", + "dev": true + }, + "own-or-env": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-or-env/-/own-or-env-1.0.1.tgz", + "integrity": "sha512-y8qULRbRAlL6x2+M0vIe7jJbJx/kmUTzYonRAa2ayesR2qWLswninkVyeJe4x3IEXhdgoNodzjQRKAoEs6Fmrw==", + "dev": true, + "requires": { + "own-or": "^1.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "package-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-3.0.0.tgz", + "integrity": "sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "hasha": "^3.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" }, "dependencies": { - "align-text": { - "version": "0.1.4", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^3.0.2", - "longest": "^1.0.1", - "repeat-string": "^1.5.2" - } - }, - "amdefine": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "bundled": true, - "dev": true - }, - "append-transform": { - "version": "0.4.0", - "bundled": true, - "dev": true, - "requires": { - "default-require-extensions": "^1.0.0" - } - }, - "archy": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "arr-diff": { - "version": "4.0.0", - "bundled": true, - "dev": true - }, - "arr-flatten": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "bundled": true, - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "bundled": true, - "dev": true - }, - "arrify": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "async": { - "version": "1.5.2", - "bundled": true, - "dev": true - }, - "atob": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "babel-code-frame": { - "version": "6.26.0", - "bundled": true, - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - } - }, - "babel-generator": { - "version": "6.26.1", - "bundled": true, - "dev": true, - "requires": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.17.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" - } - }, - "babel-messages": { - "version": "6.23.0", - "bundled": true, - "dev": true, - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-runtime": { - "version": "6.26.0", - "bundled": true, - "dev": true, - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "babel-template": { - "version": "6.26.0", - "bundled": true, - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" - } - }, - "babel-traverse": { - "version": "6.26.0", - "bundled": true, - "dev": true, - "requires": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" - } - }, - "babel-types": { - "version": "6.26.0", - "bundled": true, - "dev": true, - "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" - } - }, - "babylon": { - "version": "6.18.0", - "bundled": true, - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "base": { - "version": "0.11.2", - "bundled": true, - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "bundled": true, - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "bundled": true, - "dev": true - } - } - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "2.3.2", - "bundled": true, - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "builtin-modules": { - "version": "1.1.1", - "bundled": true, - "dev": true - }, - "cache-base": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "bundled": true, - "dev": true - } - } - }, - "caching-transform": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "md5-hex": "^1.2.0", - "mkdirp": "^0.5.1", - "write-file-atomic": "^1.1.4" - } - }, - "camelcase": { - "version": "1.2.1", - "bundled": true, - "dev": true, - "optional": true - }, - "center-align": { - "version": "0.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "align-text": "^0.1.3", - "lazy-cache": "^1.0.3" - } - }, - "chalk": { - "version": "1.1.3", - "bundled": true, - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "class-utils": { - "version": "0.3.6", - "bundled": true, - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "bundled": true, - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "bundled": true, - "dev": true - } - } - }, - "cliui": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "center-align": "^0.1.1", - "right-align": "^0.1.1", - "wordwrap": "0.0.2" - }, - "dependencies": { - "wordwrap": { - "version": "0.0.2", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "collection-visit": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "commondir": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "component-emitter": { - "version": "1.2.1", - "bundled": true, - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true - }, - "convert-source-map": { - "version": "1.5.1", - "bundled": true, - "dev": true - }, - "copy-descriptor": { - "version": "0.1.1", - "bundled": true, - "dev": true - }, - "core-js": { - "version": "2.5.6", - "bundled": true, - "dev": true - }, - "cross-spawn": { - "version": "4.0.2", - "bundled": true, - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "which": "^1.2.9" - } - }, - "debug": { - "version": "2.6.9", - "bundled": true, - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "debug-log": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "decamelize": { - "version": "1.2.0", - "bundled": true, - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "bundled": true, - "dev": true - }, - "default-require-extensions": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "strip-bom": "^2.0.0" - } - }, - "define-property": { - "version": "2.0.2", - "bundled": true, - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "bundled": true, - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "bundled": true, - "dev": true - } - } - }, - "detect-indent": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "repeating": "^2.0.0" - } - }, - "error-ex": { - "version": "1.3.1", - "bundled": true, - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "bundled": true, - "dev": true - }, - "esutils": { - "version": "2.0.2", - "bundled": true, - "dev": true - }, - "execa": { - "version": "0.7.0", - "bundled": true, - "dev": true, - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "dependencies": { - "cross-spawn": { - "version": "5.1.0", - "bundled": true, - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - } - } - }, - "expand-brackets": { - "version": "2.1.4", - "bundled": true, - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "bundled": true, - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "extend-shallow": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "2.0.4", - "bundled": true, - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "kind-of": { - "version": "6.0.2", - "bundled": true, - "dev": true - } - } - }, - "fill-range": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "find-cache-dir": { - "version": "0.1.1", - "bundled": true, - "dev": true, - "requires": { - "commondir": "^1.0.1", - "mkdirp": "^0.5.1", - "pkg-dir": "^1.0.0" - } - }, - "find-up": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "for-in": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "foreground-child": { - "version": "1.5.6", - "bundled": true, - "dev": true, - "requires": { - "cross-spawn": "^4", - "signal-exit": "^3.0.0" - } - }, - "fragment-cache": { - "version": "0.2.1", - "bundled": true, - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "get-caller-file": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "get-stream": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "get-value": { - "version": "2.0.6", - "bundled": true, - "dev": true - }, - "glob": { - "version": "7.1.2", - "bundled": true, - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "globals": { - "version": "9.18.0", - "bundled": true, - "dev": true - }, - "graceful-fs": { - "version": "4.1.11", - "bundled": true, - "dev": true - }, - "handlebars": { - "version": "4.0.11", - "bundled": true, - "dev": true, - "requires": { - "async": "^1.4.0", - "optimist": "^0.6.1", - "source-map": "^0.4.4", - "uglify-js": "^2.6" - }, - "dependencies": { - "source-map": { - "version": "0.4.4", - "bundled": true, - "dev": true, - "requires": { - "amdefine": ">=0.0.4" - } - } - } - }, - "has-ansi": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "has-value": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "bundled": true, - "dev": true - } - } - }, - "has-values": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "bundled": true, - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "bundled": true, - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hosted-git-info": { - "version": "2.6.0", - "bundled": true, - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "bundled": true, - "dev": true - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true - }, - "invariant": { - "version": "2.2.4", - "bundled": true, - "dev": true, - "requires": { - "loose-envify": "^1.0.0" - } - }, - "invert-kv": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-arrayish": { - "version": "0.2.1", - "bundled": true, - "dev": true - }, - "is-buffer": { - "version": "1.1.6", - "bundled": true, - "dev": true - }, - "is-builtin-module": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "builtin-modules": "^1.0.0" - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-descriptor": { - "version": "0.1.6", - "bundled": true, - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "bundled": true, - "dev": true - } - } - }, - "is-extendable": { - "version": "0.1.1", - "bundled": true, - "dev": true - }, - "is-finite": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "is-number": { + "pify": { "version": "3.0.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-odd": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "is-number": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "bundled": true, - "dev": true - } - } - }, - "is-plain-object": { - "version": "2.0.4", - "bundled": true, - "dev": true, - "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "bundled": true, - "dev": true - } - } - }, - "is-stream": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "is-utf8": { - "version": "0.2.1", - "bundled": true, - "dev": true - }, - "is-windows": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "isexe": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "isobject": { - "version": "3.0.1", - "bundled": true, - "dev": true - }, - "istanbul-lib-coverage": { - "version": "1.2.0", - "bundled": true, - "dev": true - }, - "istanbul-lib-hook": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "requires": { - "append-transform": "^0.4.0" - } - }, - "istanbul-lib-instrument": { - "version": "1.10.1", - "bundled": true, - "dev": true, - "requires": { - "babel-generator": "^6.18.0", - "babel-template": "^6.16.0", - "babel-traverse": "^6.18.0", - "babel-types": "^6.18.0", - "babylon": "^6.18.0", - "istanbul-lib-coverage": "^1.2.0", - "semver": "^5.3.0" - } - }, - "istanbul-lib-report": { - "version": "1.1.3", - "bundled": true, - "dev": true, - "requires": { - "istanbul-lib-coverage": "^1.1.2", - "mkdirp": "^0.5.1", - "path-parse": "^1.0.5", - "supports-color": "^3.1.2" - }, - "dependencies": { - "supports-color": { - "version": "3.2.3", - "bundled": true, - "dev": true, - "requires": { - "has-flag": "^1.0.0" - } - } - } - }, - "istanbul-lib-source-maps": { - "version": "1.2.3", - "bundled": true, - "dev": true, - "requires": { - "debug": "^3.1.0", - "istanbul-lib-coverage": "^1.1.2", - "mkdirp": "^0.5.1", - "rimraf": "^2.6.1", - "source-map": "^0.5.3" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "bundled": true, - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, - "istanbul-reports": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "requires": { - "handlebars": "^4.0.3" - } - }, - "js-tokens": { - "version": "3.0.2", - "bundled": true, - "dev": true - }, - "jsesc": { - "version": "1.3.0", - "bundled": true, - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "bundled": true, - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lazy-cache": { - "version": "1.0.4", - "bundled": true, - "dev": true, - "optional": true - }, - "lcid": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, - "load-json-file": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "dependencies": { - "path-exists": { - "version": "3.0.0", - "bundled": true, - "dev": true - } - } - }, - "lodash": { - "version": "4.17.10", - "bundled": true, + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true - }, - "longest": { - "version": "1.0.1", - "bundled": true, + } + } + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pirates": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-3.0.2.tgz", + "integrity": "sha512-c5CgUJq6H2k6MJz72Ak1F5sN9n9wlSlJyEnwvpm9/y3WB4E3pHBDT2c6PEiS1vyJvq2bUxUAIu0EGf8Cx4Ic7Q==", + "dev": true, + "requires": { + "node-modules-regexp": "^1.0.0" + } + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "dev": true, + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "pump": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", + "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "react": { + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", + "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", + "dev": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2" + } + }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", + "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", + "dev": true, + "requires": { + "find-up": "^3.0.0", + "read-pkg": "^3.0.0" + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true - }, - "loose-envify": { + } + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", + "dev": true, + "requires": { + "es6-error": "^4.0.1" + } + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-inject": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/require-inject/-/require-inject-1.4.4.tgz", + "integrity": "sha512-5Y5ctRN84+I4iOZO61gm+48tgP/6Hcd3VZydkaEM3MCuOvnHRsTJYQBOc01faI/Z9at5nsCAJVHhlfPA6Pc0Og==", + "dev": true, + "requires": { + "caller": "^1.0.1" + } + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "spawn-wrap": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.3.tgz", + "integrity": "sha512-IgB8md0QW/+tWqcavuFgKYR/qIRvJkRLPJDFaoXtLLUaVcCDK0+HeFTkmQHj3eprcYhc+gOl0aEA1w7qZlYezw==", + "dev": true, + "requires": { + "foreground-child": "^1.5.6", + "mkdirp": "^0.5.0", + "os-homedir": "^1.0.1", + "rimraf": "^2.6.2", + "signal-exit": "^3.0.2", + "which": "^1.3.0" + }, + "dependencies": { + "which": { "version": "1.3.1", - "bundled": true, - "dev": true, - "requires": { - "js-tokens": "^3.0.0" - } - }, - "lru-cache": { - "version": "4.1.3", - "bundled": true, + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" + "isexe": "^2.0.0" } - }, - "map-cache": { - "version": "0.2.2", - "bundled": true, + } + } + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz", + "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "stack-utils": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.5.tgz", + "integrity": "sha512-KZiTzuV3CnSnSvgMRrARVCj+Ht7rMbauGDK0LdVFRGyenwdylpajAp4Q0i6SX8rEmbTpMMf6ryq2gb8pPq2WgQ==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true - }, - "map-visit": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "md5-hex": { - "version": "1.3.0", - "bundled": true, - "dev": true, - "requires": { - "md5-o-matic": "^0.1.1" - } - }, - "md5-o-matic": { - "version": "0.1.1", - "bundled": true, + } + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true - }, - "mem": { - "version": "1.1.0", + } + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "tap": { + "version": "14.11.0", + "resolved": "https://registry.npmjs.org/tap/-/tap-14.11.0.tgz", + "integrity": "sha512-z8qnNFVyIjLh/bNoTLFRkEk09XZUDAZbCkz/BjvHHly3ao5H+y60gPnedALfheEjA6dA4tpp/mrKq2NWlMuq0A==", + "dev": true, + "requires": { + "@types/react": "^16.9.16", + "async-hook-domain": "^1.1.3", + "bind-obj-methods": "^2.0.0", + "browser-process-hrtime": "^1.0.0", + "chokidar": "^3.3.0", + "color-support": "^1.1.0", + "coveralls": "^3.0.11", + "diff": "^4.0.1", + "esm": "^3.2.25", + "findit": "^2.0.0", + "flow-remove-types": "^2.112.0", + "foreground-child": "^1.3.3", + "fs-exists-cached": "^1.0.0", + "function-loop": "^1.0.2", + "glob": "^7.1.6", + "import-jsx": "^3.1.0", + "ink": "^2.6.0", + "isexe": "^2.0.0", + "istanbul-lib-processinfo": "^1.0.0", + "jackspeak": "^1.4.0", + "minipass": "^3.1.1", + "mkdirp": "^0.5.4", + "nyc": "^14.1.1", + "opener": "^1.5.1", + "own-or": "^1.0.0", + "own-or-env": "^1.0.1", + "react": "^16.12.0", + "rimraf": "^2.7.1", + "signal-exit": "^3.0.0", + "source-map-support": "^0.5.16", + "stack-utils": "^1.0.3", + "tap-mocha-reporter": "^5.0.0", + "tap-parser": "^10.0.1", + "tap-yaml": "^1.0.0", + "tcompare": "^3.0.0", + "treport": "^1.0.2", + "trivial-deferred": "^1.0.1", + "ts-node": "^8.5.2", + "typescript": "^3.7.2", + "which": "^2.0.2", + "write-file-atomic": "^3.0.1", + "yaml": "^1.7.2", + "yapool": "^1.0.0" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.4", "bundled": true, "dev": true, "requires": { - "mimic-fn": "^1.0.0" + "@babel/highlight": "^7.10.4" } }, - "merge-source-map": { - "version": "1.1.0", + "@babel/core": { + "version": "7.10.5", "bundled": true, "dev": true, "requires": { - "source-map": "^0.6.1" + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.10.5", + "@babel/helper-module-transforms": "^7.10.5", + "@babel/helpers": "^7.10.4", + "@babel/parser": "^7.10.5", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.5", + "@babel/types": "^7.10.5", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.19", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" }, "dependencies": { "source-map": { - "version": "0.6.1", + "version": "0.5.7", "bundled": true, "dev": true } } }, - "micromatch": { - "version": "3.1.10", + "@babel/generator": { + "version": "7.10.5", "bundled": true, "dev": true, "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" + "@babel/types": "^7.10.5", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" }, "dependencies": { - "kind-of": { - "version": "6.0.2", + "source-map": { + "version": "0.5.7", "bundled": true, "dev": true } } }, - "mimic-fn": { - "version": "1.2.0", - "bundled": true, - "dev": true - }, - "minimatch": { - "version": "3.0.4", + "@babel/helper-annotate-as-pure": { + "version": "7.10.4", "bundled": true, "dev": true, "requires": { - "brace-expansion": "^1.1.7" + "@babel/types": "^7.10.4" } }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true - }, - "mixin-deep": { - "version": "1.3.1", + "@babel/helper-builder-react-jsx": { + "version": "7.10.4", "bundled": true, "dev": true, "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } + "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/types": "^7.10.4" } }, - "mkdirp": { - "version": "0.5.1", + "@babel/helper-builder-react-jsx-experimental": { + "version": "7.10.5", "bundled": true, "dev": true, "requires": { - "minimist": "0.0.8" + "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/helper-module-imports": "^7.10.4", + "@babel/types": "^7.10.5" } }, - "ms": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "nanomatch": { - "version": "1.2.9", + "@babel/helper-function-name": { + "version": "7.10.4", "bundled": true, "dev": true, "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-odd": "^2.0.0", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "bundled": true, - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "bundled": true, - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "bundled": true, - "dev": true - } + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" } }, - "normalize-package-data": { - "version": "2.4.0", + "@babel/helper-get-function-arity": { + "version": "7.10.4", "bundled": true, "dev": true, "requires": { - "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" + "@babel/types": "^7.10.4" } }, - "npm-run-path": { - "version": "2.0.2", + "@babel/helper-member-expression-to-functions": { + "version": "7.10.5", "bundled": true, "dev": true, "requires": { - "path-key": "^2.0.0" + "@babel/types": "^7.10.5" } }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true - }, - "object-copy": { - "version": "0.1.0", + "@babel/helper-module-imports": { + "version": "7.10.4", "bundled": true, "dev": true, "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "bundled": true, - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } + "@babel/types": "^7.10.4" } }, - "object-visit": { - "version": "1.0.1", + "@babel/helper-module-transforms": { + "version": "7.10.5", "bundled": true, "dev": true, "requires": { - "isobject": "^3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "bundled": true, - "dev": true - } + "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-simple-access": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.5", + "lodash": "^4.17.19" } }, - "object.pick": { - "version": "1.3.0", + "@babel/helper-optimise-call-expression": { + "version": "7.10.4", "bundled": true, "dev": true, "requires": { - "isobject": "^3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "bundled": true, - "dev": true - } + "@babel/types": "^7.10.4" } }, - "once": { - "version": "1.4.0", + "@babel/helper-plugin-utils": { + "version": "7.10.4", + "bundled": true, + "dev": true + }, + "@babel/helper-replace-supers": { + "version": "7.10.4", "bundled": true, "dev": true, "requires": { - "wrappy": "1" + "@babel/helper-member-expression-to-functions": "^7.10.4", + "@babel/helper-optimise-call-expression": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" } }, - "optimist": { - "version": "0.6.1", + "@babel/helper-simple-access": { + "version": "7.10.4", "bundled": true, "dev": true, "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" + "@babel/template": "^7.10.4", + "@babel/types": "^7.10.4" } }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "os-locale": { - "version": "2.1.0", + "@babel/helper-split-export-declaration": { + "version": "7.10.4", "bundled": true, "dev": true, "requires": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" + "@babel/types": "^7.10.4" } }, - "p-finally": { - "version": "1.0.0", + "@babel/helper-validator-identifier": { + "version": "7.10.4", "bundled": true, "dev": true }, - "p-limit": { - "version": "1.2.0", + "@babel/helpers": { + "version": "7.10.4", "bundled": true, "dev": true, "requires": { - "p-try": "^1.0.0" + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.10.4", + "@babel/types": "^7.10.4" } }, - "p-locate": { - "version": "2.0.0", + "@babel/highlight": { + "version": "7.10.4", "bundled": true, "dev": true, "requires": { - "p-limit": "^1.1.0" + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" } }, - "p-try": { - "version": "1.0.0", + "@babel/parser": { + "version": "7.10.5", "bundled": true, "dev": true }, - "parse-json": { - "version": "2.2.0", + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.10.4", "bundled": true, "dev": true, "requires": { - "error-ex": "^1.2.0" + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0", + "@babel/plugin-transform-parameters": "^7.10.4" } }, - "pascalcase": { - "version": "0.1.1", - "bundled": true, - "dev": true - }, - "path-exists": { - "version": "2.1.0", + "@babel/plugin-syntax-jsx": { + "version": "7.10.4", "bundled": true, "dev": true, "requires": { - "pinkie-promise": "^2.0.0" + "@babel/helper-plugin-utils": "^7.10.4" } }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "path-key": { - "version": "2.0.1", + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", "bundled": true, - "dev": true + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } }, - "path-parse": { - "version": "1.0.5", + "@babel/plugin-transform-destructuring": { + "version": "7.10.4", "bundled": true, - "dev": true + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } }, - "path-type": { - "version": "1.1.0", + "@babel/plugin-transform-parameters": { + "version": "7.10.5", "bundled": true, "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" + "@babel/helper-get-function-arity": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" } }, - "pify": { - "version": "2.3.0", + "@babel/plugin-transform-react-jsx": { + "version": "7.10.4", "bundled": true, - "dev": true + "dev": true, + "requires": { + "@babel/helper-builder-react-jsx": "^7.10.4", + "@babel/helper-builder-react-jsx-experimental": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-jsx": "^7.10.4" + } }, - "pinkie": { - "version": "2.0.4", + "@babel/template": { + "version": "7.10.4", "bundled": true, - "dev": true + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.10.4", + "@babel/types": "^7.10.4" + } }, - "pinkie-promise": { - "version": "2.0.1", + "@babel/traverse": { + "version": "7.10.5", "bundled": true, "dev": true, "requires": { - "pinkie": "^2.0.0" + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.10.5", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-split-export-declaration": "^7.10.4", + "@babel/parser": "^7.10.5", + "@babel/types": "^7.10.5", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" } }, - "pkg-dir": { - "version": "1.0.0", + "@babel/types": { + "version": "7.10.5", "bundled": true, "dev": true, "requires": { - "find-up": "^1.0.0" - }, - "dependencies": { - "find-up": { - "version": "1.1.2", - "bundled": true, - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - } + "@babel/helper-validator-identifier": "^7.10.4", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" } }, - "posix-character-classes": { - "version": "0.1.1", + "@types/color-name": { + "version": "1.1.1", "bundled": true, "dev": true }, - "pseudomap": { - "version": "1.0.2", + "@types/prop-types": { + "version": "15.7.3", "bundled": true, "dev": true }, - "read-pkg": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", + "@types/react": { + "version": "16.9.43", "bundled": true, "dev": true, "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" - }, - "dependencies": { - "find-up": { - "version": "1.1.2", - "bundled": true, - "dev": true, - "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - } + "@types/prop-types": "*", + "csstype": "^2.2.0" } }, - "regenerator-runtime": { - "version": "0.11.1", + "@types/yoga-layout": { + "version": "1.9.2", "bundled": true, "dev": true }, - "regex-not": { - "version": "1.0.2", + "ansi-escapes": { + "version": "4.3.1", "bundled": true, "dev": true, "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" + "type-fest": "^0.11.0" } }, - "repeat-element": { - "version": "1.1.2", - "bundled": true, - "dev": true - }, - "repeat-string": { - "version": "1.6.1", + "ansi-regex": { + "version": "5.0.0", "bundled": true, "dev": true }, - "repeating": { - "version": "2.0.1", + "ansi-styles": { + "version": "3.2.1", "bundled": true, "dev": true, "requires": { - "is-finite": "^1.0.0" + "color-convert": "^1.9.0" } }, - "require-directory": { - "version": "2.1.1", + "ansicolors": { + "version": "0.3.2", "bundled": true, "dev": true }, - "require-main-filename": { - "version": "1.0.1", + "arrify": { + "version": "2.0.1", "bundled": true, "dev": true }, - "resolve-from": { + "astral-regex": { "version": "2.0.0", "bundled": true, "dev": true }, - "resolve-url": { - "version": "0.2.1", - "bundled": true, - "dev": true - }, - "ret": { - "version": "0.1.15", + "auto-bind": { + "version": "4.0.0", "bundled": true, "dev": true }, - "right-align": { - "version": "0.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "align-text": "^0.1.1" - } - }, - "rimraf": { - "version": "2.6.2", + "caller-callsite": { + "version": "2.0.0", "bundled": true, "dev": true, "requires": { - "glob": "^7.0.5" + "callsites": "^2.0.0" } }, - "safe-regex": { - "version": "1.1.0", + "caller-path": { + "version": "2.0.0", "bundled": true, "dev": true, "requires": { - "ret": "~0.1.10" + "caller-callsite": "^2.0.0" } }, - "semver": { - "version": "5.5.0", - "bundled": true, - "dev": true - }, - "set-blocking": { + "callsites": { "version": "2.0.0", "bundled": true, "dev": true }, - "set-value": { - "version": "2.0.0", + "cardinal": { + "version": "2.1.1", "bundled": true, "dev": true, "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } + "ansicolors": "~0.3.2", + "redeyed": "~2.1.0" } }, - "shebang-command": { - "version": "1.2.0", + "chalk": { + "version": "2.4.2", "bundled": true, "dev": true, "requires": { - "shebang-regex": "^1.0.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, - "shebang-regex": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true - }, - "slide": { - "version": "1.1.6", + "ci-info": { + "version": "2.0.0", "bundled": true, "dev": true }, - "snapdragon": { - "version": "0.8.2", + "cli-cursor": { + "version": "3.1.0", "bundled": true, "dev": true, "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "bundled": true, - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } + "restore-cursor": "^3.1.0" } }, - "snapdragon-node": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "bundled": true, - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "bundled": true, - "dev": true - } + "cli-truncate": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" } }, - "snapdragon-util": { - "version": "3.0.1", + "color-convert": { + "version": "1.9.3", "bundled": true, "dev": true, "requires": { - "kind-of": "^3.2.0" + "color-name": "1.1.3" } }, - "source-map": { - "version": "0.5.7", + "color-name": { + "version": "1.1.3", "bundled": true, "dev": true }, - "source-map-resolve": { - "version": "0.5.1", + "convert-source-map": { + "version": "1.7.0", "bundled": true, "dev": true, "requires": { - "atob": "^2.0.0", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" + "safe-buffer": "~5.1.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true + } } }, - "source-map-url": { - "version": "0.4.0", + "csstype": { + "version": "2.6.11", "bundled": true, "dev": true }, - "spawn-wrap": { - "version": "1.4.2", + "debug": { + "version": "4.1.1", "bundled": true, "dev": true, "requires": { - "foreground-child": "^1.5.6", - "mkdirp": "^0.5.0", - "os-homedir": "^1.0.1", - "rimraf": "^2.6.2", - "signal-exit": "^3.0.2", - "which": "^1.3.0" + "ms": "^2.1.1" } }, - "spdx-correct": { - "version": "3.0.0", + "emoji-regex": { + "version": "8.0.0", "bundled": true, - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } + "dev": true }, - "spdx-exceptions": { - "version": "2.1.0", + "escape-string-regexp": { + "version": "1.0.5", "bundled": true, "dev": true }, - "spdx-expression-parse": { - "version": "3.0.0", + "esprima": { + "version": "4.0.1", "bundled": true, - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } + "dev": true + }, + "events-to-array": { + "version": "1.1.2", + "bundled": true, + "dev": true + }, + "gensync": { + "version": "1.0.0-beta.1", + "bundled": true, + "dev": true + }, + "globals": { + "version": "11.12.0", + "bundled": true, + "dev": true }, - "spdx-license-ids": { + "has-flag": { "version": "3.0.0", "bundled": true, "dev": true }, - "split-string": { + "import-jsx": { "version": "3.1.0", "bundled": true, "dev": true, "requires": { - "extend-shallow": "^3.0.0" + "@babel/core": "^7.5.5", + "@babel/plugin-proposal-object-rest-spread": "^7.5.5", + "@babel/plugin-transform-destructuring": "^7.5.0", + "@babel/plugin-transform-react-jsx": "^7.3.0", + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" } }, - "static-extend": { - "version": "0.1.2", + "ink": { + "version": "2.7.1", "bundled": true, "dev": true, "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" + "ansi-escapes": "^4.2.1", + "arrify": "^2.0.1", + "auto-bind": "^4.0.0", + "chalk": "^3.0.0", + "cli-cursor": "^3.1.0", + "cli-truncate": "^2.1.0", + "is-ci": "^2.0.0", + "lodash.throttle": "^4.1.1", + "log-update": "^3.0.0", + "prop-types": "^15.6.2", + "react-reconciler": "^0.24.0", + "scheduler": "^0.18.0", + "signal-exit": "^3.0.2", + "slice-ansi": "^3.0.0", + "string-length": "^3.1.0", + "widest-line": "^3.1.0", + "wrap-ansi": "^6.2.0", + "yoga-layout-prebuilt": "^1.9.3" }, "dependencies": { - "define-property": { - "version": "0.2.5", + "ansi-styles": { + "version": "4.2.1", "bundled": true, "dev": true, "requires": { - "is-descriptor": "^0.1.0" + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" } - } - } - }, - "string-width": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "ansi-regex": { + }, + "chalk": { "version": "3.0.0", "bundled": true, + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "bundled": true, "dev": true }, - "strip-ansi": { + "has-flag": { "version": "4.0.0", "bundled": true, + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "bundled": true, "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "has-flag": "^4.0.0" } } } }, - "strip-ansi": { - "version": "3.0.1", + "is-ci": { + "version": "2.0.0", "bundled": true, "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "ci-info": "^2.0.0" } }, - "strip-bom": { - "version": "2.0.0", + "is-fullwidth-code-point": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "jsesc": { + "version": "2.5.2", + "bundled": true, + "dev": true + }, + "json5": { + "version": "2.1.3", "bundled": true, "dev": true, "requires": { - "is-utf8": "^0.2.0" + "minimist": "^1.2.5" } }, - "strip-eof": { - "version": "1.0.0", + "lodash": { + "version": "4.17.19", "bundled": true, "dev": true }, - "supports-color": { - "version": "2.0.0", + "lodash.throttle": { + "version": "4.1.1", "bundled": true, "dev": true }, - "test-exclude": { - "version": "4.2.1", + "log-update": { + "version": "3.4.0", "bundled": true, "dev": true, "requires": { - "arrify": "^1.0.1", - "micromatch": "^3.1.8", - "object-assign": "^4.1.0", - "read-pkg-up": "^1.0.1", - "require-main-filename": "^1.0.1" + "ansi-escapes": "^3.2.0", + "cli-cursor": "^2.1.0", + "wrap-ansi": "^5.0.0" }, "dependencies": { - "arr-diff": { - "version": "4.0.0", + "ansi-escapes": { + "version": "3.2.0", "bundled": true, "dev": true }, - "array-unique": { - "version": "0.3.2", + "ansi-regex": { + "version": "4.1.0", "bundled": true, "dev": true }, - "braces": { - "version": "2.3.2", + "cli-cursor": { + "version": "2.1.0", "bundled": true, "dev": true, "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } + "restore-cursor": "^2.0.0" } }, - "expand-brackets": { - "version": "2.1.4", + "emoji-regex": { + "version": "7.0.3", "bundled": true, - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "bundled": true, - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "bundled": true, - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "bundled": true, - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "bundled": true, - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "bundled": true, - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "bundled": true, - "dev": true - } - } + "dev": true }, - "extglob": { - "version": "2.0.4", + "is-fullwidth-code-point": { + "version": "2.0.0", "bundled": true, - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } + "dev": true }, - "fill-range": { - "version": "4.0.0", + "mimic-fn": { + "version": "1.2.0", "bundled": true, - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } + "dev": true }, - "is-accessor-descriptor": { - "version": "1.0.0", + "onetime": { + "version": "2.0.1", "bundled": true, "dev": true, "requires": { - "kind-of": "^6.0.0" + "mimic-fn": "^1.0.0" } }, - "is-data-descriptor": { - "version": "1.0.0", + "restore-cursor": { + "version": "2.0.0", "bundled": true, "dev": true, "requires": { - "kind-of": "^6.0.0" + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" } }, - "is-descriptor": { - "version": "1.0.2", + "string-width": { + "version": "3.1.0", "bundled": true, "dev": true, "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" } }, - "is-number": { - "version": "3.0.0", + "strip-ansi": { + "version": "5.2.0", "bundled": true, "dev": true, "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "bundled": true, - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } + "ansi-regex": "^4.1.0" } }, - "isobject": { - "version": "3.0.1", - "bundled": true, - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "bundled": true, - "dev": true - }, - "micromatch": { - "version": "3.1.10", + "wrap-ansi": { + "version": "5.1.0", "bundled": true, "dev": true, "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" } } } }, - "to-fast-properties": { - "version": "1.0.3", - "bundled": true, - "dev": true - }, - "to-object-path": { - "version": "0.3.0", + "loose-envify": { + "version": "1.4.0", "bundled": true, "dev": true, "requires": { - "kind-of": "^3.0.2" + "js-tokens": "^3.0.0 || ^4.0.0" } }, - "to-regex": { - "version": "3.0.2", + "mimic-fn": { + "version": "2.1.0", "bundled": true, - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } + "dev": true }, - "to-regex-range": { - "version": "2.1.1", + "minimist": { + "version": "1.2.5", + "bundled": true, + "dev": true + }, + "minipass": { + "version": "3.1.3", "bundled": true, "dev": true, "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" + "yallist": "^4.0.0" }, "dependencies": { - "is-number": { - "version": "3.0.0", + "yallist": { + "version": "4.0.0", "bundled": true, - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } + "dev": true } } }, - "trim-right": { - "version": "1.0.1", + "ms": { + "version": "2.1.2", + "bundled": true, + "dev": true + }, + "object-assign": { + "version": "4.1.1", "bundled": true, "dev": true }, - "uglify-js": { - "version": "2.8.29", + "onetime": { + "version": "5.1.0", "bundled": true, "dev": true, - "optional": true, "requires": { - "source-map": "~0.5.1", - "uglify-to-browserify": "~1.0.0", - "yargs": "~3.10.0" - }, - "dependencies": { - "yargs": { - "version": "3.10.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "camelcase": "^1.0.2", - "cliui": "^2.1.0", - "decamelize": "^1.0.0", - "window-size": "0.1.0" - } - } + "mimic-fn": "^2.1.0" } }, - "uglify-to-browserify": { - "version": "1.0.2", + "path-parse": { + "version": "1.0.6", "bundled": true, - "dev": true, - "optional": true + "dev": true }, - "union-value": { - "version": "1.0.0", + "prop-types": { + "version": "15.7.2", "bundled": true, "dev": true, "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "set-value": { - "version": "0.4.3", - "bundled": true, - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" - } - } + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" } }, - "unset-value": { - "version": "1.0.0", + "punycode": { + "version": "2.1.1", "bundled": true, - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "bundled": true, - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "bundled": true, - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "bundled": true, - "dev": true - }, - "isobject": { - "version": "3.0.1", - "bundled": true, - "dev": true - } - } + "dev": true }, - "urix": { - "version": "0.1.0", + "react-is": { + "version": "16.13.1", "bundled": true, "dev": true }, - "use": { - "version": "3.1.0", + "react-reconciler": { + "version": "0.24.0", "bundled": true, "dev": true, "requires": { - "kind-of": "^6.0.2" - }, - "dependencies": { - "kind-of": { - "version": "6.0.2", - "bundled": true, - "dev": true - } + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.18.0" } }, - "validate-npm-package-license": { - "version": "3.0.3", + "redeyed": { + "version": "2.1.1", "bundled": true, "dev": true, "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" + "esprima": "~4.0.0" } }, - "which": { - "version": "1.3.0", + "resolve": { + "version": "1.17.0", "bundled": true, "dev": true, "requires": { - "isexe": "^2.0.0" + "path-parse": "^1.0.6" } }, - "which-module": { - "version": "2.0.0", + "resolve-from": { + "version": "3.0.0", "bundled": true, "dev": true }, - "window-size": { - "version": "0.1.0", + "restore-cursor": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "scheduler": { + "version": "0.18.0", "bundled": true, "dev": true, - "optional": true + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } }, - "wordwrap": { - "version": "0.0.3", + "semver": { + "version": "5.7.1", "bundled": true, "dev": true }, - "wrap-ansi": { - "version": "2.1.0", + "signal-exit": { + "version": "3.0.3", + "bundled": true, + "dev": true + }, + "slice-ansi": { + "version": "3.0.0", "bundled": true, "dev": true, "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.2.1", + "bundled": true, + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "bundled": true, + "dev": true + } + } + }, + "string-length": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "astral-regex": "^1.0.0", + "strip-ansi": "^5.2.0" }, "dependencies": { - "is-fullwidth-code-point": { + "ansi-regex": { + "version": "4.1.0", + "bundled": true, + "dev": true + }, + "astral-regex": { "version": "1.0.0", "bundled": true, - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } + "dev": true }, - "string-width": { - "version": "1.0.2", + "strip-ansi": { + "version": "5.2.0", "bundled": true, "dev": true, "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "ansi-regex": "^4.1.0" } } } }, - "wrappy": { - "version": "1.0.2", + "string-width": { + "version": "4.2.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } }, - "write-file-atomic": { - "version": "1.3.4", + "strip-ansi": { + "version": "6.0.0", "bundled": true, "dev": true, "requires": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "slide": "^1.1.5" + "ansi-regex": "^5.0.0" } }, - "y18n": { - "version": "3.2.1", + "supports-color": { + "version": "5.5.0", "bundled": true, - "dev": true + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } }, - "yallist": { - "version": "2.1.2", + "tap-parser": { + "version": "10.0.1", + "bundled": true, + "dev": true, + "requires": { + "events-to-array": "^1.0.1", + "minipass": "^3.0.0", + "tap-yaml": "^1.0.0" + } + }, + "tap-yaml": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "yaml": "^1.5.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", "bundled": true, "dev": true }, - "yargs": { - "version": "11.1.0", + "treport": { + "version": "1.0.2", "bundled": true, "dev": true, "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.1.1", - "find-up": "^2.1.0", - "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^9.0.2" + "cardinal": "^2.1.1", + "chalk": "^3.0.0", + "import-jsx": "^3.1.0", + "ink": "^2.6.0", + "ms": "^2.1.2", + "string-length": "^3.1.0", + "tap-parser": "^10.0.1", + "unicode-length": "^2.0.2" }, "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "camelcase": { - "version": "4.1.0", - "bundled": true, - "dev": true - }, - "cliui": { - "version": "4.1.0", - "bundled": true, - "dev": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", + "ansi-styles": { + "version": "4.2.1", "bundled": true, "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" } }, - "yargs-parser": { - "version": "9.0.2", - "bundled": true, - "dev": true, - "requires": { - "camelcase": "^4.1.0" - } - } - } - }, - "yargs-parser": { - "version": "8.1.0", - "bundled": true, - "dev": true, - "requires": { - "camelcase": "^4.1.0" - }, - "dependencies": { - "camelcase": { - "version": "4.1.0", + "chalk": { + "version": "3.0.0", "bundled": true, - "dev": true - } - } - } - } - }, - "oauth-sign": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "opener": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.4.3.tgz", - "integrity": "sha1-XG2ixdflgx6P+jlklQ+NZnSskLg=", - "dev": true - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "own-or": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/own-or/-/own-or-1.0.0.tgz", - "integrity": "sha1-Tod/vtqaLsgAD7wLyuOWRe6L+Nw=", - "dev": true - }, - "own-or-env": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/own-or-env/-/own-or-env-1.0.1.tgz", - "integrity": "sha512-y8qULRbRAlL6x2+M0vIe7jJbJx/kmUTzYonRAa2ayesR2qWLswninkVyeJe4x3IEXhdgoNodzjQRKAoEs6Fmrw==", - "dev": true, - "requires": { - "own-or": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "dev": true - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "pump": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", - "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "request": { - "version": "2.87.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz", - "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==", - "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.6.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.5", - "extend": "~3.0.1", - "forever-agent": "~0.6.1", - "form-data": "~2.3.1", - "har-validator": "~5.0.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.17", - "oauth-sign": "~0.8.2", - "performance-now": "^2.1.0", - "qs": "~6.5.1", - "safe-buffer": "^5.1.1", - "tough-cookie": "~2.3.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.1.0" - } - }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, - "requires": { - "glob": "^7.0.5" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.6.tgz", - "integrity": "sha512-N4KXEz7jcKqPf2b2vZF11lQIz9W5ZMuUcIOGj243lduidkf2fjkVKJS9vNxVWn3u/uxX38AcE8U9nnH9FPcq+g==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "sshpk": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.1.tgz", - "integrity": "sha1-Ew9Zde3a2WPx1W+SuaxsUfqfg+s=", - "dev": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "tweetnacl": "~0.14.0" - } - }, - "stack-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.1.tgz", - "integrity": "sha1-1PM6tU6OOHeLDKXP07OvsS22hiA=", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "bundled": true, + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "bundled": true, + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "type-fest": { + "version": "0.11.0", + "bundled": true, + "dev": true + }, + "unicode-length": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "punycode": "^2.0.0", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "widest-line": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^4.0.0" + } + }, + "wrap-ansi": { + "version": "6.2.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.2.1", + "bundled": true, + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "bundled": true, + "dev": true + } + } + }, + "yaml": { + "version": "1.10.0", + "bundled": true, + "dev": true + }, + "yoga-layout-prebuilt": { + "version": "1.9.6", + "bundled": true, + "dev": true, + "requires": { + "@types/yoga-layout": "1.9.2" + } + } } }, - "tap": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/tap/-/tap-12.0.1.tgz", - "integrity": "sha512-iEJytWaZy8risvfRjuV4+ST+Lrrui/MW2ZCWn01ZaMn0NKFej4+PpBy6bXGOg9+cEGNmI7d3Sdka/zTUZUGidA==", + "tap-mocha-reporter": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/tap-mocha-reporter/-/tap-mocha-reporter-5.0.1.tgz", + "integrity": "sha512-1knFWOwd4khx/7uSEnUeaP9IPW3w+sqTgJMhrwah6t46nZ8P25atOKAjSvVDsT67lOPu0nfdOqUwoyKn+3E5pA==", "dev": true, "requires": { - "bind-obj-methods": "^2.0.0", - "bluebird": "^3.5.1", - "clean-yaml-object": "^0.1.0", "color-support": "^1.1.0", - "coveralls": "^3.0.1", - "foreground-child": "^1.3.3", - "fs-exists-cached": "^1.0.0", - "function-loop": "^1.0.1", - "glob": "^7.0.0", - "isexe": "^2.0.0", - "js-yaml": "^3.11.0", - "minipass": "^2.3.0", - "mkdirp": "^0.5.1", - "nyc": "^11.8.0", - "opener": "^1.4.1", - "os-homedir": "^1.0.2", - "own-or": "^1.0.0", - "own-or-env": "^1.0.1", - "rimraf": "^2.6.2", - "signal-exit": "^3.0.0", - "source-map-support": "^0.5.6", - "stack-utils": "^1.0.0", - "tap-mocha-reporter": "^3.0.7", - "tap-parser": "^7.0.0", - "tmatch": "^4.0.0", - "trivial-deferred": "^1.0.1", - "tsame": "^2.0.0", - "write-file-atomic": "^2.3.0", - "yapool": "^1.0.0" + "debug": "^4.1.1", + "diff": "^4.0.1", + "escape-string-regexp": "^2.0.0", + "glob": "^7.0.5", + "tap-parser": "^10.0.0", + "tap-yaml": "^1.0.0", + "unicode-length": "^2.0.2" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + } } }, - "tap-mocha-reporter": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/tap-mocha-reporter/-/tap-mocha-reporter-3.0.7.tgz", - "integrity": "sha512-GHVXJ38C3oPRpM3YUc43JlGdpVZYiKeT1fmAd3HH2+J+ZWwsNAUFvRRdoGsXLw9+gU9o+zXpBqhS/oXyRQYwlA==", + "tap-parser": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-10.1.0.tgz", + "integrity": "sha512-FujQeciDaOiOvaIVGS1Rpb0v4R6XkOjvWCWowlz5oKuhPkEJ8U6pxgqt38xuzYhPt8dWEnfHn2jqpZdJEkW7pA==", "dev": true, "requires": { - "color-support": "^1.1.0", - "debug": "^2.1.3", - "diff": "^1.3.2", - "escape-string-regexp": "^1.0.3", - "glob": "^7.0.5", - "js-yaml": "^3.3.1", - "readable-stream": "^2.1.5", - "tap-parser": "^5.1.0", - "unicode-length": "^1.0.0" + "events-to-array": "^1.0.1", + "minipass": "^3.0.0", + "tap-yaml": "^1.0.0" }, "dependencies": { - "tap-parser": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-5.4.0.tgz", - "integrity": "sha512-BIsIaGqv7uTQgTW1KLTMNPSEQf4zDDPgYOBRdgOfuB+JFOLRBfEu6cLa/KvMvmqggu1FKXDfitjLwsq4827RvA==", + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", "dev": true, "requires": { - "events-to-array": "^1.0.1", - "js-yaml": "^3.2.7", - "readable-stream": "^2" + "yallist": "^4.0.0" } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } }, - "tap-parser": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-7.0.0.tgz", - "integrity": "sha512-05G8/LrzqOOFvZhhAk32wsGiPZ1lfUrl+iV7+OkKgfofZxiceZWMHkKmow71YsyVQ8IvGBP2EjcIjE5gL4l5lA==", + "tap-yaml": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tap-yaml/-/tap-yaml-1.0.0.tgz", + "integrity": "sha512-Rxbx4EnrWkYk0/ztcm5u3/VznbyFJpyXO12dDBHKWiDVxy7O2Qw6MRrwO5H6Ww0U5YhRY/4C/VzWmFPhBQc4qQ==", "dev": true, "requires": { - "events-to-array": "^1.0.1", - "js-yaml": "^3.2.7", - "minipass": "^2.2.0" + "yaml": "^1.5.0" } }, "tar-fs": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.2.tgz", - "integrity": "sha512-LdknWjPEiZC1nOBwhv0JBzfJBGPJar08dZg2rwZe0ZTLQoRGEzgrl7vF3qUEkCHpI/wN9e7RyCuDhMsJUCLPPQ==", + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.3.tgz", + "integrity": "sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw==", "dev": true, "requires": { "chownr": "^1.0.1", @@ -3553,25 +3264,40 @@ } }, "tar-stream": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.0.tgz", - "integrity": "sha512-lh2iAPG/BHNmN6WB9Ybdynk9rEJ5GD/dy4zscHmVlwa1dq2tpE+BH78i5vjYwYVWEaOXGBjzxr89aVACF17Cpw==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", "dev": true, "requires": { "bl": "^1.0.0", - "buffer-alloc": "^1.1.0", + "buffer-alloc": "^1.2.0", "end-of-stream": "^1.0.0", "fs-constants": "^1.0.0", - "readable-stream": "^2.0.0", - "to-buffer": "^1.1.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.1", "xtend": "^4.0.0" } }, - "tmatch": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tmatch/-/tmatch-4.0.0.tgz", - "integrity": "sha512-Ynn2Gsp+oCvYScQXeV+cCs7citRDilq0qDXA6tuvFwDgiYyyaq7D5vKUlAPezzZR5NDobc/QMeN6e5guOYmvxg==", - "dev": true + "tcompare": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/tcompare/-/tcompare-3.0.5.tgz", + "integrity": "sha512-+tmloQj1buaShBX+LP1i1NF5riJm110Yr0flIJAEoKf01tFVoMZvW2jq1JLqaW8fspOUVPm5NKKW5qLwT0ETDQ==", + "dev": true, + "requires": { + "diff-frag": "^1.0.1" + } + }, + "test-exclude": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", + "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", + "dev": true, + "requires": { + "glob": "^7.1.3", + "minimatch": "^3.0.4", + "read-pkg-up": "^4.0.0", + "require-main-filename": "^2.0.0" + } }, "to-buffer": { "version": "1.1.1", @@ -3579,13 +3305,29 @@ "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", "dev": true }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, "tough-cookie": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", - "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", "dev": true, "requires": { - "punycode": "^1.4.1" + "psl": "^1.1.28", + "punycode": "^2.1.1" } }, "trivial-deferred": { @@ -3594,11 +3336,18 @@ "integrity": "sha1-N21NKdlR1jaKb3oK6FwvTV4GWPM=", "dev": true }, - "tsame": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/tsame/-/tsame-2.0.0.tgz", - "integrity": "sha512-dAuzcnOPdqZYojylFQzEes95UDjve3HqKrlTCeLZKSDPMTsn3smzHZqsJj/sWD8wOUkg0RD++B11evyLn2+bIw==", - "dev": true + "ts-node": { + "version": "8.10.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", + "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==", + "dev": true, + "requires": { + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + } }, "tunnel-agent": { "version": "0.6.0", @@ -3613,17 +3362,57 @@ "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", "dev": true, - "optional": true + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "typescript": { + "version": "3.9.10", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", + "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", + "dev": true }, "unicode-length": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/unicode-length/-/unicode-length-1.0.3.tgz", - "integrity": "sha1-Wtp6f+1RhBpBijKM8UlHisg1irs=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unicode-length/-/unicode-length-2.0.2.tgz", + "integrity": "sha512-Ph/j1VbS3/r77nhoY2WU0GWGjVYOHL3xpKp0y/Eq2e5r0mT/6b649vm7KFO6RdAdrZkYLdxphYVgvODxPB+Ebg==", "dev": true, "requires": { - "punycode": "^1.3.2", + "punycode": "^2.0.0", "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" } }, "util-deprecate": { @@ -3633,11 +3422,21 @@ "dev": true }, "uuid": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", - "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "dev": true }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", @@ -3649,15 +3448,74 @@ "extsprintf": "^1.2.0" } }, + "vlq": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz", + "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==", + "dev": true + }, "which": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", - "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" } }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -3665,14 +3523,15 @@ "dev": true }, "write-file-atomic": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz", - "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", "dev": true, "requires": { - "graceful-fs": "^4.1.11", "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" } }, "xtend": { @@ -3681,16 +3540,112 @@ "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", "dev": true }, + "y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, "yallist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz", - "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true }, "yapool": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/yapool/-/yapool-1.0.0.tgz", "integrity": "sha1-9pPymjFbUNmp2iZGp6ZkXJaYW2o=", "dev": true + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + } + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true } } } diff --git a/package.json b/package.json index a06bcf3c..0185237c 100644 --- a/package.json +++ b/package.json @@ -2,37 +2,43 @@ "author": "Isaac Z. Schlueter (http://blog.izs.me/)", "name": "tar", "description": "tar for node", - "version": "4.4.4", + "version": "4.4.19", + "publishConfig": { + "tag": "v4-legacy" + }, "repository": { "type": "git", "url": "https://github.com/npm/node-tar.git" }, "scripts": { - "test": "tap test/*.js --100 -J --coverage-report=text -c", + "test:posix": "tap", + "test:win32": "tap --lines=98 --branches=98 --statements=98 --functions=98", + "test": "node test/fixtures/test.js", "preversion": "npm test", "postversion": "npm publish", - "postpublish": "git push origin --all; git push origin --tags", + "postpublish": "git push origin --follow-tags", "genparse": "node scripts/generate-parse-fixtures.js", "bench": "for i in benchmarks/*/*.js; do echo $i; for j in {1..5}; do node $i || break; done; done" }, "dependencies": { - "chownr": "^1.0.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.3", - "minizlib": "^1.1.0", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.2" + "chownr": "^1.1.4", + "fs-minipass": "^1.2.7", + "minipass": "^2.9.0", + "minizlib": "^1.3.3", + "mkdirp": "^0.5.5", + "safe-buffer": "^5.2.1", + "yallist": "^3.1.1" }, "devDependencies": { - "chmodr": "^1.0.2", - "end-of-stream": "^1.4.1", + "chmodr": "^1.2.0", + "end-of-stream": "^1.4.4", "events-to-array": "^1.1.2", "mutate-fs": "^2.1.1", - "rimraf": "^2.6.2", - "tap": "^12.0.1", - "tar-fs": "^1.16.2", - "tar-stream": "^1.6.0" + "require-inject": "^1.4.4", + "rimraf": "^2.7.1", + "tap": "^14.11.0", + "tar-fs": "^1.16.3", + "tar-stream": "^1.6.2" }, "license": "ISC", "engines": { @@ -41,5 +47,9 @@ "files": [ "index.js", "lib/" - ] + ], + "tap": { + "coverage-map": "map.js", + "check-coverage": true + } } diff --git a/scripts/generate-parse-fixtures.js b/scripts/generate-parse-fixtures.js index af3476c3..30a2180b 100644 --- a/scripts/generate-parse-fixtures.js +++ b/scripts/generate-parse-fixtures.js @@ -4,7 +4,7 @@ const fs = require('fs') const path = require('path') const tardir = path.resolve(__dirname, '../test/fixtures/tars') const parsedir = path.resolve(__dirname, '../test/fixtures/parse') -const maxMetaOpt = [50, null] +const maxMetaOpt = [250, null] const filterOpt = [ true, false ] const strictOpt = [ true, false ] diff --git a/test/create.js b/test/create.js index 2adc9e53..9aa66d19 100644 --- a/test/create.js +++ b/test/create.js @@ -1,5 +1,6 @@ 'use strict' +const isWindows = process.platform === 'win32' const t = require('tap') const c = require('../lib/create.js') const list = require('../lib/list.js') @@ -7,11 +8,12 @@ const fs = require('fs') const path = require('path') const dir = path.resolve(__dirname, 'fixtures/create') const tars = path.resolve(__dirname, 'fixtures/tars') -const rimraf = require('rimraf') -const mkdirp = require('mkdirp') const spawn = require('child_process').spawn const Pack = require('../lib/pack.js') const mutateFS = require('mutate-fs') +const {promisify} = require('util') +const rimraf = promisify(require('rimraf')) +const mkdirp = promisify(require('mkdirp')) const readtar = (file, cb) => { const child = spawn('tar', ['tf', file]) @@ -21,12 +23,11 @@ const readtar = (file, cb) => { cb(code, signal, Buffer.concat(out).toString())) } -t.teardown(_ => rimraf.sync(dir)) +t.teardown(() => rimraf(dir)) -t.test('setup', t => { - rimraf.sync(dir) - mkdirp.sync(dir) - t.end() +t.test('setup', async () => { + await rimraf(dir) + await mkdirp(dir) }) t.test('no cb if sync or without file', t => { @@ -88,7 +89,7 @@ t.test('create file', t => { }) t.test('with specific mode', t => { - const mode = 0o740 + const mode = isWindows ? 0o666 : 0o740 t.test('sync', t => { const file = path.resolve(dir, 'sync-mode.tar') c({ diff --git a/test/extract.js b/test/extract.js index f6c992b1..8c1064de 100644 --- a/test/extract.js +++ b/test/extract.js @@ -6,49 +6,47 @@ const path = require('path') const fs = require('fs') const extractdir = path.resolve(__dirname, 'fixtures/extract') const tars = path.resolve(__dirname, 'fixtures/tars') -const mkdirp = require('mkdirp') -const rimraf = require('rimraf') +const {promisify} = require('util') +const mkdirp = promisify(require('mkdirp')) +const rimraf = promisify(require('rimraf')) const mutateFS = require('mutate-fs') -t.teardown(_ => rimraf.sync(extractdir)) +t.teardown(_ => rimraf(extractdir)) t.test('basic extracting', t => { const file = path.resolve(tars, 'utf8.tar') const dir = path.resolve(extractdir, 'basic') - t.beforeEach(cb => { - rimraf.sync(dir) - mkdirp.sync(dir) - cb() + t.beforeEach(async () => { + await rimraf(dir) + await mkdirp(dir) }) - const check = t => { + const check = async t => { fs.lstatSync(dir + '/Ω.txt') fs.lstatSync(dir + '/🌟.txt') t.throws(_ => fs.lstatSync(dir + '/long-path/r/e/a/l/l/y/-/d/e/e/p/-' + '/f/o/l/d/e/r/-/p/a/t/h/Ω.txt')) - rimraf.sync(dir) + await rimraf(dir) t.end() } const files = [ '🌟.txt', 'Ω.txt' ] t.test('sync', t => { x({ file: file, sync: true, C: dir }, files) - check(t) + return check(t) }) t.test('async promisey', t => { - return x({ file: file, cwd: dir }, files).then(_ => { - check(t) - }) + return x({ file: file, cwd: dir }, files).then(_ => check(t)) }) t.test('async cb', t => { return x({ file: file, cwd: dir }, files, er => { if (er) throw er - check(t) + return check(t) }) }) @@ -59,32 +57,31 @@ t.test('file list and filter', t => { const file = path.resolve(tars, 'utf8.tar') const dir = path.resolve(extractdir, 'filter') - t.beforeEach(cb => { - rimraf.sync(dir) - mkdirp.sync(dir) - cb() + t.beforeEach(async () => { + await rimraf(dir) + await mkdirp(dir) }) - const check = t => { + const check = async t => { fs.lstatSync(dir + '/Ω.txt') t.throws(_ => fs.lstatSync(dir + '/🌟.txt')) t.throws(_ => fs.lstatSync(dir + '/long-path/r/e/a/l/l/y/-/d/e/e/p/-' + '/f/o/l/d/e/r/-/p/a/t/h/Ω.txt')) - rimraf.sync(dir) + await rimraf(dir) t.end() } const filter = path => path === 'Ω.txt' t.test('sync', t => { - x({ filter: filter, file: file, sync: true, C: dir }, [ '🌟.txt', 'Ω.txt' ]) - check(t) + x({ filter: filter, file: file, sync: true, C: dir }, ['🌟.txt', 'Ω.txt']) + return check(t) }) t.test('async promisey', t => { - return x({ filter: filter, file: file, cwd: dir }, [ '🌟.txt', 'Ω.txt' ]).then(_ => { - check(t) + return x({ filter: filter, file: file, cwd: dir }, ['🌟.txt', 'Ω.txt']).then(_ => { + return check(t) }) }) @@ -92,7 +89,7 @@ t.test('file list and filter', t => { return x({ filter: filter, file: file, cwd: dir }, [ '🌟.txt', 'Ω.txt' ], er => { if (er) throw er - check(t) + return check(t) }) }) @@ -103,29 +100,28 @@ t.test('no file list', t => { const file = path.resolve(tars, 'body-byte-counts.tar') const dir = path.resolve(extractdir, 'no-list') - t.beforeEach(cb => { - rimraf.sync(dir) - mkdirp.sync(dir) - cb() + t.beforeEach(async () => { + await rimraf(dir) + await mkdirp(dir) }) - const check = t => { + const check = async t => { t.equal(fs.lstatSync(path.resolve(dir, '1024-bytes.txt')).size, 1024) t.equal(fs.lstatSync(path.resolve(dir, '512-bytes.txt')).size, 512) t.equal(fs.lstatSync(path.resolve(dir, 'one-byte.txt')).size, 1) t.equal(fs.lstatSync(path.resolve(dir, 'zero-byte.txt')).size, 0) - rimraf.sync(dir) + await rimraf(dir) t.end() } t.test('sync', t => { x({ file: file, sync: true, C: dir }) - check(t) + return check(t) }) t.test('async promisey', t => { return x({ file: file, cwd: dir }).then(_ => { - check(t) + return check(t) }) }) @@ -133,7 +129,7 @@ t.test('no file list', t => { return x({ file: file, cwd: dir }, er => { if (er) throw er - check(t) + return check(t) }) }) @@ -145,29 +141,28 @@ t.test('read in itty bits', t => { const file = path.resolve(tars, 'body-byte-counts.tar') const dir = path.resolve(extractdir, 'no-list') - t.beforeEach(cb => { - rimraf.sync(dir) - mkdirp.sync(dir) - cb() + t.beforeEach(async () => { + await rimraf(dir) + await mkdirp(dir) }) - const check = t => { + const check = async t => { t.equal(fs.lstatSync(path.resolve(dir, '1024-bytes.txt')).size, 1024) t.equal(fs.lstatSync(path.resolve(dir, '512-bytes.txt')).size, 512) t.equal(fs.lstatSync(path.resolve(dir, 'one-byte.txt')).size, 1) t.equal(fs.lstatSync(path.resolve(dir, 'zero-byte.txt')).size, 0) - rimraf.sync(dir) + await rimraf(dir) t.end() } t.test('sync', t => { x({ file: file, sync: true, C: dir, maxReadSize: maxReadSize }) - check(t) + return check(t) }) t.test('async promisey', t => { return x({ file: file, cwd: dir, maxReadSize: maxReadSize }).then(_ => { - check(t) + return check(t) }) }) @@ -175,7 +170,7 @@ t.test('read in itty bits', t => { return x({ file: file, cwd: dir, maxReadSize: maxReadSize }, er => { if (er) throw er - check(t) + return check(t) }) }) @@ -210,16 +205,15 @@ t.test('read fail', t => { t.end() }) -t.test('sync gzip error edge case test', t => { - const zlib = require('minizlib') +t.test('sync gzip error edge case test', async t => { const file = path.resolve(__dirname, 'fixtures/sync-gzip-fail.tgz') const dir = path.resolve(__dirname, 'sync-gzip-fail') const cwd = process.cwd() - mkdirp.sync(dir + '/x') + await mkdirp(dir + '/x') process.chdir(dir) - t.teardown(() => { + t.teardown(async () => { process.chdir(cwd) - rimraf.sync(dir) + await rimraf(dir) }) x({ diff --git a/test/fixtures/files/99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt b/test/fixtures/files/99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt new file mode 100644 index 00000000..578ff710 --- /dev/null +++ b/test/fixtures/files/99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt @@ -0,0 +1,3 @@ +Behold! I am a text file and NOT a tar header. + +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx diff --git a/test/fixtures/files/99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt b/test/fixtures/files/99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt new file mode 100644 index 00000000..578ff710 --- /dev/null +++ b/test/fixtures/files/99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt @@ -0,0 +1,3 @@ +Behold! I am a text file and NOT a tar header. + +xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx diff --git a/test/fixtures/files/strip-dir/1/2/3/hardlink-3 b/test/fixtures/files/strip-dir/1/2/3/hardlink-3 new file mode 100644 index 00000000..84c7ae52 --- /dev/null +++ b/test/fixtures/files/strip-dir/1/2/3/hardlink-3 @@ -0,0 +1 @@ +this link is like diamond diff --git a/test/fixtures/files/strip-dir/hardlink-1 b/test/fixtures/files/strip-dir/hardlink-1 new file mode 100644 index 00000000..84c7ae52 --- /dev/null +++ b/test/fixtures/files/strip-dir/hardlink-1 @@ -0,0 +1 @@ +this link is like diamond diff --git a/test/fixtures/files/strip-dir/hardlink-2 b/test/fixtures/files/strip-dir/hardlink-2 new file mode 100644 index 00000000..84c7ae52 --- /dev/null +++ b/test/fixtures/files/strip-dir/hardlink-2 @@ -0,0 +1 @@ +this link is like diamond diff --git a/test/fixtures/files/strip-dir/symlink b/test/fixtures/files/strip-dir/symlink new file mode 120000 index 00000000..c30d3102 --- /dev/null +++ b/test/fixtures/files/strip-dir/symlink @@ -0,0 +1 @@ +hardlink-2 \ No newline at end of file diff --git a/test/fixtures/parse/bad-cksum--meta-50-filter-strict.json b/test/fixtures/parse/bad-cksum--meta-250-filter-strict.json similarity index 100% rename from test/fixtures/parse/bad-cksum--meta-50-filter-strict.json rename to test/fixtures/parse/bad-cksum--meta-250-filter-strict.json diff --git a/test/fixtures/parse/bad-cksum--meta-50-filter.json b/test/fixtures/parse/bad-cksum--meta-250-filter.json similarity index 100% rename from test/fixtures/parse/bad-cksum--meta-50-filter.json rename to test/fixtures/parse/bad-cksum--meta-250-filter.json diff --git a/test/fixtures/parse/bad-cksum--meta-50-strict.json b/test/fixtures/parse/bad-cksum--meta-250-strict.json similarity index 100% rename from test/fixtures/parse/bad-cksum--meta-50-strict.json rename to test/fixtures/parse/bad-cksum--meta-250-strict.json diff --git a/test/fixtures/parse/bad-cksum--meta-50.json b/test/fixtures/parse/bad-cksum--meta-250.json similarity index 100% rename from test/fixtures/parse/bad-cksum--meta-50.json rename to test/fixtures/parse/bad-cksum--meta-250.json diff --git a/test/fixtures/parse/body-byte-counts--meta-50-filter-strict.json b/test/fixtures/parse/body-byte-counts--meta-250-filter-strict.json similarity index 100% rename from test/fixtures/parse/body-byte-counts--meta-50-filter-strict.json rename to test/fixtures/parse/body-byte-counts--meta-250-filter-strict.json diff --git a/test/fixtures/parse/body-byte-counts--meta-50-filter.json b/test/fixtures/parse/body-byte-counts--meta-250-filter.json similarity index 100% rename from test/fixtures/parse/body-byte-counts--meta-50-filter.json rename to test/fixtures/parse/body-byte-counts--meta-250-filter.json diff --git a/test/fixtures/parse/body-byte-counts--meta-50-strict.json b/test/fixtures/parse/body-byte-counts--meta-250-strict.json similarity index 100% rename from test/fixtures/parse/body-byte-counts--meta-50-strict.json rename to test/fixtures/parse/body-byte-counts--meta-250-strict.json diff --git a/test/fixtures/parse/body-byte-counts--meta-50.json b/test/fixtures/parse/body-byte-counts--meta-250.json similarity index 100% rename from test/fixtures/parse/body-byte-counts--meta-50.json rename to test/fixtures/parse/body-byte-counts--meta-250.json diff --git a/test/fixtures/parse/dir--meta-50-filter-strict.json b/test/fixtures/parse/dir--meta-250-filter-strict.json similarity index 100% rename from test/fixtures/parse/dir--meta-50-filter-strict.json rename to test/fixtures/parse/dir--meta-250-filter-strict.json diff --git a/test/fixtures/parse/dir--meta-50-filter.json b/test/fixtures/parse/dir--meta-250-filter.json similarity index 100% rename from test/fixtures/parse/dir--meta-50-filter.json rename to test/fixtures/parse/dir--meta-250-filter.json diff --git a/test/fixtures/parse/dir--meta-50-strict.json b/test/fixtures/parse/dir--meta-250-strict.json similarity index 100% rename from test/fixtures/parse/dir--meta-50-strict.json rename to test/fixtures/parse/dir--meta-250-strict.json diff --git a/test/fixtures/parse/dir--meta-50.json b/test/fixtures/parse/dir--meta-250.json similarity index 100% rename from test/fixtures/parse/dir--meta-50.json rename to test/fixtures/parse/dir--meta-250.json diff --git a/test/fixtures/parse/emptypax--meta-50-strict.json b/test/fixtures/parse/emptypax--meta-250-filter-strict.json similarity index 64% rename from test/fixtures/parse/emptypax--meta-50-strict.json rename to test/fixtures/parse/emptypax--meta-250-filter-strict.json index 7e593753..406e08cb 100644 --- a/test/fixtures/parse/emptypax--meta-50-strict.json +++ b/test/fixtures/parse/emptypax--meta-250-filter-strict.json @@ -1,51 +1,33 @@ [ [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "ExtendedHeader", - "meta": true, - "ignore": true, - "path": "PaxHeader/🌟.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 120, - "mtime": "2017-04-10T17:05:55.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "PaxHeader/🌟.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 120, - "mtime": "2017-04-10T17:05:55.000Z", - "cksum": 7024, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } + "meta", + "17 path=🌟.txt\n20 ctime=1491843956\n20 atime=1491845601\n23 SCHILY.dev=16777220\n22 SCHILY.ino=9836716\n18 SCHILY.nlink=1\n" ], [ - "entry", + "ignoredEntry", { - "extended": null, + "extended": { + "atime": "2017-04-10T17:33:21.000Z", + "charset": null, + "comment": null, + "ctime": "2017-04-10T17:05:56.000Z", + "gid": null, + "gname": null, + "linkpath": null, + "mtime": null, + "path": "🌟.txt", + "size": null, + "uid": null, + "uname": null, + "dev": 16777220, + "ino": 9836716, + "nlink": 1, + "global": false + }, "globalExtended": null, "type": "File", "meta": false, - "ignore": false, + "ignore": true, "path": "🌟.txt", "mode": 420, "uid": 501, @@ -54,8 +36,8 @@ "gname": "staff", "size": 106, "mtime": "2017-04-10T17:05:55.000Z", - "atime": null, - "ctime": null, + "atime": "2017-04-10T17:33:21.000Z", + "ctime": "2017-04-10T17:05:56.000Z", "linkpath": "", "header": { "cksumValid": true, diff --git a/test/fixtures/parse/emptypax--meta-50.json b/test/fixtures/parse/emptypax--meta-250-filter.json similarity index 64% rename from test/fixtures/parse/emptypax--meta-50.json rename to test/fixtures/parse/emptypax--meta-250-filter.json index 7e593753..406e08cb 100644 --- a/test/fixtures/parse/emptypax--meta-50.json +++ b/test/fixtures/parse/emptypax--meta-250-filter.json @@ -1,51 +1,33 @@ [ [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "ExtendedHeader", - "meta": true, - "ignore": true, - "path": "PaxHeader/🌟.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 120, - "mtime": "2017-04-10T17:05:55.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "PaxHeader/🌟.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 120, - "mtime": "2017-04-10T17:05:55.000Z", - "cksum": 7024, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } + "meta", + "17 path=🌟.txt\n20 ctime=1491843956\n20 atime=1491845601\n23 SCHILY.dev=16777220\n22 SCHILY.ino=9836716\n18 SCHILY.nlink=1\n" ], [ - "entry", + "ignoredEntry", { - "extended": null, + "extended": { + "atime": "2017-04-10T17:33:21.000Z", + "charset": null, + "comment": null, + "ctime": "2017-04-10T17:05:56.000Z", + "gid": null, + "gname": null, + "linkpath": null, + "mtime": null, + "path": "🌟.txt", + "size": null, + "uid": null, + "uname": null, + "dev": 16777220, + "ino": 9836716, + "nlink": 1, + "global": false + }, "globalExtended": null, "type": "File", "meta": false, - "ignore": false, + "ignore": true, "path": "🌟.txt", "mode": 420, "uid": 501, @@ -54,8 +36,8 @@ "gname": "staff", "size": 106, "mtime": "2017-04-10T17:05:55.000Z", - "atime": null, - "ctime": null, + "atime": "2017-04-10T17:33:21.000Z", + "ctime": "2017-04-10T17:05:56.000Z", "linkpath": "", "header": { "cksumValid": true, diff --git a/test/fixtures/parse/emptypax--meta-50-filter.json b/test/fixtures/parse/emptypax--meta-250-strict.json similarity index 63% rename from test/fixtures/parse/emptypax--meta-50-filter.json rename to test/fixtures/parse/emptypax--meta-250-strict.json index 3e55b7e7..45453890 100644 --- a/test/fixtures/parse/emptypax--meta-50-filter.json +++ b/test/fixtures/parse/emptypax--meta-250-strict.json @@ -1,51 +1,33 @@ [ [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "ExtendedHeader", - "meta": true, - "ignore": true, - "path": "PaxHeader/🌟.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 120, - "mtime": "2017-04-10T17:05:55.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "PaxHeader/🌟.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 120, - "mtime": "2017-04-10T17:05:55.000Z", - "cksum": 7024, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } + "meta", + "17 path=🌟.txt\n20 ctime=1491843956\n20 atime=1491845601\n23 SCHILY.dev=16777220\n22 SCHILY.ino=9836716\n18 SCHILY.nlink=1\n" ], [ - "ignoredEntry", + "entry", { - "extended": null, + "extended": { + "atime": "2017-04-10T17:33:21.000Z", + "charset": null, + "comment": null, + "ctime": "2017-04-10T17:05:56.000Z", + "gid": null, + "gname": null, + "linkpath": null, + "mtime": null, + "path": "🌟.txt", + "size": null, + "uid": null, + "uname": null, + "dev": 16777220, + "ino": 9836716, + "nlink": 1, + "global": false + }, "globalExtended": null, "type": "File", "meta": false, - "ignore": true, + "ignore": false, "path": "🌟.txt", "mode": 420, "uid": 501, @@ -54,8 +36,8 @@ "gname": "staff", "size": 106, "mtime": "2017-04-10T17:05:55.000Z", - "atime": null, - "ctime": null, + "atime": "2017-04-10T17:33:21.000Z", + "ctime": "2017-04-10T17:05:56.000Z", "linkpath": "", "header": { "cksumValid": true, diff --git a/test/fixtures/parse/emptypax--meta-50-filter-strict.json b/test/fixtures/parse/emptypax--meta-250.json similarity index 63% rename from test/fixtures/parse/emptypax--meta-50-filter-strict.json rename to test/fixtures/parse/emptypax--meta-250.json index 3e55b7e7..45453890 100644 --- a/test/fixtures/parse/emptypax--meta-50-filter-strict.json +++ b/test/fixtures/parse/emptypax--meta-250.json @@ -1,51 +1,33 @@ [ [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "ExtendedHeader", - "meta": true, - "ignore": true, - "path": "PaxHeader/🌟.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 120, - "mtime": "2017-04-10T17:05:55.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "PaxHeader/🌟.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 120, - "mtime": "2017-04-10T17:05:55.000Z", - "cksum": 7024, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } + "meta", + "17 path=🌟.txt\n20 ctime=1491843956\n20 atime=1491845601\n23 SCHILY.dev=16777220\n22 SCHILY.ino=9836716\n18 SCHILY.nlink=1\n" ], [ - "ignoredEntry", + "entry", { - "extended": null, + "extended": { + "atime": "2017-04-10T17:33:21.000Z", + "charset": null, + "comment": null, + "ctime": "2017-04-10T17:05:56.000Z", + "gid": null, + "gname": null, + "linkpath": null, + "mtime": null, + "path": "🌟.txt", + "size": null, + "uid": null, + "uname": null, + "dev": 16777220, + "ino": 9836716, + "nlink": 1, + "global": false + }, "globalExtended": null, "type": "File", "meta": false, - "ignore": true, + "ignore": false, "path": "🌟.txt", "mode": 420, "uid": 501, @@ -54,8 +36,8 @@ "gname": "staff", "size": 106, "mtime": "2017-04-10T17:05:55.000Z", - "atime": null, - "ctime": null, + "atime": "2017-04-10T17:33:21.000Z", + "ctime": "2017-04-10T17:05:56.000Z", "linkpath": "", "header": { "cksumValid": true, diff --git a/test/fixtures/parse/file--meta-50-filter-strict.json b/test/fixtures/parse/file--meta-250-filter-strict.json similarity index 100% rename from test/fixtures/parse/file--meta-50-filter-strict.json rename to test/fixtures/parse/file--meta-250-filter-strict.json diff --git a/test/fixtures/parse/file--meta-50-filter.json b/test/fixtures/parse/file--meta-250-filter.json similarity index 100% rename from test/fixtures/parse/file--meta-50-filter.json rename to test/fixtures/parse/file--meta-250-filter.json diff --git a/test/fixtures/parse/file--meta-50-strict.json b/test/fixtures/parse/file--meta-250-strict.json similarity index 100% rename from test/fixtures/parse/file--meta-50-strict.json rename to test/fixtures/parse/file--meta-250-strict.json diff --git a/test/fixtures/parse/file--meta-50.json b/test/fixtures/parse/file--meta-250.json similarity index 100% rename from test/fixtures/parse/file--meta-50.json rename to test/fixtures/parse/file--meta-250.json diff --git a/test/fixtures/parse/global-header--meta-50-filter-strict.json b/test/fixtures/parse/global-header--meta-250-filter-strict.json similarity index 100% rename from test/fixtures/parse/global-header--meta-50-filter-strict.json rename to test/fixtures/parse/global-header--meta-250-filter-strict.json diff --git a/test/fixtures/parse/global-header--meta-50-filter.json b/test/fixtures/parse/global-header--meta-250-filter.json similarity index 100% rename from test/fixtures/parse/global-header--meta-50-filter.json rename to test/fixtures/parse/global-header--meta-250-filter.json diff --git a/test/fixtures/parse/global-header--meta-50-strict.json b/test/fixtures/parse/global-header--meta-250-strict.json similarity index 100% rename from test/fixtures/parse/global-header--meta-50-strict.json rename to test/fixtures/parse/global-header--meta-250-strict.json diff --git a/test/fixtures/parse/global-header--meta-50.json b/test/fixtures/parse/global-header--meta-250.json similarity index 100% rename from test/fixtures/parse/global-header--meta-50.json rename to test/fixtures/parse/global-header--meta-250.json diff --git a/test/fixtures/parse/links--meta-50-filter-strict.json b/test/fixtures/parse/links--meta-250-filter-strict.json similarity index 100% rename from test/fixtures/parse/links--meta-50-filter-strict.json rename to test/fixtures/parse/links--meta-250-filter-strict.json diff --git a/test/fixtures/parse/links--meta-50-filter.json b/test/fixtures/parse/links--meta-250-filter.json similarity index 100% rename from test/fixtures/parse/links--meta-50-filter.json rename to test/fixtures/parse/links--meta-250-filter.json diff --git a/test/fixtures/parse/links--meta-50-strict.json b/test/fixtures/parse/links--meta-250-strict.json similarity index 100% rename from test/fixtures/parse/links--meta-50-strict.json rename to test/fixtures/parse/links--meta-250-strict.json diff --git a/test/fixtures/parse/links--meta-50.json b/test/fixtures/parse/links--meta-250.json similarity index 100% rename from test/fixtures/parse/links--meta-50.json rename to test/fixtures/parse/links--meta-250.json diff --git a/test/fixtures/parse/links-invalid--meta-50-filter-strict.json b/test/fixtures/parse/links-invalid--meta-250-filter-strict.json similarity index 100% rename from test/fixtures/parse/links-invalid--meta-50-filter-strict.json rename to test/fixtures/parse/links-invalid--meta-250-filter-strict.json diff --git a/test/fixtures/parse/links-invalid--meta-50-filter.json b/test/fixtures/parse/links-invalid--meta-250-filter.json similarity index 100% rename from test/fixtures/parse/links-invalid--meta-50-filter.json rename to test/fixtures/parse/links-invalid--meta-250-filter.json diff --git a/test/fixtures/parse/links-invalid--meta-50-strict.json b/test/fixtures/parse/links-invalid--meta-250-strict.json similarity index 100% rename from test/fixtures/parse/links-invalid--meta-50-strict.json rename to test/fixtures/parse/links-invalid--meta-250-strict.json diff --git a/test/fixtures/parse/links-invalid--meta-50.json b/test/fixtures/parse/links-invalid--meta-250.json similarity index 100% rename from test/fixtures/parse/links-invalid--meta-50.json rename to test/fixtures/parse/links-invalid--meta-250.json diff --git a/test/fixtures/parse/links-strip--filter-strict.json b/test/fixtures/parse/links-strip--filter-strict.json new file mode 100644 index 00000000..9a640e0b --- /dev/null +++ b/test/fixtures/parse/links-strip--filter-strict.json @@ -0,0 +1,200 @@ +[ + [ + "ignoredEntry", + { + "extended": null, + "globalExtended": null, + "type": "Directory", + "meta": false, + "ignore": true, + "path": "strip-dir/", + "mode": 493, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/", + "mode": 493, + "uid": 0, + "gid": 0, + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 4708, + "linkpath": "", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "ignoredEntry", + { + "extended": null, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": true, + "path": "strip-dir/hardlink-1", + "mode": 420, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 26, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/hardlink-1", + "mode": 420, + "uid": 0, + "gid": 0, + "size": 26, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 5644, + "linkpath": "", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "ignoredEntry", + { + "extended": null, + "globalExtended": null, + "type": "Link", + "meta": false, + "ignore": true, + "path": "strip-dir/hardlink-2", + "mode": 420, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "strip-dir/hardlink-1", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/hardlink-2", + "mode": 420, + "uid": 0, + "gid": 0, + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 7553, + "linkpath": "strip-dir/hardlink-1", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "ignoredEntry", + { + "extended": null, + "globalExtended": null, + "type": "Link", + "meta": false, + "ignore": true, + "path": "strip-dir/1/2/3/hardlink-3", + "mode": 420, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "strip-dir/hardlink-1", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/1/2/3/hardlink-3", + "mode": 420, + "uid": 0, + "gid": 0, + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 7845, + "linkpath": "strip-dir/hardlink-1", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "ignoredEntry", + { + "extended": null, + "globalExtended": null, + "type": "SymbolicLink", + "meta": false, + "ignore": true, + "path": "strip-dir/symlink", + "mode": 420, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "hardlink-2", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/symlink", + "mode": 420, + "uid": 0, + "gid": 0, + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 6417, + "linkpath": "hardlink-2", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "end" + ] +] diff --git a/test/fixtures/parse/links-strip--filter.json b/test/fixtures/parse/links-strip--filter.json new file mode 100644 index 00000000..9a640e0b --- /dev/null +++ b/test/fixtures/parse/links-strip--filter.json @@ -0,0 +1,200 @@ +[ + [ + "ignoredEntry", + { + "extended": null, + "globalExtended": null, + "type": "Directory", + "meta": false, + "ignore": true, + "path": "strip-dir/", + "mode": 493, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/", + "mode": 493, + "uid": 0, + "gid": 0, + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 4708, + "linkpath": "", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "ignoredEntry", + { + "extended": null, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": true, + "path": "strip-dir/hardlink-1", + "mode": 420, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 26, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/hardlink-1", + "mode": 420, + "uid": 0, + "gid": 0, + "size": 26, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 5644, + "linkpath": "", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "ignoredEntry", + { + "extended": null, + "globalExtended": null, + "type": "Link", + "meta": false, + "ignore": true, + "path": "strip-dir/hardlink-2", + "mode": 420, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "strip-dir/hardlink-1", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/hardlink-2", + "mode": 420, + "uid": 0, + "gid": 0, + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 7553, + "linkpath": "strip-dir/hardlink-1", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "ignoredEntry", + { + "extended": null, + "globalExtended": null, + "type": "Link", + "meta": false, + "ignore": true, + "path": "strip-dir/1/2/3/hardlink-3", + "mode": 420, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "strip-dir/hardlink-1", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/1/2/3/hardlink-3", + "mode": 420, + "uid": 0, + "gid": 0, + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 7845, + "linkpath": "strip-dir/hardlink-1", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "ignoredEntry", + { + "extended": null, + "globalExtended": null, + "type": "SymbolicLink", + "meta": false, + "ignore": true, + "path": "strip-dir/symlink", + "mode": 420, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "hardlink-2", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/symlink", + "mode": 420, + "uid": 0, + "gid": 0, + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 6417, + "linkpath": "hardlink-2", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "end" + ] +] diff --git a/test/fixtures/parse/links-strip--meta-250-filter-strict.json b/test/fixtures/parse/links-strip--meta-250-filter-strict.json new file mode 100644 index 00000000..9a640e0b --- /dev/null +++ b/test/fixtures/parse/links-strip--meta-250-filter-strict.json @@ -0,0 +1,200 @@ +[ + [ + "ignoredEntry", + { + "extended": null, + "globalExtended": null, + "type": "Directory", + "meta": false, + "ignore": true, + "path": "strip-dir/", + "mode": 493, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/", + "mode": 493, + "uid": 0, + "gid": 0, + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 4708, + "linkpath": "", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "ignoredEntry", + { + "extended": null, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": true, + "path": "strip-dir/hardlink-1", + "mode": 420, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 26, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/hardlink-1", + "mode": 420, + "uid": 0, + "gid": 0, + "size": 26, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 5644, + "linkpath": "", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "ignoredEntry", + { + "extended": null, + "globalExtended": null, + "type": "Link", + "meta": false, + "ignore": true, + "path": "strip-dir/hardlink-2", + "mode": 420, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "strip-dir/hardlink-1", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/hardlink-2", + "mode": 420, + "uid": 0, + "gid": 0, + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 7553, + "linkpath": "strip-dir/hardlink-1", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "ignoredEntry", + { + "extended": null, + "globalExtended": null, + "type": "Link", + "meta": false, + "ignore": true, + "path": "strip-dir/1/2/3/hardlink-3", + "mode": 420, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "strip-dir/hardlink-1", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/1/2/3/hardlink-3", + "mode": 420, + "uid": 0, + "gid": 0, + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 7845, + "linkpath": "strip-dir/hardlink-1", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "ignoredEntry", + { + "extended": null, + "globalExtended": null, + "type": "SymbolicLink", + "meta": false, + "ignore": true, + "path": "strip-dir/symlink", + "mode": 420, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "hardlink-2", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/symlink", + "mode": 420, + "uid": 0, + "gid": 0, + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 6417, + "linkpath": "hardlink-2", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "end" + ] +] diff --git a/test/fixtures/parse/links-strip--meta-250-filter.json b/test/fixtures/parse/links-strip--meta-250-filter.json new file mode 100644 index 00000000..9a640e0b --- /dev/null +++ b/test/fixtures/parse/links-strip--meta-250-filter.json @@ -0,0 +1,200 @@ +[ + [ + "ignoredEntry", + { + "extended": null, + "globalExtended": null, + "type": "Directory", + "meta": false, + "ignore": true, + "path": "strip-dir/", + "mode": 493, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/", + "mode": 493, + "uid": 0, + "gid": 0, + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 4708, + "linkpath": "", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "ignoredEntry", + { + "extended": null, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": true, + "path": "strip-dir/hardlink-1", + "mode": 420, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 26, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/hardlink-1", + "mode": 420, + "uid": 0, + "gid": 0, + "size": 26, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 5644, + "linkpath": "", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "ignoredEntry", + { + "extended": null, + "globalExtended": null, + "type": "Link", + "meta": false, + "ignore": true, + "path": "strip-dir/hardlink-2", + "mode": 420, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "strip-dir/hardlink-1", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/hardlink-2", + "mode": 420, + "uid": 0, + "gid": 0, + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 7553, + "linkpath": "strip-dir/hardlink-1", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "ignoredEntry", + { + "extended": null, + "globalExtended": null, + "type": "Link", + "meta": false, + "ignore": true, + "path": "strip-dir/1/2/3/hardlink-3", + "mode": 420, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "strip-dir/hardlink-1", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/1/2/3/hardlink-3", + "mode": 420, + "uid": 0, + "gid": 0, + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 7845, + "linkpath": "strip-dir/hardlink-1", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "ignoredEntry", + { + "extended": null, + "globalExtended": null, + "type": "SymbolicLink", + "meta": false, + "ignore": true, + "path": "strip-dir/symlink", + "mode": 420, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "hardlink-2", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/symlink", + "mode": 420, + "uid": 0, + "gid": 0, + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 6417, + "linkpath": "hardlink-2", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "end" + ] +] diff --git a/test/fixtures/parse/links-strip--meta-250-strict.json b/test/fixtures/parse/links-strip--meta-250-strict.json new file mode 100644 index 00000000..17e5397d --- /dev/null +++ b/test/fixtures/parse/links-strip--meta-250-strict.json @@ -0,0 +1,200 @@ +[ + [ + "entry", + { + "extended": null, + "globalExtended": null, + "type": "Directory", + "meta": false, + "ignore": false, + "path": "strip-dir/", + "mode": 493, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/", + "mode": 493, + "uid": 0, + "gid": 0, + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 4708, + "linkpath": "", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "entry", + { + "extended": null, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": false, + "path": "strip-dir/hardlink-1", + "mode": 420, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 26, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/hardlink-1", + "mode": 420, + "uid": 0, + "gid": 0, + "size": 26, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 5644, + "linkpath": "", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "entry", + { + "extended": null, + "globalExtended": null, + "type": "Link", + "meta": false, + "ignore": false, + "path": "strip-dir/hardlink-2", + "mode": 420, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "strip-dir/hardlink-1", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/hardlink-2", + "mode": 420, + "uid": 0, + "gid": 0, + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 7553, + "linkpath": "strip-dir/hardlink-1", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "entry", + { + "extended": null, + "globalExtended": null, + "type": "Link", + "meta": false, + "ignore": false, + "path": "strip-dir/1/2/3/hardlink-3", + "mode": 420, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "strip-dir/hardlink-1", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/1/2/3/hardlink-3", + "mode": 420, + "uid": 0, + "gid": 0, + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 7845, + "linkpath": "strip-dir/hardlink-1", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "entry", + { + "extended": null, + "globalExtended": null, + "type": "SymbolicLink", + "meta": false, + "ignore": false, + "path": "strip-dir/symlink", + "mode": 420, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "hardlink-2", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/symlink", + "mode": 420, + "uid": 0, + "gid": 0, + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 6417, + "linkpath": "hardlink-2", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "end" + ] +] diff --git a/test/fixtures/parse/links-strip--meta-250.json b/test/fixtures/parse/links-strip--meta-250.json new file mode 100644 index 00000000..17e5397d --- /dev/null +++ b/test/fixtures/parse/links-strip--meta-250.json @@ -0,0 +1,200 @@ +[ + [ + "entry", + { + "extended": null, + "globalExtended": null, + "type": "Directory", + "meta": false, + "ignore": false, + "path": "strip-dir/", + "mode": 493, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/", + "mode": 493, + "uid": 0, + "gid": 0, + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 4708, + "linkpath": "", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "entry", + { + "extended": null, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": false, + "path": "strip-dir/hardlink-1", + "mode": 420, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 26, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/hardlink-1", + "mode": 420, + "uid": 0, + "gid": 0, + "size": 26, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 5644, + "linkpath": "", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "entry", + { + "extended": null, + "globalExtended": null, + "type": "Link", + "meta": false, + "ignore": false, + "path": "strip-dir/hardlink-2", + "mode": 420, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "strip-dir/hardlink-1", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/hardlink-2", + "mode": 420, + "uid": 0, + "gid": 0, + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 7553, + "linkpath": "strip-dir/hardlink-1", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "entry", + { + "extended": null, + "globalExtended": null, + "type": "Link", + "meta": false, + "ignore": false, + "path": "strip-dir/1/2/3/hardlink-3", + "mode": 420, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "strip-dir/hardlink-1", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/1/2/3/hardlink-3", + "mode": 420, + "uid": 0, + "gid": 0, + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 7845, + "linkpath": "strip-dir/hardlink-1", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "entry", + { + "extended": null, + "globalExtended": null, + "type": "SymbolicLink", + "meta": false, + "ignore": false, + "path": "strip-dir/symlink", + "mode": 420, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "hardlink-2", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/symlink", + "mode": 420, + "uid": 0, + "gid": 0, + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 6417, + "linkpath": "hardlink-2", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "end" + ] +] diff --git a/test/fixtures/parse/links-strip--strict.json b/test/fixtures/parse/links-strip--strict.json new file mode 100644 index 00000000..17e5397d --- /dev/null +++ b/test/fixtures/parse/links-strip--strict.json @@ -0,0 +1,200 @@ +[ + [ + "entry", + { + "extended": null, + "globalExtended": null, + "type": "Directory", + "meta": false, + "ignore": false, + "path": "strip-dir/", + "mode": 493, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/", + "mode": 493, + "uid": 0, + "gid": 0, + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 4708, + "linkpath": "", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "entry", + { + "extended": null, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": false, + "path": "strip-dir/hardlink-1", + "mode": 420, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 26, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/hardlink-1", + "mode": 420, + "uid": 0, + "gid": 0, + "size": 26, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 5644, + "linkpath": "", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "entry", + { + "extended": null, + "globalExtended": null, + "type": "Link", + "meta": false, + "ignore": false, + "path": "strip-dir/hardlink-2", + "mode": 420, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "strip-dir/hardlink-1", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/hardlink-2", + "mode": 420, + "uid": 0, + "gid": 0, + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 7553, + "linkpath": "strip-dir/hardlink-1", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "entry", + { + "extended": null, + "globalExtended": null, + "type": "Link", + "meta": false, + "ignore": false, + "path": "strip-dir/1/2/3/hardlink-3", + "mode": 420, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "strip-dir/hardlink-1", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/1/2/3/hardlink-3", + "mode": 420, + "uid": 0, + "gid": 0, + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 7845, + "linkpath": "strip-dir/hardlink-1", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "entry", + { + "extended": null, + "globalExtended": null, + "type": "SymbolicLink", + "meta": false, + "ignore": false, + "path": "strip-dir/symlink", + "mode": 420, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "hardlink-2", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/symlink", + "mode": 420, + "uid": 0, + "gid": 0, + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 6417, + "linkpath": "hardlink-2", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "end" + ] +] diff --git a/test/fixtures/parse/links-strip.json b/test/fixtures/parse/links-strip.json new file mode 100644 index 00000000..17e5397d --- /dev/null +++ b/test/fixtures/parse/links-strip.json @@ -0,0 +1,200 @@ +[ + [ + "entry", + { + "extended": null, + "globalExtended": null, + "type": "Directory", + "meta": false, + "ignore": false, + "path": "strip-dir/", + "mode": 493, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/", + "mode": 493, + "uid": 0, + "gid": 0, + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 4708, + "linkpath": "", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "entry", + { + "extended": null, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": false, + "path": "strip-dir/hardlink-1", + "mode": 420, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 26, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/hardlink-1", + "mode": 420, + "uid": 0, + "gid": 0, + "size": 26, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 5644, + "linkpath": "", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "entry", + { + "extended": null, + "globalExtended": null, + "type": "Link", + "meta": false, + "ignore": false, + "path": "strip-dir/hardlink-2", + "mode": 420, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "strip-dir/hardlink-1", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/hardlink-2", + "mode": 420, + "uid": 0, + "gid": 0, + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 7553, + "linkpath": "strip-dir/hardlink-1", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "entry", + { + "extended": null, + "globalExtended": null, + "type": "Link", + "meta": false, + "ignore": false, + "path": "strip-dir/1/2/3/hardlink-3", + "mode": 420, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "strip-dir/hardlink-1", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/1/2/3/hardlink-3", + "mode": 420, + "uid": 0, + "gid": 0, + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 7845, + "linkpath": "strip-dir/hardlink-1", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "entry", + { + "extended": null, + "globalExtended": null, + "type": "SymbolicLink", + "meta": false, + "ignore": false, + "path": "strip-dir/symlink", + "mode": 420, + "uid": 0, + "gid": 0, + "uname": "", + "gname": "", + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "atime": null, + "ctime": null, + "linkpath": "hardlink-2", + "header": { + "cksumValid": true, + "needPax": false, + "path": "strip-dir/symlink", + "mode": 420, + "uid": 0, + "gid": 0, + "size": 0, + "mtime": "2018-11-06T01:45:25.000Z", + "cksum": 6417, + "linkpath": "hardlink-2", + "uname": "", + "gname": "", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "end" + ] +] diff --git a/test/fixtures/parse/long-paths--filter-strict.json b/test/fixtures/parse/long-paths--filter-strict.json index c50db7bb..350a2bce 100644 --- a/test/fixtures/parse/long-paths--filter-strict.json +++ b/test/fixtures/parse/long-paths--filter-strict.json @@ -81,7 +81,7 @@ "header": { "cksumValid": true, "needPax": false, - "path": "120-byte-filename-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "path": "120-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "mode": 420, "uid": 501, "gid": 20, @@ -141,7 +141,7 @@ "header": { "cksumValid": true, "needPax": false, - "path": "170-byte-filename-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "path": "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "mode": 420, "uid": 501, "gid": 20, @@ -1215,7 +1215,7 @@ "header": { "cksumValid": true, "needPax": false, - "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "mode": 420, "uid": 501, "gid": 20, @@ -1275,7 +1275,7 @@ "header": { "cksumValid": true, "needPax": false, - "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxccccccccccccccccccccccccccccccccccccccccccccccccc", + "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "mode": 420, "uid": 501, "gid": 20, diff --git a/test/fixtures/parse/long-paths--filter.json b/test/fixtures/parse/long-paths--filter.json index c50db7bb..350a2bce 100644 --- a/test/fixtures/parse/long-paths--filter.json +++ b/test/fixtures/parse/long-paths--filter.json @@ -81,7 +81,7 @@ "header": { "cksumValid": true, "needPax": false, - "path": "120-byte-filename-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "path": "120-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "mode": 420, "uid": 501, "gid": 20, @@ -141,7 +141,7 @@ "header": { "cksumValid": true, "needPax": false, - "path": "170-byte-filename-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "path": "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "mode": 420, "uid": 501, "gid": 20, @@ -1215,7 +1215,7 @@ "header": { "cksumValid": true, "needPax": false, - "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "mode": 420, "uid": 501, "gid": 20, @@ -1275,7 +1275,7 @@ "header": { "cksumValid": true, "needPax": false, - "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxccccccccccccccccccccccccccccccccccccccccccccccccc", + "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "mode": 420, "uid": 501, "gid": 20, diff --git a/test/fixtures/parse/long-paths--meta-50-filter-strict.json b/test/fixtures/parse/long-paths--meta-250-filter-strict.json similarity index 93% rename from test/fixtures/parse/long-paths--meta-50-filter-strict.json rename to test/fixtures/parse/long-paths--meta-250-filter-strict.json index 09b10197..bf2babab 100644 --- a/test/fixtures/parse/long-paths--meta-50-filter-strict.json +++ b/test/fixtures/parse/long-paths--meta-250-filter-strict.json @@ -39,53 +39,35 @@ } ], [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "ExtendedHeader", - "meta": true, - "ignore": true, - "path": "PaxHeader/120-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 233, - "mtime": "2017-04-10T16:54:12.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "PaxHeader/120-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 233, - "mtime": "2017-04-10T16:54:12.000Z", - "cksum": 14407, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } + "meta", + "130 path=120-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\n20 ctime=1491843252\n20 atime=1491843717\n23 SCHILY.dev=16777220\n22 SCHILY.ino=9836297\n18 SCHILY.nlink=1\n" ], [ "ignoredEntry", { - "extended": null, + "extended": { + "atime": "2017-04-10T17:01:57.000Z", + "charset": null, + "comment": null, + "ctime": "2017-04-10T16:54:12.000Z", + "gid": null, + "gname": null, + "linkpath": null, + "mtime": null, + "path": "120-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "size": null, + "uid": null, + "uname": null, + "dev": 16777220, + "ino": 9836297, + "nlink": 1, + "global": false + }, "globalExtended": null, "type": "File", "meta": false, "ignore": true, - "path": "120-byte-filename-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "path": "120-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "mode": 420, "uid": 501, "gid": 20, @@ -93,13 +75,13 @@ "gname": "staff", "size": 100, "mtime": "2017-04-10T16:54:12.000Z", - "atime": null, - "ctime": null, + "atime": "2017-04-10T17:01:57.000Z", + "ctime": "2017-04-10T16:54:12.000Z", "linkpath": "", "header": { "cksumValid": true, "needPax": false, - "path": "120-byte-filename-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "path": "120-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "mode": 420, "uid": 501, "gid": 20, @@ -1365,48 +1347,30 @@ } ], [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "ExtendedHeader", - "meta": true, - "ignore": true, - "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/PaxHeader/Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 174, - "mtime": "2017-04-10T16:58:47.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/PaxHeader/Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 174, - "mtime": "2017-04-10T16:58:47.000Z", - "cksum": 11002, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } + "meta", + "71 path=long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/Ω.txt\n20 ctime=1491843527\n20 atime=1491844045\n23 SCHILY.dev=16777220\n22 SCHILY.ino=9836396\n18 SCHILY.nlink=1\n" ], [ "ignoredEntry", { - "extended": null, + "extended": { + "atime": "2017-04-10T17:07:25.000Z", + "charset": null, + "comment": null, + "ctime": "2017-04-10T16:58:47.000Z", + "gid": null, + "gname": null, + "linkpath": null, + "mtime": null, + "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/Ω.txt", + "size": null, + "uid": null, + "uname": null, + "dev": 16777220, + "ino": 9836396, + "nlink": 1, + "global": false + }, "globalExtended": null, "type": "File", "meta": false, @@ -1419,8 +1383,8 @@ "gname": "staff", "size": 2, "mtime": "2017-04-10T16:58:47.000Z", - "atime": null, - "ctime": null, + "atime": "2017-04-10T17:07:25.000Z", + "ctime": "2017-04-10T16:58:47.000Z", "linkpath": "", "header": { "cksumValid": true, diff --git a/test/fixtures/parse/long-paths--meta-50-filter.json b/test/fixtures/parse/long-paths--meta-250-filter.json similarity index 93% rename from test/fixtures/parse/long-paths--meta-50-filter.json rename to test/fixtures/parse/long-paths--meta-250-filter.json index 09b10197..bf2babab 100644 --- a/test/fixtures/parse/long-paths--meta-50-filter.json +++ b/test/fixtures/parse/long-paths--meta-250-filter.json @@ -39,53 +39,35 @@ } ], [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "ExtendedHeader", - "meta": true, - "ignore": true, - "path": "PaxHeader/120-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 233, - "mtime": "2017-04-10T16:54:12.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "PaxHeader/120-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 233, - "mtime": "2017-04-10T16:54:12.000Z", - "cksum": 14407, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } + "meta", + "130 path=120-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\n20 ctime=1491843252\n20 atime=1491843717\n23 SCHILY.dev=16777220\n22 SCHILY.ino=9836297\n18 SCHILY.nlink=1\n" ], [ "ignoredEntry", { - "extended": null, + "extended": { + "atime": "2017-04-10T17:01:57.000Z", + "charset": null, + "comment": null, + "ctime": "2017-04-10T16:54:12.000Z", + "gid": null, + "gname": null, + "linkpath": null, + "mtime": null, + "path": "120-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "size": null, + "uid": null, + "uname": null, + "dev": 16777220, + "ino": 9836297, + "nlink": 1, + "global": false + }, "globalExtended": null, "type": "File", "meta": false, "ignore": true, - "path": "120-byte-filename-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "path": "120-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "mode": 420, "uid": 501, "gid": 20, @@ -93,13 +75,13 @@ "gname": "staff", "size": 100, "mtime": "2017-04-10T16:54:12.000Z", - "atime": null, - "ctime": null, + "atime": "2017-04-10T17:01:57.000Z", + "ctime": "2017-04-10T16:54:12.000Z", "linkpath": "", "header": { "cksumValid": true, "needPax": false, - "path": "120-byte-filename-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "path": "120-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "mode": 420, "uid": 501, "gid": 20, @@ -1365,48 +1347,30 @@ } ], [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "ExtendedHeader", - "meta": true, - "ignore": true, - "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/PaxHeader/Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 174, - "mtime": "2017-04-10T16:58:47.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/PaxHeader/Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 174, - "mtime": "2017-04-10T16:58:47.000Z", - "cksum": 11002, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } + "meta", + "71 path=long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/Ω.txt\n20 ctime=1491843527\n20 atime=1491844045\n23 SCHILY.dev=16777220\n22 SCHILY.ino=9836396\n18 SCHILY.nlink=1\n" ], [ "ignoredEntry", { - "extended": null, + "extended": { + "atime": "2017-04-10T17:07:25.000Z", + "charset": null, + "comment": null, + "ctime": "2017-04-10T16:58:47.000Z", + "gid": null, + "gname": null, + "linkpath": null, + "mtime": null, + "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/Ω.txt", + "size": null, + "uid": null, + "uname": null, + "dev": 16777220, + "ino": 9836396, + "nlink": 1, + "global": false + }, "globalExtended": null, "type": "File", "meta": false, @@ -1419,8 +1383,8 @@ "gname": "staff", "size": 2, "mtime": "2017-04-10T16:58:47.000Z", - "atime": null, - "ctime": null, + "atime": "2017-04-10T17:07:25.000Z", + "ctime": "2017-04-10T16:58:47.000Z", "linkpath": "", "header": { "cksumValid": true, diff --git a/test/fixtures/parse/long-paths--meta-50-strict.json b/test/fixtures/parse/long-paths--meta-250-strict.json similarity index 93% rename from test/fixtures/parse/long-paths--meta-50-strict.json rename to test/fixtures/parse/long-paths--meta-250-strict.json index ead9d39c..78263cf6 100644 --- a/test/fixtures/parse/long-paths--meta-50-strict.json +++ b/test/fixtures/parse/long-paths--meta-250-strict.json @@ -39,53 +39,35 @@ } ], [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "ExtendedHeader", - "meta": true, - "ignore": true, - "path": "PaxHeader/120-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 233, - "mtime": "2017-04-10T16:54:12.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "PaxHeader/120-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 233, - "mtime": "2017-04-10T16:54:12.000Z", - "cksum": 14407, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } + "meta", + "130 path=120-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\n20 ctime=1491843252\n20 atime=1491843717\n23 SCHILY.dev=16777220\n22 SCHILY.ino=9836297\n18 SCHILY.nlink=1\n" ], [ "entry", { - "extended": null, + "extended": { + "atime": "2017-04-10T17:01:57.000Z", + "charset": null, + "comment": null, + "ctime": "2017-04-10T16:54:12.000Z", + "gid": null, + "gname": null, + "linkpath": null, + "mtime": null, + "path": "120-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "size": null, + "uid": null, + "uname": null, + "dev": 16777220, + "ino": 9836297, + "nlink": 1, + "global": false + }, "globalExtended": null, "type": "File", "meta": false, "ignore": false, - "path": "120-byte-filename-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "path": "120-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "mode": 420, "uid": 501, "gid": 20, @@ -93,13 +75,13 @@ "gname": "staff", "size": 100, "mtime": "2017-04-10T16:54:12.000Z", - "atime": null, - "ctime": null, + "atime": "2017-04-10T17:01:57.000Z", + "ctime": "2017-04-10T16:54:12.000Z", "linkpath": "", "header": { "cksumValid": true, "needPax": false, - "path": "120-byte-filename-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "path": "120-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "mode": 420, "uid": 501, "gid": 20, @@ -1365,48 +1347,30 @@ } ], [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "ExtendedHeader", - "meta": true, - "ignore": true, - "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/PaxHeader/Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 174, - "mtime": "2017-04-10T16:58:47.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/PaxHeader/Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 174, - "mtime": "2017-04-10T16:58:47.000Z", - "cksum": 11002, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } + "meta", + "71 path=long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/Ω.txt\n20 ctime=1491843527\n20 atime=1491844045\n23 SCHILY.dev=16777220\n22 SCHILY.ino=9836396\n18 SCHILY.nlink=1\n" ], [ "entry", { - "extended": null, + "extended": { + "atime": "2017-04-10T17:07:25.000Z", + "charset": null, + "comment": null, + "ctime": "2017-04-10T16:58:47.000Z", + "gid": null, + "gname": null, + "linkpath": null, + "mtime": null, + "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/Ω.txt", + "size": null, + "uid": null, + "uname": null, + "dev": 16777220, + "ino": 9836396, + "nlink": 1, + "global": false + }, "globalExtended": null, "type": "File", "meta": false, @@ -1419,8 +1383,8 @@ "gname": "staff", "size": 2, "mtime": "2017-04-10T16:58:47.000Z", - "atime": null, - "ctime": null, + "atime": "2017-04-10T17:07:25.000Z", + "ctime": "2017-04-10T16:58:47.000Z", "linkpath": "", "header": { "cksumValid": true, diff --git a/test/fixtures/parse/long-paths--meta-50.json b/test/fixtures/parse/long-paths--meta-250.json similarity index 93% rename from test/fixtures/parse/long-paths--meta-50.json rename to test/fixtures/parse/long-paths--meta-250.json index ead9d39c..78263cf6 100644 --- a/test/fixtures/parse/long-paths--meta-50.json +++ b/test/fixtures/parse/long-paths--meta-250.json @@ -39,53 +39,35 @@ } ], [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "ExtendedHeader", - "meta": true, - "ignore": true, - "path": "PaxHeader/120-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 233, - "mtime": "2017-04-10T16:54:12.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "PaxHeader/120-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 233, - "mtime": "2017-04-10T16:54:12.000Z", - "cksum": 14407, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } + "meta", + "130 path=120-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\n20 ctime=1491843252\n20 atime=1491843717\n23 SCHILY.dev=16777220\n22 SCHILY.ino=9836297\n18 SCHILY.nlink=1\n" ], [ "entry", { - "extended": null, + "extended": { + "atime": "2017-04-10T17:01:57.000Z", + "charset": null, + "comment": null, + "ctime": "2017-04-10T16:54:12.000Z", + "gid": null, + "gname": null, + "linkpath": null, + "mtime": null, + "path": "120-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "size": null, + "uid": null, + "uname": null, + "dev": 16777220, + "ino": 9836297, + "nlink": 1, + "global": false + }, "globalExtended": null, "type": "File", "meta": false, "ignore": false, - "path": "120-byte-filename-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "path": "120-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "mode": 420, "uid": 501, "gid": 20, @@ -93,13 +75,13 @@ "gname": "staff", "size": 100, "mtime": "2017-04-10T16:54:12.000Z", - "atime": null, - "ctime": null, + "atime": "2017-04-10T17:01:57.000Z", + "ctime": "2017-04-10T16:54:12.000Z", "linkpath": "", "header": { "cksumValid": true, "needPax": false, - "path": "120-byte-filename-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "path": "120-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "mode": 420, "uid": 501, "gid": 20, @@ -1365,48 +1347,30 @@ } ], [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "ExtendedHeader", - "meta": true, - "ignore": true, - "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/PaxHeader/Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 174, - "mtime": "2017-04-10T16:58:47.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/PaxHeader/Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 174, - "mtime": "2017-04-10T16:58:47.000Z", - "cksum": 11002, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } + "meta", + "71 path=long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/Ω.txt\n20 ctime=1491843527\n20 atime=1491844045\n23 SCHILY.dev=16777220\n22 SCHILY.ino=9836396\n18 SCHILY.nlink=1\n" ], [ "entry", { - "extended": null, + "extended": { + "atime": "2017-04-10T17:07:25.000Z", + "charset": null, + "comment": null, + "ctime": "2017-04-10T16:58:47.000Z", + "gid": null, + "gname": null, + "linkpath": null, + "mtime": null, + "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/Ω.txt", + "size": null, + "uid": null, + "uname": null, + "dev": 16777220, + "ino": 9836396, + "nlink": 1, + "global": false + }, "globalExtended": null, "type": "File", "meta": false, @@ -1419,8 +1383,8 @@ "gname": "staff", "size": 2, "mtime": "2017-04-10T16:58:47.000Z", - "atime": null, - "ctime": null, + "atime": "2017-04-10T17:07:25.000Z", + "ctime": "2017-04-10T16:58:47.000Z", "linkpath": "", "header": { "cksumValid": true, diff --git a/test/fixtures/parse/long-paths--strict.json b/test/fixtures/parse/long-paths--strict.json index 06f166ab..1a82c70d 100644 --- a/test/fixtures/parse/long-paths--strict.json +++ b/test/fixtures/parse/long-paths--strict.json @@ -81,7 +81,7 @@ "header": { "cksumValid": true, "needPax": false, - "path": "120-byte-filename-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "path": "120-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "mode": 420, "uid": 501, "gid": 20, @@ -141,7 +141,7 @@ "header": { "cksumValid": true, "needPax": false, - "path": "170-byte-filename-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "path": "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "mode": 420, "uid": 501, "gid": 20, @@ -1215,7 +1215,7 @@ "header": { "cksumValid": true, "needPax": false, - "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "mode": 420, "uid": 501, "gid": 20, @@ -1275,7 +1275,7 @@ "header": { "cksumValid": true, "needPax": false, - "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxccccccccccccccccccccccccccccccccccccccccccccccccc", + "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "mode": 420, "uid": 501, "gid": 20, diff --git a/test/fixtures/parse/long-paths.json b/test/fixtures/parse/long-paths.json index 06f166ab..1a82c70d 100644 --- a/test/fixtures/parse/long-paths.json +++ b/test/fixtures/parse/long-paths.json @@ -81,7 +81,7 @@ "header": { "cksumValid": true, "needPax": false, - "path": "120-byte-filename-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "path": "120-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "mode": 420, "uid": 501, "gid": 20, @@ -141,7 +141,7 @@ "header": { "cksumValid": true, "needPax": false, - "path": "170-byte-filename-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "path": "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "mode": 420, "uid": 501, "gid": 20, @@ -1215,7 +1215,7 @@ "header": { "cksumValid": true, "needPax": false, - "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "mode": 420, "uid": 501, "gid": 20, @@ -1275,7 +1275,7 @@ "header": { "cksumValid": true, "needPax": false, - "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxccccccccccccccccccccccccccccccccccccccccccccccccc", + "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "mode": 420, "uid": 501, "gid": 20, diff --git a/test/fixtures/parse/long-pax--filter-strict.json b/test/fixtures/parse/long-pax--filter-strict.json index 57b7f375..7e9df8bb 100644 --- a/test/fixtures/parse/long-pax--filter-strict.json +++ b/test/fixtures/parse/long-pax--filter-strict.json @@ -42,7 +42,7 @@ "header": { "cksumValid": true, "needPax": false, - "path": "120-byte-filename-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "path": "120-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "mode": 420, "uid": 501, "gid": 20, diff --git a/test/fixtures/parse/long-pax--filter.json b/test/fixtures/parse/long-pax--filter.json index 57b7f375..7e9df8bb 100644 --- a/test/fixtures/parse/long-pax--filter.json +++ b/test/fixtures/parse/long-pax--filter.json @@ -42,7 +42,7 @@ "header": { "cksumValid": true, "needPax": false, - "path": "120-byte-filename-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "path": "120-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "mode": 420, "uid": 501, "gid": 20, diff --git a/test/fixtures/parse/long-pax--meta-50-filter-strict.json b/test/fixtures/parse/long-pax--meta-250-filter-strict.json similarity index 100% rename from test/fixtures/parse/long-pax--meta-50-filter-strict.json rename to test/fixtures/parse/long-pax--meta-250-filter-strict.json diff --git a/test/fixtures/parse/long-pax--meta-50-filter.json b/test/fixtures/parse/long-pax--meta-250-filter.json similarity index 100% rename from test/fixtures/parse/long-pax--meta-50-filter.json rename to test/fixtures/parse/long-pax--meta-250-filter.json diff --git a/test/fixtures/parse/long-pax--meta-50-strict.json b/test/fixtures/parse/long-pax--meta-250-strict.json similarity index 100% rename from test/fixtures/parse/long-pax--meta-50-strict.json rename to test/fixtures/parse/long-pax--meta-250-strict.json diff --git a/test/fixtures/parse/long-pax--meta-50.json b/test/fixtures/parse/long-pax--meta-250.json similarity index 100% rename from test/fixtures/parse/long-pax--meta-50.json rename to test/fixtures/parse/long-pax--meta-250.json diff --git a/test/fixtures/parse/long-pax--strict.json b/test/fixtures/parse/long-pax--strict.json index 32ee13ee..c72def09 100644 --- a/test/fixtures/parse/long-pax--strict.json +++ b/test/fixtures/parse/long-pax--strict.json @@ -42,7 +42,7 @@ "header": { "cksumValid": true, "needPax": false, - "path": "120-byte-filename-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "path": "120-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "mode": 420, "uid": 501, "gid": 20, diff --git a/test/fixtures/parse/long-pax.json b/test/fixtures/parse/long-pax.json index 32ee13ee..c72def09 100644 --- a/test/fixtures/parse/long-pax.json +++ b/test/fixtures/parse/long-pax.json @@ -42,7 +42,7 @@ "header": { "cksumValid": true, "needPax": false, - "path": "120-byte-filename-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "path": "120-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "mode": 420, "uid": 501, "gid": 20, diff --git a/test/fixtures/parse/next-file-has-long--filter-strict.json b/test/fixtures/parse/next-file-has-long--filter-strict.json index 4d1a69f4..20c10f48 100644 --- a/test/fixtures/parse/next-file-has-long--filter-strict.json +++ b/test/fixtures/parse/next-file-has-long--filter-strict.json @@ -27,7 +27,7 @@ "header": { "cksumValid": true, "needPax": false, - "path": "170-byte-filename-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "path": "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "mode": 420, "uid": 501, "gid": 20, diff --git a/test/fixtures/parse/next-file-has-long--filter.json b/test/fixtures/parse/next-file-has-long--filter.json index 4d1a69f4..20c10f48 100644 --- a/test/fixtures/parse/next-file-has-long--filter.json +++ b/test/fixtures/parse/next-file-has-long--filter.json @@ -27,7 +27,7 @@ "header": { "cksumValid": true, "needPax": false, - "path": "170-byte-filename-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "path": "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "mode": 420, "uid": 501, "gid": 20, diff --git a/test/fixtures/parse/next-file-has-long--meta-250-filter-strict.json b/test/fixtures/parse/next-file-has-long--meta-250-filter-strict.json new file mode 100644 index 00000000..20c10f48 --- /dev/null +++ b/test/fixtures/parse/next-file-has-long--meta-250-filter-strict.json @@ -0,0 +1,101 @@ +[ + [ + "meta", + "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + ], + [ + "ignoredEntry", + { + "extended": { + "path": "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + }, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": true, + "path": "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "mode": 420, + "uid": 501, + "gid": 20, + "uname": "isaacs", + "gname": "staff", + "size": 100, + "mtime": "2017-04-10T16:56:18.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "mode": 420, + "uid": 501, + "gid": 20, + "size": 100, + "mtime": "2017-04-10T16:56:18.000Z", + "cksum": 14500, + "linkpath": "", + "uname": "isaacs", + "gname": "staff", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "meta", + "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + ], + [ + "ignoredEntry", + { + "extended": { + "linkpath": "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + }, + "globalExtended": null, + "type": "SymbolicLink", + "meta": false, + "ignore": true, + "path": "longlink", + "mode": 493, + "uid": 501, + "gid": 20, + "uname": "isaacs", + "gname": "staff", + "size": 0, + "mtime": "2017-04-10T23:22:33.000Z", + "atime": null, + "ctime": null, + "linkpath": "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "header": { + "cksumValid": true, + "needPax": false, + "path": "longlink", + "mode": 493, + "uid": 501, + "gid": 20, + "size": 0, + "mtime": "2017-04-10T23:22:33.000Z", + "cksum": 7135, + "linkpath": "././@LongSymLink", + "uname": "isaacs", + "gname": "staff", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "end" + ] +] diff --git a/test/fixtures/parse/next-file-has-long--meta-250-filter.json b/test/fixtures/parse/next-file-has-long--meta-250-filter.json new file mode 100644 index 00000000..20c10f48 --- /dev/null +++ b/test/fixtures/parse/next-file-has-long--meta-250-filter.json @@ -0,0 +1,101 @@ +[ + [ + "meta", + "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + ], + [ + "ignoredEntry", + { + "extended": { + "path": "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + }, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": true, + "path": "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "mode": 420, + "uid": 501, + "gid": 20, + "uname": "isaacs", + "gname": "staff", + "size": 100, + "mtime": "2017-04-10T16:56:18.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "mode": 420, + "uid": 501, + "gid": 20, + "size": 100, + "mtime": "2017-04-10T16:56:18.000Z", + "cksum": 14500, + "linkpath": "", + "uname": "isaacs", + "gname": "staff", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "meta", + "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + ], + [ + "ignoredEntry", + { + "extended": { + "linkpath": "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + }, + "globalExtended": null, + "type": "SymbolicLink", + "meta": false, + "ignore": true, + "path": "longlink", + "mode": 493, + "uid": 501, + "gid": 20, + "uname": "isaacs", + "gname": "staff", + "size": 0, + "mtime": "2017-04-10T23:22:33.000Z", + "atime": null, + "ctime": null, + "linkpath": "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "header": { + "cksumValid": true, + "needPax": false, + "path": "longlink", + "mode": 493, + "uid": 501, + "gid": 20, + "size": 0, + "mtime": "2017-04-10T23:22:33.000Z", + "cksum": 7135, + "linkpath": "././@LongSymLink", + "uname": "isaacs", + "gname": "staff", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "end" + ] +] diff --git a/test/fixtures/parse/next-file-has-long--meta-250-strict.json b/test/fixtures/parse/next-file-has-long--meta-250-strict.json new file mode 100644 index 00000000..25fdb331 --- /dev/null +++ b/test/fixtures/parse/next-file-has-long--meta-250-strict.json @@ -0,0 +1,101 @@ +[ + [ + "meta", + "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + ], + [ + "entry", + { + "extended": { + "path": "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + }, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": false, + "path": "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "mode": 420, + "uid": 501, + "gid": 20, + "uname": "isaacs", + "gname": "staff", + "size": 100, + "mtime": "2017-04-10T16:56:18.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "mode": 420, + "uid": 501, + "gid": 20, + "size": 100, + "mtime": "2017-04-10T16:56:18.000Z", + "cksum": 14500, + "linkpath": "", + "uname": "isaacs", + "gname": "staff", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "meta", + "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + ], + [ + "entry", + { + "extended": { + "linkpath": "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + }, + "globalExtended": null, + "type": "SymbolicLink", + "meta": false, + "ignore": false, + "path": "longlink", + "mode": 493, + "uid": 501, + "gid": 20, + "uname": "isaacs", + "gname": "staff", + "size": 0, + "mtime": "2017-04-10T23:22:33.000Z", + "atime": null, + "ctime": null, + "linkpath": "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "header": { + "cksumValid": true, + "needPax": false, + "path": "longlink", + "mode": 493, + "uid": 501, + "gid": 20, + "size": 0, + "mtime": "2017-04-10T23:22:33.000Z", + "cksum": 7135, + "linkpath": "././@LongSymLink", + "uname": "isaacs", + "gname": "staff", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "end" + ] +] diff --git a/test/fixtures/parse/next-file-has-long--meta-250.json b/test/fixtures/parse/next-file-has-long--meta-250.json new file mode 100644 index 00000000..25fdb331 --- /dev/null +++ b/test/fixtures/parse/next-file-has-long--meta-250.json @@ -0,0 +1,101 @@ +[ + [ + "meta", + "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + ], + [ + "entry", + { + "extended": { + "path": "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + }, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": false, + "path": "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "mode": 420, + "uid": 501, + "gid": 20, + "uname": "isaacs", + "gname": "staff", + "size": 100, + "mtime": "2017-04-10T16:56:18.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "mode": 420, + "uid": 501, + "gid": 20, + "size": 100, + "mtime": "2017-04-10T16:56:18.000Z", + "cksum": 14500, + "linkpath": "", + "uname": "isaacs", + "gname": "staff", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "meta", + "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + ], + [ + "entry", + { + "extended": { + "linkpath": "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" + }, + "globalExtended": null, + "type": "SymbolicLink", + "meta": false, + "ignore": false, + "path": "longlink", + "mode": 493, + "uid": 501, + "gid": 20, + "uname": "isaacs", + "gname": "staff", + "size": 0, + "mtime": "2017-04-10T23:22:33.000Z", + "atime": null, + "ctime": null, + "linkpath": "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "header": { + "cksumValid": true, + "needPax": false, + "path": "longlink", + "mode": 493, + "uid": 501, + "gid": 20, + "size": 0, + "mtime": "2017-04-10T23:22:33.000Z", + "cksum": 7135, + "linkpath": "././@LongSymLink", + "uname": "isaacs", + "gname": "staff", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "end" + ] +] diff --git a/test/fixtures/parse/next-file-has-long--meta-50-filter-strict.json b/test/fixtures/parse/next-file-has-long--meta-50-filter-strict.json deleted file mode 100644 index a37e9192..00000000 --- a/test/fixtures/parse/next-file-has-long--meta-50-filter-strict.json +++ /dev/null @@ -1,167 +0,0 @@ -[ - [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "NextFileHasLongPath", - "meta": true, - "ignore": true, - "path": "NextFileHasLongPath", - "mode": null, - "uid": null, - "gid": null, - "uname": "", - "gname": "", - "size": 170, - "mtime": null, - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "NextFileHasLongPath", - "mode": null, - "uid": null, - "gid": null, - "size": 170, - "mtime": null, - "cksum": 4028, - "linkpath": "", - "uname": "", - "gname": "", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "File", - "meta": false, - "ignore": true, - "path": "170-byte-filename-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 100, - "mtime": "2017-04-10T16:56:18.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "170-byte-filename-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 100, - "mtime": "2017-04-10T16:56:18.000Z", - "cksum": 14500, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "NextFileHasLongLinkpath", - "meta": true, - "ignore": true, - "path": "NextFileHasLongLinkpath", - "mode": null, - "uid": null, - "gid": null, - "uname": "", - "gname": "", - "size": 170, - "mtime": null, - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "NextFileHasLongLinkpath", - "mode": null, - "uid": null, - "gid": null, - "size": 170, - "mtime": null, - "cksum": 4457, - "linkpath": "", - "uname": "", - "gname": "", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "SymbolicLink", - "meta": false, - "ignore": true, - "path": "longlink", - "mode": 493, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 0, - "mtime": "2017-04-10T23:22:33.000Z", - "atime": null, - "ctime": null, - "linkpath": "././@LongSymLink", - "header": { - "cksumValid": true, - "needPax": false, - "path": "longlink", - "mode": 493, - "uid": 501, - "gid": 20, - "size": 0, - "mtime": "2017-04-10T23:22:33.000Z", - "cksum": 7135, - "linkpath": "././@LongSymLink", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "nullBlock" - ], - [ - "nullBlock" - ], - [ - "end" - ] -] diff --git a/test/fixtures/parse/next-file-has-long--meta-50-filter.json b/test/fixtures/parse/next-file-has-long--meta-50-filter.json deleted file mode 100644 index a37e9192..00000000 --- a/test/fixtures/parse/next-file-has-long--meta-50-filter.json +++ /dev/null @@ -1,167 +0,0 @@ -[ - [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "NextFileHasLongPath", - "meta": true, - "ignore": true, - "path": "NextFileHasLongPath", - "mode": null, - "uid": null, - "gid": null, - "uname": "", - "gname": "", - "size": 170, - "mtime": null, - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "NextFileHasLongPath", - "mode": null, - "uid": null, - "gid": null, - "size": 170, - "mtime": null, - "cksum": 4028, - "linkpath": "", - "uname": "", - "gname": "", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "File", - "meta": false, - "ignore": true, - "path": "170-byte-filename-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 100, - "mtime": "2017-04-10T16:56:18.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "170-byte-filename-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 100, - "mtime": "2017-04-10T16:56:18.000Z", - "cksum": 14500, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "NextFileHasLongLinkpath", - "meta": true, - "ignore": true, - "path": "NextFileHasLongLinkpath", - "mode": null, - "uid": null, - "gid": null, - "uname": "", - "gname": "", - "size": 170, - "mtime": null, - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "NextFileHasLongLinkpath", - "mode": null, - "uid": null, - "gid": null, - "size": 170, - "mtime": null, - "cksum": 4457, - "linkpath": "", - "uname": "", - "gname": "", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "SymbolicLink", - "meta": false, - "ignore": true, - "path": "longlink", - "mode": 493, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 0, - "mtime": "2017-04-10T23:22:33.000Z", - "atime": null, - "ctime": null, - "linkpath": "././@LongSymLink", - "header": { - "cksumValid": true, - "needPax": false, - "path": "longlink", - "mode": 493, - "uid": 501, - "gid": 20, - "size": 0, - "mtime": "2017-04-10T23:22:33.000Z", - "cksum": 7135, - "linkpath": "././@LongSymLink", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "nullBlock" - ], - [ - "nullBlock" - ], - [ - "end" - ] -] diff --git a/test/fixtures/parse/next-file-has-long--meta-50-strict.json b/test/fixtures/parse/next-file-has-long--meta-50-strict.json deleted file mode 100644 index 53b99820..00000000 --- a/test/fixtures/parse/next-file-has-long--meta-50-strict.json +++ /dev/null @@ -1,167 +0,0 @@ -[ - [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "NextFileHasLongPath", - "meta": true, - "ignore": true, - "path": "NextFileHasLongPath", - "mode": null, - "uid": null, - "gid": null, - "uname": "", - "gname": "", - "size": 170, - "mtime": null, - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "NextFileHasLongPath", - "mode": null, - "uid": null, - "gid": null, - "size": 170, - "mtime": null, - "cksum": 4028, - "linkpath": "", - "uname": "", - "gname": "", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "entry", - { - "extended": null, - "globalExtended": null, - "type": "File", - "meta": false, - "ignore": false, - "path": "170-byte-filename-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 100, - "mtime": "2017-04-10T16:56:18.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "170-byte-filename-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 100, - "mtime": "2017-04-10T16:56:18.000Z", - "cksum": 14500, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "NextFileHasLongLinkpath", - "meta": true, - "ignore": true, - "path": "NextFileHasLongLinkpath", - "mode": null, - "uid": null, - "gid": null, - "uname": "", - "gname": "", - "size": 170, - "mtime": null, - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "NextFileHasLongLinkpath", - "mode": null, - "uid": null, - "gid": null, - "size": 170, - "mtime": null, - "cksum": 4457, - "linkpath": "", - "uname": "", - "gname": "", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "entry", - { - "extended": null, - "globalExtended": null, - "type": "SymbolicLink", - "meta": false, - "ignore": false, - "path": "longlink", - "mode": 493, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 0, - "mtime": "2017-04-10T23:22:33.000Z", - "atime": null, - "ctime": null, - "linkpath": "././@LongSymLink", - "header": { - "cksumValid": true, - "needPax": false, - "path": "longlink", - "mode": 493, - "uid": 501, - "gid": 20, - "size": 0, - "mtime": "2017-04-10T23:22:33.000Z", - "cksum": 7135, - "linkpath": "././@LongSymLink", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "nullBlock" - ], - [ - "nullBlock" - ], - [ - "end" - ] -] diff --git a/test/fixtures/parse/next-file-has-long--meta-50.json b/test/fixtures/parse/next-file-has-long--meta-50.json deleted file mode 100644 index 53b99820..00000000 --- a/test/fixtures/parse/next-file-has-long--meta-50.json +++ /dev/null @@ -1,167 +0,0 @@ -[ - [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "NextFileHasLongPath", - "meta": true, - "ignore": true, - "path": "NextFileHasLongPath", - "mode": null, - "uid": null, - "gid": null, - "uname": "", - "gname": "", - "size": 170, - "mtime": null, - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "NextFileHasLongPath", - "mode": null, - "uid": null, - "gid": null, - "size": 170, - "mtime": null, - "cksum": 4028, - "linkpath": "", - "uname": "", - "gname": "", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "entry", - { - "extended": null, - "globalExtended": null, - "type": "File", - "meta": false, - "ignore": false, - "path": "170-byte-filename-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 100, - "mtime": "2017-04-10T16:56:18.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "170-byte-filename-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 100, - "mtime": "2017-04-10T16:56:18.000Z", - "cksum": 14500, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "NextFileHasLongLinkpath", - "meta": true, - "ignore": true, - "path": "NextFileHasLongLinkpath", - "mode": null, - "uid": null, - "gid": null, - "uname": "", - "gname": "", - "size": 170, - "mtime": null, - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "NextFileHasLongLinkpath", - "mode": null, - "uid": null, - "gid": null, - "size": 170, - "mtime": null, - "cksum": 4457, - "linkpath": "", - "uname": "", - "gname": "", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "entry", - { - "extended": null, - "globalExtended": null, - "type": "SymbolicLink", - "meta": false, - "ignore": false, - "path": "longlink", - "mode": 493, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 0, - "mtime": "2017-04-10T23:22:33.000Z", - "atime": null, - "ctime": null, - "linkpath": "././@LongSymLink", - "header": { - "cksumValid": true, - "needPax": false, - "path": "longlink", - "mode": 493, - "uid": 501, - "gid": 20, - "size": 0, - "mtime": "2017-04-10T23:22:33.000Z", - "cksum": 7135, - "linkpath": "././@LongSymLink", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "nullBlock" - ], - [ - "nullBlock" - ], - [ - "end" - ] -] diff --git a/test/fixtures/parse/next-file-has-long--strict.json b/test/fixtures/parse/next-file-has-long--strict.json index 95fecab0..25fdb331 100644 --- a/test/fixtures/parse/next-file-has-long--strict.json +++ b/test/fixtures/parse/next-file-has-long--strict.json @@ -27,7 +27,7 @@ "header": { "cksumValid": true, "needPax": false, - "path": "170-byte-filename-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "path": "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "mode": 420, "uid": 501, "gid": 20, diff --git a/test/fixtures/parse/next-file-has-long.json b/test/fixtures/parse/next-file-has-long.json index 95fecab0..25fdb331 100644 --- a/test/fixtures/parse/next-file-has-long.json +++ b/test/fixtures/parse/next-file-has-long.json @@ -27,7 +27,7 @@ "header": { "cksumValid": true, "needPax": false, - "path": "170-byte-filename-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", + "path": "170-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc", "mode": 420, "uid": 501, "gid": 20, diff --git a/test/fixtures/parse/null-byte--filter-strict.json b/test/fixtures/parse/null-byte--filter-strict.json index 3adb6da5..ccfb2ae8 100644 --- a/test/fixtures/parse/null-byte--filter-strict.json +++ b/test/fixtures/parse/null-byte--filter-strict.json @@ -66,7 +66,7 @@ "header": { "cksumValid": true, "needPax": false, - "path": "this_is_a_really_long_directory_name_with_a_lot_of_characters/this_is_a_really_long_tgz_file_with_a_", + "path": "this_is_a_really_long_directory_name_with_a_lot_of_characters/this_is_a_really_long_tgz_file_with_a_lot_of_characters.tgz", "mode": 436, "uid": 1000, "gid": 1000, diff --git a/test/fixtures/parse/null-byte--filter.json b/test/fixtures/parse/null-byte--filter.json index 3adb6da5..ccfb2ae8 100644 --- a/test/fixtures/parse/null-byte--filter.json +++ b/test/fixtures/parse/null-byte--filter.json @@ -66,7 +66,7 @@ "header": { "cksumValid": true, "needPax": false, - "path": "this_is_a_really_long_directory_name_with_a_lot_of_characters/this_is_a_really_long_tgz_file_with_a_", + "path": "this_is_a_really_long_directory_name_with_a_lot_of_characters/this_is_a_really_long_tgz_file_with_a_lot_of_characters.tgz", "mode": 436, "uid": 1000, "gid": 1000, diff --git a/test/fixtures/parse/null-byte--meta-50-filter-strict.json b/test/fixtures/parse/null-byte--meta-250-filter-strict.json similarity index 69% rename from test/fixtures/parse/null-byte--meta-50-filter-strict.json rename to test/fixtures/parse/null-byte--meta-250-filter-strict.json index 9cc3588a..ccfb2ae8 100644 --- a/test/fixtures/parse/null-byte--meta-50-filter-strict.json +++ b/test/fixtures/parse/null-byte--meta-250-filter-strict.json @@ -39,53 +39,20 @@ } ], [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "NextFileHasLongPath", - "meta": true, - "ignore": true, - "path": "././@LongLink", - "mode": 420, - "uid": 0, - "gid": 0, - "uname": null, - "gname": null, - "size": 122, - "mtime": "1970-01-01T00:00:00.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "././@LongLink", - "mode": 420, - "uid": 0, - "gid": 0, - "size": 122, - "mtime": "1970-01-01T00:00:00.000Z", - "cksum": 4995, - "linkpath": "", - "uname": null, - "gname": null, - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } + "meta", + "this_is_a_really_long_directory_name_with_a_lot_of_characters/this_is_a_really_long_tgz_file_with_a_lot_of_characters.tgz\u0000" ], [ "ignoredEntry", { - "extended": null, + "extended": { + "path": "this_is_a_really_long_directory_name_with_a_lot_of_characters/this_is_a_really_long_tgz_file_with_a_lot_of_characters.tgz" + }, "globalExtended": null, "type": "File", "meta": false, "ignore": true, - "path": "this_is_a_really_long_directory_name_with_a_lot_of_characters/this_is_a_really_long_tgz_file_with_a_", + "path": "this_is_a_really_long_directory_name_with_a_lot_of_characters/this_is_a_really_long_tgz_file_with_a_lot_of_characters.tgz", "mode": 436, "uid": 1000, "gid": 1000, @@ -99,7 +66,7 @@ "header": { "cksumValid": true, "needPax": false, - "path": "this_is_a_really_long_directory_name_with_a_lot_of_characters/this_is_a_really_long_tgz_file_with_a_", + "path": "this_is_a_really_long_directory_name_with_a_lot_of_characters/this_is_a_really_long_tgz_file_with_a_lot_of_characters.tgz", "mode": 436, "uid": 1000, "gid": 1000, diff --git a/test/fixtures/parse/null-byte--meta-50-filter.json b/test/fixtures/parse/null-byte--meta-250-filter.json similarity index 69% rename from test/fixtures/parse/null-byte--meta-50-filter.json rename to test/fixtures/parse/null-byte--meta-250-filter.json index 9cc3588a..ccfb2ae8 100644 --- a/test/fixtures/parse/null-byte--meta-50-filter.json +++ b/test/fixtures/parse/null-byte--meta-250-filter.json @@ -39,53 +39,20 @@ } ], [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "NextFileHasLongPath", - "meta": true, - "ignore": true, - "path": "././@LongLink", - "mode": 420, - "uid": 0, - "gid": 0, - "uname": null, - "gname": null, - "size": 122, - "mtime": "1970-01-01T00:00:00.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "././@LongLink", - "mode": 420, - "uid": 0, - "gid": 0, - "size": 122, - "mtime": "1970-01-01T00:00:00.000Z", - "cksum": 4995, - "linkpath": "", - "uname": null, - "gname": null, - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } + "meta", + "this_is_a_really_long_directory_name_with_a_lot_of_characters/this_is_a_really_long_tgz_file_with_a_lot_of_characters.tgz\u0000" ], [ "ignoredEntry", { - "extended": null, + "extended": { + "path": "this_is_a_really_long_directory_name_with_a_lot_of_characters/this_is_a_really_long_tgz_file_with_a_lot_of_characters.tgz" + }, "globalExtended": null, "type": "File", "meta": false, "ignore": true, - "path": "this_is_a_really_long_directory_name_with_a_lot_of_characters/this_is_a_really_long_tgz_file_with_a_", + "path": "this_is_a_really_long_directory_name_with_a_lot_of_characters/this_is_a_really_long_tgz_file_with_a_lot_of_characters.tgz", "mode": 436, "uid": 1000, "gid": 1000, @@ -99,7 +66,7 @@ "header": { "cksumValid": true, "needPax": false, - "path": "this_is_a_really_long_directory_name_with_a_lot_of_characters/this_is_a_really_long_tgz_file_with_a_", + "path": "this_is_a_really_long_directory_name_with_a_lot_of_characters/this_is_a_really_long_tgz_file_with_a_lot_of_characters.tgz", "mode": 436, "uid": 1000, "gid": 1000, diff --git a/test/fixtures/parse/null-byte--meta-50-strict.json b/test/fixtures/parse/null-byte--meta-250-strict.json similarity index 69% rename from test/fixtures/parse/null-byte--meta-50-strict.json rename to test/fixtures/parse/null-byte--meta-250-strict.json index 8c74912f..fb7cc97d 100644 --- a/test/fixtures/parse/null-byte--meta-50-strict.json +++ b/test/fixtures/parse/null-byte--meta-250-strict.json @@ -39,53 +39,20 @@ } ], [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "NextFileHasLongPath", - "meta": true, - "ignore": true, - "path": "././@LongLink", - "mode": 420, - "uid": 0, - "gid": 0, - "uname": null, - "gname": null, - "size": 122, - "mtime": "1970-01-01T00:00:00.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "././@LongLink", - "mode": 420, - "uid": 0, - "gid": 0, - "size": 122, - "mtime": "1970-01-01T00:00:00.000Z", - "cksum": 4995, - "linkpath": "", - "uname": null, - "gname": null, - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } + "meta", + "this_is_a_really_long_directory_name_with_a_lot_of_characters/this_is_a_really_long_tgz_file_with_a_lot_of_characters.tgz\u0000" ], [ "entry", { - "extended": null, + "extended": { + "path": "this_is_a_really_long_directory_name_with_a_lot_of_characters/this_is_a_really_long_tgz_file_with_a_lot_of_characters.tgz" + }, "globalExtended": null, "type": "File", "meta": false, "ignore": false, - "path": "this_is_a_really_long_directory_name_with_a_lot_of_characters/this_is_a_really_long_tgz_file_with_a_", + "path": "this_is_a_really_long_directory_name_with_a_lot_of_characters/this_is_a_really_long_tgz_file_with_a_lot_of_characters.tgz", "mode": 436, "uid": 1000, "gid": 1000, @@ -99,7 +66,7 @@ "header": { "cksumValid": true, "needPax": false, - "path": "this_is_a_really_long_directory_name_with_a_lot_of_characters/this_is_a_really_long_tgz_file_with_a_", + "path": "this_is_a_really_long_directory_name_with_a_lot_of_characters/this_is_a_really_long_tgz_file_with_a_lot_of_characters.tgz", "mode": 436, "uid": 1000, "gid": 1000, diff --git a/test/fixtures/parse/null-byte--meta-50.json b/test/fixtures/parse/null-byte--meta-250.json similarity index 69% rename from test/fixtures/parse/null-byte--meta-50.json rename to test/fixtures/parse/null-byte--meta-250.json index 8c74912f..fb7cc97d 100644 --- a/test/fixtures/parse/null-byte--meta-50.json +++ b/test/fixtures/parse/null-byte--meta-250.json @@ -39,53 +39,20 @@ } ], [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "NextFileHasLongPath", - "meta": true, - "ignore": true, - "path": "././@LongLink", - "mode": 420, - "uid": 0, - "gid": 0, - "uname": null, - "gname": null, - "size": 122, - "mtime": "1970-01-01T00:00:00.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "././@LongLink", - "mode": 420, - "uid": 0, - "gid": 0, - "size": 122, - "mtime": "1970-01-01T00:00:00.000Z", - "cksum": 4995, - "linkpath": "", - "uname": null, - "gname": null, - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } + "meta", + "this_is_a_really_long_directory_name_with_a_lot_of_characters/this_is_a_really_long_tgz_file_with_a_lot_of_characters.tgz\u0000" ], [ "entry", { - "extended": null, + "extended": { + "path": "this_is_a_really_long_directory_name_with_a_lot_of_characters/this_is_a_really_long_tgz_file_with_a_lot_of_characters.tgz" + }, "globalExtended": null, "type": "File", "meta": false, "ignore": false, - "path": "this_is_a_really_long_directory_name_with_a_lot_of_characters/this_is_a_really_long_tgz_file_with_a_", + "path": "this_is_a_really_long_directory_name_with_a_lot_of_characters/this_is_a_really_long_tgz_file_with_a_lot_of_characters.tgz", "mode": 436, "uid": 1000, "gid": 1000, @@ -99,7 +66,7 @@ "header": { "cksumValid": true, "needPax": false, - "path": "this_is_a_really_long_directory_name_with_a_lot_of_characters/this_is_a_really_long_tgz_file_with_a_", + "path": "this_is_a_really_long_directory_name_with_a_lot_of_characters/this_is_a_really_long_tgz_file_with_a_lot_of_characters.tgz", "mode": 436, "uid": 1000, "gid": 1000, diff --git a/test/fixtures/parse/null-byte--strict.json b/test/fixtures/parse/null-byte--strict.json index 717f9836..fb7cc97d 100644 --- a/test/fixtures/parse/null-byte--strict.json +++ b/test/fixtures/parse/null-byte--strict.json @@ -66,7 +66,7 @@ "header": { "cksumValid": true, "needPax": false, - "path": "this_is_a_really_long_directory_name_with_a_lot_of_characters/this_is_a_really_long_tgz_file_with_a_", + "path": "this_is_a_really_long_directory_name_with_a_lot_of_characters/this_is_a_really_long_tgz_file_with_a_lot_of_characters.tgz", "mode": 436, "uid": 1000, "gid": 1000, diff --git a/test/fixtures/parse/null-byte.json b/test/fixtures/parse/null-byte.json index 717f9836..fb7cc97d 100644 --- a/test/fixtures/parse/null-byte.json +++ b/test/fixtures/parse/null-byte.json @@ -66,7 +66,7 @@ "header": { "cksumValid": true, "needPax": false, - "path": "this_is_a_really_long_directory_name_with_a_lot_of_characters/this_is_a_really_long_tgz_file_with_a_", + "path": "this_is_a_really_long_directory_name_with_a_lot_of_characters/this_is_a_really_long_tgz_file_with_a_lot_of_characters.tgz", "mode": 436, "uid": 1000, "gid": 1000, diff --git a/test/fixtures/parse/path-missing--meta-50-filter-strict.json b/test/fixtures/parse/path-missing--meta-250-filter-strict.json similarity index 100% rename from test/fixtures/parse/path-missing--meta-50-filter-strict.json rename to test/fixtures/parse/path-missing--meta-250-filter-strict.json diff --git a/test/fixtures/parse/path-missing--meta-50-filter.json b/test/fixtures/parse/path-missing--meta-250-filter.json similarity index 100% rename from test/fixtures/parse/path-missing--meta-50-filter.json rename to test/fixtures/parse/path-missing--meta-250-filter.json diff --git a/test/fixtures/parse/path-missing--meta-50-strict.json b/test/fixtures/parse/path-missing--meta-250-strict.json similarity index 100% rename from test/fixtures/parse/path-missing--meta-50-strict.json rename to test/fixtures/parse/path-missing--meta-250-strict.json diff --git a/test/fixtures/parse/path-missing--meta-50.json b/test/fixtures/parse/path-missing--meta-250.json similarity index 100% rename from test/fixtures/parse/path-missing--meta-50.json rename to test/fixtures/parse/path-missing--meta-250.json diff --git a/test/fixtures/parse/trailing-slash-corner-case--filter-strict.json b/test/fixtures/parse/trailing-slash-corner-case--filter-strict.json new file mode 100644 index 00000000..82709536 --- /dev/null +++ b/test/fixtures/parse/trailing-slash-corner-case--filter-strict.json @@ -0,0 +1,161 @@ +[ + [ + "ignoredEntry", + { + "extended": null, + "globalExtended": null, + "type": "Directory", + "meta": false, + "ignore": true, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/", + "mode": 493, + "uid": 501, + "gid": 20, + "uname": null, + "gname": null, + "size": 0, + "mtime": "2018-06-19T00:03:11.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/", + "mode": 493, + "uid": 501, + "gid": 20, + "size": 0, + "mtime": "2018-06-19T00:03:11.000Z", + "cksum": 13612, + "linkpath": "", + "uname": null, + "gname": null, + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "meta", + "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt\u0000" + ], + [ + "ignoredEntry", + { + "extended": { + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt" + }, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": true, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "uname": null, + "gname": null, + "size": 560, + "mtime": "2018-06-19T00:03:11.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "size": 560, + "mtime": "2018-06-19T00:03:11.000Z", + "cksum": 13611, + "linkpath": "", + "uname": null, + "gname": null, + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "meta", + "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt\u0000" + ], + [ + "ignoredEntry", + { + "extended": { + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt" + }, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": true, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "uname": null, + "gname": null, + "size": 560, + "mtime": "2018-06-18T23:49:44.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "size": 560, + "mtime": "2018-06-18T23:49:44.000Z", + "cksum": 13602, + "linkpath": "", + "uname": null, + "gname": null, + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "end" + ] +] diff --git a/test/fixtures/parse/trailing-slash-corner-case--filter.json b/test/fixtures/parse/trailing-slash-corner-case--filter.json new file mode 100644 index 00000000..82709536 --- /dev/null +++ b/test/fixtures/parse/trailing-slash-corner-case--filter.json @@ -0,0 +1,161 @@ +[ + [ + "ignoredEntry", + { + "extended": null, + "globalExtended": null, + "type": "Directory", + "meta": false, + "ignore": true, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/", + "mode": 493, + "uid": 501, + "gid": 20, + "uname": null, + "gname": null, + "size": 0, + "mtime": "2018-06-19T00:03:11.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/", + "mode": 493, + "uid": 501, + "gid": 20, + "size": 0, + "mtime": "2018-06-19T00:03:11.000Z", + "cksum": 13612, + "linkpath": "", + "uname": null, + "gname": null, + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "meta", + "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt\u0000" + ], + [ + "ignoredEntry", + { + "extended": { + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt" + }, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": true, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "uname": null, + "gname": null, + "size": 560, + "mtime": "2018-06-19T00:03:11.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "size": 560, + "mtime": "2018-06-19T00:03:11.000Z", + "cksum": 13611, + "linkpath": "", + "uname": null, + "gname": null, + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "meta", + "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt\u0000" + ], + [ + "ignoredEntry", + { + "extended": { + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt" + }, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": true, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "uname": null, + "gname": null, + "size": 560, + "mtime": "2018-06-18T23:49:44.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "size": 560, + "mtime": "2018-06-18T23:49:44.000Z", + "cksum": 13602, + "linkpath": "", + "uname": null, + "gname": null, + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "end" + ] +] diff --git a/test/fixtures/parse/trailing-slash-corner-case--meta-250-filter-strict.json b/test/fixtures/parse/trailing-slash-corner-case--meta-250-filter-strict.json new file mode 100644 index 00000000..82709536 --- /dev/null +++ b/test/fixtures/parse/trailing-slash-corner-case--meta-250-filter-strict.json @@ -0,0 +1,161 @@ +[ + [ + "ignoredEntry", + { + "extended": null, + "globalExtended": null, + "type": "Directory", + "meta": false, + "ignore": true, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/", + "mode": 493, + "uid": 501, + "gid": 20, + "uname": null, + "gname": null, + "size": 0, + "mtime": "2018-06-19T00:03:11.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/", + "mode": 493, + "uid": 501, + "gid": 20, + "size": 0, + "mtime": "2018-06-19T00:03:11.000Z", + "cksum": 13612, + "linkpath": "", + "uname": null, + "gname": null, + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "meta", + "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt\u0000" + ], + [ + "ignoredEntry", + { + "extended": { + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt" + }, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": true, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "uname": null, + "gname": null, + "size": 560, + "mtime": "2018-06-19T00:03:11.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "size": 560, + "mtime": "2018-06-19T00:03:11.000Z", + "cksum": 13611, + "linkpath": "", + "uname": null, + "gname": null, + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "meta", + "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt\u0000" + ], + [ + "ignoredEntry", + { + "extended": { + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt" + }, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": true, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "uname": null, + "gname": null, + "size": 560, + "mtime": "2018-06-18T23:49:44.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "size": 560, + "mtime": "2018-06-18T23:49:44.000Z", + "cksum": 13602, + "linkpath": "", + "uname": null, + "gname": null, + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "end" + ] +] diff --git a/test/fixtures/parse/trailing-slash-corner-case--meta-250-filter.json b/test/fixtures/parse/trailing-slash-corner-case--meta-250-filter.json new file mode 100644 index 00000000..82709536 --- /dev/null +++ b/test/fixtures/parse/trailing-slash-corner-case--meta-250-filter.json @@ -0,0 +1,161 @@ +[ + [ + "ignoredEntry", + { + "extended": null, + "globalExtended": null, + "type": "Directory", + "meta": false, + "ignore": true, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/", + "mode": 493, + "uid": 501, + "gid": 20, + "uname": null, + "gname": null, + "size": 0, + "mtime": "2018-06-19T00:03:11.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/", + "mode": 493, + "uid": 501, + "gid": 20, + "size": 0, + "mtime": "2018-06-19T00:03:11.000Z", + "cksum": 13612, + "linkpath": "", + "uname": null, + "gname": null, + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "meta", + "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt\u0000" + ], + [ + "ignoredEntry", + { + "extended": { + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt" + }, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": true, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "uname": null, + "gname": null, + "size": 560, + "mtime": "2018-06-19T00:03:11.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "size": 560, + "mtime": "2018-06-19T00:03:11.000Z", + "cksum": 13611, + "linkpath": "", + "uname": null, + "gname": null, + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "meta", + "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt\u0000" + ], + [ + "ignoredEntry", + { + "extended": { + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt" + }, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": true, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "uname": null, + "gname": null, + "size": 560, + "mtime": "2018-06-18T23:49:44.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "size": 560, + "mtime": "2018-06-18T23:49:44.000Z", + "cksum": 13602, + "linkpath": "", + "uname": null, + "gname": null, + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "end" + ] +] diff --git a/test/fixtures/parse/trailing-slash-corner-case--meta-250-strict.json b/test/fixtures/parse/trailing-slash-corner-case--meta-250-strict.json new file mode 100644 index 00000000..5b157bdb --- /dev/null +++ b/test/fixtures/parse/trailing-slash-corner-case--meta-250-strict.json @@ -0,0 +1,161 @@ +[ + [ + "entry", + { + "extended": null, + "globalExtended": null, + "type": "Directory", + "meta": false, + "ignore": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/", + "mode": 493, + "uid": 501, + "gid": 20, + "uname": null, + "gname": null, + "size": 0, + "mtime": "2018-06-19T00:03:11.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/", + "mode": 493, + "uid": 501, + "gid": 20, + "size": 0, + "mtime": "2018-06-19T00:03:11.000Z", + "cksum": 13612, + "linkpath": "", + "uname": null, + "gname": null, + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "meta", + "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt\u0000" + ], + [ + "entry", + { + "extended": { + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt" + }, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "uname": null, + "gname": null, + "size": 560, + "mtime": "2018-06-19T00:03:11.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "size": 560, + "mtime": "2018-06-19T00:03:11.000Z", + "cksum": 13611, + "linkpath": "", + "uname": null, + "gname": null, + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "meta", + "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt\u0000" + ], + [ + "entry", + { + "extended": { + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt" + }, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "uname": null, + "gname": null, + "size": 560, + "mtime": "2018-06-18T23:49:44.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "size": 560, + "mtime": "2018-06-18T23:49:44.000Z", + "cksum": 13602, + "linkpath": "", + "uname": null, + "gname": null, + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "end" + ] +] diff --git a/test/fixtures/parse/trailing-slash-corner-case--meta-250.json b/test/fixtures/parse/trailing-slash-corner-case--meta-250.json new file mode 100644 index 00000000..5b157bdb --- /dev/null +++ b/test/fixtures/parse/trailing-slash-corner-case--meta-250.json @@ -0,0 +1,161 @@ +[ + [ + "entry", + { + "extended": null, + "globalExtended": null, + "type": "Directory", + "meta": false, + "ignore": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/", + "mode": 493, + "uid": 501, + "gid": 20, + "uname": null, + "gname": null, + "size": 0, + "mtime": "2018-06-19T00:03:11.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/", + "mode": 493, + "uid": 501, + "gid": 20, + "size": 0, + "mtime": "2018-06-19T00:03:11.000Z", + "cksum": 13612, + "linkpath": "", + "uname": null, + "gname": null, + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "meta", + "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt\u0000" + ], + [ + "entry", + { + "extended": { + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt" + }, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "uname": null, + "gname": null, + "size": 560, + "mtime": "2018-06-19T00:03:11.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "size": 560, + "mtime": "2018-06-19T00:03:11.000Z", + "cksum": 13611, + "linkpath": "", + "uname": null, + "gname": null, + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "meta", + "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt\u0000" + ], + [ + "entry", + { + "extended": { + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt" + }, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "uname": null, + "gname": null, + "size": 560, + "mtime": "2018-06-18T23:49:44.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "size": 560, + "mtime": "2018-06-18T23:49:44.000Z", + "cksum": 13602, + "linkpath": "", + "uname": null, + "gname": null, + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "end" + ] +] diff --git a/test/fixtures/parse/trailing-slash-corner-case--strict.json b/test/fixtures/parse/trailing-slash-corner-case--strict.json new file mode 100644 index 00000000..5b157bdb --- /dev/null +++ b/test/fixtures/parse/trailing-slash-corner-case--strict.json @@ -0,0 +1,161 @@ +[ + [ + "entry", + { + "extended": null, + "globalExtended": null, + "type": "Directory", + "meta": false, + "ignore": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/", + "mode": 493, + "uid": 501, + "gid": 20, + "uname": null, + "gname": null, + "size": 0, + "mtime": "2018-06-19T00:03:11.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/", + "mode": 493, + "uid": 501, + "gid": 20, + "size": 0, + "mtime": "2018-06-19T00:03:11.000Z", + "cksum": 13612, + "linkpath": "", + "uname": null, + "gname": null, + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "meta", + "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt\u0000" + ], + [ + "entry", + { + "extended": { + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt" + }, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "uname": null, + "gname": null, + "size": 560, + "mtime": "2018-06-19T00:03:11.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "size": 560, + "mtime": "2018-06-19T00:03:11.000Z", + "cksum": 13611, + "linkpath": "", + "uname": null, + "gname": null, + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "meta", + "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt\u0000" + ], + [ + "entry", + { + "extended": { + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt" + }, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "uname": null, + "gname": null, + "size": 560, + "mtime": "2018-06-18T23:49:44.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "size": 560, + "mtime": "2018-06-18T23:49:44.000Z", + "cksum": 13602, + "linkpath": "", + "uname": null, + "gname": null, + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "end" + ] +] diff --git a/test/fixtures/parse/trailing-slash-corner-case.json b/test/fixtures/parse/trailing-slash-corner-case.json new file mode 100644 index 00000000..5b157bdb --- /dev/null +++ b/test/fixtures/parse/trailing-slash-corner-case.json @@ -0,0 +1,161 @@ +[ + [ + "entry", + { + "extended": null, + "globalExtended": null, + "type": "Directory", + "meta": false, + "ignore": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/", + "mode": 493, + "uid": 501, + "gid": 20, + "uname": null, + "gname": null, + "size": 0, + "mtime": "2018-06-19T00:03:11.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/", + "mode": 493, + "uid": 501, + "gid": 20, + "size": 0, + "mtime": "2018-06-19T00:03:11.000Z", + "cksum": 13612, + "linkpath": "", + "uname": null, + "gname": null, + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "meta", + "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt\u0000" + ], + [ + "entry", + { + "extended": { + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt" + }, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "uname": null, + "gname": null, + "size": 560, + "mtime": "2018-06-19T00:03:11.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/a-truly-unlucky-file-beyond-130-byte-path-length.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "size": 560, + "mtime": "2018-06-19T00:03:11.000Z", + "cksum": 13611, + "linkpath": "", + "uname": null, + "gname": null, + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "meta", + "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt\u0000" + ], + [ + "entry", + { + "extended": { + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt" + }, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "uname": null, + "gname": null, + "size": 560, + "mtime": "2018-06-18T23:49:44.000Z", + "atime": null, + "ctime": null, + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "99-byte-dirname-ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc/some-unlucky-file.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "size": 560, + "mtime": "2018-06-18T23:49:44.000Z", + "cksum": 13602, + "linkpath": "", + "uname": null, + "gname": null, + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "end" + ] +] diff --git a/test/fixtures/parse/utf8--meta-250-filter-strict.json b/test/fixtures/parse/utf8--meta-250-filter-strict.json new file mode 100644 index 00000000..2657a354 --- /dev/null +++ b/test/fixtures/parse/utf8--meta-250-filter-strict.json @@ -0,0 +1,191 @@ +[ + [ + "meta", + "15 path=Ω.txt\n20 ctime=1491843102\n20 atime=1491843758\n23 SCHILY.dev=16777220\n22 SCHILY.ino=9836217\n18 SCHILY.nlink=1\n" + ], + [ + "ignoredEntry", + { + "extended": { + "atime": "2017-04-10T17:02:38.000Z", + "charset": null, + "comment": null, + "ctime": "2017-04-10T16:51:42.000Z", + "gid": null, + "gname": null, + "linkpath": null, + "mtime": null, + "path": "Ω.txt", + "size": null, + "uid": null, + "uname": null, + "dev": 16777220, + "ino": 9836217, + "nlink": 1, + "global": false + }, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": true, + "path": "Ω.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "uname": "isaacs", + "gname": "staff", + "size": 2, + "mtime": "2017-04-10T16:51:42.000Z", + "atime": "2017-04-10T17:02:38.000Z", + "ctime": "2017-04-10T16:51:42.000Z", + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "Ω.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "size": 2, + "mtime": "2017-04-10T16:51:42.000Z", + "cksum": 5688, + "linkpath": "", + "uname": "isaacs", + "gname": "staff", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "meta", + "17 path=🌟.txt\n20 ctime=1491843956\n20 atime=1491843993\n23 SCHILY.dev=16777220\n22 SCHILY.ino=9836716\n18 SCHILY.nlink=1\n" + ], + [ + "ignoredEntry", + { + "extended": { + "atime": "2017-04-10T17:06:33.000Z", + "charset": null, + "comment": null, + "ctime": "2017-04-10T17:05:56.000Z", + "gid": null, + "gname": null, + "linkpath": null, + "mtime": null, + "path": "🌟.txt", + "size": null, + "uid": null, + "uname": null, + "dev": 16777220, + "ino": 9836716, + "nlink": 1, + "global": false + }, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": true, + "path": "🌟.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "uname": "isaacs", + "gname": "staff", + "size": 106, + "mtime": "2017-04-10T17:05:55.000Z", + "atime": "2017-04-10T17:06:33.000Z", + "ctime": "2017-04-10T17:05:56.000Z", + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "🌟.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "size": 106, + "mtime": "2017-04-10T17:05:55.000Z", + "cksum": 6023, + "linkpath": "", + "uname": "isaacs", + "gname": "staff", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "meta", + "71 path=long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/Ω.txt\n20 ctime=1491843527\n20 atime=1491843758\n23 SCHILY.dev=16777220\n22 SCHILY.ino=9836396\n18 SCHILY.nlink=1\n" + ], + [ + "ignoredEntry", + { + "extended": { + "atime": "2017-04-10T17:02:38.000Z", + "charset": null, + "comment": null, + "ctime": "2017-04-10T16:58:47.000Z", + "gid": null, + "gname": null, + "linkpath": null, + "mtime": null, + "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/Ω.txt", + "size": null, + "uid": null, + "uname": null, + "dev": 16777220, + "ino": 9836396, + "nlink": 1, + "global": false + }, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": true, + "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/Ω.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "uname": "isaacs", + "gname": "staff", + "size": 2, + "mtime": "2017-04-10T16:58:47.000Z", + "atime": "2017-04-10T17:02:38.000Z", + "ctime": "2017-04-10T16:58:47.000Z", + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/Ω.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "size": 2, + "mtime": "2017-04-10T16:58:47.000Z", + "cksum": 9990, + "linkpath": "", + "uname": "isaacs", + "gname": "staff", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "end" + ] +] diff --git a/test/fixtures/parse/utf8--meta-250-filter.json b/test/fixtures/parse/utf8--meta-250-filter.json new file mode 100644 index 00000000..2657a354 --- /dev/null +++ b/test/fixtures/parse/utf8--meta-250-filter.json @@ -0,0 +1,191 @@ +[ + [ + "meta", + "15 path=Ω.txt\n20 ctime=1491843102\n20 atime=1491843758\n23 SCHILY.dev=16777220\n22 SCHILY.ino=9836217\n18 SCHILY.nlink=1\n" + ], + [ + "ignoredEntry", + { + "extended": { + "atime": "2017-04-10T17:02:38.000Z", + "charset": null, + "comment": null, + "ctime": "2017-04-10T16:51:42.000Z", + "gid": null, + "gname": null, + "linkpath": null, + "mtime": null, + "path": "Ω.txt", + "size": null, + "uid": null, + "uname": null, + "dev": 16777220, + "ino": 9836217, + "nlink": 1, + "global": false + }, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": true, + "path": "Ω.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "uname": "isaacs", + "gname": "staff", + "size": 2, + "mtime": "2017-04-10T16:51:42.000Z", + "atime": "2017-04-10T17:02:38.000Z", + "ctime": "2017-04-10T16:51:42.000Z", + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "Ω.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "size": 2, + "mtime": "2017-04-10T16:51:42.000Z", + "cksum": 5688, + "linkpath": "", + "uname": "isaacs", + "gname": "staff", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "meta", + "17 path=🌟.txt\n20 ctime=1491843956\n20 atime=1491843993\n23 SCHILY.dev=16777220\n22 SCHILY.ino=9836716\n18 SCHILY.nlink=1\n" + ], + [ + "ignoredEntry", + { + "extended": { + "atime": "2017-04-10T17:06:33.000Z", + "charset": null, + "comment": null, + "ctime": "2017-04-10T17:05:56.000Z", + "gid": null, + "gname": null, + "linkpath": null, + "mtime": null, + "path": "🌟.txt", + "size": null, + "uid": null, + "uname": null, + "dev": 16777220, + "ino": 9836716, + "nlink": 1, + "global": false + }, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": true, + "path": "🌟.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "uname": "isaacs", + "gname": "staff", + "size": 106, + "mtime": "2017-04-10T17:05:55.000Z", + "atime": "2017-04-10T17:06:33.000Z", + "ctime": "2017-04-10T17:05:56.000Z", + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "🌟.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "size": 106, + "mtime": "2017-04-10T17:05:55.000Z", + "cksum": 6023, + "linkpath": "", + "uname": "isaacs", + "gname": "staff", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "meta", + "71 path=long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/Ω.txt\n20 ctime=1491843527\n20 atime=1491843758\n23 SCHILY.dev=16777220\n22 SCHILY.ino=9836396\n18 SCHILY.nlink=1\n" + ], + [ + "ignoredEntry", + { + "extended": { + "atime": "2017-04-10T17:02:38.000Z", + "charset": null, + "comment": null, + "ctime": "2017-04-10T16:58:47.000Z", + "gid": null, + "gname": null, + "linkpath": null, + "mtime": null, + "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/Ω.txt", + "size": null, + "uid": null, + "uname": null, + "dev": 16777220, + "ino": 9836396, + "nlink": 1, + "global": false + }, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": true, + "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/Ω.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "uname": "isaacs", + "gname": "staff", + "size": 2, + "mtime": "2017-04-10T16:58:47.000Z", + "atime": "2017-04-10T17:02:38.000Z", + "ctime": "2017-04-10T16:58:47.000Z", + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/Ω.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "size": 2, + "mtime": "2017-04-10T16:58:47.000Z", + "cksum": 9990, + "linkpath": "", + "uname": "isaacs", + "gname": "staff", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "end" + ] +] diff --git a/test/fixtures/parse/utf8--meta-250-strict.json b/test/fixtures/parse/utf8--meta-250-strict.json new file mode 100644 index 00000000..cff8acca --- /dev/null +++ b/test/fixtures/parse/utf8--meta-250-strict.json @@ -0,0 +1,191 @@ +[ + [ + "meta", + "15 path=Ω.txt\n20 ctime=1491843102\n20 atime=1491843758\n23 SCHILY.dev=16777220\n22 SCHILY.ino=9836217\n18 SCHILY.nlink=1\n" + ], + [ + "entry", + { + "extended": { + "atime": "2017-04-10T17:02:38.000Z", + "charset": null, + "comment": null, + "ctime": "2017-04-10T16:51:42.000Z", + "gid": null, + "gname": null, + "linkpath": null, + "mtime": null, + "path": "Ω.txt", + "size": null, + "uid": null, + "uname": null, + "dev": 16777220, + "ino": 9836217, + "nlink": 1, + "global": false + }, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": false, + "path": "Ω.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "uname": "isaacs", + "gname": "staff", + "size": 2, + "mtime": "2017-04-10T16:51:42.000Z", + "atime": "2017-04-10T17:02:38.000Z", + "ctime": "2017-04-10T16:51:42.000Z", + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "Ω.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "size": 2, + "mtime": "2017-04-10T16:51:42.000Z", + "cksum": 5688, + "linkpath": "", + "uname": "isaacs", + "gname": "staff", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "meta", + "17 path=🌟.txt\n20 ctime=1491843956\n20 atime=1491843993\n23 SCHILY.dev=16777220\n22 SCHILY.ino=9836716\n18 SCHILY.nlink=1\n" + ], + [ + "entry", + { + "extended": { + "atime": "2017-04-10T17:06:33.000Z", + "charset": null, + "comment": null, + "ctime": "2017-04-10T17:05:56.000Z", + "gid": null, + "gname": null, + "linkpath": null, + "mtime": null, + "path": "🌟.txt", + "size": null, + "uid": null, + "uname": null, + "dev": 16777220, + "ino": 9836716, + "nlink": 1, + "global": false + }, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": false, + "path": "🌟.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "uname": "isaacs", + "gname": "staff", + "size": 106, + "mtime": "2017-04-10T17:05:55.000Z", + "atime": "2017-04-10T17:06:33.000Z", + "ctime": "2017-04-10T17:05:56.000Z", + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "🌟.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "size": 106, + "mtime": "2017-04-10T17:05:55.000Z", + "cksum": 6023, + "linkpath": "", + "uname": "isaacs", + "gname": "staff", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "meta", + "71 path=long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/Ω.txt\n20 ctime=1491843527\n20 atime=1491843758\n23 SCHILY.dev=16777220\n22 SCHILY.ino=9836396\n18 SCHILY.nlink=1\n" + ], + [ + "entry", + { + "extended": { + "atime": "2017-04-10T17:02:38.000Z", + "charset": null, + "comment": null, + "ctime": "2017-04-10T16:58:47.000Z", + "gid": null, + "gname": null, + "linkpath": null, + "mtime": null, + "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/Ω.txt", + "size": null, + "uid": null, + "uname": null, + "dev": 16777220, + "ino": 9836396, + "nlink": 1, + "global": false + }, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": false, + "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/Ω.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "uname": "isaacs", + "gname": "staff", + "size": 2, + "mtime": "2017-04-10T16:58:47.000Z", + "atime": "2017-04-10T17:02:38.000Z", + "ctime": "2017-04-10T16:58:47.000Z", + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/Ω.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "size": 2, + "mtime": "2017-04-10T16:58:47.000Z", + "cksum": 9990, + "linkpath": "", + "uname": "isaacs", + "gname": "staff", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "end" + ] +] diff --git a/test/fixtures/parse/utf8--meta-250.json b/test/fixtures/parse/utf8--meta-250.json new file mode 100644 index 00000000..cff8acca --- /dev/null +++ b/test/fixtures/parse/utf8--meta-250.json @@ -0,0 +1,191 @@ +[ + [ + "meta", + "15 path=Ω.txt\n20 ctime=1491843102\n20 atime=1491843758\n23 SCHILY.dev=16777220\n22 SCHILY.ino=9836217\n18 SCHILY.nlink=1\n" + ], + [ + "entry", + { + "extended": { + "atime": "2017-04-10T17:02:38.000Z", + "charset": null, + "comment": null, + "ctime": "2017-04-10T16:51:42.000Z", + "gid": null, + "gname": null, + "linkpath": null, + "mtime": null, + "path": "Ω.txt", + "size": null, + "uid": null, + "uname": null, + "dev": 16777220, + "ino": 9836217, + "nlink": 1, + "global": false + }, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": false, + "path": "Ω.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "uname": "isaacs", + "gname": "staff", + "size": 2, + "mtime": "2017-04-10T16:51:42.000Z", + "atime": "2017-04-10T17:02:38.000Z", + "ctime": "2017-04-10T16:51:42.000Z", + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "Ω.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "size": 2, + "mtime": "2017-04-10T16:51:42.000Z", + "cksum": 5688, + "linkpath": "", + "uname": "isaacs", + "gname": "staff", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "meta", + "17 path=🌟.txt\n20 ctime=1491843956\n20 atime=1491843993\n23 SCHILY.dev=16777220\n22 SCHILY.ino=9836716\n18 SCHILY.nlink=1\n" + ], + [ + "entry", + { + "extended": { + "atime": "2017-04-10T17:06:33.000Z", + "charset": null, + "comment": null, + "ctime": "2017-04-10T17:05:56.000Z", + "gid": null, + "gname": null, + "linkpath": null, + "mtime": null, + "path": "🌟.txt", + "size": null, + "uid": null, + "uname": null, + "dev": 16777220, + "ino": 9836716, + "nlink": 1, + "global": false + }, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": false, + "path": "🌟.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "uname": "isaacs", + "gname": "staff", + "size": 106, + "mtime": "2017-04-10T17:05:55.000Z", + "atime": "2017-04-10T17:06:33.000Z", + "ctime": "2017-04-10T17:05:56.000Z", + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "🌟.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "size": 106, + "mtime": "2017-04-10T17:05:55.000Z", + "cksum": 6023, + "linkpath": "", + "uname": "isaacs", + "gname": "staff", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "meta", + "71 path=long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/Ω.txt\n20 ctime=1491843527\n20 atime=1491843758\n23 SCHILY.dev=16777220\n22 SCHILY.ino=9836396\n18 SCHILY.nlink=1\n" + ], + [ + "entry", + { + "extended": { + "atime": "2017-04-10T17:02:38.000Z", + "charset": null, + "comment": null, + "ctime": "2017-04-10T16:58:47.000Z", + "gid": null, + "gname": null, + "linkpath": null, + "mtime": null, + "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/Ω.txt", + "size": null, + "uid": null, + "uname": null, + "dev": 16777220, + "ino": 9836396, + "nlink": 1, + "global": false + }, + "globalExtended": null, + "type": "File", + "meta": false, + "ignore": false, + "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/Ω.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "uname": "isaacs", + "gname": "staff", + "size": 2, + "mtime": "2017-04-10T16:58:47.000Z", + "atime": "2017-04-10T17:02:38.000Z", + "ctime": "2017-04-10T16:58:47.000Z", + "linkpath": "", + "header": { + "cksumValid": true, + "needPax": false, + "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/Ω.txt", + "mode": 420, + "uid": 501, + "gid": 20, + "size": 2, + "mtime": "2017-04-10T16:58:47.000Z", + "cksum": 9990, + "linkpath": "", + "uname": "isaacs", + "gname": "staff", + "devmaj": 0, + "devmin": 0, + "atime": null, + "ctime": null + } + } + ], + [ + "nullBlock" + ], + [ + "nullBlock" + ], + [ + "end" + ] +] diff --git a/test/fixtures/parse/utf8--meta-50-filter-strict.json b/test/fixtures/parse/utf8--meta-50-filter-strict.json deleted file mode 100644 index 6e3baad8..00000000 --- a/test/fixtures/parse/utf8--meta-50-filter-strict.json +++ /dev/null @@ -1,245 +0,0 @@ -[ - [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "ExtendedHeader", - "meta": true, - "ignore": true, - "path": "PaxHeader/Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 118, - "mtime": "2017-04-10T16:51:42.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "PaxHeader/Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 118, - "mtime": "2017-04-10T16:51:42.000Z", - "cksum": 6700, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "File", - "meta": false, - "ignore": true, - "path": "Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 2, - "mtime": "2017-04-10T16:51:42.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 2, - "mtime": "2017-04-10T16:51:42.000Z", - "cksum": 5688, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "ExtendedHeader", - "meta": true, - "ignore": true, - "path": "PaxHeader/🌟.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 120, - "mtime": "2017-04-10T17:05:55.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "PaxHeader/🌟.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 120, - "mtime": "2017-04-10T17:05:55.000Z", - "cksum": 7024, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "File", - "meta": false, - "ignore": true, - "path": "🌟.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 106, - "mtime": "2017-04-10T17:05:55.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "🌟.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 106, - "mtime": "2017-04-10T17:05:55.000Z", - "cksum": 6023, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "ExtendedHeader", - "meta": true, - "ignore": true, - "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/PaxHeader/Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 174, - "mtime": "2017-04-10T16:58:47.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/PaxHeader/Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 174, - "mtime": "2017-04-10T16:58:47.000Z", - "cksum": 11002, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "File", - "meta": false, - "ignore": true, - "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 2, - "mtime": "2017-04-10T16:58:47.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 2, - "mtime": "2017-04-10T16:58:47.000Z", - "cksum": 9990, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "nullBlock" - ], - [ - "nullBlock" - ], - [ - "end" - ] -] diff --git a/test/fixtures/parse/utf8--meta-50-filter.json b/test/fixtures/parse/utf8--meta-50-filter.json deleted file mode 100644 index 6e3baad8..00000000 --- a/test/fixtures/parse/utf8--meta-50-filter.json +++ /dev/null @@ -1,245 +0,0 @@ -[ - [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "ExtendedHeader", - "meta": true, - "ignore": true, - "path": "PaxHeader/Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 118, - "mtime": "2017-04-10T16:51:42.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "PaxHeader/Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 118, - "mtime": "2017-04-10T16:51:42.000Z", - "cksum": 6700, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "File", - "meta": false, - "ignore": true, - "path": "Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 2, - "mtime": "2017-04-10T16:51:42.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 2, - "mtime": "2017-04-10T16:51:42.000Z", - "cksum": 5688, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "ExtendedHeader", - "meta": true, - "ignore": true, - "path": "PaxHeader/🌟.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 120, - "mtime": "2017-04-10T17:05:55.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "PaxHeader/🌟.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 120, - "mtime": "2017-04-10T17:05:55.000Z", - "cksum": 7024, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "File", - "meta": false, - "ignore": true, - "path": "🌟.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 106, - "mtime": "2017-04-10T17:05:55.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "🌟.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 106, - "mtime": "2017-04-10T17:05:55.000Z", - "cksum": 6023, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "ExtendedHeader", - "meta": true, - "ignore": true, - "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/PaxHeader/Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 174, - "mtime": "2017-04-10T16:58:47.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/PaxHeader/Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 174, - "mtime": "2017-04-10T16:58:47.000Z", - "cksum": 11002, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "File", - "meta": false, - "ignore": true, - "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 2, - "mtime": "2017-04-10T16:58:47.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 2, - "mtime": "2017-04-10T16:58:47.000Z", - "cksum": 9990, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "nullBlock" - ], - [ - "nullBlock" - ], - [ - "end" - ] -] diff --git a/test/fixtures/parse/utf8--meta-50-strict.json b/test/fixtures/parse/utf8--meta-50-strict.json deleted file mode 100644 index 7b8bf94b..00000000 --- a/test/fixtures/parse/utf8--meta-50-strict.json +++ /dev/null @@ -1,245 +0,0 @@ -[ - [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "ExtendedHeader", - "meta": true, - "ignore": true, - "path": "PaxHeader/Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 118, - "mtime": "2017-04-10T16:51:42.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "PaxHeader/Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 118, - "mtime": "2017-04-10T16:51:42.000Z", - "cksum": 6700, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "entry", - { - "extended": null, - "globalExtended": null, - "type": "File", - "meta": false, - "ignore": false, - "path": "Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 2, - "mtime": "2017-04-10T16:51:42.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 2, - "mtime": "2017-04-10T16:51:42.000Z", - "cksum": 5688, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "ExtendedHeader", - "meta": true, - "ignore": true, - "path": "PaxHeader/🌟.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 120, - "mtime": "2017-04-10T17:05:55.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "PaxHeader/🌟.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 120, - "mtime": "2017-04-10T17:05:55.000Z", - "cksum": 7024, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "entry", - { - "extended": null, - "globalExtended": null, - "type": "File", - "meta": false, - "ignore": false, - "path": "🌟.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 106, - "mtime": "2017-04-10T17:05:55.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "🌟.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 106, - "mtime": "2017-04-10T17:05:55.000Z", - "cksum": 6023, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "ExtendedHeader", - "meta": true, - "ignore": true, - "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/PaxHeader/Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 174, - "mtime": "2017-04-10T16:58:47.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/PaxHeader/Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 174, - "mtime": "2017-04-10T16:58:47.000Z", - "cksum": 11002, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "entry", - { - "extended": null, - "globalExtended": null, - "type": "File", - "meta": false, - "ignore": false, - "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 2, - "mtime": "2017-04-10T16:58:47.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 2, - "mtime": "2017-04-10T16:58:47.000Z", - "cksum": 9990, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "nullBlock" - ], - [ - "nullBlock" - ], - [ - "end" - ] -] diff --git a/test/fixtures/parse/utf8--meta-50.json b/test/fixtures/parse/utf8--meta-50.json deleted file mode 100644 index 7b8bf94b..00000000 --- a/test/fixtures/parse/utf8--meta-50.json +++ /dev/null @@ -1,245 +0,0 @@ -[ - [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "ExtendedHeader", - "meta": true, - "ignore": true, - "path": "PaxHeader/Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 118, - "mtime": "2017-04-10T16:51:42.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "PaxHeader/Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 118, - "mtime": "2017-04-10T16:51:42.000Z", - "cksum": 6700, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "entry", - { - "extended": null, - "globalExtended": null, - "type": "File", - "meta": false, - "ignore": false, - "path": "Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 2, - "mtime": "2017-04-10T16:51:42.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 2, - "mtime": "2017-04-10T16:51:42.000Z", - "cksum": 5688, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "ExtendedHeader", - "meta": true, - "ignore": true, - "path": "PaxHeader/🌟.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 120, - "mtime": "2017-04-10T17:05:55.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "PaxHeader/🌟.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 120, - "mtime": "2017-04-10T17:05:55.000Z", - "cksum": 7024, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "entry", - { - "extended": null, - "globalExtended": null, - "type": "File", - "meta": false, - "ignore": false, - "path": "🌟.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 106, - "mtime": "2017-04-10T17:05:55.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "🌟.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 106, - "mtime": "2017-04-10T17:05:55.000Z", - "cksum": 6023, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "ignoredEntry", - { - "extended": null, - "globalExtended": null, - "type": "ExtendedHeader", - "meta": true, - "ignore": true, - "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/PaxHeader/Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 174, - "mtime": "2017-04-10T16:58:47.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/PaxHeader/Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 174, - "mtime": "2017-04-10T16:58:47.000Z", - "cksum": 11002, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "entry", - { - "extended": null, - "globalExtended": null, - "type": "File", - "meta": false, - "ignore": false, - "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "uname": "isaacs", - "gname": "staff", - "size": 2, - "mtime": "2017-04-10T16:58:47.000Z", - "atime": null, - "ctime": null, - "linkpath": "", - "header": { - "cksumValid": true, - "needPax": false, - "path": "long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/Ω.txt", - "mode": 420, - "uid": 501, - "gid": 20, - "size": 2, - "mtime": "2017-04-10T16:58:47.000Z", - "cksum": 9990, - "linkpath": "", - "uname": "isaacs", - "gname": "staff", - "devmaj": 0, - "devmin": 0, - "atime": null, - "ctime": null - } - } - ], - [ - "nullBlock" - ], - [ - "nullBlock" - ], - [ - "end" - ] -] diff --git a/test/fixtures/parses.tar b/test/fixtures/parses.tar index f0f71756..4d76160f 100644 Binary files a/test/fixtures/parses.tar and b/test/fixtures/parses.tar differ diff --git a/test/fixtures/tars/links-strip.tar b/test/fixtures/tars/links-strip.tar new file mode 100644 index 00000000..e23e26f7 Binary files /dev/null and b/test/fixtures/tars/links-strip.tar differ diff --git a/test/fixtures/tars/trailing-slash-corner-case.tar b/test/fixtures/tars/trailing-slash-corner-case.tar new file mode 100644 index 00000000..5f262130 Binary files /dev/null and b/test/fixtures/tars/trailing-slash-corner-case.tar differ diff --git a/test/fixtures/test.js b/test/fixtures/test.js new file mode 100644 index 00000000..e1a34da7 --- /dev/null +++ b/test/fixtures/test.js @@ -0,0 +1,20 @@ +const platform = process.platform === 'win32' ? 'win32' : 'posix' +const {spawn} = require('child_process') +const c = spawn(process.execPath, [ + process.env.npm_execpath, + 'run', + `test:${platform}`, + '--', + ...process.argv.slice(2), +], { + stdio: 'inherit', +}) +c.on('close', (code, signal) => { + process.exitCode = code + if (signal) { + process.kill(process.pid, signal) + setTimeout(() => {}, 200) + } +}) +process.on('SIGTERM', () => c.kill('SIGTERM')) +process.on('SIGINT', () => c.kill('SIGINT')) diff --git a/test/header.js b/test/header.js index ae4ece36..d20e54ba 100644 --- a/test/header.js +++ b/test/header.js @@ -557,3 +557,59 @@ t.test('dir with long body', t => { t.equal(h.size, 0) t.end() }) + +t.test('null block, global extended header', t => { + const h = new Header(Buffer.alloc(512), 0, { + undef: undefined, + blerg: 'bloo', + }, { + path: '/global.path', + foo: 'global foo' + }) + t.match(h, { + cksumValid: false, + needPax: false, + path: '', + type: 'File', + mode: null, + uid: null, + gid: null, + size: null, + mtime: null, + cksum: null, + linkpath: '', + uname: null, + gname: null, + devmaj: 0, + devmin: 0, + atime: null, + ctime: null, + nullBlock: true, + blerg: 'bloo', + foo: 'global foo', + }) + t.end() +}) + +t.test('gnutar-generated 10gb file size', t => { + const b = Buffer.from( + '313067622e696d67000000000000000000000000000000000000000000000000' + + '0000000000000000000000000000000000000000000000000000000000000000' + + '0000000000000000000000000000000000000000000000000000000000000000' + + '0000000030303030363634003030303137353000303030313735300080000000' + + '0000000280000000313334373434303132303500303131313437002030000000' + + '0000000000000000000000000000000000000000000000000000000000000000' + + '0000000000000000000000000000000000000000000000000000000000000000' + + '0000000000000000000000000000000000000000000000000000000000000000' + + '0075737461722020006973616163730000000000000000000000000000000000' + + '0000000000000000006973616163730000000000000000000000000000000000' + + '0000000000000000000000000000000000000000000000000000000000000000' + + '0000000000000000000000000000000000000000000000000000000000000000' + + '0000000000000000000000000000000000000000000000000000000000000000' + + '0000000000000000000000000000000000000000000000000000000000000000' + + '0000000000000000000000000000000000000000000000000000000000000000' + + '0000000000000000000000000000000000000000000000000000000000000000', 'hex') + const h = new Header(b) + t.equal(h.size, 1024 * 1024 * 1024 * 10, 'should be 10gb file') + t.end() +}) diff --git a/test/index.js b/test/index.js new file mode 100644 index 00000000..3be46922 --- /dev/null +++ b/test/index.js @@ -0,0 +1,73 @@ +const t = require('tap') +const tar = require('../') +t.match(tar, { + create: Function, + c: Function, + replace: Function, + r: Function, + list: Function, + t: Function, + update: Function, + u: Function, + extract: Function, + x: Function, + Pack: Function, + Unpack: Function, + Parse: Function, + ReadEntry: Function, + WriteEntry: Function, + Header: Function, + Pax: Function, + types: { + name: new Map([ + ['0', 'File'], + ['', 'OldFile'], + ['1', 'Link'], + ['2', 'SymbolicLink'], + ['3', 'CharacterDevice'], + ['4', 'BlockDevice'], + ['5', 'Directory'], + ['6', 'FIFO'], + ['7', 'ContiguousFile'], + ['g', 'GlobalExtendedHeader'], + ['x', 'ExtendedHeader'], + ['A', 'SolarisACL'], + ['D', 'GNUDumpDir'], + ['I', 'Inode'], + ['K', 'NextFileHasLongLinkpath'], + ['L', 'NextFileHasLongPath'], + ['M', 'ContinuationFile'], + ['N', 'OldGnuLongPath'], + ['S', 'SparseFile'], + ['V', 'TapeVolumeHeader'], + ['X', 'OldExtendedHeader'], + ]), + code: new Map([ + ['File', '0'], + ['OldFile', ''], + ['Link', '1'], + ['SymbolicLink', '2'], + ['CharacterDevice', '3'], + ['BlockDevice', '4'], + ['Directory', '5'], + ['FIFO', '6'], + ['ContiguousFile', '7'], + ['GlobalExtendedHeader', 'g'], + ['ExtendedHeader', 'x'], + ['SolarisACL', 'A'], + ['GNUDumpDir', 'D'], + ['Inode', 'I'], + ['NextFileHasLongLinkpath', 'K'], + ['NextFileHasLongPath', 'L'], + ['ContinuationFile', 'M'], + ['OldGnuLongPath', 'N'], + ['SparseFile', 'S'], + ['TapeVolumeHeader', 'V'], + ['OldExtendedHeader', 'X'], + ]), + } +}) +t.match(tar.Pack.Sync, Function) +t.match(tar.WriteEntry.Sync, Function) +t.match(tar.WriteEntry.Tar, Function) +t.match(tar.Pax.parse, Function) diff --git a/test/large-numbers.js b/test/large-numbers.js index 0e23d260..e323611c 100644 --- a/test/large-numbers.js +++ b/test/large-numbers.js @@ -7,29 +7,56 @@ const t = require('tap') t.test('parse', t => { const cases = new Map([ - ['ffffffffffffffffffffff20', -1], - ['800000000000100000000020', 68719476736], - ['fffffffffffffffe1ecc8020', -31536000], - ['fffffffffffffff000000020', -268435456], - ['800000010203040506070020', 72623859790382850], - ['ffffffffffffffffffffff00', -1], - ['800000000000100000000000', 68719476736], - ['fffffffffffffffe1ecc8000', -31536000], - ['fffffffffffffff000000000', -268435456], - ['800000010203040506070000', 72623859790382850] + ['ffffffffffffffffffffffff', -1], + ['800000000000100000000020', 17592186044448], + ['fffffffffffffffe1ecc8020', -8073215968], + ['fffffffffffffff000000020', -68719476704], + ['80000000001fffffffffffff', 9007199254740991], // MAX_SAFE_INTEGER + ['ffffffffffe0000000000001', -9007199254740991], // MIN_SAFE_INTEGER + ['800000000000100000000000', 17592186044416], + ['fffffffffffffffe1ecc8000', -8073216000], + ['fffffffffffffff000000000', -68719476736], + ['800000000000000353b66200', 14289363456] ]) t.plan(cases.size) cases.forEach((value, hex) => t.equal(parse(Buffer.from(hex, 'hex')), value)) }) +t.test('parse out of range', t => { + const cases = [ + '800000030000000000000000', + '800000000020000000000000', // MAX_SAFE_INTEGER + 1 + 'ffffffffffe0000000000000', // MIN_SAFE_INTEGER - 1 + 'fffffffffdd0000000000000', + ] + t.plan(cases.length) + cases.forEach((hex) => + t.throws(_ => parse(Buffer.from(hex, 'hex')), + TypeError('parsed number outside of javascript safe integer range'))) +}) + +t.test('parse invalid base256 encoding', t => { + const cases = [ + '313233343536373131', // octal encoded + '700000030000000000000000', // does not start with 0x80 or 0xff + ] + t.plan(cases.length) + cases.forEach((hex) => + t.throws(_ => parse(Buffer.from(hex, 'hex')), + TypeError('invalid base256 encoding'))) +}) + t.test('encode', t => { const cases = new Map([ - ['ffffffffffffffffffffff20', -1], - ['800000000000100000000020', 68719476736], - ['fffffffffffffffe1ecc8020', -31536000], - ['fffffffffffffff000000020', -268435456], - ['800000010203040506070020', 72623859790382850] + ['ffffffffffffffffffffffff', -1], + ['800000000000100000000020', 17592186044448], + ['800000000000100000000000', 17592186044416], + ['fffffffffffffffe1ecc8020', -8073215968], + ['fffffffffffffff000000020', -68719476704], + ['fffffffffffffff000000000', -68719476736], // Allows us to test the case where there's a trailing 00 + ['80000000001fffffffffffff', 9007199254740991], // MAX_SAFE_INTEGER + ['ffffffffffe0000000000001', -9007199254740991] // MIN_SAFE_INTEGER ]) t.plan(2) t.test('alloc', t => { @@ -43,3 +70,18 @@ t.test('encode', t => { t.equal(encode(value, Buffer.allocUnsafe(12)).toString('hex'), hex)) }) }) + +t.test('encode unsafe numbers', t => { + const cases = [ + Number.MAX_VALUE, + Number.MAX_SAFE_INTEGER + 1, + Number.MIN_SAFE_INTEGER - 1, + Number.MIN_VALUE, + ] + + t.plan(cases.length) + cases.forEach((value) => + t.throws(_ => encode(value), + TypeError('cannot encode number outside of javascript safe integer range'))) +}) + diff --git a/test/map.js b/test/map.js new file mode 100644 index 00000000..fcd4e47f --- /dev/null +++ b/test/map.js @@ -0,0 +1,7 @@ +const t = require('tap') +const map = require('../map.js') +t.equal(map('test/index.js'), 'index.js') +t.same(map('test/unpack.js'), ['lib/unpack.js', 'lib/mkdir.js']) +t.same(map('test/load-all.js'), []) +t.equal(map(__filename), 'map.js') +t.equal(map('test/asdf'), 'lib/asdf') diff --git a/test/normalize-windows-path.js b/test/normalize-windows-path.js new file mode 100644 index 00000000..e631c8ac --- /dev/null +++ b/test/normalize-windows-path.js @@ -0,0 +1,27 @@ +const t = require('tap') + +const realPlatform = process.platform +const fakePlatform = realPlatform === 'win32' ? 'posix' : 'win32' +const requireInject = require('require-inject') + +t.test('posix', t => { + if (realPlatform === 'win32') + process.env.TESTING_TAR_FAKE_PLATFORM = fakePlatform + else + delete process.env.TESTING_TAR_FAKE_PLATFORM + const normPath = requireInject('../lib/normalize-windows-path.js') + t.equal(normPath('/some/path/back\\slashes'), '/some/path/back\\slashes') + t.equal(normPath('c:\\foo\\bar'), 'c:\\foo\\bar') + t.end() +}) + +t.test('win32', t => { + if (realPlatform !== 'win32') + process.env.TESTING_TAR_FAKE_PLATFORM = fakePlatform + else + delete process.env.TESTING_TAR_FAKE_PLATFORM + const normPath = requireInject('../lib/normalize-windows-path.js') + t.equal(normPath('/some/path/back\\slashes'), '/some/path/back/slashes') + t.equal(normPath('c:\\foo\\bar'), 'c:/foo/bar') + t.end() +}) diff --git a/test/pack.js b/test/pack.js index ef02a15d..6b06c681 100644 --- a/test/pack.js +++ b/test/pack.js @@ -20,6 +20,8 @@ const EE = require('events').EventEmitter const rimraf = require('rimraf') const mkdirp = require('mkdirp') const ReadEntry = require('../lib/read-entry.js') +const isWindows = process.platform === 'win32' +const normPath = require('../lib/normalize-windows-path.js') const ctime = new Date('2017-05-10T01:03:12.000Z') const atime = new Date('2017-04-17T00:00:00.000Z') @@ -58,7 +60,7 @@ t.test('pack a file', t => { cksumValid: true, needPax: false, path: 'one-byte.txt', - mode: 0o644, + mode: isWindows ? 0o666 : 0o644, size: 1, mtime: mtime, cksum: Number, @@ -102,7 +104,7 @@ t.test('pack a file with a prefix', t => { cksumValid: true, needPax: false, path: 'package/.dotfile', - mode: 0o644, + mode: isWindows ? 0o666 : 0o644, size: 2, mtime: mtime, cksum: Number, @@ -143,7 +145,7 @@ t.test('pack a dir', t => { cksumValid: true, needPax: false, path: 'dir/', - mode: 0o755, + mode: Number, size: 0, mtime: null, cksum: Number, @@ -171,7 +173,7 @@ t.test('pack a dir', t => { cksumValid: true, needPax: false, path: 'dir/x', - mode: 0o644, + mode: Number, size: 0, mtime: mtime, cksum: Number, @@ -211,7 +213,7 @@ t.test('use process cwd if cwd not specified', t => { cksumValid: true, needPax: false, path: 'dir/', - mode: 0o755, + mode: isWindows ? 0o777 : 0o755, size: 0, mtime: mtime, cksum: Number, @@ -239,7 +241,7 @@ t.test('use process cwd if cwd not specified', t => { cksumValid: true, needPax: false, path: 'dir/x', - mode: 0o644, + mode: isWindows ? 0o666 : 0o644, size: 0, mtime: mtime, cksum: Number, @@ -277,7 +279,7 @@ t.test('filter', t => { cksumValid: true, needPax: false, path: 'dir/', - mode: 0o755, + mode: isWindows ? 0o777 : 0o755, size: 0, mtime: mtime, cksum: Number, @@ -323,7 +325,7 @@ t.test('add the same dir twice (exercise cache code)', t => { cksumValid: true, needPax: false, path: 'dir/', - mode: 0o755, + mode: isWindows ? 0o777 : 0o755, size: 0, mtime: mtime, cksum: Number, @@ -571,7 +573,7 @@ t.test('pipe into a slow reader', t => { cksumValid: true, needPax: false, path: 'long-path/', - mode: 0o755, + mode: isWindows ? 0o777 : 0o755, size: 0, mtime: mtime, cksum: Number, @@ -629,7 +631,7 @@ t.test('pipe into a slow gzip reader', t => { cksumValid: true, needPax: false, path: 'long-path/', - mode: 0o755, + mode: isWindows ? 0o777 : 0o755, size: 0, mtime: mtime, cksum: Number, @@ -695,11 +697,12 @@ t.test('warnings', t => { const data = Buffer.concat(out) t.equal(data.length, 2048) t.match(warnings, [[ - /stripping .* from absolute path/, f + /stripping .* from absolute path/, + normPath(f), ]]) t.match(new Header(data), { - path: f.replace(/^(\/|[a-z]:\\\\)/, '') + path: normPath(f).replace(/^(\/|[a-z]:\/)/i, ''), }) t.end() }) @@ -724,7 +727,7 @@ t.test('warnings', t => { t.equal(warnings.length, 0) t.match(new Header(data), { - path: f + path: normPath(f), }) t.end() }) @@ -737,7 +740,10 @@ t.test('warnings', t => { strict: true, cwd: files }).end(f).on('error', e => { - t.match(e, { message: /stripping .* from absolute path/, data: f }) + t.match(e, { + message: /stripping .* from absolute path/, + data: normPath(f), + }) t.end() }) }) @@ -791,7 +797,7 @@ t.test('no dir recurse', t => { t.end() }) -t.test('follow', t => { +t.test('follow', { skip: isWindows && 'file symlinks not available' }, t => { const check = (out, t) => { const data = Buffer.concat(out) t.equal(data.length, 2048) @@ -800,8 +806,8 @@ t.test('follow', t => { cksumValid: true, needPax: false, path: 'symlink', - mode: 0o644, - size: 26 + mode: isWindows ? 0o666 : 0o644, + size: 26, }) t.match(data.slice(512).toString(), /this link is like diamond\n\0+$/) t.end() @@ -1055,3 +1061,97 @@ t.test('prefix and subdirs', t => { return t.test('./', t => runTest(t, './', Pack.Sync)) }) }) + +// https://github.com/npm/node-tar/issues/284 +t.test('prefix and hard links', t => { + const dir = path.resolve(fixtures, 'pack-prefix-hardlinks') + t.teardown(_ => rimraf.sync(dir)) + mkdirp.sync(dir + '/in/z/b/c') + fs.writeFileSync(dir + '/in/target', 'ddd') + fs.linkSync(dir + '/in/target', dir + '/in/z/b/c/d') + fs.linkSync(dir + '/in/target', dir + '/in/z/b/d') + fs.linkSync(dir + '/in/target', dir + '/in/z/d') + fs.linkSync(dir + '/in/target', dir + '/in/y') + + const expect = [ + 'out/x/\0', + { + type: 'File', + size: 3, + path: 'out/x/target', + linkpath: '', + }, + 'ddd\0\0\0\0\0\0\0\0\0\0\0', + { + path: 'out/x/y', + type: 'Link', + linkpath: 'out/x/target', + }, + 'out/x/z/\0', + 'out/x/z/b/\0', + { + path: 'out/x/z/d', + type: 'Link', + linkpath: 'out/x/target', + }, + 'out/x/z/b/c/\0', + { + path: 'out/x/z/b/d', + type: 'Link', + linkpath: 'out/x/target', + }, + { + path: 'out/x/z/b/c/d', + type: 'Link', + linkpath: 'out/x/target', + }, + '\0', + '\0', + ] + + const check = (out, t) => { + const data = Buffer.concat(out) + expect.forEach((e, i) => { + if (typeof e === 'string') + t.equal(data.slice(i * 512, i * 512 + e.length).toString(), e) + else + t.match(new Header(data.slice(i * 512, (i + 1) * 512)), e) + }) + t.end() + } + + const runTest = (t, path, Class) => { + const p = new Class({ + cwd: dir + '/in', + prefix: 'out/x', + noDirRecurse: true, + }) + const out = [] + p.on('data', d => out.push(d)) + p.on('end', () => check(out, t)) + p.write(path) + if (path === '.') + path = './' + p.write(`${path}target`) + p.write(`${path}y`) + p.write(`${path}z`) + p.write(`${path}z/b`) + p.write(`${path}z/d`) + p.write(`${path}z/b/c`) + p.write(`${path}z/b/d`) + p.write(`${path}z/b/c/d`) + p.end() + } + + t.test('async', t => { + t.test('.', t => runTest(t, '.', Pack)) + return t.test('./', t => runTest(t, './', Pack)) + }) + + t.test('sync', t => { + t.test('.', t => runTest(t, '.', Pack.Sync)) + return t.test('./', t => runTest(t, './', Pack.Sync)) + }) + + t.end() +}) diff --git a/test/parse.js b/test/parse.js index ccefe8ad..6092c833 100644 --- a/test/parse.js +++ b/test/parse.js @@ -58,7 +58,7 @@ t.test('fixture tests', t => { const tardir = path.resolve(__dirname, 'fixtures/tars') const parsedir = path.resolve(__dirname, 'fixtures/parse') const files = fs.readdirSync(tardir) - const maxMetaOpt = [50, null] + const maxMetaOpt = [250, null] const filterOpt = [ true, false ] const strictOpt = [ true, false ] const runTest = (file, maxMeta, filter, strict) => { @@ -172,6 +172,15 @@ t.test('onentry gets added to entry event', t => { }) t.test('drain event timings', t => { + let sawOndone = false + const ondone = function () { + sawOndone = true + this.emit('prefinish') + this.emit('finish') + this.emit('end') + this.emit('close') + } + // write 1 header and body, write 2 header, verify false return // wait for drain event before continuing. // write 2 body, 3 header and body, 4 header, verify false return @@ -311,6 +320,7 @@ t.test('drain event timings', t => { let currentEntry let autoPipe = true const p = new Parse({ + ondone, onentry: entry => { t.equal(entry.path, expect.shift()) currentEntry = entry @@ -361,6 +371,7 @@ t.test('drain event timings', t => { p.once('drain', go) p.on('end', _ => { clearInterval(interval) + t.ok(sawOndone) t.end() }) go() @@ -595,3 +606,27 @@ t.test('end while consuming', t => { mp.end(data) mp.pipe(p) }) + +t.test('header that throws', t => { + const expect = { message: 'invalid base256 encoding' } + const p = new Parse() + p.on('warn', (m, d) => { + t.match(d, expect) + t.end() + }) + const h = new Header({ + path: 'path', + mode: 0o07777, // gonna make this one invalid + uid: 1234, + gid: 4321, + size: 99, + type: 'File', + size: 1, + }) + h.encode() + const buf = h.block + const bad = Buffer.from([0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]) + bad.copy(buf, 100) + t.throws(() => new Header(buf), expect, 'the header with that buffer throws') + p.write(buf) +}) diff --git a/test/path-reservations.js b/test/path-reservations.js new file mode 100644 index 00000000..c495f310 --- /dev/null +++ b/test/path-reservations.js @@ -0,0 +1,149 @@ +const t = require('tap') +const requireInject = require('require-inject') + +// load up the posix and windows versions of the reserver +if (process.platform === 'win32') + process.env.TESTING_TAR_FAKE_PLATFORM = 'posix' +const { reserve } = require('../lib/path-reservations.js')() +delete process.env.TESTING_TAR_FAKE_PLATFORM +if (process.platform !== 'win32') + process.env.TESTING_TAR_FAKE_PLATFORM = 'win32' +const { reserve: winReserve } = requireInject('../lib/path-reservations.js')() + +t.test('basic race', t => { + // simulate the race conditions we care about + let didFile = false + const file = done => { + t.equal(didFile, false, 'only call file once') + didFile = true + t.equal(didLink, false, 'do file before link') + setTimeout(done) + } + + let didLink = false + const link = done => { + t.equal(didLink, false, 'only call once') + t.equal(didFile, true, 'do file before link') + didLink = true + // make sure this one is super duper cleared lol + // the subsequent calls are no-ops, but verify as much + done() + done() + done() + } + + let didDir = false + const dir = done => { + t.equal(didDir, false, 'only do dir once') + t.equal(didLink, true, 'do link before dir') + didDir = true + done() + } + + let didDir2 = false + const dir2 = done => { + t.equal(didDir, true, 'did dir before dir2') + t.equal(didDir2, false, 'only do dir2 once') + didDir2 = true + done() + } + + let didDir3 = false + const dir3 = done => { + t.equal(didDir2, true, 'did dir2 before dir3') + t.equal(didDir3, false, 'only do dir3 once') + didDir3 = true + done() + t.end() + } + + t.ok(reserve(['a/b/c/d'], file), 'file starts right away') + t.notOk(reserve(['a/B/c////D', 'a/b/e'], link), 'link waits') + t.notOk(reserve(['a/b/e/f'], dir), 'dir waits') + t.notOk(reserve(['a/b'], dir2), 'dir2 waits') + t.notOk(reserve(['a/b/x'], dir3), 'dir3 waits') +}) + +t.test('unicode shenanigans', t => { + const e1 = Buffer.from([0xc3, 0xa9]) + const e2 = Buffer.from([0x65, 0xcc, 0x81]) + let didCafe1 = false + const cafe1 = done => { + t.equal(didCafe1, false, 'did cafe1 only once') + t.equal(didCafe2, false, 'did cafe1 before cafe2') + didCafe1 = true + setTimeout(done) + } + let didCafe2 = false + const cafe2 = done => { + t.equal(didCafe1, true, 'did cafe1 before cafe2') + t.equal(didCafe2, false, 'did cafe2 only once') + didCafe2 = true + done() + t.end() + } + const cafePath1 = `c/a/f/${e1}` + const cafePath2 = `c/a/f/${e2}` + t.ok(reserve([cafePath1], cafe1)) + t.notOk(reserve([cafePath2], cafe2)) +}) + +t.test('absolute paths and trailing slash', t => { + let calledA1 = false + let calledA2 = false + const a1 = done => { + t.equal(calledA1, false, 'called a1 only once') + t.equal(calledA2, false, 'called a1 before 2') + calledA1 = true + setTimeout(done) + } + const a2 = done => { + t.equal(calledA1, true, 'called a1 before 2') + t.equal(calledA2, false, 'called a2 only once') + calledA2 = true + done() + if (calledR2) + t.end() + } + let calledR1 = false + let calledR2 = false + const r1 = done => { + t.equal(calledR1, false, 'called r1 only once') + t.equal(calledR2, false, 'called r1 before 2') + calledR1 = true + setTimeout(done) + } + const r2 = done => { + t.equal(calledR1, true, 'called r1 before 2') + t.equal(calledR2, false, 'called r1 only once') + calledR2 = true + done() + if (calledA2) + t.end() + } + t.ok(reserve(['/p/a/t/h'], a1)) + t.notOk(reserve(['/p/a/t/h/'], a2)) + t.ok(reserve(['p/a/t/h'], r1)) + t.notOk(reserve(['p/a/t/h/'], r2)) +}) + +t.test('on windows, everything collides with everything', t => { + const reserve = winReserve + let called1 = false + let called2 = false + const f1 = done => { + t.equal(called1, false, 'only call 1 once') + t.equal(called2, false, 'call 1 before 2') + called1 = true + setTimeout(done) + } + const f2 = done => { + t.equal(called1, true, 'call 1 before 2') + t.equal(called2, false, 'only call 2 once') + called2 = true + done() + t.end() + } + t.equal(reserve(['some/path'], f1), true) + t.equal(reserve(['other/path'], f2), false) +}) diff --git a/test/read-entry.js b/test/read-entry.js index e0feb7ed..40662ea4 100644 --- a/test/read-entry.js +++ b/test/read-entry.js @@ -6,7 +6,7 @@ const Header = require('../lib/header.js') t.test('create read entry', t => { const h = new Header({ - path: 'foo.txt', + path: 'oof.txt', mode: 0o755, uid: 24561, gid: 20, @@ -20,17 +20,17 @@ t.test('create read entry', t => { }) h.encode() - const entry = new ReadEntry(h, { x: 'y' }, { z: 0, a: null, b: undefined }) + const entry = new ReadEntry(h, { x: 'y', path: 'foo.txt' }, { z: 0, a: null, b: undefined }) t.ok(entry.header.cksumValid, 'header checksum should be valid') t.match(entry, { - extended: { x: 'y' }, + extended: { x: 'y', path: 'foo.txt' }, globalExtended: { z: 0, a: null, b: undefined }, header: { cksumValid: true, needPax: false, - path: 'foo.txt', + path: 'oof.txt', mode: 0o755, uid: 24561, gid: 20, diff --git a/test/replace.js b/test/replace.js index b6821582..1ce30d46 100644 --- a/test/replace.js +++ b/test/replace.js @@ -4,59 +4,29 @@ const t = require('tap') const r = require('../lib/replace.js') const path = require('path') const fs = require('fs') -const mkdirp = require('mkdirp') -const rimraf = require('rimraf') const mutateFS = require('mutate-fs') const list = require('../lib/list.js') +const {resolve} = require('path') const fixtures = path.resolve(__dirname, 'fixtures') -const dir = path.resolve(fixtures, 'replace') const tars = path.resolve(fixtures, 'tars') -const file = dir + '/body-byte-counts.tar' -const fileNoNulls = dir + '/no-null-eof.tar' -const fileTruncHead = dir + '/truncated-head.tar' -const fileTruncBody = dir + '/truncated-body.tar' -const fileNonExistent = dir + '/does-not-exist.tar' -const fileZeroByte = dir + '/zero.tar' -const fileEmpty = dir + '/empty.tar' -const fileCompressed = dir + '/compressed.tgz' const zlib = require('zlib') const spawn = require('child_process').spawn -t.teardown(_ => rimraf.sync(dir)) - -const reset = cb => { - rimraf.sync(dir) - mkdirp.sync(dir) - const data = fs.readFileSync(tars + '/body-byte-counts.tar') - fs.writeFileSync(file, data) - - const dataNoNulls = data.slice(0, data.length - 1024) - fs.writeFileSync(fileNoNulls, dataNoNulls) - - const dataTruncHead = Buffer.concat([dataNoNulls, data.slice(0, 500)]) - fs.writeFileSync(fileTruncHead, dataTruncHead) - - const dataTruncBody = Buffer.concat([dataNoNulls, data.slice(0, 700)]) - fs.writeFileSync(fileTruncBody, dataTruncBody) - - fs.writeFileSync(fileZeroByte, '') - fs.writeFileSync(fileEmpty, Buffer.alloc(1024)) - - fs.writeFileSync(fileCompressed, zlib.gzipSync(data)) - - if (cb) - cb() +const data = fs.readFileSync(tars + '/body-byte-counts.tar') +const dataNoNulls = data.slice(0, data.length - 1024) +const fixtureDef = { + 'body-byte-counts.tar': data, + 'no-null-eof.tar': dataNoNulls, + 'truncated-head.tar': Buffer.concat([dataNoNulls, data.slice(0, 500)]), + 'truncated-body.tar': Buffer.concat([dataNoNulls, data.slice(0, 700)]), + 'zero.tar': Buffer.from(''), + 'empty.tar': Buffer.alloc(512), + 'compressed.tgz': zlib.gzipSync(data), } -t.test('setup', t => { - reset(t.end) -}) - t.test('basic file add to archive (good or truncated)', t => { - t.beforeEach(reset) - const check = (file, t) => { const c = spawn('tar', ['tf', file], { stdio: [ 0, 'pipe', 2 ] }) const out = [] @@ -64,7 +34,7 @@ t.test('basic file add to archive (good or truncated)', t => { c.on('close', (code, signal) => { t.equal(code, 0) t.equal(signal, null) - const actual = Buffer.concat(out).toString().trim().split('\n') + const actual = Buffer.concat(out).toString().trim().split(/\r?\n/) t.same(actual, [ '1024-bytes.txt', '512-bytes.txt', @@ -76,50 +46,68 @@ t.test('basic file add to archive (good or truncated)', t => { }) } - ;[file, - fileNoNulls, - fileTruncHead, - fileTruncBody - ].forEach(file => { - const fileList = [ path.basename(__filename) ] - t.test(path.basename(file), t => { - t.test('sync', t => { + const files = [ + 'body-byte-counts.tar', + 'no-null-eof.tar', + 'truncated-head.tar', + 'truncated-body.tar', + ] + const td = files.map(f => [f, fixtureDef[f]]).reduce((s, [k, v]) => { + s[k] = v + return s + }, {}) + const fileList = [path.basename(__filename)] + t.test('sync', t => { + t.plan(files.length) + const dir = t.testdir(td) + for (const file of files) { + t.test(file, t => { r({ sync: true, - file: file, - cwd: __dirname + file: resolve(dir, file), + cwd: __dirname, }, fileList) - check(file, t) + check(resolve(dir, file), t) }) + } + }) - t.test('async cb', t => { + t.test('async cb', t => { + t.plan(files.length) + const dir = t.testdir(td) + for (const file of files) { + t.test(file, t => { r({ - file: file, - cwd: __dirname + file: resolve(dir, file), + cwd: __dirname, }, fileList, er => { if (er) throw er - check(file, t) + check(resolve(dir, file), t) }) }) + } + }) - t.test('async promise', t => { + t.test('async', t => { + t.plan(files.length) + const dir = t.testdir(td) + for (const file of files) { + t.test(file, t => { r({ - file: file, - cwd: __dirname - }, fileList).then(_ => check(file, t)) + file: resolve(dir, file), + cwd: __dirname, + }, fileList).then(() => { + check(resolve(dir, file), t) + }) }) - - t.end() - }) + } }) t.end() }) t.test('add to empty archive', t => { - t.beforeEach(reset) - const check = (file, t) => { const c = spawn('tar', ['tf', file]) const out = [] @@ -135,70 +123,91 @@ t.test('add to empty archive', t => { }) } - ;[fileNonExistent, - fileEmpty, - fileZeroByte - ].forEach(file => { - t.test(path.basename(file), t => { - t.test('sync', t => { + const files = [ + 'empty.tar', + 'zero.tar', + ] + const td = files.map(f => [f, fixtureDef[f]]).reduce((s, [k, v]) => { + s[k] = v + return s + }, {}) + files.push('not-existing.tar') + + t.test('sync', t => { + const dir = t.testdir(td) + t.plan(files.length) + for (const file of files) { + t.test(file, t => { r({ sync: true, - file: file, - cwd: __dirname + file: resolve(dir, file), + cwd: __dirname, }, [path.basename(__filename)]) - check(file, t) + check(resolve(dir, file), t) }) + } + }) - t.test('async cb', t => { + t.test('async cb', t => { + const dir = t.testdir(td) + t.plan(files.length) + for (const file of files) { + t.test(file, t => { r({ - file: file, - cwd: __dirname + file: resolve(dir, file), + cwd: __dirname, }, [path.basename(__filename)], er => { if (er) throw er - check(file, t) + check(resolve(dir, file), t) }) }) + } + }) - t.test('async promise', t => { + t.test('async', async t => { + const dir = t.testdir(td) + t.plan(files.length) + for (const file of files) { + t.test(file, t => { r({ - file: file, - cwd: __dirname - }, [path.basename(__filename)]).then(_ => check(file, t)) + file: resolve(dir, file), + cwd: __dirname, + }, [path.basename(__filename)]).then(() => { + check(resolve(dir, file), t) + }) }) - - t.end() - }) + } }) t.end() }) -t.test('cannot append to gzipped archives', t => { - reset() +t.test('cannot append to gzipped archives', async t => { + const dir = t.testdir({ + 'compressed.tgz': fixtureDef['compressed.tgz'], + }) + const file = resolve(dir, 'compressed.tgz') const expect = new Error('cannot append to compressed archives') const expectT = new TypeError('cannot append to compressed archives') t.throws(_ => r({ - file: fileCompressed, + file, cwd: __dirname, gzip: true }, [path.basename(__filename)]), expectT) t.throws(_ => r({ - file: fileCompressed, + file, cwd: __dirname, sync: true }, [path.basename(__filename)]), expect) - r({ - file: fileCompressed, + return r({ + file, cwd: __dirname, - }, [path.basename(__filename)], er => { - t.match(er, expect) - t.end() - }) + }, [path.basename(__filename)], er => t.match(er, expect)) }) t.test('other throws', t => { @@ -209,37 +218,61 @@ t.test('other throws', t => { }) t.test('broken open', t => { + const dir = t.testdir({ + 'body-byte-counts.tar': fixtureDef['body-byte-counts.tar'], + }) + const file = resolve(dir, 'body-byte-counts.tar') const poop = new Error('poop') t.teardown(mutateFS.fail('open', poop)) - t.throws(_ => r({ sync: true, file: file }, ['README.md']), poop) - r({ file: file }, ['README.md'], er => { + t.throws(_ => r({ sync: true, file }, ['README.md']), poop) + r({ file }, ['README.md'], er => { t.match(er, poop) t.end() }) }) t.test('broken fstat', t => { + const td = { + 'body-byte-counts.tar': fixtureDef['body-byte-counts.tar'], + } const poop = new Error('poop') - t.teardown(mutateFS.fail('fstat', poop)) - t.throws(_ => r({ sync: true, file: file }, ['README.md']), poop) - r({ file: file }, ['README.md'], er => { - t.match(er, poop) + t.test('sync', t => { + const dir = t.testdir(td) + const file = resolve(dir, 'body-byte-counts.tar') + t.teardown(mutateFS.fail('fstat', poop)) + t.throws(_ => r({ sync: true, file }, ['README.md']), poop) t.end() }) + t.test('async', t => { + const dir = t.testdir(td) + const file = resolve(dir, 'body-byte-counts.tar') + t.teardown(mutateFS.fail('fstat', poop)) + r({ file }, ['README.md'], async er => { + t.match(er, poop) + t.end() + }) + }) + t.end() }) t.test('broken read', t => { + const dir = t.testdir({ + 'body-byte-counts.tar': fixtureDef['body-byte-counts.tar'], + }) + const file = resolve(dir, 'body-byte-counts.tar') const poop = new Error('poop') t.teardown(mutateFS.fail('read', poop)) - t.throws(_ => r({ sync: true, file: file }, ['README.md']), poop) - r({ file: file }, ['README.md'], er => { + t.throws(_ => r({ sync: true, file }, ['README.md']), poop) + r({ file }, ['README.md'], er => { t.match(er, poop) t.end() }) }) -t.test('mtime cache', t => { - t.beforeEach(reset) +t.test('mtime cache', async t => { + const td = { + 'body-byte-counts.tar': fixtureDef['body-byte-counts.tar'], + } let mtimeCache @@ -250,7 +283,7 @@ t.test('mtime cache', t => { c.on('close', (code, signal) => { t.equal(code, 0) t.equal(signal, null) - const actual = Buffer.concat(out).toString().trim().split('\n') + const actual = Buffer.concat(out).toString().trim().split(/\r?\n/) t.same(actual, [ '1024-bytes.txt', '512-bytes.txt', @@ -271,9 +304,11 @@ t.test('mtime cache', t => { } t.test('sync', t => { + const dir = t.testdir(td) + const file = resolve(dir, 'body-byte-counts.tar') r({ sync: true, - file: file, + file, cwd: __dirname, mtimeCache: mtimeCache = new Map() }, [path.basename(__filename)]) @@ -281,8 +316,10 @@ t.test('mtime cache', t => { }) t.test('async cb', t => { + const dir = t.testdir(td) + const file = resolve(dir, 'body-byte-counts.tar') r({ - file: file, + file, cwd: __dirname, mtimeCache: mtimeCache = new Map() }, [path.basename(__filename)], er => { @@ -293,8 +330,10 @@ t.test('mtime cache', t => { }) t.test('async promise', t => { + const dir = t.testdir(td) + const file = resolve(dir, 'body-byte-counts.tar') r({ - file: file, + file, cwd: __dirname, mtimeCache: mtimeCache = new Map() }, [path.basename(__filename)]).then(_ => check(file, t)) @@ -304,40 +343,58 @@ t.test('mtime cache', t => { }) t.test('create tarball out of another tarball', t => { - const out = path.resolve(dir, 'out.tar') - - t.beforeEach(cb => { - fs.writeFile(out, fs.readFileSync(path.resolve(tars, 'dir.tar')), cb) - }) + const td = { + 'out.tar': fs.readFileSync(path.resolve(tars, 'dir.tar')), + } - const check = t => { + const check = (out, t) => { const expect = [ 'dir/', 'Ω.txt', '🌟.txt', 'long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/Ω.txt' ] - list({ f: out, sync: true, onentry: entry => { - t.equal(entry.path, expect.shift()) - }}) + list({ + f: out, + sync: true, + onentry: entry => { + t.equal(entry.path, expect.shift()) + }}) t.same(expect, []) t.end() } t.test('sync', t => { + const dir = t.testdir(td) + const out = resolve(dir, 'out.tar') r({ f: out, cwd: tars, sync: true }, ['@utf8.tar']) - check(t) + check(out, t) + }) + + t.test('async cb', t => { + const dir = t.testdir(td) + const out = resolve(dir, 'out.tar') + r({ + f: out, + cwd: tars, + }, ['@utf8.tar'], er => { + if (er) + throw er + check(out, t) + }) }) t.test('async', t => { + const dir = t.testdir(td) + const out = resolve(dir, 'out.tar') r({ f: out, - cwd: tars - }, ['@utf8.tar'], _ => check(t)) + cwd: tars, + }, ['@utf8.tar']).then(() => check(out, t)) }) t.end() diff --git a/test/strip-absolute-path.js b/test/strip-absolute-path.js new file mode 100644 index 00000000..c50e2858 --- /dev/null +++ b/test/strip-absolute-path.js @@ -0,0 +1,52 @@ +const t = require('tap') +const stripAbsolutePath = require('../lib/strip-absolute-path.js') +const cwd = process.cwd() +const requireInject = require('require-inject') + +t.test('basic', t => { + const cases = { + '/': ['/', ''], + '////': ['////', ''], + 'c:///a/b/c': ['c:///', 'a/b/c'], + '\\\\foo\\bar\\baz': ['\\\\foo\\bar\\', 'baz'], + '//foo//bar//baz': ['//', 'foo//bar//baz'], + 'c:\\c:\\c:\\c:\\\\d:\\e/f/g': ['c:\\c:\\c:\\c:\\\\d:\\', 'e/f/g'], + } + + for (const [input, [root, stripped]] of Object.entries(cases)) + t.strictSame(stripAbsolutePath(input, cwd), [root, stripped], input) + t.end() +}) + +t.test('drive-local paths', t => { + const env = process.env + t.teardown(() => process.env = env) + const cwd = 'D:\\safety\\land' + const realPath = require('path') + // be windowsy + const path = { + ...realPath.win32, + win32: realPath.win32, + posix: realPath.posix, + } + const stripAbsolutePath = requireInject('../lib/strip-absolute-path.js', { path }) + const cases = { + '/': ['/', ''], + '////': ['////', ''], + 'c:///a/b/c': ['c:///', 'a/b/c'], + '\\\\foo\\bar\\baz': ['\\\\foo\\bar\\', 'baz'], + '//foo//bar//baz': ['//', 'foo//bar//baz'], + 'c:\\c:\\c:\\c:\\\\d:\\e/f/g': ['c:\\c:\\c:\\c:\\\\d:\\', 'e/f/g'], + 'c:..\\system\\explorer.exe': ['c:', '..\\system\\explorer.exe'], + 'd:..\\..\\unsafe\\land': ['d:', '..\\..\\unsafe\\land'], + 'c:foo': ['c:', 'foo'], + 'D:mark': ['D:', 'mark'], + '//?/X:/y/z': ['//?/X:/', 'y/z'], + '\\\\?\\X:\\y\\z': ['\\\\?\\X:\\', 'y\\z'], + } + for (const [input, [root, stripped]] of Object.entries(cases)) { + if (!t.strictSame(stripAbsolutePath(input, cwd), [root, stripped], input)) + break + } + t.end() +}) diff --git a/test/strip-trailing-slashes.js b/test/strip-trailing-slashes.js new file mode 100644 index 00000000..198797bf --- /dev/null +++ b/test/strip-trailing-slashes.js @@ -0,0 +1,7 @@ +const t = require('tap') +const stripSlash = require('../lib/strip-trailing-slashes.js') +const short = '///a///b///c///' +const long = short.repeat(10) + '/'.repeat(1000000) + +t.equal(stripSlash(short), '///a///b///c') +t.equal(stripSlash(long), short.repeat(9) + '///a///b///c') diff --git a/test/unpack.js b/test/unpack.js index 20ca79ac..bc1cc270 100644 --- a/test/unpack.js +++ b/test/unpack.js @@ -17,22 +17,31 @@ const files = path.resolve(fixtures, 'files') const tars = path.resolve(fixtures, 'tars') const parses = path.resolve(fixtures, 'parse') const unpackdir = path.resolve(fixtures, 'unpack') -const rimraf = require('rimraf') -const mkdirp = require('mkdirp') +const {promisify} = require('util') +const rimraf = promisify(require('rimraf')) +const mkdirp = promisify(require('mkdirp')) const mutateFS = require('mutate-fs') const eos = require('end-of-stream') +const normPath = require('../lib/normalize-windows-path.js') +const requireInject = require('require-inject') -t.teardown(_ => rimraf.sync(unpackdir)) +// On Windows in particular, the "really deep folder path" file +// often tends to cause problems, which don't indicate a failure +// of this library, it's just what happens on Windows with super +// long file paths. +const isWindows = process.platform === 'win32' +const isLongFile = f => f.match(/r.e.a.l.l.y.-.d.e.e.p.-.f.o.l.d.e.r.-.p.a.t.h/) -t.test('setup', t => { - rimraf.sync(unpackdir) - mkdirp.sync(unpackdir) - t.end() +t.teardown(_ => rimraf(unpackdir)) + +t.test('setup', async () => { + await rimraf(unpackdir) + await mkdirp(unpackdir) }) t.test('basic file unpack tests', t => { const basedir = path.resolve(unpackdir, 'basic') - t.teardown(_ => rimraf.sync(basedir)) + t.teardown(_ => rimraf(basedir)) const cases = { 'emptypax.tar': { @@ -79,16 +88,20 @@ t.test('basic file unpack tests', t => { t.test(tarfile, t => { const tf = path.resolve(tars, tarfile) const dir = path.resolve(basedir, tarfile) - t.beforeEach(cb => { - rimraf.sync(dir) - mkdirp.sync(dir) - cb() + const linkdir = path.resolve(basedir, tarfile + '.link') + t.beforeEach(async () => { + await rimraf(dir) + await rimraf(linkdir) + await mkdirp(dir) + fs.symlinkSync(dir, linkdir, 'junction') }) const check = t => { const expect = cases[tarfile] Object.keys(expect).forEach(file => { const f = path.resolve(dir, file) + if (isWindows && isLongFile(file)) + return t.equal(fs.readFileSync(f, 'utf8'), expect[file], file) }) t.end() @@ -99,12 +112,12 @@ t.test('basic file unpack tests', t => { t.test('async unpack', t => { t.plan(2) t.test('strict', t => { - const unpack = new Unpack({ cwd: dir, strict: true }) + const unpack = new Unpack({ cwd: linkdir, strict: true }) fs.createReadStream(tf).pipe(unpack) eos(unpack, _ => check(t)) }) t.test('loose', t => { - const unpack = new Unpack({ cwd: dir }) + const unpack = new Unpack({ cwd: linkdir }) fs.createReadStream(tf).pipe(unpack) eos(unpack, _ => check(t)) }) @@ -113,12 +126,12 @@ t.test('basic file unpack tests', t => { t.test('sync unpack', t => { t.plan(2) t.test('strict', t => { - const unpack = new UnpackSync({ cwd: dir }) + const unpack = new UnpackSync({ cwd: linkdir }) unpack.end(fs.readFileSync(tf)) check(t) }) t.test('loose', t => { - const unpack = new UnpackSync({ cwd: dir }) + const unpack = new UnpackSync({ cwd: linkdir }) unpack.end(fs.readFileSync(tf)) check(t) }) @@ -130,7 +143,7 @@ t.test('basic file unpack tests', t => { t.test('cwd default to process cwd', t => { const u = new Unpack() const us = new UnpackSync() - const cwd = process.cwd() + const cwd = normPath(process.cwd()) t.equal(u.cwd, cwd) t.equal(us.cwd, cwd) t.end() @@ -139,10 +152,11 @@ t.test('cwd default to process cwd', t => { t.test('links!', t => { const dir = path.resolve(unpackdir, 'links') const data = fs.readFileSync(tars + '/links.tar') + const stripData = fs.readFileSync(tars + '/links-strip.tar') - t.plan(2) - t.beforeEach(cb => mkdirp(dir, cb)) - t.afterEach(cb => rimraf(dir, cb)) + t.plan(6) + t.beforeEach(() => mkdirp(dir)) + t.afterEach(() => rimraf(dir)) const check = t => { const hl1 = fs.lstatSync(dir + '/hardlink-1') @@ -151,9 +165,34 @@ t.test('links!', t => { t.equal(hl1.ino, hl2.ino) t.equal(hl1.nlink, 2) t.equal(hl2.nlink, 2) - const sym = fs.lstatSync(dir + '/symlink') - t.ok(sym.isSymbolicLink()) - t.equal(fs.readlinkSync(dir + '/symlink'), 'hardlink-2') + if (!isWindows) { + // doesn't work on win32 without special privs + const sym = fs.lstatSync(dir + '/symlink') + t.ok(sym.isSymbolicLink()) + t.equal(fs.readlinkSync(dir + '/symlink'), 'hardlink-2') + } + t.end() + } + const checkForStrip = t => { + const hl1 = fs.lstatSync(dir + '/hardlink-1') + const hl2 = fs.lstatSync(dir + '/hardlink-2') + const hl3 = fs.lstatSync(dir + '/1/2/3/hardlink-3') + t.equal(hl1.dev, hl2.dev) + t.equal(hl1.ino, hl2.ino) + t.equal(hl1.dev, hl3.dev) + t.equal(hl1.ino, hl3.ino) + t.equal(hl1.nlink, 3) + t.equal(hl2.nlink, 3) + if (!isWindows) { + const sym = fs.lstatSync(dir + '/symlink') + t.ok(sym.isSymbolicLink()) + t.equal(fs.readlinkSync(dir + '/symlink'), 'hardlink-2') + } + t.end() + } + const checkForStrip3 = t => { + // strips the linkpath entirely, so the link doesn't get extracted. + t.throws(() => fs.lstatSync(dir + '/3'), { code: 'ENOENT' }) t.end() } @@ -171,6 +210,36 @@ t.test('links!', t => { unpack.end(data) check(t) }) + + t.test('sync strip', t => { + const unpack = new UnpackSync({ cwd: dir, strip: 1 }) + unpack.end(stripData) + checkForStrip(t) + }) + + t.test('async strip', t => { + const unpack = new Unpack({ cwd: dir, strip: 1 }) + let finished = false + unpack.on('finish', _ => finished = true) + unpack.on('close', _ => t.ok(finished, 'emitted finish before close')) + unpack.on('close', _ => checkForStrip(t)) + unpack.end(stripData) + }) + + t.test('sync strip 3', t => { + const unpack = new UnpackSync({ cwd: dir, strip: 3 }) + unpack.end(fs.readFileSync(tars + '/links-strip.tar')) + checkForStrip3(t) + }) + + t.test('async strip 3', t => { + const unpack = new Unpack({ cwd: dir, strip: 3 }) + let finished = false + unpack.on('finish', _ => finished = true) + unpack.on('close', _ => t.ok(finished, 'emitted finish before close')) + unpack.on('close', _ => checkForStrip3(t)) + unpack.end(stripData) + }) }) t.test('links without cleanup (exercise clobbering code)', t => { @@ -179,7 +248,7 @@ t.test('links without cleanup (exercise clobbering code)', t => { t.plan(6) mkdirp.sync(dir) - t.teardown(_ => rimraf.sync(dir)) + t.teardown(_ => rimraf(dir)) t.beforeEach(cb => { // clobber this junk @@ -198,9 +267,11 @@ t.test('links without cleanup (exercise clobbering code)', t => { t.equal(hl1.ino, hl2.ino) t.equal(hl1.nlink, 2) t.equal(hl2.nlink, 2) - const sym = fs.lstatSync(dir + '/symlink') - t.ok(sym.isSymbolicLink()) - t.equal(fs.readlinkSync(dir + '/symlink'), 'hardlink-2') + if (!isWindows) { + const sym = fs.lstatSync(dir + '/symlink') + t.ok(sym.isSymbolicLink()) + t.equal(fs.readlinkSync(dir + '/symlink'), 'hardlink-2') + } t.end() } @@ -248,7 +319,7 @@ t.test('links without cleanup (exercise clobbering code)', t => { t.test('nested dir dupe', t => { const dir = path.resolve(unpackdir, 'nested-dir') mkdirp.sync(dir + '/d/e/e/p') - t.teardown(_ => rimraf.sync(dir)) + t.teardown(_ => rimraf(dir)) const expect = { 'd/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/a.txt': 'short\n', 'd/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc': 'cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc', @@ -277,14 +348,15 @@ t.test('nested dir dupe', t => { zip.end(data) }) -t.test('symlink in dir path', t => { +t.test('symlink in dir path', { + skip: isWindows && 'symlinks not fully supported', +}, t => { const dir = path.resolve(unpackdir, 'symlink-junk') - t.teardown(_ => rimraf.sync(dir)) - t.beforeEach(cb => { - rimraf.sync(dir) - mkdirp.sync(dir) - cb() + t.teardown(_ => rimraf(dir)) + t.beforeEach(async () => { + await rimraf(dir) + await mkdirp(dir) }) const data = makeTar([ @@ -338,18 +410,22 @@ t.test('symlink in dir path', t => { const warnings = [] const u = new Unpack({ cwd: dir, onwarn: (w,d) => warnings.push([w,d]) }) u.on('close', _ => { - t.equal(fs.lstatSync(dir + '/d/i').mode & 0o7777, 0o755) - t.equal(fs.lstatSync(dir + '/d/i/r/dir').mode & 0o7777, 0o751) + t.equal(fs.lstatSync(dir + '/d/i').mode & 0o7777, isWindows ? 0o666 : 0o755) + t.equal(fs.lstatSync(dir + '/d/i/r/dir').mode & 0o7777, isWindows ? 0o666 : 0o751) t.ok(fs.lstatSync(dir + '/d/i/r/file').isFile(), 'got file') - t.ok(fs.lstatSync(dir + '/d/i/r/symlink').isSymbolicLink(), 'got symlink') - t.throws(_ => fs.statSync(dir + '/d/i/r/symlink/x')) + if (!isWindows) { + t.ok(fs.lstatSync(dir + '/d/i/r/symlink').isSymbolicLink(), 'got symlink') + t.throws(_ => fs.statSync(dir + '/d/i/r/symlink/x')) + } + if (!isWindows) { + t.equal(warnings[0][0], 'Cannot extract through symbolic link') + t.match(warnings[0][1], { + name: 'SylinkError', + path: dir + '/d/i/r/symlink/', + symlink: dir + '/d/i/r/symlink', + }) + } t.equal(warnings.length, 1) - t.equal(warnings[0][0], 'Cannot extract through symbolic link') - t.match(warnings[0][1], { - name: 'SylinkError', - path: dir + '/d/i/r/symlink/', - symlink: dir + '/d/i/r/symlink' - }) t.end() }) u.end(data) @@ -362,10 +438,12 @@ t.test('symlink in dir path', t => { onwarn: (w,d) => warnings.push([w,d]) }) u.end(data) - t.equal(fs.lstatSync(dir + '/d/i/r/dir').mode & 0o7777, 0o751) + t.equal(fs.lstatSync(dir + '/d/i/r/dir').mode & 0o7777, isWindows ? 0o666 : 0o751) t.ok(fs.lstatSync(dir + '/d/i/r/file').isFile(), 'got file') - t.ok(fs.lstatSync(dir + '/d/i/r/symlink').isSymbolicLink(), 'got symlink') - t.throws(_ => fs.statSync(dir + '/d/i/r/symlink/x')) + if (!isWindows) { + t.ok(fs.lstatSync(dir + '/d/i/r/symlink').isSymbolicLink(), 'got symlink') + t.throws(_ => fs.statSync(dir + '/d/i/r/symlink/x')) + } t.equal(warnings.length, 1) t.equal(warnings[0][0], 'Cannot extract through symbolic link') t.match(warnings[0][1], { @@ -525,7 +603,7 @@ t.test('symlink in dir path', t => { t.test('unsupported entries', t => { const dir = path.resolve(unpackdir, 'unsupported-entries') mkdirp.sync(dir) - t.teardown(_ => rimraf.sync(dir)) + t.teardown(_ => rimraf(dir)) const unknown = new Header({ path: 'qux', type: 'File', size: 4 }) unknown.type = 'Z' unknown.encode() @@ -602,11 +680,10 @@ t.test('unsupported entries', t => { t.test('file in dir path', t => { const dir = path.resolve(unpackdir, 'file-junk') - t.teardown(_ => rimraf.sync(dir)) - t.beforeEach(cb => { - rimraf.sync(dir) - mkdirp.sync(dir) - cb() + t.teardown(_ => rimraf(dir)) + t.beforeEach(async () => { + await rimraf(dir) + await mkdirp(dir) }) const data = makeTar([ @@ -676,7 +753,7 @@ t.test('file in dir path', t => { t.test('set umask option', t => { const dir = path.resolve(unpackdir, 'umask') mkdirp.sync(dir) - t.tearDown(_ => rimraf.sync(dir)) + t.teardown(_ => rimraf(dir)) const data = makeTar([ { @@ -692,22 +769,24 @@ t.test('set umask option', t => { umask: 0o027, cwd: dir }).on('close', _ => { - t.equal(fs.statSync(dir + '/d/i/r').mode & 0o7777, 0o750) - t.equal(fs.statSync(dir + '/d/i/r/dir').mode & 0o7777, 0o751) + t.equal(fs.statSync(dir + '/d/i/r').mode & 0o7777, isWindows ? 0o666 : 0o750) + t.equal(fs.statSync(dir + '/d/i/r/dir').mode & 0o7777, isWindows ? 0o666 : 0o751) t.end() }).end(data) }) t.test('absolute paths', t => { const dir = path.join(unpackdir, 'absolute-paths') - t.teardown(_ => rimraf.sync(dir)) - t.beforeEach(cb => { - rimraf.sync(dir) - mkdirp.sync(dir) - cb() + t.teardown(_ => rimraf(dir)) + t.beforeEach(async () => { + await rimraf(dir) + await mkdirp(dir) }) const absolute = path.resolve(dir, 'd/i/r/absolute') + const root = path.parse(absolute).root + const extraAbsolute = root + root + root + absolute + t.ok(path.isAbsolute(extraAbsolute)) t.ok(path.isAbsolute(absolute)) const parsed = path.parse(absolute) const relative = absolute.substr(parsed.root.length) @@ -715,7 +794,7 @@ t.test('absolute paths', t => { const data = makeTar([ { - path: absolute, + path: extraAbsolute, type: 'File', size: 1, atime: new Date('1979-07-01T19:10:00.000Z'), @@ -729,9 +808,10 @@ t.test('absolute paths', t => { t.test('warn and correct', t => { const check = t => { - t.same(warnings, [[ - 'stripping / from absolute path', - absolute + const r = normPath(root) + t.match(warnings, [[ + `stripping ${r}${r}${r}${r} from absolute path`, + normPath(absolute), ]]) t.ok(fs.lstatSync(path.resolve(dir, relative)).isFile(), 'is file') t.end() @@ -760,6 +840,22 @@ t.test('absolute paths', t => { }) t.test('preserve absolute path', t => { + // if we use the extraAbsolute path here, we end up creating a dir + // like C:\C:\C:\C:\path\to\absolute, which is both 100% valid on + // windows, as well as SUUUUUPER annoying. + const data = makeTar([ + { + path: isWindows ? absolute : extraAbsolute, + type: 'File', + size: 1, + atime: new Date('1979-07-01T19:10:00.000Z'), + ctime: new Date('2011-03-27T22:16:31.000Z'), + mtime: new Date('2011-03-27T22:16:31.000Z'), + }, + 'a', + '', + '', + ]) const check = t => { t.same(warnings, []) t.ok(fs.lstatSync(absolute).isFile(), 'is file') @@ -795,11 +891,10 @@ t.test('absolute paths', t => { t.test('.. paths', t => { const dir = path.join(unpackdir, 'dotted-paths') - t.teardown(_ => rimraf.sync(dir)) - t.beforeEach(cb => { - rimraf.sync(dir) - mkdirp.sync(dir) - cb() + t.teardown(_ => rimraf(dir)) + t.beforeEach(async () => { + await rimraf(dir) + await mkdirp(dir) }) const fmode = 0o755 @@ -858,7 +953,7 @@ t.test('.. paths', t => { const check = t => { t.same(warnings, []) t.ok(fs.lstatSync(resolved).isFile(), 'is file') - t.equal(fs.lstatSync(resolved).mode & 0o777, fmode, 'mode is 0755') + t.equal(fs.lstatSync(resolved).mode & 0o777, isWindows ? 0o666 : fmode) t.end() } @@ -894,20 +989,46 @@ t.test('.. paths', t => { t.test('fail all stats', t => { const poop = new Error('poop') poop.code = 'EPOOP' - let unmutate - const dir = path.join(unpackdir, 'stat-fail') + const dir = normPath(path.join(unpackdir, 'stat-fail')) + const { + stat, + fstat, + lstat, + statSync, + fstatSync, + lstatSync, + } = fs + const unmutate = () => Object.assign(fs, { + stat, + fstat, + lstat, + statSync, + fstatSync, + lstatSync, + }) + const mutate = () => { + fs.stat = fs.lstat = fs.fstat = (...args) => { + // don't fail statting the cwd, or we get different errors + if (normPath(args[0]) === dir) + return lstat(dir, args.pop()) + process.nextTick(() => args.pop()(poop)) + } + fs.statSync = fs.lstatSync = fs.fstatSync = (...args) => { + if (normPath(args[0]) === dir) + return lstatSync(dir) + throw poop + } + } const warnings = [] - t.beforeEach(cb => { + t.beforeEach(async () => { warnings.length = 0 - mkdirp.sync(dir) - unmutate = mutateFS.statFail(poop) - cb() + await mkdirp(dir) + mutate() }) - t.afterEach(cb => { + t.afterEach(async () => { unmutate() - rimraf.sync(dir) - cb() + await rimraf(dir) }) const data = makeTar([ @@ -978,18 +1099,18 @@ t.test('fail all stats', t => { String, { code: 'EISDIR', - path: path.resolve(dir, 'd/i/r/file'), - syscall: 'open' - } + path: normPath(path.resolve(dir, 'd/i/r/file')), + syscall: 'open', + }, ], [ String, { - dest: path.resolve(dir, 'd/i/r/link'), - path: path.resolve(dir, 'd/i/r/file'), - syscall: 'link' - } - ] + dest: normPath(path.resolve(dir, 'd/i/r/link')), + path: normPath(path.resolve(dir, 'd/i/r/file')), + syscall: 'link', + }, + ], ] new UnpackSync({ cwd: dir, @@ -1006,14 +1127,16 @@ t.test('fail symlink', t => { poop.code = 'EPOOP' const unmutate = mutateFS.fail('symlink', poop) const dir = path.join(unpackdir, 'symlink-fail') - t.teardown(_ => (unmutate(), rimraf.sync(dir))) + t.teardown(async _ => { + unmutate() + await rimraf(dir) + }) const warnings = [] - t.beforeEach(cb => { + t.beforeEach(async () => { warnings.length = 0 - rimraf.sync(dir) - mkdirp.sync(dir) - cb() + await rimraf(dir) + await mkdirp(dir) }) const data = makeTar([ @@ -1068,14 +1191,16 @@ t.test('fail chmod', t => { poop.code = 'EPOOP' const unmutate = mutateFS.fail('chmod', poop) const dir = path.join(unpackdir, 'chmod-fail') - t.teardown(_ => (unmutate(), rimraf.sync(dir))) + t.teardown(async _ => { + unmutate() + await rimraf(dir) + }) const warnings = [] - t.beforeEach(cb => { + t.beforeEach(async () => { warnings.length = 0 - rimraf.sync(dir) - mkdirp.sync(dir) - cb() + await rimraf(dir) + await mkdirp(dir) }) const data = makeTar([ @@ -1129,19 +1254,17 @@ t.test('fail mkdir', t => { poop.code = 'EPOOP' let unmutate const dir = path.join(unpackdir, 'mkdir-fail') - t.teardown(_ => rimraf.sync(dir)) + t.teardown(_ => rimraf(dir)) const warnings = [] - t.beforeEach(cb => { + t.beforeEach(async () => { warnings.length = 0 - rimraf.sync(dir) - mkdirp.sync(dir) + await rimraf(dir) + await mkdirp(dir) unmutate = mutateFS.fail('mkdir', poop) - cb() }) - t.afterEach(cb => { + t.afterEach(async () => { unmutate() - cb() }) const data = makeTar([ @@ -1157,15 +1280,14 @@ t.test('fail mkdir', t => { '' ]) - const expect = [ [ - 'ENOENT: no such file or directory, lstat \'' + - path.resolve(dir, 'dir') + '\'', + const expect = [[ + 'ENOENT: no such file or directory', { code: 'ENOENT', syscall: 'lstat', - path: path.resolve(dir, 'dir') - } - ] ] + path: normPath(path.resolve(dir, 'dir')), + }, + ]] const check = t => { t.match(warnings, expect) @@ -1173,13 +1295,6 @@ t.test('fail mkdir', t => { t.end() } - t.test('async', t => { - new Unpack({ - cwd: dir, - onwarn: (w, d) => warnings.push([w, d]) - }).on('close', _ => check(t)).end(data) - }) - t.test('sync', t => { new UnpackSync({ cwd: dir, @@ -1188,6 +1303,13 @@ t.test('fail mkdir', t => { check(t) }) + t.test('async', t => { + new Unpack({ + cwd: dir, + onwarn: (w, d) => warnings.push([w, d]), + }).on('close', _ => check(t)).end(data) + }) + t.end() }) @@ -1196,14 +1318,16 @@ t.test('fail write', t => { poop.code = 'EPOOP' const unmutate = mutateFS.fail('write', poop) const dir = path.join(unpackdir, 'write-fail') - t.teardown(_ => (unmutate(), rimraf.sync(dir))) + t.teardown(async _ => { + unmutate() + await rimraf(dir) + }) const warnings = [] - t.beforeEach(cb => { + t.beforeEach(async () => { warnings.length = 0 - rimraf.sync(dir) - mkdirp.sync(dir) - cb() + await rimraf(dir) + await mkdirp(dir) }) const data = makeTar([ @@ -1247,15 +1371,14 @@ t.test('fail write', t => { t.test('skip existing', t => { const dir = path.join(unpackdir, 'skip-newer') - t.teardown(_ => rimraf.sync(dir)) + t.teardown(_ => rimraf(dir)) const date = new Date('2011-03-27T22:16:31.000Z') - t.beforeEach(cb => { - rimraf.sync(dir) - mkdirp.sync(dir) + t.beforeEach(async () => { + await rimraf(dir) + await mkdirp(dir) fs.writeFileSync(dir + '/x', 'y') fs.utimesSync(dir + '/x', date, date) - cb() }) const data = makeTar([ @@ -1300,15 +1423,14 @@ t.test('skip existing', t => { t.test('skip newer', t => { const dir = path.join(unpackdir, 'skip-newer') - t.teardown(_ => rimraf.sync(dir)) + t.teardown(_ => rimraf(dir)) const date = new Date('2013-12-19T17:00:00.000Z') - t.beforeEach(cb => { - rimraf.sync(dir) - mkdirp.sync(dir) + t.beforeEach(async () => { + await rimraf(dir) + await mkdirp(dir) fs.writeFileSync(dir + '/x', 'y') fs.utimesSync(dir + '/x', date, date) - cb() }) const data = makeTar([ @@ -1353,12 +1475,11 @@ t.test('skip newer', t => { t.test('no mtime', t => { const dir = path.join(unpackdir, 'skip-newer') - t.teardown(_ => rimraf.sync(dir)) + t.teardown(_ => rimraf(dir)) - t.beforeEach(cb => { - rimraf.sync(dir) - mkdirp.sync(dir) - cb() + t.beforeEach(async () => { + await rimraf(dir) + await mkdirp(dir) }) const date = new Date('2011-03-27T22:16:31.000Z') @@ -1419,7 +1540,7 @@ t.test('no mtime', t => { t.test('unpack big enough to pause/drain', t => { const dir = path.resolve(unpackdir, 'drain-clog') mkdirp.sync(dir) - t.tearDown(_ => rimraf.sync(dir)) + t.teardown(_ => rimraf(dir)) const stream = fs.createReadStream(fixtures + '/parses.tar') const u = new Unpack({ cwd: dir, @@ -1539,13 +1660,19 @@ t.test('set owner', t => { const dir = path.resolve(unpackdir, 'chown') const poop = new Error('expected chown failure') const un = mutateFS.fail('chown', poop) + const unl = mutateFS.fail('lchown', poop) const unf = mutateFS.fail('fchown', poop) - t.teardown(_ => (un(), unf())) + t.teardown(async () => { + un() + unf() + unl() + await rimraf(dir) + }) t.test('sync', t => { mkdirp.sync(dir) - t.teardown(_ => rimraf.sync(dir)) + t.teardown(_ => rimraf(dir)) let warned = false const u = new Unpack.Sync({ cwd: dir, @@ -1563,7 +1690,7 @@ t.test('set owner', t => { t.test('async', t => { mkdirp.sync(dir) - t.teardown(_ => rimraf.sync(dir)) + t.teardown(_ => rimraf(dir)) let warned = false const u = new Unpack({ cwd: dir, @@ -1579,11 +1706,6 @@ t.test('set owner', t => { u.end(data) }) - t.test('cleanup', t => { - rimraf.sync(dir) - t.end() - }) - t.end() }) @@ -1607,7 +1729,7 @@ t.test('set owner', t => { t.test('sync', t => { mkdirp.sync(dir) - t.teardown(_ => rimraf.sync(dir)) + t.teardown(_ => rimraf(dir)) called = 0 const u = new Unpack.Sync({ cwd: dir, preserveOwner: true }) u.end(data) @@ -1617,7 +1739,7 @@ t.test('set owner', t => { t.test('async', t => { mkdirp.sync(dir) - t.teardown(_ => rimraf.sync(dir)) + t.teardown(_ => rimraf(dir)) called = 0 const u = new Unpack({ cwd: dir, preserveOwner: true }) u.end(data) @@ -1635,14 +1757,16 @@ t.test('set owner', t => { const poop = new Error('poop') const un = mutateFS.fail('chown', poop) const unf = mutateFS.fail('fchown', poop) - t.teardown(_ => { - rimraf.sync(dir) + const unl = mutateFS.fail('lchown', poop) + t.teardown(async _ => { un() unf() + unl() + await rimraf(dir) }) - t.beforeEach(cb => mkdirp(dir, cb)) - t.afterEach(cb => rimraf(dir, cb)) + t.beforeEach(() => mkdirp(dir)) + t.afterEach(() => rimraf(dir)) const check = t => { const dirStat = fs.statSync(dir + '/foo') @@ -1694,11 +1818,11 @@ t.test('unpack when dir is not writable', t => { ]) const dir = path.resolve(unpackdir, 'nowrite-dir') - t.beforeEach(cb => mkdirp(dir, cb)) - t.afterEach(cb => rimraf(dir, cb)) + t.beforeEach(() => mkdirp(dir)) + t.afterEach(() => rimraf(dir)) const check = t => { - t.equal(fs.statSync(dir + '/a').mode & 0o7777, 0o744) + t.equal(fs.statSync(dir + '/a').mode & 0o7777, isWindows ? 0o666 : 0o744) t.equal(fs.readFileSync(dir + '/a/b', 'utf8'), 'a') t.end() } @@ -1731,8 +1855,8 @@ t.test('transmute chars on windows', t => { ]) const dir = path.resolve(unpackdir, 'winchars') - t.beforeEach(cb => mkdirp(dir, cb)) - t.afterEach(cb => rimraf(dir, cb)) + t.beforeEach(() => mkdirp(dir)) + t.afterEach(() => rimraf(dir)) const hex = 'ef80bcef81bcef80beef80bfef80ba2e747874' const uglyName = Buffer.from(hex, 'hex').toString() @@ -1767,8 +1891,17 @@ t.test('transmute chars on windows', t => { t.test('safely transmute chars on windows with absolutes', t => { // don't actually make the directory - const poop = new Error('poop') - t.teardown(mutateFS.fail('mkdir', poop)) + const fsMock = { + ...fs, + mkdir: (path, mode, cb) => process.nextTick(cb), + mkdirSync: (path) => {}, + } + const mkdirp = requireInject('mkdirp', { fs: fsMock }) + const Unpack = requireInject('../lib/unpack.js', { + fs: fsMock, + mkdirp, + '../lib/mkdir.js': requireInject('../lib/mkdir.js', { fs: fsMock, mkdirp }), + }) const data = makeTar([ { @@ -1791,8 +1924,11 @@ t.test('safely transmute chars on windows with absolutes', t => { }) u.on('entry', entry => { t.equal(entry.path, uglyPath) + entry.skipped = true + entry.resume() t.end() }) + u.on('error', () => {}) u.end(data) }) @@ -1812,10 +1948,10 @@ t.test('use explicit chmod when required by umask', t => { '' ]) - const check = t => { + const check = async t => { const st = fs.statSync(basedir + '/x/y/z') - t.equal(st.mode & 0o777, 0o775) - rimraf.sync(basedir) + t.equal(st.mode & 0o777, isWindows ? 0o666 : 0o775) + await rimraf(basedir) t.end() } @@ -1840,12 +1976,20 @@ t.test('chown implicit dirs and also the entries', t => { // club these so that the test can run as non-root const chown = fs.chown const chownSync = fs.chownSync + const lchown = fs.lchown + const lchownSync = fs.lchownSync + const fchown = fs.fchown + const fchownSync = fs.fchownSync const getuid = process.getuid const getgid = process.getgid t.teardown(_ => { fs.chown = chown fs.chownSync = chownSync + fs.lchown = lchown + fs.lchownSync = lchownSync + fs.fchown = fchown + fs.fchownSync = fchownSync process.getgid = getgid }) @@ -1858,12 +2002,16 @@ t.test('chown implicit dirs and also the entries', t => { chowns ++ cb() } + if (fs.lchown) + fs.lchown = fs.fchown fs.chownSync = fs.fchownSync = (path, uid, gid) => { currentTest.equal(uid, 420, 'chownSync(' + path + ') uid') currentTest.equal(gid, 666, 'chownSync(' + path + ') gid') chowns ++ } + if (fs.lchownSync) + fs.lchownSync = fs.fchownSync const data = makeTar([ { @@ -1888,11 +2036,11 @@ t.test('chown implicit dirs and also the entries', t => { '' ]) - const check = t => { + const check = async t => { currentTest = null - t.equal(chowns, 6) + t.equal(chowns, 8) chowns = 0 - rimraf.sync(basedir) + await rimraf(basedir) t.end() } @@ -1942,7 +2090,7 @@ t.test('chown implicit dirs and also the entries', t => { t.test('bad cwd setting', t => { const basedir = path.resolve(unpackdir, 'bad-cwd') mkdirp.sync(basedir) - t.teardown(_ => rimraf.sync(basedir)) + t.teardown(_ => rimraf(basedir)) const cases = [ // the cwd itself @@ -1984,17 +2132,17 @@ t.test('bad cwd setting', t => { t.throws(_ => new Unpack.Sync(opt).end(data), { name: 'CwdError', - message: 'ENOTDIR: Cannot cd into \'' + cwd + '\'', - path: cwd, - code: 'ENOTDIR' + message: 'ENOTDIR: Cannot cd into \'' + normPath(cwd) + '\'', + path: normPath(cwd), + code: 'ENOTDIR', }) new Unpack(opt).on('error', er => { t.match(er, { name: 'CwdError', - message: 'ENOTDIR: Cannot cd into \'' + cwd + '\'', - path: cwd, - code: 'ENOTDIR' + message: 'ENOTDIR: Cannot cd into \'' + normPath(cwd) + '\'', + path: normPath(cwd), + code: 'ENOTDIR', }) t.end() }).end(data) @@ -2006,17 +2154,17 @@ t.test('bad cwd setting', t => { t.throws(_ => new Unpack.Sync(opt).end(data), { name: 'CwdError', - message: 'ENOENT: Cannot cd into \'' + cwd + '\'', - path: cwd, - code: 'ENOENT' + message: 'ENOENT: Cannot cd into \'' + normPath(cwd) + '\'', + path: normPath(cwd), + code: 'ENOENT', }) new Unpack(opt).on('error', er => { t.match(er, { name: 'CwdError', - message: 'ENOENT: Cannot cd into \'' + cwd + '\'', - path: cwd, - code: 'ENOENT' + message: 'ENOENT: Cannot cd into \'' + normPath(cwd) + '\'', + path: normPath(cwd), + code: 'ENOENT', }) t.end() }).end(data) @@ -2028,7 +2176,7 @@ t.test('bad cwd setting', t => { t.test('transform', t => { const basedir = path.resolve(unpackdir, 'transform') - t.teardown(_ => rimraf.sync(basedir)) + t.teardown(_ => rimraf(basedir)) const cases = { 'emptypax.tar': { @@ -2076,10 +2224,9 @@ t.test('transform', t => { t.test(tarfile, t => { const tf = path.resolve(tars, tarfile) const dir = path.resolve(basedir, tarfile) - t.beforeEach(cb => { - rimraf.sync(dir) - mkdirp.sync(dir) - cb() + t.beforeEach(async () => { + await rimraf(dir) + await mkdirp(dir) }) const check = t => { @@ -2110,7 +2257,7 @@ t.test('transform', t => { t.test('sync unpack', t => { t.plan(2) t.test('strict', t => { - const unpack = new UnpackSync({ cwd: dir, transform: txFn }) + const unpack = new UnpackSync({ cwd: dir, strict: true, transform: txFn }) unpack.end(fs.readFileSync(tf)) check(t) }) @@ -2124,6 +2271,74 @@ t.test('transform', t => { }) }) +t.test('transform error', t => { + const dir = path.resolve(unpackdir, 'transform-error') + mkdirp.sync(dir) + t.teardown(_ => rimraf(dir)) + + const tarfile = path.resolve(tars, 'body-byte-counts.tar') + const tardata = fs.readFileSync(tarfile) + const poop = new Error('poop') + + const txFn = () => { + const tx = new MiniPass() + tx.write = () => tx.emit('error', poop) + tx.resume() + return tx + } + + t.test('sync unpack', t => { + t.test('strict', t => { + const unpack = new UnpackSync({ cwd: dir, strict: true, transform: txFn }) + const expect = 3 + let actual = 0 + unpack.on('error', er => { + t.equal(er, poop) + actual ++ + }) + unpack.end(tardata) + t.equal(actual, expect, 'error count') + t.end() + }) + t.test('loose', t => { + const unpack = new UnpackSync({ cwd: dir, transform: txFn }) + const expect = 3 + let actual = 0 + unpack.on('warn', (msg, er) => { + t.equal(er, poop) + actual ++ + }) + unpack.end(tardata) + t.equal(actual, expect, 'error count') + t.end() + }) + t.end() + }) + t.test('async unpack', t => { + // the last error is about the folder being deleted, just ignore that one + t.test('strict', t => { + const unpack = new Unpack({ cwd: dir, strict: true, transform: txFn }) + t.plan(3) + t.teardown(() => { + unpack.removeAllListeners('error') + unpack.on('error', () => {}) + }) + unpack.on('error', er => t.equal(er, poop)) + unpack.end(tardata) + }) + t.test('loose', t => { + const unpack = new Unpack({ cwd: dir, transform: txFn }) + t.plan(3) + t.teardown(() => unpack.removeAllListeners('warn')) + unpack.on('warn', (msg, er) => t.equal(er, poop)) + unpack.end(tardata) + }) + t.end() + }) + + t.end() +}) + t.test('futimes/fchown failures', t => { const archive = path.resolve(tars, 'utf8.tar') const dir = path.resolve(unpackdir, 'futimes-fchown-fails') @@ -2132,13 +2347,12 @@ t.test('futimes/fchown failures', t => { const poop = new Error('poop') const second = new Error('second error') - const reset = cb => { - rimraf.sync(dir) - mkdirp.sync(dir) - } + t.beforeEach(async () => { + await rimraf(dir) + await mkdirp(dir) + }) - reset() - t.teardown(() => rimraf.sync(dir)) + t.teardown(() => rimraf(dir)) const methods = ['utimes', 'chown'] methods.forEach(method => { @@ -2153,13 +2367,11 @@ t.test('futimes/fchown failures', t => { t.test('async unpack', t => { t.plan(2) t.test('strict', t => { - reset() const unpack = new Unpack({ cwd: dir, strict: true, forceChown: fc }) unpack.on('finish', t.end) unpack.end(tardata) }) t.test('loose', t => { - reset() const unpack = new Unpack({ cwd: dir, forceChown: fc }) unpack.on('finish', t.end) unpack.on('warn', t.fail) @@ -2169,13 +2381,11 @@ t.test('futimes/fchown failures', t => { t.test('sync unpack', t => { t.plan(2) t.test('strict', t => { - reset() const unpack = new Unpack.Sync({ cwd: dir, strict: true, forceChown: fc }) unpack.end(tardata) t.end() }) t.test('loose', t => { - reset() const unpack = new Unpack.Sync({ cwd: dir, forceChown: fc }) unpack.on('warn', t.fail) unpack.end(tardata) @@ -2195,14 +2405,12 @@ t.test('futimes/fchown failures', t => { t.test('async unpack', t => { t.plan(2) t.test('strict', t => { - reset() const unpack = new Unpack({ cwd: dir, strict: true, forceChown: fc }) t.plan(3) unpack.on('error', er => t.equal(er, poop)) unpack.end(tardata) }) t.test('loose', t => { - reset() const unpack = new Unpack({ cwd: dir, forceChown: fc }) t.plan(3) unpack.on('warn', (m, er) => t.equal(er, poop)) @@ -2212,14 +2420,12 @@ t.test('futimes/fchown failures', t => { t.test('sync unpack', t => { t.plan(2) t.test('strict', t => { - reset() const unpack = new Unpack.Sync({ cwd: dir, strict: true, forceChown: fc }) t.plan(3) unpack.on('error', er => t.equal(er, poop)) unpack.end(tardata) }) t.test('loose', t => { - reset() const unpack = new Unpack.Sync({ cwd: dir, forceChown: fc }) t.plan(3) unpack.on('warn', (m, er) => t.equal(er, poop)) @@ -2235,7 +2441,7 @@ t.test('futimes/fchown failures', t => { t.test('onentry option is preserved', t => { const basedir = path.resolve(unpackdir, 'onentry-method') mkdirp.sync(basedir) - t.teardown(() => rimraf.sync(basedir)) + t.teardown(() => rimraf(basedir)) let oecalls = 0 const onentry = entry => oecalls++ @@ -2290,7 +2496,7 @@ t.test('onentry option is preserved', t => { t.test('do not reuse hardlinks, only nlink=1 files', t => { const basedir = path.resolve(unpackdir, 'hardlink-reuse') mkdirp.sync(basedir) - t.teardown(() => rimraf.sync(basedir)) + t.teardown(() => rimraf(basedir)) const now = new Date('2018-04-30T18:30:39.025Z') @@ -2349,3 +2555,287 @@ t.test('do not reuse hardlinks, only nlink=1 files', t => { t.end() }) + +t.test('trying to unpack a javascript file should fail', t => { + const data = fs.readFileSync(__filename) + const dataGzip = Buffer.concat([Buffer.from([0x1f, 0x8b]), data]) + const basedir = path.resolve(unpackdir, 'bad-archive') + t.test('abort if gzip has an error', t => { + t.plan(2) + const expect = { + message: /^zlib/, + errno: Number, + code: /^Z/, + } + const opts = { + cwd: basedir, + gzip: true, + } + new Unpack(opts) + .once('error', er => t.match(er, expect, 'async emits')) + .on('error', () => { /* zlib emits a few times here */ }) + .end(dataGzip) + const skip = !/^v([0-9]|1[0-4])\./.test(process.version) ? false + : 'node prior to v14 did not raise sync zlib errors properly' + t.test('sync throws', { skip }, t => { + t.plan(1) + t.throws(() => new UnpackSync(opts).end(dataGzip), expect, 'sync throws') + }) + }) + + t.end() +}) + +t.test('drop entry from dirCache if no longer a directory', { + skip: isWindows && 'symlinks not fully supported', +}, t => { + const dir = path.resolve(unpackdir, 'dir-cache-error') + mkdirp.sync(dir + '/sync/y') + mkdirp.sync(dir + '/async/y') + const data = makeTar([ + { + path: 'x', + type: 'Directory', + }, + { + path: 'x', + type: 'SymbolicLink', + linkpath: './y', + }, + { + path: 'x/ginkoid', + type: 'File', + size: 'ginkoid'.length, + }, + 'ginkoid', + '', + '', + ]) + t.plan(2) + const WARNINGS = {} + const check = (t, path) => { + t.equal(fs.statSync(path + '/x').isDirectory(), true) + t.equal(fs.lstatSync(path + '/x').isSymbolicLink(), true) + t.equal(fs.statSync(path + '/y').isDirectory(), true) + t.strictSame(fs.readdirSync(path + '/y'), []) + t.throws(() => fs.readFileSync(path + '/x/ginkoid'), { code: 'ENOENT' }) + t.strictSame(WARNINGS[path], [ + 'Cannot extract through symbolic link', + ]) + t.end() + } + t.test('async', t => { + const path = dir + '/async' + new Unpack({ cwd: path }) + .on('warn', (msg) => WARNINGS[path] = [msg]) + .on('end', () => check(t, path)) + .end(data) + }) + t.test('sync', t => { + const path = dir + '/sync' + new UnpackSync({ cwd: path }) + .on('warn', (msg) => WARNINGS[path] = [msg]) + .end(data) + check(t, path) + }) +}) + +t.test('using strip option when top level file exists', t => { + const dir = path.resolve(unpackdir, 'strip-with-top-file') + mkdirp.sync(dir + '/sync/y') + mkdirp.sync(dir + '/async/y') + const data = makeTar([ + { + path: 'top', + type: 'File', + size: 0, + }, + { + path: 'x', + type: 'Directory', + }, + { + path: 'x/a', + type: 'File', + size: 'a'.length, + }, + 'a', + { + path: 'y', + type: 'GNUDumpDir', + }, + { + path: 'y/b', + type: 'File', + size: 'b'.length, + }, + 'b', + '', + '', + ]) + t.plan(2) + const check = (t, path) => { + t.equal(fs.statSync(path).isDirectory(), true) + t.equal(fs.readFileSync(path + '/a', 'utf8'), 'a') + t.equal(fs.readFileSync(path + '/b', 'utf8'), 'b') + t.throws(() => fs.statSync(path + '/top'), { code: 'ENOENT' }) + t.end() + } + t.test('async', t => { + const path = dir + '/async' + new Unpack({ cwd: path, strip: 1 }) + .on('end', () => check(t, path)) + .end(data) + }) + t.test('sync', t => { + const path = dir + '/sync' + new UnpackSync({ cwd: path, strip: 1 }).end(data) + check(t, path) + }) +}) + +t.test('dirCache pruning unicode normalized collisions', { + skip: isWindows && 'symlinks not fully supported', +}, t => { + const data = makeTar([ + { + type: 'Directory', + path: 'foo', + }, + { + type: 'File', + path: 'foo/bar', + size: 1, + }, + 'x', + { + type: 'Directory', + // café + path: Buffer.from([0x63, 0x61, 0x66, 0xc3, 0xa9]).toString(), + }, + { + type: 'SymbolicLink', + // cafe with a ` + path: Buffer.from([0x63, 0x61, 0x66, 0x65, 0xcc, 0x81]).toString(), + linkpath: 'foo', + }, + { + type: 'Directory', + path: 'foo', + }, + { + type: 'File', + path: Buffer.from([0x63, 0x61, 0x66, 0xc3, 0xa9]).toString() + '/bar', + size: 1, + }, + 'y', + '', + '', + ]) + + const check = (path, dirCache, t) => { + path = path.replace(/\\/g, '/') + t.strictSame([...dirCache.entries()], [ + [`${path}/foo`, true], + ]) + t.equal(fs.readFileSync(path + '/foo/bar', 'utf8'), 'x') + t.end() + } + + t.test('sync', t => { + const path = t.testdir() + const dirCache = new Map() + new UnpackSync({ cwd: path, dirCache }).end(data) + check(path, dirCache, t) + }) + t.test('async', t => { + const path = t.testdir() + const dirCache = new Map() + new Unpack({ cwd: path, dirCache }) + .on('close', () => check(path, dirCache, t)) + .end(data) + }) + + t.end() +}) + +t.test('dircache prune all on windows when symlink encountered', t => { + if (process.platform !== 'win32') { + process.env.TESTING_TAR_FAKE_PLATFORM = 'win32' + t.teardown(() => { + delete process.env.TESTING_TAR_FAKE_PLATFORM + }) + } + const symlinks = [] + const Unpack = requireInject('../lib/unpack.js', { + fs: { + ...fs, + symlink: (target, dest, cb) => { + symlinks.push(['async', target, dest]) + process.nextTick(cb) + }, + symlinkSync: (target, dest) => symlinks.push(['sync', target, dest]), + }, + }) + const UnpackSync = Unpack.Sync + + const data = makeTar([ + { + type: 'Directory', + path: 'foo', + }, + { + type: 'File', + path: 'foo/bar', + size: 1, + }, + 'x', + { + type: 'Directory', + // café + path: Buffer.from([0x63, 0x61, 0x66, 0xc3, 0xa9]).toString(), + }, + { + type: 'SymbolicLink', + // cafe with a ` + path: Buffer.from([0x63, 0x61, 0x66, 0x65, 0xcc, 0x81]).toString(), + linkpath: 'safe/actually/but/cannot/be/too/careful', + }, + { + type: 'File', + path: 'bar/baz', + size: 1, + }, + 'z', + '', + '', + ]) + + const check = (path, dirCache, t) => { + // symlink blew away all dirCache entries before it + path = path.replace(/\\/g, '/') + t.strictSame([...dirCache.entries()], [ + [`${path}/bar`, true], + ]) + t.equal(fs.readFileSync(`${path}/foo/bar`, 'utf8'), 'x') + t.equal(fs.readFileSync(`${path}/bar/baz`, 'utf8'), 'z') + t.end() + } + + t.test('sync', t => { + const path = t.testdir() + const dirCache = new Map() + new UnpackSync({ cwd: path, dirCache }).end(data) + check(path, dirCache, t) + }) + + t.test('async', t => { + const path = t.testdir() + const dirCache = new Map() + new Unpack({ cwd: path, dirCache }) + .on('close', () => check(path, dirCache, t)) + .end(data) + }) + + t.end() +}) diff --git a/test/update.js b/test/update.js index 0d3394f7..70e9b8e1 100644 --- a/test/update.js +++ b/test/update.js @@ -4,58 +4,28 @@ const t = require('tap') const u = require('../lib/update.js') const path = require('path') const fs = require('fs') -const mkdirp = require('mkdirp') -const rimraf = require('rimraf') const mutateFS = require('mutate-fs') +const {resolve} = require('path') const fixtures = path.resolve(__dirname, 'fixtures') -const dir = path.resolve(fixtures, 'update') const tars = path.resolve(fixtures, 'tars') -const file = dir + '/body-byte-counts.tar' -const fileNoNulls = dir + '/no-null-eof.tar' -const fileTruncHead = dir + '/truncated-head.tar' -const fileTruncBody = dir + '/truncated-body.tar' -const fileNonExistent = dir + '/does-not-exist.tar' -const fileZeroByte = dir + '/zero.tar' -const fileEmpty = dir + '/empty.tar' -const fileCompressed = dir + '/compressed.tgz' const zlib = require('zlib') const spawn = require('child_process').spawn -t.teardown(_ => rimraf.sync(dir)) - -const reset = cb => { - rimraf.sync(dir) - mkdirp.sync(dir) - const data = fs.readFileSync(tars + '/body-byte-counts.tar') - fs.writeFileSync(file, data) - - const dataNoNulls = data.slice(0, data.length - 1024) - fs.writeFileSync(fileNoNulls, dataNoNulls) - - const dataTruncHead = Buffer.concat([dataNoNulls, data.slice(0, 500)]) - fs.writeFileSync(fileTruncHead, dataTruncHead) - - const dataTruncBody = Buffer.concat([dataNoNulls, data.slice(0, 700)]) - fs.writeFileSync(fileTruncBody, dataTruncBody) - - fs.writeFileSync(fileZeroByte, '') - fs.writeFileSync(fileEmpty, Buffer.alloc(1024)) - - fs.writeFileSync(fileCompressed, zlib.gzipSync(data)) - - if (cb) - cb() +const data = fs.readFileSync(tars + '/body-byte-counts.tar') +const dataNoNulls = data.slice(0, data.length - 1024) +const fixtureDef = { + 'body-byte-counts.tar': data, + 'no-null-eof.tar': dataNoNulls, + 'truncated-head.tar': Buffer.concat([dataNoNulls, data.slice(0, 500)]), + 'truncated-body.tar': Buffer.concat([dataNoNulls, data.slice(0, 700)]), + 'zero.tar': Buffer.from(''), + 'empty.tar': Buffer.alloc(512), + 'compressed.tgz': zlib.gzipSync(data), } -t.test('setup', t => { - reset(t.end) -}) - t.test('basic file add to archive (good or truncated)', t => { - t.beforeEach(reset) - const check = (file, t) => { const c = spawn('tar', ['tf', file]) const out = [] @@ -63,7 +33,7 @@ t.test('basic file add to archive (good or truncated)', t => { c.on('close', (code, signal) => { t.equal(code, 0) t.equal(signal, null) - const actual = Buffer.concat(out).toString().trim().split('\n') + const actual = Buffer.concat(out).toString().trim().split(/\r?\n/) t.same(actual, [ '1024-bytes.txt', '512-bytes.txt', @@ -75,50 +45,68 @@ t.test('basic file add to archive (good or truncated)', t => { }) } - ;[file, - fileNoNulls, - fileTruncHead, - fileTruncBody - ].forEach(file => { - t.test(path.basename(file), t => { - const fileList = [path.basename(__filename)] - t.test('sync', t => { + const files = [ + 'body-byte-counts.tar', + 'no-null-eof.tar', + 'truncated-head.tar', + 'truncated-body.tar', + ] + const td = files.map(f => [f, fixtureDef[f]]).reduce((s, [k, v]) => { + s[k] = v + return s + }, {}) + const fileList = [path.basename(__filename)] + t.test('sync', t => { + t.plan(files.length) + const dir = t.testdir(td) + for (const file of files) { + t.test(file, t => { u({ sync: true, - file: file, - cwd: __dirname + file: resolve(dir, file), + cwd: __dirname, }, fileList) - check(file, t) + check(resolve(dir, file), t) }) + } + }) - t.test('async cb', t => { + t.test('async cb', t => { + t.plan(files.length) + const dir = t.testdir(td) + for (const file of files) { + t.test(file, t => { u({ - file: file, - cwd: __dirname + file: resolve(dir, file), + cwd: __dirname, }, fileList, er => { if (er) throw er - check(file, t) + check(resolve(dir, file), t) }) }) + } + }) - t.test('async promise', t => { + t.test('async', t => { + t.plan(files.length) + const dir = t.testdir(td) + for (const file of files) { + t.test(file, t => { u({ - file: file, - cwd: __dirname - }, fileList).then(_ => check(file, t)) + file: resolve(dir, file), + cwd: __dirname, + }, fileList).then(() => { + check(resolve(dir, file), t) + }) }) - - t.end() - }) + } }) t.end() }) t.test('add to empty archive', t => { - t.beforeEach(reset) - const check = (file, t) => { const c = spawn('tar', ['tf', file]) const out = [] @@ -126,7 +114,7 @@ t.test('add to empty archive', t => { c.on('close', (code, signal) => { t.equal(code, 0) t.equal(signal, null) - const actual = Buffer.concat(out).toString().trim().split('\n') + const actual = Buffer.concat(out).toString().trim().split(/\r?\n/) t.same(actual, [ path.basename(__filename) ]) @@ -134,66 +122,89 @@ t.test('add to empty archive', t => { }) } - ;[fileNonExistent, - fileEmpty, - fileZeroByte - ].forEach(file => { - t.test(path.basename(file), t => { - const fileList = [path.basename(__filename)] - t.test('sync', t => { + const files = [ + 'empty.tar', + 'zero.tar', + ] + const td = files.map(f => [f, fixtureDef[f]]).reduce((s, [k, v]) => { + s[k] = v + return s + }, {}) + files.push('not-existing.tar') + + t.test('sync', t => { + const dir = t.testdir(td) + t.plan(files.length) + for (const file of files) { + t.test(file, t => { u({ sync: true, - file: file, - cwd: __dirname - }, fileList) - check(file, t) + file: resolve(dir, file), + cwd: __dirname, + }, [path.basename(__filename)]) + check(resolve(dir, file), t) }) + } + }) - t.test('async cb', t => { + t.test('async cb', t => { + const dir = t.testdir(td) + t.plan(files.length) + for (const file of files) { + t.test(file, t => { u({ - file: file, - cwd: __dirname - }, fileList, er => { + file: resolve(dir, file), + cwd: __dirname, + }, [path.basename(__filename)], er => { if (er) throw er - check(file, t) + check(resolve(dir, file), t) }) }) + } + }) - t.test('async promise', t => { + t.test('async', async t => { + const dir = t.testdir(td) + t.plan(files.length) + for (const file of files) { + t.test(file, t => { u({ - file: file, - cwd: __dirname - }, fileList).then(_ => check(file, t)) + file: resolve(dir, file), + cwd: __dirname, + }, [path.basename(__filename)]).then(() => { + check(resolve(dir, file), t) + }) }) - - t.end() - }) + } }) t.end() }) t.test('cannot append to gzipped archives', t => { - reset() + const dir = t.testdir({ + 'compressed.tgz': fixtureDef['compressed.tgz'], + }) + const file = resolve(dir, 'compressed.tgz') const expect = new Error('cannot append to compressed archives') const expectT = new TypeError('cannot append to compressed archives') t.throws(_ => u({ - file: fileCompressed, + file, cwd: __dirname, gzip: true }, [path.basename(__filename)]), expectT) t.throws(_ => u({ - file: fileCompressed, + file, cwd: __dirname, sync: true }, [path.basename(__filename)]), expect) u({ - file: fileCompressed, + file, cwd: __dirname, }, [path.basename(__filename)], er => { t.match(er, expect) @@ -209,88 +220,150 @@ t.test('other throws', t => { }) t.test('broken open', t => { + const dir = t.testdir({ + 'body-byte-counts.tar': fixtureDef['body-byte-counts.tar'], + }) + const file = resolve(dir, 'body-byte-counts.tar') const poop = new Error('poop') t.teardown(mutateFS.fail('open', poop)) t.throws(_ => u({ sync: true, file: file }, ['README.md']), poop) - u({ file: file }, ['README.md'], er => { + u({ file }, ['README.md'], er => { t.match(er, poop) t.end() }) }) t.test('broken fstat', t => { + const td = { + 'body-byte-counts.tar': fixtureDef['body-byte-counts.tar'], + } const poop = new Error('poop') - t.teardown(mutateFS.fail('fstat', poop)) - t.throws(_ => u({ sync: true, file: file }, ['README.md']), poop) - u({ file: file }, ['README.md'], er => { - t.match(er, poop) + t.test('sync', t => { + const dir = t.testdir(td) + const file = resolve(dir, 'body-byte-counts.tar') + t.teardown(mutateFS.fail('fstat', poop)) + t.throws(_ => u({ sync: true, file }, ['README.md']), poop) t.end() }) + t.test('async', t => { + const dir = t.testdir(td) + const file = resolve(dir, 'body-byte-counts.tar') + t.teardown(mutateFS.fail('fstat', poop)) + u({ file }, ['README.md'], async er => { + t.match(er, poop) + t.end() + }) + }) + t.end() }) t.test('broken read', t => { + const dir = t.testdir({ + 'body-byte-counts.tar': fixtureDef['body-byte-counts.tar'], + }) + const file = resolve(dir, 'body-byte-counts.tar') const poop = new Error('poop') t.teardown(mutateFS.fail('read', poop)) - t.throws(_ => u({ sync: true, file: file }, ['README.md']), poop) - u({ file: file }, ['README.md'], er => { + t.throws(_ => u({ sync: true, file }, ['README.md']), poop) + u({ file }, ['README.md'], er => { t.match(er, poop) t.end() }) }) t.test('do not add older file', t => { - reset() + const dir = t.testdir({ + 'body-byte-counts.tar': fixtureDef['body-byte-counts.tar'], + '1024-bytes.txt': '.'.repeat(1024), + foo: 'foo', + }) + const file = resolve(dir, 'body-byte-counts.tar') - const f = dir + '/1024-bytes.txt' - fs.writeFileSync(f, new Array(1025).join('.')) + const f = resolve(dir, '1024-bytes.txt') const oldDate = new Date('1997-04-10T16:57:47.000Z') fs.utimesSync(f, oldDate, oldDate) + // file size should not change + const expect = fixtureDef['body-byte-counts.tar'].length const check = t => { - t.equal(fs.statSync(file).size, 5120) + t.equal(fs.statSync(file).size, expect) t.end() } t.test('sync', t => { - u({ file: file, cwd: dir, sync: true }, ['1024-bytes.txt']) + u({ + mtimeCache: new Map(), + file, + cwd: dir, + sync: true, + filter: path => path === '1024-bytes.txt', + }, ['1024-bytes.txt', 'foo']) check(t) }) t.test('async', t => { - u({ file: file, cwd: dir }, ['1024-bytes.txt']).then(_ => check(t)) + u({ file, cwd: dir }, ['1024-bytes.txt']).then(_ => check(t)) + }) + + t.test('async cb', t => { + u({ file, cwd: dir }, ['1024-bytes.txt'], er => { + if (er) + throw er + check(t) + }) }) t.end() }) t.test('do add newer file', t => { - t.beforeEach(cb => { - reset() - const f = dir + '/1024-bytes.txt' - fs.writeFileSync(f, new Array(1025).join('.')) - const newDate = new Date('2017-05-01T22:06:43.736Z') + const setup = t => { + const dir = t.testdir({ + 'body-byte-counts.tar': fixtureDef['body-byte-counts.tar'], + '1024-bytes.txt': '.'.repeat(1024), + foo: 'foo', + }) + + const f = resolve(dir, '1024-bytes.txt') + const newDate = new Date(Date.now() + 24 * 60 * 60 * 1000) fs.utimesSync(f, newDate, newDate) - cb() - }) + return dir + } - const check = t => { - t.equal(fs.statSync(file).size, 6656) + // a chunk for the header, then 2 for the body + const expect = fixtureDef['body-byte-counts.tar'].length + 512 + 1024 + const check = (file, t) => { + t.equal(fs.statSync(file).size, expect) t.end() } t.test('sync', t => { + const dir = setup(t) + const file = resolve(dir, 'body-byte-counts.tar') u({ mtimeCache: new Map(), - file: file, + file, cwd: dir, sync: true, - filter: path => path === '1024-bytes.txt' - }, ['1024-bytes.txt', 'compressed.tgz']) - check(t) + filter: path => path === '1024-bytes.txt', + }, ['1024-bytes.txt', 'foo']) + check(file, t) }) t.test('async', t => { - u({ file: file, cwd: dir }, ['1024-bytes.txt']).then(_ => check(t)) + const dir = setup(t) + const file = resolve(dir, 'body-byte-counts.tar') + u({ file, cwd: dir }, ['1024-bytes.txt']).then(_ => check(file, t)) + }) + + t.test('async cb', t => { + const dir = setup(t) + const file = resolve(dir, 'body-byte-counts.tar') + u({ file, cwd: dir }, ['1024-bytes.txt'], er => { + if (er) + throw er + check(file, t) + }) }) t.end() diff --git a/test/write-entry.js b/test/write-entry.js index fa7933e1..ac8cf862 100644 --- a/test/write-entry.js +++ b/test/write-entry.js @@ -1,9 +1,22 @@ 'use strict' const t = require('tap') + +// make our tests verify that windows link targets get turned into / paths +const fs = require('fs') +const {readlink, readlinkSync} = fs +fs.readlink = (path, cb) => { + readlink(path, (er, path) => { + if (er) + return cb(er) + else + cb(null, path.replace(/\//g, '\\')) + }) +} +fs.readlinkSync = path => readlinkSync(path).replace(/\//g, '\\') + const ReadEntry = require('../lib/read-entry.js') const makeTar = require('./make-tar.js') const WriteEntry = require('../lib/write-entry.js') -const fs = require('fs') const path = require('path') const fixtures = path.resolve(__dirname, 'fixtures') const files = path.resolve(fixtures, 'files') @@ -15,6 +28,7 @@ const Parser = require('../lib/parse.js') const rimraf = require('rimraf') const mkdirp = require('mkdirp') const isWindows = process.platform === 'win32' +const normPath = require('../lib/normalize-windows-path.js') t.test('set up', t => { const one = fs.statSync(files + '/hardlink-1') @@ -23,7 +37,7 @@ t.test('set up', t => { fs.unlinkSync(files + '/hardlink-2') fs.linkSync(files + '/hardlink-1', files + '/hardlink-2') } - chmodr.sync(files, 0o644) + chmodr.sync(files, isWindows ? 0o666 : 0o644) t.end() }) @@ -50,7 +64,7 @@ t.test('100 byte filename', t => { cksumValid: true, needPax: false, path: '100-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc', - mode: 0o644, + mode: isWindows ? 0o666 : 0o644, size: 100, linkpath: null, uname: 'isaacs', @@ -78,7 +92,7 @@ t.test('100 byte filename', t => { cksumValid: true, needPax: false, path: '100-byte-filename-cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc', - mode: 0o644, + mode: isWindows ? 0o666 : 0o644, size: 100, linkpath: '', uname: 'isaacs', @@ -126,7 +140,7 @@ t.test('directory', t => { cksumValid: true, needPax: false, path: 'dir/', - mode: 0o755, + mode: isWindows ? 0o777 : 0o755, size: 0, linkpath: null, uname: 'isaacs', @@ -142,7 +156,7 @@ t.test('directory', t => { cksumValid: true, needPax: false, path: 'dir/', - mode: 0o755, + mode: isWindows ? 0o777 : 0o755, size: 0, linkpath: null, uname: 'isaacs', @@ -166,7 +180,7 @@ t.test('empty path for cwd', t => { cksumValid: true, needPax: false, path: './', - mode: fs.statSync('./').mode & 0o7777, + mode: isWindows ? 0o777 : fs.statSync('./').mode & 0o7777, size: 0, linkpath: null, uname: 'isaacs', @@ -178,7 +192,9 @@ t.test('empty path for cwd', t => { }) }) -t.test('symlink', t => { +t.test('symlink', { + skip: isWindows && 'symlinks not fully supported', +}, t => { const ws = new WriteEntry('symlink', { cwd: files }) let out = [] ws.on('data', c => out.push(c)) @@ -217,7 +233,7 @@ t.test('zero-byte file', t => { path: 'files/zero-byte.txt', cksumValid: true, needPax: false, - mode: 0o644, + mode: isWindows ? 0o666 : 0o644, size: 0, linkpath: null, uname: 'isaacs', @@ -229,6 +245,22 @@ t.test('zero-byte file', t => { }) }) +t.test('zero-byte file, but close fails', t => { + const poop = new Error('poop') + t.tearDown(mutateFS.fail('close', poop)) + + const ws = new WriteEntry('files/1024-bytes.txt', { cwd: fixtures }) + + ws.on('end', _ => + t.fail('should not get an end, because the close fails')) + + ws.on('error', er => { + t.match(er, { message: 'poop' }) + t.end() + }) + ws.resume() +}) + t.test('hardlinks', t => { const h1 = 'hardlink-1' const h2 = 'hardlink-2' @@ -253,7 +285,7 @@ t.test('hardlinks', t => { path: 'files/hardlink-2', cksumValid: true, needPax: false, - mode: 0o644, + mode: isWindows ? 0o666 : 0o644, size: 0, linkpath: 'files/hardlink-1', uname: 'isaacs', @@ -285,7 +317,7 @@ t.test('hardlinks far away', t => { path: 'files/hardlink-2', cksumValid: true, needPax: false, - mode: 0o644, + mode: isWindows ? 0o666 : 0o644, size: 26, linkpath: null, uname: 'isaacs', @@ -309,7 +341,7 @@ t.test('really deep path', t => { cksumValid: true, needPax: true, path: 'long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc', - mode: 0o644, + mode: isWindows ? 0o666 : 0o644, size: 100, linkpath: null, uname: 'isaacs', @@ -334,7 +366,7 @@ t.test('no pax', t => { cksumValid: true, needPax: true, path: 'long-path/r/e/a/l/l/y/-/d/e/e/p/-/f/o/l/d/e/r/-/p/a/t/h/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxcccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc', - mode: 0o644, + mode: isWindows ? 0o666 : 0o644, size: 100, linkpath: null, uname: 'isaacs', @@ -362,10 +394,15 @@ t.test('nonexistent file', t => { }) t.test('absolute path', t => { - const f = path.resolve(files, '512-bytes.txt') + const absolute = path.resolve(files, '512-bytes.txt') + const { root } = path.parse(absolute) + const f = root + root + root + absolute + const warn = normPath(isWindows ? root : root + root + root + root) t.test('preservePaths=false strict=false', t => { const warnings = [] - const ws = new WriteEntry(f, { + // on windows, c:\c:\c:\... is a valid path, so just use the + // single-root absolute version of it. + const ws = new WriteEntry(isWindows ? absolute : f, { cwd: files, onwarn: (m, p) => warnings.push([m, p]) }) @@ -375,14 +412,15 @@ t.test('absolute path', t => { out = Buffer.concat(out) t.equal(out.length, 1024) t.match(warnings, [[ - /stripping .* from absolute path/, f + `stripping ${warn} from absolute path`, + normPath(isWindows ? absolute : f), ]]) t.match(ws.header, { cksumValid: true, needPax: false, - path: f.replace(/^(\/|[a-z]:\\\\)/, ''), - mode: 0o644, + path: normPath(absolute.replace(/^(\/|[a-z]:[/\\])*/i, '')), + mode: isWindows ? 0o666 : 0o644, size: 512, linkpath: null, uname: 'isaacs', @@ -401,7 +439,7 @@ t.test('absolute path', t => { t.test('strict=' + strict, t => { const warnings = [] - const ws = new WriteEntry(f, { + const ws = new WriteEntry(isWindows ? absolute : f, { cwd: files, strict: strict, preservePaths: true, @@ -416,8 +454,8 @@ t.test('absolute path', t => { t.match(ws.header, { cksumValid: true, needPax: false, - path: f, - mode: 0o644, + path: normPath(isWindows ? absolute : f), + mode: isWindows ? 0o666 : 0o644, size: 512, linkpath: null, uname: 'isaacs', @@ -433,11 +471,13 @@ t.test('absolute path', t => { t.test('preservePaths=false strict=true', t => { t.throws(_ => { - new WriteEntry(f, { + new WriteEntry(isWindows ? absolute : f, { strict: true, cwd: files }) - }, { message: /stripping .* from absolute path/, data: f }) + }, { + message: /stripping .* from absolute path/ + }) t.end() }) @@ -458,7 +498,7 @@ t.test('no user environ, sets uname to empty string', t => { cksumValid: true, needPax: false, path: '512-bytes.txt', - mode: 0o644, + mode: isWindows ? 0o666 : 0o644, size: 512, uname: '', linkpath: null, @@ -497,17 +537,17 @@ t.test('an unsuppored type', { t.test('readlink fail', t => { const expect = { - message: 'EINVAL: invalid argument, readlink \'' + __filename + '\'', - code: 'EINVAL', syscall: 'readlink', - path: __filename + path: String, } // pretend everything is a symbolic link, then read something that isn't - t.tearDown(mutateFS.statType('SymbolicLink')) - t.throws(_ => new WriteEntry.Sync('write-entry.js', { cwd: __dirname }), - expect) + t.teardown(mutateFS.statType('SymbolicLink')) + t.throws(_ => { + return new WriteEntry.Sync('write-entry.js', { cwd: __dirname }) + }, expect) new WriteEntry('write-entry.js', { cwd: __dirname }).on('error', er => { t.match(er, expect) + t.equal(normPath(er.path), normPath(__filename)) t.end() }) }) @@ -528,10 +568,16 @@ t.test('read fail', t => { code: 'EISDIR', syscall: 'read' } - // pretend everything is a symbolic link, then read something that isn't - t.tearDown(mutateFS.statType('File')) - t.throws(_ => new WriteEntry.Sync('fixtures', { cwd: __dirname }), - expect) + // pretend everything is a file, then read something that isn't + t.teardown(mutateFS.statMutate((er, st) => { + if (er) + return [er, st] + st.isFile = () => true + st.size = 123 + })) + t.throws(_ => new WriteEntry.Sync('fixtures', { + cwd: __dirname, + }), expect) new WriteEntry('fixtures', { cwd: __dirname }).on('error', er => { t.match(er, expect) t.end() @@ -541,8 +587,8 @@ t.test('read fail', t => { t.test('read invalid EOF', t => { t.tearDown(mutateFS.mutate('read', (er, br) => [er, 0])) const expect = { - message: 'unexpected EOF', - path: __filename, + message: 'encountered unexpected EOF', + path: normPath(__filename), syscall: 'read', code: 'EOF' } @@ -554,6 +600,25 @@ t.test('read invalid EOF', t => { }) }) +t.test('read overflow expectation', t => { + t.tearDown(mutateFS.statMutate((er, st) => { + if (st) + st.size = 3 + })); + const f = '512-bytes.txt' + const expect = { + message: 'did not encounter expected EOF', + path: normPath(path.resolve(files, f)), + syscall: 'read', + code: 'EOF' + } + t.throws(_ => new WriteEntry.Sync(f, { cwd: files, maxReadSize: 2 }), expect) + new WriteEntry(f, { cwd: files, maxReadSize: 2 }).on('error', er => { + t.match(er, expect) + t.end() + }).resume() +}) + t.test('short reads', t => { t.tearDown(mutateFS.zenoRead()) const cases = { @@ -881,13 +946,27 @@ t.test('portable dir entries, no mtime', t => { }) }) +t.test('writing more data than is appropriate', t => { + const path = t.testdir({ + file: 'hello', + }) + const wss = new WriteEntry(`${path}/file`) + wss.on('error', er => { + t.match(er, { + message: 'writing more data than expected', + }) + t.end() + }) + wss.on('stat', () => wss.write(Buffer.from('some more stuff'))) +}) + t.test('write entry from read entry', t => { const data = makeTar([ { path: '$', type: 'File', size: 10, - mode: 0o755, + mode: isWindows ? 0o777 : 0o755, uid: 123, gid: 321, ctime: new Date('1979-07-01'), @@ -928,7 +1007,7 @@ t.test('write entry from read entry', t => { path: '$', type: 'Directory', size: 0, - mode: 0o755, + mode: isWindows ? 0o777 : 0o755, uid: 123, gid: 321, ctime: new Date('1979-07-01'), @@ -1095,3 +1174,530 @@ t.test('write entry from read entry', t => { t.end() }) + +// https://github.com/npm/node-tar/issues/284 +t.test('prefix and hard links', t => { + const dir = path.resolve(fixtures, 'writeentry-prefix-hardlinks') + rimraf.sync(dir) + t.teardown(_ => rimraf.sync(dir)) + mkdirp.sync(dir + '/in/z/b/c') + fs.writeFileSync(dir + '/in/target', 'ddd') + fs.linkSync(dir + '/in/target', dir + '/in/z/b/c/d') + fs.linkSync(dir + '/in/target', dir + '/in/z/b/d') + fs.linkSync(dir + '/in/target', dir + '/in/z/d') + fs.linkSync(dir + '/in/target', dir + '/in/y') + const long = 'y'.repeat(250) + fs.linkSync(dir + '/in/target', dir + '/in/' + long) + + const expect = [ + { + type: 'Directory', + path: 'out/x/', + }, + { + type: 'File', + size: 3, + path: 'out/x/target', + }, + 'ddd\0', + { + path: 'out/x/y', + type: 'Link', + linkpath: 'out/x/target', + }, + { + path: 'PaxHeader/yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy', + type: 'ExtendedHeader', + }, + new RegExp('^266 path=out.x.' + long + '[\\w\\W]*linkpath=out.x.target'), + { + path: 'out/x/yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy', + type: 'Link', + linkpath: 'out/x/target', + }, + { + type: 'Directory', + path: 'out/x/z/', + }, + { + type: 'Directory', + path: 'out/x/z/b/', + }, + { + path: 'out/x/z/d', + type: 'Link', + linkpath: 'out/x/target', + }, + { + type: 'Directory', + path: 'out/x/z/b/c/', + }, + { + path: 'out/x/z/b/d', + type: 'Link', + linkpath: 'out/x/target', + }, + { + path: 'out/x/z/b/c/d', + type: 'Link', + linkpath: 'out/x/target', + }, + ] + + const check = (out, t) => { + const data = Buffer.concat(out) + expect.forEach((e, i) => { + if (typeof e === 'string') + t.equal(data.slice(i * 512, i * 512 + e.length).toString(), e) + else if (e instanceof RegExp) + t.match(data.slice(i * 512, (i + 1) * 512).toString(), e) + else + t.match(new Header(data.slice(i * 512, (i + 1) * 512)), e) + }) + } + + const runTest = async (t, path, Class) => { + const linkCache = new Map() + const statCache = new Map() + const opt = { + cwd: dir + '/in', + prefix: 'out/x', + noDirRecurse: true, + linkCache, + statCache, + } + const out = [] + const entry = (path) => new Promise(resolve => { + const p = new Class(path, opt) + p.on('end', resolve) + p.on('data', d => out.push(d)) + }) + + await entry(path) + if (path === '.') + path = './' + await entry(`${path}target`) + await entry(`${path}y`) + await entry(`${path}${long}`) + await entry(`${path}z`) + await entry(`${path}z/b`) + await entry(`${path}z/d`) + await entry(`${path}z/b/c`) + await entry(`${path}z/b/d`) + await entry(`${path}z/b/c/d`) + check(out, t) + } + + t.test('async', t => { + t.test('.', t => runTest(t, '.', WriteEntry)) + return t.test('./', t => runTest(t, './', WriteEntry)) + }) + + t.test('sync', t => { + t.test('.', t => runTest(t, '.', WriteEntry.Sync)) + return t.test('./', t => runTest(t, './', WriteEntry.Sync)) + }) + + t.end() +}) + +t.test('prefix and hard links from tar entries', t => { + const long = 'y'.repeat(250) + const expect = [ + { + type: 'Directory', + path: 'out/x/', + }, + { + type: 'File', + size: 3, + path: 'out/x/target', + }, + 'ddd\0', + { + path: 'out/x/y', + type: 'Link', + linkpath: 'out/x/target', + }, + { + path: 'PaxHeader/yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy', + type: 'ExtendedHeader', + }, + new RegExp('^266 path=out.x.' + long + '[\\w\\W]*linkpath=out.x.target'), + { + path: 'out/x/yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy', + type: 'Link', + linkpath: 'out/x/target', + }, + { + type: 'Directory', + path: 'out/x/z/', + }, + { + type: 'Directory', + path: 'out/x/z/b/', + }, + { + path: 'out/x/z/d', + type: 'Link', + linkpath: 'out/x/target', + }, + { + type: 'Directory', + path: 'out/x/z/b/c/', + }, + { + path: 'out/x/z/b/d', + type: 'Link', + linkpath: 'out/x/target', + }, + { + path: 'out/x/z/b/c/d', + type: 'Link', + linkpath: 'out/x/target', + }, + ] + + const data = makeTar([ + { + type: 'Directory', + path: './', + }, + { + type: 'File', + size: 3, + path: 'target', + }, + 'ddd\0', + { + path: 'y', + type: 'Link', + linkpath: 'target', + }, + { + path: 'PaxHeader/yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy', + type: 'ExtendedHeader', + size: ('260 path=' + long + '\n19 linkpath=target\n').length, + }, + '260 path=' + long + '\n19 linkpath=target\n', + { + path: 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy', + type: 'Link', + linkpath: 'target', + }, + { + type: 'Directory', + path: 'z/', + }, + { + type: 'Directory', + path: 'z/b/', + }, + { + path: 'z/d', + type: 'Link', + linkpath: 'target', + }, + { + type: 'Directory', + path: 'z/b/c/', + }, + { + path: 'z/b/d', + type: 'Link', + linkpath: 'target', + }, + { + path: 'z/b/c/d', + type: 'Link', + linkpath: 'target', + }, + '', + '', + ]) + + const check = (out, t) => { + const data = Buffer.concat(out) + expect.forEach((e, i) => { + if (typeof e === 'string') + t.equal(data.slice(i * 512, i * 512 + e.length).toString(), e) + else if (e instanceof RegExp) + t.match(data.slice(i * 512, (i + 1) * 512).toString(), e) + else + t.match(new Header(data.slice(i * 512, (i + 1) * 512)), e) + }) + } + + const runTest = async (t, path) => { + const linkCache = new Map() + const statCache = new Map() + const opt = { + prefix: 'out/x', + noDirRecurse: true, + linkCache, + statCache, + } + const out = [] + const parser = new Parser({ + strict: true, + onentry: readEntry => { + const p = new WriteEntry.Tar(readEntry, opt) + p.on('data', d => out.push(d)) + }, + }) + parser.on('end', () => check(out, t)) + parser.end(data) + } + + t.test('.', t => runTest(t, '.')) + t.test('./', t => runTest(t, './')) + + t.end() +}) + +t.test('hard links and no prefix', t => { + const dir = path.resolve(fixtures, 'writeentry-prefix-hardlinks') + t.teardown(_ => rimraf.sync(dir)) + mkdirp.sync(dir + '/in/z/b/c') + fs.writeFileSync(dir + '/in/target', 'ddd') + fs.linkSync(dir + '/in/target', dir + '/in/z/b/c/d') + fs.linkSync(dir + '/in/target', dir + '/in/z/b/d') + fs.linkSync(dir + '/in/target', dir + '/in/z/d') + fs.linkSync(dir + '/in/target', dir + '/in/y') + + const expect = [ + { + type: 'Directory', + path: './', + }, + { + type: 'File', + size: 3, + path: 'target', + }, + 'ddd\0', + { + path: 'y', + type: 'Link', + linkpath: 'target', + }, + { + type: 'Directory', + path: 'z/', + }, + { + type: 'Directory', + path: 'z/b/', + }, + { + path: 'z/d', + type: 'Link', + linkpath: 'target', + }, + { + type: 'Directory', + path: 'z/b/c/', + }, + { + path: 'z/b/d', + type: 'Link', + linkpath: 'target', + }, + { + path: 'z/b/c/d', + type: 'Link', + linkpath: 'target', + }, + ] + + const check = (out, t) => { + const data = Buffer.concat(out) + expect.forEach((e, i) => { + if (typeof e === 'string') + t.equal(data.slice(i * 512, i * 512 + e.length).toString(), e) + else + t.match(new Header(data.slice(i * 512, (i + 1) * 512)), e) + }) + } + + const runTest = async (t, path, Class) => { + const linkCache = new Map() + const statCache = new Map() + const opt = { + cwd: dir + '/in', + linkCache, + statCache, + } + const out = [] + const entry = (path) => new Promise(resolve => { + const p = new Class(path, opt) + p.on('end', resolve) + p.on('data', d => out.push(d)) + }) + + await entry(path) + if (path === '.') + path = './' + await entry(`${path}target`) + await entry(`${path}y`) + await entry(`${path}z`) + await entry(`${path}z/b`) + await entry(`${path}z/d`) + await entry(`${path}z/b/c`) + await entry(`${path}z/b/d`) + await entry(`${path}z/b/c/d`) + check(out, t) + } + + t.test('async', t => { + t.test('.', t => runTest(t, '.', WriteEntry)) + return t.test('./', t => runTest(t, './', WriteEntry)) + }) + + t.test('sync', t => { + t.test('.', t => runTest(t, '.', WriteEntry.Sync)) + return t.test('./', t => runTest(t, './', WriteEntry.Sync)) + }) + + t.end() +}) + +t.test('hard links from tar entries and no prefix', t => { + const expect = [ + { + type: 'Directory', + path: './', + }, + { + type: 'File', + size: 3, + path: 'target', + }, + 'ddd\0', + { + path: 'y', + type: 'Link', + linkpath: 'target', + }, + { + type: 'Directory', + path: 'z/', + }, + { + type: 'Directory', + path: 'z/b/', + }, + { + path: 'z/d', + type: 'Link', + linkpath: 'target', + }, + { + type: 'Directory', + path: 'z/b/c/', + }, + { + path: 'z/b/d', + type: 'Link', + linkpath: 'target', + }, + { + path: 'z/b/c/d', + type: 'Link', + linkpath: 'target', + }, + ] + + const data = makeTar([ + { + type: 'Directory', + path: './', + }, + { + type: 'File', + size: 3, + path: 'target', + }, + 'ddd\0', + { + path: 'y', + type: 'Link', + linkpath: 'target', + }, + { + type: 'Directory', + path: 'z/', + }, + { + type: 'Directory', + path: 'z/b/', + }, + { + path: 'z/d', + type: 'Link', + linkpath: 'target', + }, + { + type: 'Directory', + path: 'z/b/c/', + }, + { + path: 'z/b/d', + type: 'Link', + linkpath: 'target', + }, + { + path: 'z/b/c/d', + type: 'Link', + linkpath: 'target', + }, + ]) + + const check = (out, t) => { + const data = Buffer.concat(out) + expect.forEach((e, i) => { + if (typeof e === 'string') + t.equal(data.slice(i * 512, i * 512 + e.length).toString(), e) + else if (e instanceof RegExp) + t.match(data.slice(i * 512, (i + 1) * 512).toString(), e) + else + t.match(new Header(data.slice(i * 512, (i + 1) * 512)), e) + }) + } + + const runTest = async (t, path) => { + const linkCache = new Map() + const statCache = new Map() + const opt = { + noDirRecurse: true, + linkCache, + statCache, + } + const out = [] + const parser = new Parser({ + onentry: readEntry => { + const p = new WriteEntry.Tar(readEntry, opt) + p.on('data', d => out.push(d)) + }, + }) + parser.on('end', () => check(out, t)) + parser.end(data) + } + + t.test('.', t => runTest(t, '.')) + t.test('./', t => runTest(t, './')) + + t.end() +}) + +t.test('myuid set by getuid() if available, otherwise 0', t => { + const {getuid} = process + process.getuid = null + const noUid = new WriteEntry(__filename) + t.equal(noUid.myuid, 0, 'set to zero if no getuid function') + process.getuid = () => 123456789 + const hasUid = new WriteEntry(__filename) + t.equal(hasUid.myuid, 123456789, 'set to process.getuid()') + process.getuid = getuid + t.end() +})