diff options
author | claudiahdz <cghr1990@gmail.com> | 2020-02-06 23:43:20 +0300 |
---|---|---|
committer | isaacs <i@izs.me> | 2020-05-08 04:11:51 +0300 |
commit | 0a30b0d8a1c448b6d89d781ad81f46117d014953 (patch) | |
tree | 8b2443c75e95cd29e8a06cb990282f87a886115a /node_modules/tar | |
parent | 0a45514d8beba749bebbd973ca9750ee0dc13b40 (diff) |
tar@6.0.1
Diffstat (limited to 'node_modules/tar')
39 files changed, 2108 insertions, 308 deletions
diff --git a/node_modules/tar/CHANGELOG.md b/node_modules/tar/CHANGELOG.md new file mode 100644 index 000000000..14b5c4ee8 --- /dev/null +++ b/node_modules/tar/CHANGELOG.md @@ -0,0 +1,66 @@ +# Charge Long + +## 6.0 + +- Drop support for node 6 and 8 +- fix symlinks and hardlinks on windows being packed with `\`-style path + targets + +## 5.0 + +- Address unpack race conditions using path reservations +- Change large-numbers errors from TypeError to Error +- Add `TAR_*` error codes +- do not treat ignored entries as an invalid archive +- drop support for node v4 +- unpack: conditionally use a file mapping to write files on Windows +- Set more portable 'mode' value in portable mode +- Set `portable` gzip option in portable mode + +## 4.4 + +- Add 'mtime' option to tar creation to force mtime +- unpack: only reuse file fs entries if nlink = 1 +- unpack: rename before unlinking files on Windows +- Fix encoding/decoding of base-256 numbers +- Use `stat` instead of `lstat` when checking CWD +- Always provide a callback to fs.close() + +## 4.3 + +- Add 'transform' unpack option + +## 4.2 + +- Fail when zlib fails + +## 4.1 + +- Add noMtime flag for tar creation + +## 4.0 + +- unpack: raise error if cwd is missing or not a dir +- pack: don't drop dots from dotfiles when prefixing + +## 3.1 + +- Support `@file.tar` as an entry argument to copy entries from one tar + file to another. +- Add `noPax` option +- `noResume` option for tar.t +- win32: convert `>|<?:` chars to windows-friendly form +- Exclude mtime for dirs in portable mode + +## 3.0 + +- Minipass-based implementation +- Entirely new API surface, `tar.c()`, `tar.x()` etc., much closer to + system tar semantics +- Massive performance improvement +- Require node 4.x and higher + +## 0.x, 1.x, 2.x - 2011-2014 + +- fstream-based implementation +- slow and kinda bad, but better than npm shelling out to the system `tar` diff --git a/node_modules/tar/README.md b/node_modules/tar/README.md index 034e4865c..5e635e622 100644 --- a/node_modules/tar/README.md +++ b/node_modules/tar/README.md @@ -63,23 +63,93 @@ that all of the data is immediately available by calling `stream.read()`. For writable streams, it will be acted upon as soon as it is provided, but this can be at any time. -### Warnings - -Some things cause tar to emit a warning, but should usually not cause -the entire operation to fail. There are three ways to handle -warnings: - -1. **Ignore them** (default) Invalid entries won't be put in the - archive, and invalid entries won't be unpacked. This is usually - fine, but can hide failures that you might care about. -2. **Notice them** Add an `onwarn` function to the options, or listen - to the `'warn'` event on any tar stream. The function will get - called as `onwarn(message, data)`. Handle as appropriate. -3. **Explode them.** Set `strict: true` in the options object, and - `warn` messages will be emitted as `'error'` events instead. If - there's no `error` handler, this causes the program to crash. If - used with a promise-returning/callback-taking method, then it'll - send the error to the promise/callback. +### Warnings and Errors + +Tar emits warnings and errors for recoverable and unrecoverable situations, +respectively. In many cases, a warning only affects a single entry in an +archive, or is simply informing you that it's modifying an entry to comply +with the settings provided. + +Unrecoverable warnings will always raise an error (ie, emit `'error'` on +streaming actions, throw for non-streaming sync actions, reject the +returned Promise for non-streaming async operations, or call a provided +callback with an `Error` as the first argument). Recoverable errors will +raise an error only if `strict: true` is set in the options. + +Respond to (recoverable) warnings by listening to the `warn` event. +Handlers receive 3 arguments: + +- `code` String. One of the error codes below. This may not match + `data.code`, which preserves the original error code from fs and zlib. +- `message` String. More details about the error. +- `data` Metadata about the error. An `Error` object for errors raised by + fs and zlib. All fields are attached to errors raisd by tar. Typically + contains the following fields, as relevant: + - `tarCode` The tar error code. + - `code` Either the tar error code, or the error code set by the + underlying system. + - `file` The archive file being read or written. + - `cwd` Working directory for creation and extraction operations. + - `entry` The entry object (if it could be created) for `TAR_ENTRY_INFO`, + `TAR_ENTRY_INVALID`, and `TAR_ENTRY_ERROR` warnings. + - `header` The header object (if it could be created, and the entry could + not be created) for `TAR_ENTRY_INFO` and `TAR_ENTRY_INVALID` warnings. + - `recoverable` Boolean. If `false`, then the warning will emit an + `error`, even in non-strict mode. + +#### Error Codes + +* `TAR_ENTRY_INFO` An informative error indicating that an entry is being + modified, but otherwise processed normally. For example, removing `/` or + `C:\` from absolute paths if `preservePaths` is not set. + +* `TAR_ENTRY_INVALID` An indication that a given entry is not a valid tar + archive entry, and will be skipped. This occurs when: + - a checksum fails, + - a `linkpath` is missing for a link type, or + - a `linkpath` is provided for a non-link type. + + If every entry in a parsed archive raises an `TAR_ENTRY_INVALID` error, + then the archive is presumed to be unrecoverably broken, and + `TAR_BAD_ARCHIVE` will be raised. + +* `TAR_ENTRY_ERROR` The entry appears to be a valid tar archive entry, but + encountered an error which prevented it from being unpacked. This occurs + when: + - an unrecoverable fs error happens during unpacking, + - an entry has `..` in the path and `preservePaths` is not set, or + - an entry is extracting through a symbolic link, when `preservePaths` is + not set. + +* `TAR_ENTRY_UNSUPPORTED` An indication that a given entry is + a valid archive entry, but of a type that is unsupported, and so will be + skipped in archive creation or extracting. + +* `TAR_ABORT` When parsing gzipped-encoded archives, the parser will + abort the parse process raise a warning for any zlib errors encountered. + Aborts are considered unrecoverable for both parsing and unpacking. + +* `TAR_BAD_ARCHIVE` The archive file is totally hosed. This can happen for + a number of reasons, and always occurs at the end of a parse or extract: + + - An entry body was truncated before seeing the full number of bytes. + - The archive contained only invalid entries, indicating that it is + likely not an archive, or at least, not an archive this library can + parse. + + `TAR_BAD_ARCHIVE` is considered informative for parse operations, but + unrecoverable for extraction. Note that, if encountered at the end of an + extraction, tar WILL still have extracted as much it could from the + archive, so there may be some garbage files to clean up. + +Errors that occur deeper in the system (ie, either the filesystem or zlib) +will have their error codes left intact, and a `tarCode` matching one of +the above will be added to the warning metadata or the raised error object. + +Errors generated by tar will have one of the above codes set as the +`error.code` field as well, but since errors originating in zlib or fs will +have their original codes, it's better to read `error.tarCode` if you wish +to see how tar is handling the issue. ### Examples @@ -201,8 +271,8 @@ The following options are supported: and a file is not provided, then the resulting stream will already have the data ready to `read` or `emit('data')` as soon as you request it. -- `onwarn` A function that will get called with `(message, data)` for - any warnings encountered. +- `onwarn` A function that will get called with `(code, message, data)` for + any warnings encountered. (See "Warnings and Errors") - `strict` Treat warnings as crash-worthy errors. Default false. - `cwd` The current working directory for creating the archive. Defaults to `process.cwd()`. [Alias: `C`] @@ -214,8 +284,9 @@ The following options are supported: or `false` to omit it. - `portable` Omit metadata that is system-specific: `ctime`, `atime`, `uid`, `gid`, `uname`, `gname`, `dev`, `ino`, and `nlink`. Note - that `mtime` is still included, because this is necessary other - time-based operations. + that `mtime` is still included, because this is necessary for other + time-based operations. Additionally, `mode` is set to a "reasonable + default" for most unix systems, based on a `umask` value of `0o22`. - `preservePaths` Allow absolute paths. By default, `/` is stripped from absolute paths. [Alias: `P`] - `mode` The mode to set on the created file archive @@ -297,8 +368,8 @@ The following options are supported: Pathnames with fewer elements will be silently skipped. Note that the pathname is edited after applying the filter, but before security checks. [Alias: `strip-components`, `stripComponents`] -- `onwarn` A function that will get called with `(message, data)` for - any warnings encountered. +- `onwarn` A function that will get called with `(code, message, data)` for + any warnings encountered. (See "Warnings and Errors") - `preserveOwner` If true, tar will set the `uid` and `gid` of extracted entries to the `uid` and `gid` fields in the archive. This defaults to true when run as root, and false otherwise. If @@ -401,8 +472,8 @@ The following options are supported: filename. [Alias: `f`] - `sync` Act synchronously. If this is set, then any provided file will be fully written after the call to `tar.c`. -- `onwarn` A function that will get called with `(message, data)` for - any warnings encountered. +- `onwarn` A function that will get called with `(code, message, data)` for + any warnings encountered. (See "Warnings and Errors") - `strict` Treat warnings as crash-worthy errors. Default false. - `cwd` The current working directory for adding entries to the archive. Defaults to `process.cwd()`. [Alias: `C`] @@ -414,8 +485,9 @@ The following options are supported: or `false` to omit it. - `portable` Omit metadata that is system-specific: `ctime`, `atime`, `uid`, `gid`, `uname`, `gname`, `dev`, `ino`, and `nlink`. Note - that `mtime` is still included, because this is necessary other - time-based operations. + that `mtime` is still included, because this is necessary for other + time-based operations. Additionally, `mode` is set to a "reasonable + default" for most unix systems, based on a `umask` value of `0o22`. - `preservePaths` Allow absolute paths. By default, `/` is stripped from absolute paths. [Alias: `P`] - `maxReadSize` The maximum buffer size for `fs.read()` operations. @@ -452,8 +524,8 @@ The following options are supported: filename. [Alias: `f`] - `sync` Act synchronously. If this is set, then any provided file will be fully written after the call to `tar.c`. -- `onwarn` A function that will get called with `(message, data)` for - any warnings encountered. +- `onwarn` A function that will get called with `(code, message, data)` for + any warnings encountered. (See "Warnings and Errors") - `strict` Treat warnings as crash-worthy errors. Default false. - `cwd` The current working directory for adding entries to the archive. Defaults to `process.cwd()`. [Alias: `C`] @@ -465,8 +537,9 @@ The following options are supported: or `false` to omit it. - `portable` Omit metadata that is system-specific: `ctime`, `atime`, `uid`, `gid`, `uname`, `gname`, `dev`, `ino`, and `nlink`. Note - that `mtime` is still included, because this is necessary other - time-based operations. + that `mtime` is still included, because this is necessary for other + time-based operations. Additionally, `mode` is set to a "reasonable + default" for most unix systems, based on a `umask` value of `0o22`. - `preservePaths` Allow absolute paths. By default, `/` is stripped from absolute paths. [Alias: `P`] - `maxReadSize` The maximum buffer size for `fs.read()` operations. @@ -499,8 +572,8 @@ Has all the standard readable stream interface stuff. `'data'` and The following options are supported: -- `onwarn` A function that will get called with `(message, data)` for - any warnings encountered. +- `onwarn` A function that will get called with `(code, message, data)` for + any warnings encountered. (See "Warnings and Errors") - `strict` Treat warnings as crash-worthy errors. Default false. - `cwd` The current working directory for creating the archive. Defaults to `process.cwd()`. @@ -512,8 +585,9 @@ The following options are supported: or `false` to omit it. - `portable` Omit metadata that is system-specific: `ctime`, `atime`, `uid`, `gid`, `uname`, `gname`, `dev`, `ino`, and `nlink`. Note - that `mtime` is still included, because this is necessary other - time-based operations. + that `mtime` is still included, because this is necessary for other + time-based operations. Additionally, `mode` is set to a "reasonable + default" for most unix systems, based on a `umask` value of `0o22`. - `preservePaths` Allow absolute paths. By default, `/` is stripped from absolute paths. - `linkCache` A Map object containing the device and inode value for @@ -595,8 +669,8 @@ Most unpack errors will cause a `warn` event to be emitted. If the Pathnames with fewer elements will be silently skipped. Note that the pathname is edited after applying the filter, but before security checks. -- `onwarn` A function that will get called with `(message, data)` for - any warnings encountered. +- `onwarn` A function that will get called with `(code, message, data)` for + any warnings encountered. (See "Warnings and Errors") - `umask` Filter the modes of entries like `process.umask()`. - `dmode` Default mode for directories - `fmode` Default mode for files @@ -634,8 +708,8 @@ Most unpack errors will cause a `warn` event to be emitted. If the - `strict` Treat warnings as crash-worthy errors. Default false. - `onentry` A function that gets called with `(entry)` for each entry that passes the filter. -- `onwarn` A function that will get called with `(message, data)` for - any warnings encountered. +- `onwarn` A function that will get called with `(code, message, data)` for + any warnings encountered. (See "Warnings and Errors") ### class tar.Unpack.Sync @@ -674,13 +748,13 @@ The following options are supported: archive, or `false` to skip it. - `onentry` A function that gets called with `(entry)` for each entry that passes the filter. -- `onwarn` A function that will get called with `(message, data)` for - any warnings encountered. +- `onwarn` A function that will get called with `(code, message, data)` for + any warnings encountered. (See "Warnings and Errors") -#### abort(message, error) +#### abort(error) Stop all parsing activities. This is called when there are zlib -errors. It also emits a warning with the message and error provided. +errors. It also emits an unrecoverable warning with the error provided. ### class tar.ReadEntry extends [MiniPass](http://npm.im/minipass) @@ -725,8 +799,9 @@ It has the following fields: object. - `portable` Omit metadata that is system-specific: `ctime`, `atime`, `uid`, `gid`, `uname`, `gname`, `dev`, `ino`, and `nlink`. Note - that `mtime` is still included, because this is necessary other - time-based operations. + that `mtime` is still included, because this is necessary for other + time-based operations. Additionally, `mode` is set to a "reasonable + default" for most unix systems, based on a `umask` value of `0o22`. - `myuid` If supported, the uid of the user running the current process. - `myuser` The `env.USER` string if set, or `''`. Set as the entry @@ -764,8 +839,9 @@ The following options are supported: - `portable` Omit metadata that is system-specific: `ctime`, `atime`, `uid`, `gid`, `uname`, `gname`, `dev`, `ino`, and `nlink`. Note - that `mtime` is still included, because this is necessary other - time-based operations. + that `mtime` is still included, because this is necessary for other + time-based operations. Additionally, `mode` is set to a "reasonable + default" for most unix systems, based on a `umask` value of `0o22`. - `maxReadSize` The maximum buffer size for `fs.read()` operations. Defaults to 1 MB. - `linkCache` A Map object containing the device and inode value for @@ -781,8 +857,8 @@ The following options are supported: - `strict` Treat warnings as crash-worthy errors. Default false. - `win32` True if on a windows platform. Causes behavior where paths replace `\` with `/`. -- `onwarn` A function that will get called with `(message, data)` for - any warnings encountered. +- `onwarn` A function that will get called with `(code, message, data)` for + any warnings encountered. (See "Warnings and Errors") - `noMtime` Set to true to omit writing `mtime` values for entries. Note that this prevents using other mtime-based features like `tar.update` or the `keepNewer` option with the resulting tar archive. @@ -813,13 +889,14 @@ The following options are supported: - `portable` Omit metadata that is system-specific: `ctime`, `atime`, `uid`, `gid`, `uname`, `gname`, `dev`, `ino`, and `nlink`. Note - that `mtime` is still included, because this is necessary other - time-based operations. + that `mtime` is still included, because this is necessary for other + time-based operations. Additionally, `mode` is set to a "reasonable + default" for most unix systems, based on a `umask` value of `0o22`. - `preservePaths` Allow absolute paths. By default, `/` is stripped from absolute paths. - `strict` Treat warnings as crash-worthy errors. Default false. -- `onwarn` A function that will get called with `(message, data)` for - any warnings encountered. +- `onwarn` A function that will get called with `(code, message, data)` for + any warnings encountered. (See "Warnings and Errors") - `noMtime` Set to true to omit writing `mtime` values for entries. Note that this prevents using other mtime-based features like `tar.update` or the `keepNewer` option with the resulting tar archive. diff --git a/node_modules/tar/lib/buffer.js b/node_modules/tar/lib/buffer.js deleted file mode 100644 index 7876d5b3e..000000000 --- a/node_modules/tar/lib/buffer.js +++ /dev/null @@ -1,11 +0,0 @@ -'use strict' - -// Buffer in node 4.x < 4.5.0 doesn't have working Buffer.from -// or Buffer.alloc, and Buffer in node 10 deprecated the ctor. -// .M, this is fine .\^/M.. -let B = Buffer -/* istanbul ignore next */ -if (!B.alloc) { - B = require('safe-buffer').Buffer -} -module.exports = B diff --git a/node_modules/tar/lib/get-write-flag.js b/node_modules/tar/lib/get-write-flag.js new file mode 100644 index 000000000..e86959996 --- /dev/null +++ b/node_modules/tar/lib/get-write-flag.js @@ -0,0 +1,20 @@ +// Get the appropriate flag to use for creating files +// We use fmap on Windows platforms for files less than +// 512kb. This is a fairly low limit, but avoids making +// things slower in some cases. Since most of what this +// library is used for is extracting tarballs of many +// relatively small files in npm packages and the like, +// it can be a big boost on Windows platforms. +// Only supported in Node v12.9.0 and above. +const platform = process.env.__FAKE_PLATFORM__ || process.platform +const isWindows = platform === 'win32' +const fs = global.__FAKE_TESTING_FS__ || require('fs') + +/* istanbul ignore next */ +const { O_CREAT, O_TRUNC, O_WRONLY, UV_FS_O_FILEMAP = 0 } = fs.constants + +const fMapEnabled = isWindows && !!UV_FS_O_FILEMAP +const fMapLimit = 512 * 1024 +const fMapFlag = UV_FS_O_FILEMAP | O_TRUNC | O_CREAT | O_WRONLY +module.exports = !fMapEnabled ? () => 'w' + : size => size < fMapLimit ? fMapFlag : 'w' diff --git a/node_modules/tar/lib/header.js b/node_modules/tar/lib/header.js index d29c3b990..5d88f6cf8 100644 --- a/node_modules/tar/lib/header.js +++ b/node_modules/tar/lib/header.js @@ -4,7 +4,6 @@ // the data could not be faithfully encoded in a simple header. // (Also, check header.needPax to see if it needs a pax header.) -const Buffer = require('./buffer.js') const types = require('./types.js') const pathModule = require('path').posix const large = require('./large-numbers.js') diff --git a/node_modules/tar/lib/large-numbers.js b/node_modules/tar/lib/large-numbers.js index 3e5c99255..ad30bc350 100644 --- a/node_modules/tar/lib/large-numbers.js +++ b/node_modules/tar/lib/large-numbers.js @@ -6,7 +6,7 @@ const encode = exports.encode = (num, buf) => { 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') + throw Error('cannot encode number outside of javascript safe integer range') else if (num < 0) encodeNegative(num, buf) else @@ -50,12 +50,12 @@ const parse = exports.parse = (buf) => { else if (pre === 0xff) value = twos(buf) else - throw TypeError('invalid base256 encoding') + throw Error('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') + throw Error('parsed number outside of javascript safe integer range') return value } diff --git a/node_modules/tar/lib/list.js b/node_modules/tar/lib/list.js index 250ebe001..9da3f812c 100644 --- a/node_modules/tar/lib/list.js +++ b/node_modules/tar/lib/list.js @@ -1,7 +1,5 @@ 'use strict' -const Buffer = require('./buffer.js') - // XXX: This shares a lot in common with extract.js // maybe some DRY opportunity here? diff --git a/node_modules/tar/lib/mkdir.js b/node_modules/tar/lib/mkdir.js index c6a154c24..381d0e1b3 100644 --- a/node_modules/tar/lib/mkdir.js +++ b/node_modules/tar/lib/mkdir.js @@ -76,7 +76,7 @@ const mkdir = module.exports = (dir, opt, cb) => { }) if (preserve) - return mkdirp(dir, mode, done) + return mkdirp(dir, {mode}).then(made => done(null, made), done) const sub = path.relative(cwd, dir) const parts = sub.split(/\/|\\/) diff --git a/node_modules/tar/lib/mode-fix.js b/node_modules/tar/lib/mode-fix.js index 3363a3b15..c3758741c 100644 --- a/node_modules/tar/lib/mode-fix.js +++ b/node_modules/tar/lib/mode-fix.js @@ -1,6 +1,16 @@ 'use strict' -module.exports = (mode, isDir) => { +module.exports = (mode, isDir, portable) => { mode &= 0o7777 + + // in portable mode, use the minimum reasonable umask + // if this system creates files with 0o664 by default + // (as some linux distros do), then we'll write the + // archive with 0o644 instead. Also, don't ever create + // a file that is not readable/writable by the owner. + if (portable) { + mode = (mode | 0o600) &~0o22 + } + // if dirs are readable, then they should be listable if (isDir) { if (mode & 0o400) diff --git a/node_modules/tar/lib/pack.js b/node_modules/tar/lib/pack.js index 857cea910..0fca4ae25 100644 --- a/node_modules/tar/lib/pack.js +++ b/node_modules/tar/lib/pack.js @@ -1,7 +1,5 @@ 'use strict' -const Buffer = require('./buffer.js') - // A readable tar stream creator // Technically, this is a transform stream that you write paths into, // and tar format comes out of. @@ -62,6 +60,7 @@ const Pack = warner(class Pack extends MiniPass { super(opt) opt = opt || Object.create(null) this.opt = opt + this.file = opt.file || '' this.cwd = opt.cwd || process.cwd() this.maxReadSize = opt.maxReadSize this.preservePaths = !!opt.preservePaths @@ -76,10 +75,13 @@ const Pack = warner(class Pack extends MiniPass { if (typeof opt.onwarn === 'function') this.on('warn', opt.onwarn) + this.portable = !!opt.portable this.zip = null if (opt.gzip) { if (typeof opt.gzip !== 'object') opt.gzip = {} + if (this.portable) + opt.gzip.portable = true this.zip = new zlib.Gzip(opt.gzip) this.zip.on('data', chunk => super.write(chunk)) this.zip.on('end', _ => super.end()) @@ -88,7 +90,6 @@ const Pack = warner(class Pack extends MiniPass { } else this.on('drain', this[ONDRAIN]) - this.portable = !!opt.portable this.noDirRecurse = !!opt.noDirRecurse this.follow = !!opt.follow this.noMtime = !!opt.noMtime @@ -285,9 +286,7 @@ const Pack = warner(class Pack extends MiniPass { [ENTRYOPT] (job) { return { - onwarn: (msg, data) => { - this.warn(msg, data) - }, + onwarn: (code, msg, data) => this.warn(code, msg, data), noPax: this.noPax, cwd: this.cwd, absolute: job.absolute, diff --git a/node_modules/tar/lib/parse.js b/node_modules/tar/lib/parse.js index 43d4383dd..d9a49ad1f 100644 --- a/node_modules/tar/lib/parse.js +++ b/node_modules/tar/lib/parse.js @@ -29,7 +29,6 @@ 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') @@ -58,6 +57,9 @@ const MAYBEEND = Symbol('maybeEnd') const WRITING = Symbol('writing') const ABORTED = Symbol('aborted') const DONE = Symbol('onDone') +const SAW_VALID_ENTRY = Symbol('sawValidEntry') +const SAW_NULL_BLOCK = Symbol('sawNullBlock') +const SAW_EOF = Symbol('sawEOF') const noop = _ => true @@ -66,6 +68,21 @@ module.exports = warner(class Parser extends EE { opt = opt || {} super(opt) + this.file = opt.file || '' + + // set to boolean false when an entry starts. 1024 bytes of \0 + // is technically a valid tarball, albeit a boring one. + this[SAW_VALID_ENTRY] = null + + // these BADARCHIVE errors can't be detected early. listen on DONE. + this.on(DONE, _ => { + if (this[STATE] === 'begin' || this[SAW_VALID_ENTRY] === false) { + // either less than 1 block of data, or all entries were invalid. + // Either way, probably not even a tarball. + this.warn('TAR_BAD_ARCHIVE', 'Unrecognized archive format') + } + }) + if (opt.ondone) this.on(DONE, opt.ondone) else @@ -95,6 +112,8 @@ module.exports = warner(class Parser extends EE { this[ENDED] = false this[UNZIP] = null this[ABORTED] = false + this[SAW_NULL_BLOCK] = false + this[SAW_EOF] = false if (typeof opt.onwarn === 'function') this.on('warn', opt.onwarn) if (typeof opt.onentry === 'function') @@ -102,58 +121,90 @@ module.exports = warner(class Parser extends EE { } [CONSUMEHEADER] (chunk, position) { + if (this[SAW_VALID_ENTRY] === null) + this[SAW_VALID_ENTRY] = false let header try { header = new Header(chunk, position, this[EX], this[GEX]) } catch (er) { - return this.warn('invalid entry', er) + return this.warn('TAR_ENTRY_INVALID', er) } - if (header.nullBlock) - this[EMIT]('nullBlock') - else if (!header.cksumValid) - this.warn('invalid entry', header) - else if (!header.path) - this.warn('invalid: path is required', header) - else { - const type = header.type - if (/^(Symbolic)?Link$/.test(type) && !header.linkpath) - this.warn('invalid: linkpath required', header) - else if (!/^(Symbolic)?Link$/.test(type) && header.linkpath) - this.warn('invalid: linkpath forbidden', header) + if (header.nullBlock) { + if (this[SAW_NULL_BLOCK]) { + this[SAW_EOF] = true + // ending an archive with no entries. pointless, but legal. + if (this[STATE] === 'begin') + this[STATE] = 'header' + this[EMIT]('eof') + } else { + this[SAW_NULL_BLOCK] = true + this[EMIT]('nullBlock') + } + } else { + this[SAW_NULL_BLOCK] = false + if (!header.cksumValid) + this.warn('TAR_ENTRY_INVALID', 'checksum failure', {header}) + else if (!header.path) + this.warn('TAR_ENTRY_INVALID', 'path is required', {header}) else { - const entry = this[WRITEENTRY] = new Entry(header, this[EX], this[GEX]) - - if (entry.meta) { - if (entry.size > this.maxMetaEntrySize) { - entry.ignore = true - this[EMIT]('ignoredEntry', entry) - this[STATE] = 'ignore' - } else if (entry.size > 0) { - this[META] = '' - entry.on('data', c => this[META] += c) - this[STATE] = 'meta' + const type = header.type + if (/^(Symbolic)?Link$/.test(type) && !header.linkpath) + this.warn('TAR_ENTRY_INVALID', 'linkpath required', {header}) + else if (!/^(Symbolic)?Link$/.test(type) && header.linkpath) + this.warn('TAR_ENTRY_INVALID', 'linkpath forbidden', {header}) + else { + const entry = this[WRITEENTRY] = new Entry(header, this[EX], this[GEX]) + + // we do this for meta & ignored entries as well, because they + // are still valid tar, or else we wouldn't know to ignore them + if (!this[SAW_VALID_ENTRY]) { + if (entry.remain) { + // this might be the one! + const onend = () => { + if (!entry.invalid) + this[SAW_VALID_ENTRY] = true + } + entry.on('end', onend) + } else { + this[SAW_VALID_ENTRY] = true + } } - } else { - this[EX] = null - entry.ignore = entry.ignore || !this.filter(entry.path, entry) - if (entry.ignore) { - this[EMIT]('ignoredEntry', entry) - this[STATE] = entry.remain ? 'ignore' : 'begin' + if (entry.meta) { + if (entry.size > this.maxMetaEntrySize) { + entry.ignore = true + this[EMIT]('ignoredEntry', entry) + this[STATE] = 'ignore' + entry.resume() + } else if (entry.size > 0) { + this[META] = '' + entry.on('data', c => this[META] += c) + this[STATE] = 'meta' + } } else { - if (entry.remain) - this[STATE] = 'body' - else { - this[STATE] = 'begin' - entry.end() + this[EX] = null + entry.ignore = entry.ignore || !this.filter(entry.path, entry) + + if (entry.ignore) { + // probably valid, just not something we care about + this[EMIT]('ignoredEntry', entry) + this[STATE] = entry.remain ? 'ignore' : 'header' + entry.resume() + } else { + if (entry.remain) + this[STATE] = 'body' + else { + this[STATE] = 'header' + entry.end() + } + + if (!this[READENTRY]) { + this[QUEUE].push(entry) + this[NEXTENTRY]() + } else + this[QUEUE].push(entry) } - - if (!this[READENTRY]) { - this[QUEUE].push(entry) - this[NEXTENTRY]() - } else - this[QUEUE].push(entry) } } } @@ -211,7 +262,7 @@ module.exports = warner(class Parser extends EE { entry.write(c) if (!entry.blockRemain) { - this[STATE] = 'begin' + this[STATE] = 'header' this[WRITEENTRY] = null entry.end() } @@ -265,11 +316,11 @@ module.exports = warner(class Parser extends EE { } } - abort (msg, error) { + abort (error) { this[ABORTED] = true - this.warn(msg, error) this.emit('abort', error) - this.emit('error', error) + // always throws, even in non-strict mode + this.warn('TAR_ABORT', error, { recoverable: false }) } write (chunk) { @@ -295,8 +346,7 @@ module.exports = warner(class Parser extends EE { this[ENDED] = false this[UNZIP] = new zlib.Unzip() this[UNZIP].on('data', chunk => this[CONSUMECHUNK](chunk)) - this[UNZIP].on('error', er => - this.abort(er.message, er)) + this[UNZIP].on('error', er => this.abort(er)) this[UNZIP].on('end', _ => { this[ENDED] = true this[CONSUMECHUNK]() @@ -341,9 +391,10 @@ module.exports = warner(class Parser extends EE { this[EMITTEDEND] = true const entry = this[WRITEENTRY] if (entry && entry.blockRemain) { + // truncated, likely a damaged file const have = this[BUFFER] ? this[BUFFER].length : 0 - this.warn('Truncated input (needed ' + entry.blockRemain + - ' more bytes, only ' + have + ' available)', entry) + this.warn('TAR_BAD_ARCHIVE', `Truncated input (needed ${ + entry.blockRemain} more bytes, only ${have} available)`, {entry}) if (this[BUFFER]) entry.write(this[BUFFER]) entry.end() @@ -353,11 +404,11 @@ module.exports = warner(class Parser extends EE { } [CONSUMECHUNK] (chunk) { - if (this[CONSUMING]) { + if (this[CONSUMING]) this[BUFFERCONCAT](chunk) - } else if (!chunk && !this[BUFFER]) { + else if (!chunk && !this[BUFFER]) this[MAYBEEND]() - } else { + else { this[CONSUMING] = true if (this[BUFFER]) { this[BUFFERCONCAT](chunk) @@ -368,7 +419,10 @@ module.exports = warner(class Parser extends EE { this[CONSUMECHUNKSUB](chunk) } - while (this[BUFFER] && this[BUFFER].length >= 512 && !this[ABORTED]) { + while (this[BUFFER] && + this[BUFFER].length >= 512 && + !this[ABORTED] && + !this[SAW_EOF]) { const c = this[BUFFER] this[BUFFER] = null this[CONSUMECHUNKSUB](c) @@ -385,9 +439,10 @@ module.exports = warner(class Parser extends EE { // the buffer. Advance the position and put any remainder in the buffer. let position = 0 let length = chunk.length - while (position + 512 <= length && !this[ABORTED]) { + while (position + 512 <= length && !this[ABORTED] && !this[SAW_EOF]) { switch (this[STATE]) { case 'begin': + case 'header': this[CONSUMEHEADER](chunk, position) position += 512 break diff --git a/node_modules/tar/lib/path-reservations.js b/node_modules/tar/lib/path-reservations.js new file mode 100644 index 000000000..3cf0c2c12 --- /dev/null +++ b/node_modules/tar/lib/path-reservations.js @@ -0,0 +1,125 @@ +// 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') + +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 + const { join } = require('path') + const getDirs = path => + join(path).split(/[\\\/]/).slice(0, -1).reduce((set, path) => + set.length ? set.concat(join(set[set.length-1], path)) : [path], []) + + // 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) => { + 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/node_modules/tar/lib/pax.js b/node_modules/tar/lib/pax.js index 9d7e4aba5..214a459f3 100644 --- a/node_modules/tar/lib/pax.js +++ b/node_modules/tar/lib/pax.js @@ -1,5 +1,4 @@ 'use strict' -const Buffer = require('./buffer.js') const Header = require('./header.js') const path = require('path') diff --git a/node_modules/tar/lib/replace.js b/node_modules/tar/lib/replace.js index 571cee94a..44126d1f8 100644 --- a/node_modules/tar/lib/replace.js +++ b/node_modules/tar/lib/replace.js @@ -1,5 +1,4 @@ 'use strict' -const Buffer = require('./buffer.js') // tar -r const hlo = require('./high-level-opt.js') diff --git a/node_modules/tar/lib/unpack.js b/node_modules/tar/lib/unpack.js index fc765096e..af0e0ffa0 100644 --- a/node_modules/tar/lib/unpack.js +++ b/node_modules/tar/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,11 @@ const path = require('path') const mkdir = require('./mkdir.js') const mkdirSync = mkdir.sync const wc = require('./winchars.js') +const pathReservations = require('./path-reservations.js') const ONENTRY = Symbol('onEntry') const CHECKFS = Symbol('checkFs') +const CHECKFS2 = Symbol('checkFs2') const ISREUSABLE = Symbol('isReusable') const MAKEFS = Symbol('makeFs') const FILE = Symbol('file') @@ -34,6 +42,12 @@ const DOCHOWN = Symbol('doChown') const UID = Symbol('uid') const GID = Symbol('gid') const crypto = require('crypto') +const getFlag = require('./get-write-flag.js') + +/* istanbul ignore next */ +const neverCalled = () => { + throw new Error('sync function called cb somehow?!?') +} // Unlinks on Windows are not atomic. // @@ -91,6 +105,8 @@ class Unpack extends Parser { super(opt) + this.reservations = pathReservations() + this.transform = typeof opt.transform === 'function' ? opt.transform : null this.writable = true @@ -163,6 +179,15 @@ class Unpack extends Parser { this.on('entry', entry => this[ONENTRY](entry)) } + // a bad or damaged archive is a warning for Parser, but an error + // when extracting. Mark those errors as unrecoverable, because + // the Unpack contract cannot be met. + warn (code, msg, data = {}) { + if (code === 'TAR_BAD_ARCHIVE' || code === 'TAR_ABORT') + data.recoverable = false + return super.warn(code, msg, data) + } + [MAYBECLOSE] () { if (this[ENDED] && this[PENDING] === 0) { this.emit('prefinish') @@ -189,7 +214,10 @@ class Unpack extends Parser { if (!this.preservePaths) { const p = entry.path if (p.match(/(^|\/|\\)\.\.(\\|\/|$)/)) { - this.warn('path contains \'..\'', p) + this.warn('TAR_ENTRY_ERROR', `path contains '..'`, { + entry, + path: p, + }) return false } @@ -197,8 +225,12 @@ class Unpack extends Parser { // 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) + const r = parsed.root + this.warn('TAR_ENTRY_INFO', `stripping ${r} from absolute path`, { + entry, + path: p, + }) } } @@ -250,7 +282,7 @@ class Unpack extends Parser { if (er.name === 'CwdError') this.emit('error', er) else { - this.warn(er.message, er) + this.warn('TAR_ENTRY_ERROR', er, {entry}) this[UNPEND]() entry.resume() } @@ -291,9 +323,10 @@ 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, { + flags: getFlag(entry.size), mode: mode, autoClose: false }) @@ -304,8 +337,12 @@ class Unpack extends Parser { if (er) return this[ONERROR](er, entry) - if (--actions === 0) - fs.close(stream.fd, _ => this[UNPEND]()) + if (--actions === 0) { + fs.close(stream.fd, er => { + fullyDone() + er ? this[ONERROR](er, entry) : this[UNPEND]() + }) + } } stream.on('finish', _ => { @@ -344,15 +381,18 @@ class Unpack extends Parser { 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() } @@ -373,16 +413,18 @@ class Unpack extends Parser { } [UNSUPPORTED] (entry) { - this.warn('unsupported entry type: ' + entry.type, entry) + entry.unsupported = true + this.warn('TAR_ENTRY_UNSUPPORTED', + `unsupported entry type: ${entry.type}`, {entry}) 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) { + this[LINK](entry, path.resolve(this.cwd, entry.linkpath), 'link', done) } [PEND] () { @@ -413,29 +455,40 @@ class Unpack extends Parser { // check if a thing is there, and if so, try to clobber it [CHECKFS] (entry) { this[PEND]() + const paths = [entry.path] + if (entry.linkpath) + paths.push(entry.linkpath) + this.reservations.reserve(paths, done => this[CHECKFS2](entry, done)) + } + [CHECKFS2] (entry, done) { this[MKDIR](path.dirname(entry.absolute), this.dmode, er => { - if (er) + if (er) { + done() return this[ONERROR](er, entry) + } fs.lstat(entry.absolute, (er, st) => { - if (st && (this.keep || this.newer && st.mtime > entry.mtime)) + if (st && (this.keep || this.newer && st.mtime > entry.mtime)) { this[SKIP](entry) - else if (er || this[ISREUSABLE](entry, st)) - this[MAKEFS](null, entry) + done() + } else if (er || this[ISREUSABLE](entry, st)) { + this[MAKEFS](null, entry, done) + } else if (st.isDirectory()) { if (entry.type === 'Directory') { if (!entry.mode || (st.mode & 0o7777) === entry.mode) - this[MAKEFS](null, entry) + this[MAKEFS](null, entry, done) else - fs.chmod(entry.absolute, entry.mode, er => this[MAKEFS](er, entry)) + fs.chmod(entry.absolute, entry.mode, + er => this[MAKEFS](er, entry, done)) } else - fs.rmdir(entry.absolute, er => this[MAKEFS](er, entry)) + fs.rmdir(entry.absolute, er => this[MAKEFS](er, entry, done)) } else - unlinkFile(entry.absolute, er => this[MAKEFS](er, entry)) + unlinkFile(entry.absolute, er => this[MAKEFS](er, entry, done)) }) }) } - [MAKEFS] (er, entry) { + [MAKEFS] (er, entry, done) { if (er) return this[ONERROR](er, entry) @@ -443,25 +496,26 @@ 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) { + [LINK] (entry, linkpath, link, done) { // XXX: get the type ('file' or 'dir') for windows fs[link](linkpath, entry.absolute, er => { if (er) return this[ONERROR](er, entry) + done() this[UNPEND]() entry.resume() }) @@ -474,7 +528,7 @@ class UnpackSync extends Unpack { } [CHECKFS] (entry) { - const er = this[MKDIR](path.dirname(entry.absolute), this.dmode) + const er = this[MKDIR](path.dirname(entry.absolute), this.dmode, neverCalled) if (er) return this[ONERROR](er, entry) try { @@ -482,7 +536,7 @@ class UnpackSync extends Unpack { if (this.keep || this.newer && st.mtime > entry.mtime) return this[SKIP](entry) else if (this[ISREUSABLE](entry, st)) - return this[MAKEFS](null, entry) + return this[MAKEFS](null, entry, neverCalled) else { try { if (st.isDirectory()) { @@ -493,29 +547,34 @@ class UnpackSync extends Unpack { fs.rmdirSync(entry.absolute) } else unlinkFileSync(entry.absolute) - return this[MAKEFS](null, entry) + return this[MAKEFS](null, entry, neverCalled) } catch (er) { return this[ONERROR](er, entry) } } } catch (er) { - return this[MAKEFS](null, entry) + return this[MAKEFS](null, entry, neverCalled) } } - [FILE] (entry) { + [FILE] (entry, _) { 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) } let stream let fd try { - fd = fs.openSync(entry.absolute, 'w', mode) + fd = fs.openSync(entry.absolute, getFlag(entry.size), mode) } catch (er) { return oner(er) } @@ -570,7 +629,7 @@ class UnpackSync extends Unpack { }) } - [DIRECTORY] (entry) { + [DIRECTORY] (entry, _) { const mode = entry.mode & 0o7777 || this.dmode const er = this[MKDIR](entry.absolute, mode) if (er) @@ -607,7 +666,7 @@ class UnpackSync extends Unpack { } } - [LINK] (entry, linkpath, link) { + [LINK] (entry, linkpath, link, _) { try { fs[link + 'Sync'](linkpath, entry.absolute) entry.resume() diff --git a/node_modules/tar/lib/warn-mixin.js b/node_modules/tar/lib/warn-mixin.js index 94a4b9b99..11eb52cc6 100644 --- a/node_modules/tar/lib/warn-mixin.js +++ b/node_modules/tar/lib/warn-mixin.js @@ -1,14 +1,21 @@ 'use strict' module.exports = Base => class extends Base { - warn (msg, data) { - if (!this.strict) - this.emit('warn', msg, data) - else if (data instanceof Error) - this.emit('error', data) - else { - const er = new Error(msg) - er.data = data - this.emit('error', er) - } + warn (code, message, data = {}) { + if (this.file) + data.file = this.file + if (this.cwd) + data.cwd = this.cwd + data.code = message instanceof Error && message.code || code + data.tarCode = code + if (!this.strict && data.recoverable !== false) { + if (message instanceof Error) { + data = Object.assign(message, data) + message = message.message + } + this.emit('warn', data.tarCode, message, data) + } else if (message instanceof Error) { + this.emit('error', Object.assign(message, data)) + } else + this.emit('error', Object.assign(new Error(`${code}: ${message}`), data)) } } diff --git a/node_modules/tar/lib/write-entry.js b/node_modules/tar/lib/write-entry.js index 0c019006f..0e33cb59d 100644 --- a/node_modules/tar/lib/write-entry.js +++ b/node_modules/tar/lib/write-entry.js @@ -1,5 +1,4 @@ 'use strict' -const Buffer = require('./buffer.js') const MiniPass = require('minipass') const Pax = require('./pax.js') const Header = require('./header.js') @@ -54,12 +53,13 @@ const WriteEntry = warner(class WriteEntry extends MiniPass { if (typeof opt.onwarn === 'function') this.on('warn', opt.onwarn) + let pathWarn = false 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) + pathWarn = parsed.root } this.win32 = !!opt.win32 || process.platform === 'win32' @@ -73,6 +73,13 @@ const WriteEntry = warner(class WriteEntry extends MiniPass { if (this.path === '') this.path = './' + if (pathWarn) { + this.warn('TAR_ENTRY_INFO', `stripping ${pathWarn} from absolute path`, { + entry: this, + path: pathWarn + this.path, + }) + } + if (this.statCache.has(this.absolute)) this[ONLSTAT](this.statCache.get(this.absolute)) else @@ -108,7 +115,7 @@ const WriteEntry = warner(class WriteEntry extends MiniPass { } [MODE] (mode) { - return modeFix(mode, this.type === 'Directory') + return modeFix(mode, this.type === 'Directory', this.portable) } [HEADER] () { @@ -167,14 +174,14 @@ const WriteEntry = warner(class WriteEntry extends MiniPass { } [ONREADLINK] (linkpath) { - this.linkpath = linkpath + this.linkpath = linkpath.replace(/\\/g, '/') this[HEADER]() this.end() } [HARDLINK] (linkpath) { this.type = 'Link' - this.linkpath = path.relative(this.cwd, linkpath) + this.linkpath = path.relative(this.cwd, linkpath).replace(/\\/g, '/') this.stat.size = 0 this[HEADER]() this.end() @@ -215,8 +222,11 @@ const WriteEntry = warner(class WriteEntry extends MiniPass { [READ] (fd, buf, offset, length, pos, remain, blockRemain) { fs.read(fd, buf, offset, length, pos, (er, bytesRead) => { - if (er) - return this[CLOSE](fd, _ => this.emit('error', er)) + 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](fd, () => this.emit('error', er)) + } this[ONREAD](fd, buf, offset, length, pos, remain, blockRemain, bytesRead) }) } @@ -231,8 +241,7 @@ const WriteEntry = warner(class WriteEntry extends MiniPass { er.path = this.absolute er.syscall = 'read' er.code = 'EOF' - this[CLOSE](fd, _ => _) - return this.emit('error', er) + return this[CLOSE](fd, () => this.emit('error', er)) } if (bytesRead > remain) { @@ -240,8 +249,7 @@ const WriteEntry = warner(class WriteEntry extends MiniPass { er.path = this.absolute er.syscall = 'read' er.code = 'EOF' - this[CLOSE](fd, _ => _) - return this.emit('error', er) + return this[CLOSE](fd, () => this.emit('error', er)) } // null out the rest of the buffer, if we could fit the block padding @@ -265,9 +273,7 @@ const WriteEntry = warner(class WriteEntry extends MiniPass { if (!remain) { if (blockRemain) this.write(Buffer.alloc(blockRemain)) - this.end() - this[CLOSE](fd, _ => _) - return + return this[CLOSE](fd, er => er ? this.emit('error', er) : this.end()) } if (offset >= length) { @@ -303,13 +309,16 @@ class WriteEntrySync extends WriteEntry { this[ONREAD](fd, buf, offset, length, pos, remain, blockRemain, bytesRead) threw = false } finally { + // 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](fd) } catch (er) {} + try { this[CLOSE](fd, () => {}) } catch (er) {} } } - [CLOSE] (fd) { + [CLOSE] (fd, cb) { fs.closeSync(fd) + cb() } } @@ -343,12 +352,10 @@ const WriteEntryTar = warner(class WriteEntryTar extends MiniPass { if (typeof opt.onwarn === 'function') this.on('warn', opt.onwarn) + let pathWarn = false if (path.isAbsolute(this.path) && !this.preservePaths) { const parsed = path.parse(this.path) - this.warn( - 'stripping ' + parsed.root + ' from absolute path', - this.path - ) + pathWarn = parsed.root this.path = this.path.substr(parsed.root.length) } @@ -371,6 +378,13 @@ const WriteEntryTar = warner(class WriteEntryTar extends MiniPass { ctime: this.portable ? null : this.ctime }) + if (pathWarn) { + this.warn('TAR_ENTRY_INFO', `stripping ${pathWarn} from absolute path`, { + entry: this, + path: pathWarn + this.path, + }) + } + if (this.header.encode() && !this.noPax) super.write(new Pax({ atime: this.portable ? null : this.atime, @@ -392,7 +406,7 @@ const WriteEntryTar = warner(class WriteEntryTar extends MiniPass { } [MODE] (mode) { - return modeFix(mode, this.type === 'Directory') + return modeFix(mode, this.type === 'Directory', this.portable) } write (data) { diff --git a/node_modules/tar/node_modules/.bin/mkdirp b/node_modules/tar/node_modules/.bin/mkdirp new file mode 120000 index 000000000..017896ceb --- /dev/null +++ b/node_modules/tar/node_modules/.bin/mkdirp @@ -0,0 +1 @@ +../mkdirp/bin/cmd.js
\ No newline at end of file diff --git a/node_modules/tar/node_modules/minipass/README.md b/node_modules/tar/node_modules/minipass/README.md index c989beea0..32ace2fb9 100644 --- a/node_modules/tar/node_modules/minipass/README.md +++ b/node_modules/tar/node_modules/minipass/README.md @@ -7,32 +7,32 @@ stream](https://nodejs.org/api/stream.html#stream_class_stream_passthrough) fast](https://docs.google.com/spreadsheets/d/1oObKSrVwLX_7Ut4Z6g3fZW-AX1j1-k6w-cDsrkaSbHM/edit#gid=0) for objects, strings, and buffers. -Supports pipe()ing (including multi-pipe() and backpressure -transmission), buffering data until either a `data` event handler or -`pipe()` is added (so you don't lose the first chunk), and most other -cases where PassThrough is a good idea. +Supports pipe()ing (including multi-pipe() and backpressure transmission), +buffering data until either a `data` event handler or `pipe()` is added (so +you don't lose the first chunk), and most other cases where PassThrough is +a good idea. -There is a `read()` method, but it's much more efficient to consume -data from this stream via `'data'` events or by calling `pipe()` into -some other stream. Calling `read()` requires the buffer to be -flattened in some cases, which requires copying memory. +There is a `read()` method, but it's much more efficient to consume data +from this stream via `'data'` events or by calling `pipe()` into some other +stream. Calling `read()` requires the buffer to be flattened in some +cases, which requires copying memory. -There is also no `unpipe()` method. Once you start piping, there is -no stopping it! +There is also no `unpipe()` method. Once you start piping, there is no +stopping it! -If you set `objectMode: true` in the options, then whatever is written -will be emitted. Otherwise, it'll do a minimal amount of Buffer -copying to ensure proper Streams semantics when `read(n)` is called. +If you set `objectMode: true` in the options, then whatever is written will +be emitted. Otherwise, it'll do a minimal amount of Buffer copying to +ensure proper Streams semantics when `read(n)` is called. `objectMode` can also be set by doing `stream.objectMode = true`, or by writing any non-string/non-buffer data. `objectMode` cannot be set to false once it is set. -This is not a `through` or `through2` stream. It doesn't transform -the data, it just passes it right through. If you want to transform -the data, extend the class, and override the `write()` method. Once -you're done transforming the data however you want, call -`super.write()` with the transform output. +This is not a `through` or `through2` stream. It doesn't transform the +data, it just passes it right through. If you want to transform the data, +extend the class, and override the `write()` method. Once you're done +transforming the data however you want, call `super.write()` with the +transform output. For some examples of streams that extend Minipass in various ways, check out: @@ -46,6 +46,7 @@ out: - [tap](http://npm.im/tap) - [tap-parser](http://npm.im/tap) - [treport](http://npm.im/tap) +- [minipass-fetch](http://npm.im/minipass-fetch) ## Differences from Node.js Streams @@ -252,7 +253,8 @@ src.pipe(tee) ## USAGE -It's a stream! Use it like a stream and it'll most likely do what you want. +It's a stream! Use it like a stream and it'll most likely do what you +want. ```js const Minipass = require('minipass') @@ -280,31 +282,30 @@ streams. * `write(chunk, [encoding], [callback])` - Put data in. (Note that, in the base Minipass class, the same data will come out.) Returns `false` if - the stream will buffer the next write, or true if it's still in - "flowing" mode. + the stream will buffer the next write, or true if it's still in "flowing" + mode. * `end([chunk, [encoding]], [callback])` - Signal that you have no more data to write. This will queue an `end` event to be fired when all the data has been consumed. -* `setEncoding(encoding)` - Set the encoding for data coming of the - stream. This can only be done once. +* `setEncoding(encoding)` - Set the encoding for data coming of the stream. + This can only be done once. * `pause()` - No more data for a while, please. This also prevents `end` from being emitted for empty streams until the stream is resumed. -* `resume()` - Resume the stream. If there's data in the buffer, it is - all discarded. Any buffered events are immediately emitted. +* `resume()` - Resume the stream. If there's data in the buffer, it is all + discarded. Any buffered events are immediately emitted. * `pipe(dest)` - Send all output to the stream provided. There is no way to unpipe. When data is emitted, it is immediately written to any and all pipe destinations. -* `on(ev, fn)`, `emit(ev, fn)` - Minipass streams are EventEmitters. - Some events are given special treatment, however. (See below under - "events".) +* `on(ev, fn)`, `emit(ev, fn)` - Minipass streams are EventEmitters. Some + events are given special treatment, however. (See below under "events".) * `promise()` - Returns a Promise that resolves when the stream emits `end`, or rejects if the stream emits `error`. * `collect()` - Return a Promise that resolves on `end` with an array - containing each chunk of data that was emitted, or rejects if the - stream emits `error`. Note that this consumes the stream data. -* `concat()` - Same as `collect()`, but concatenates the data into a - single Buffer object. Will reject the returned promise if the stream is - in objectMode, or if it goes into objectMode by the end of the data. + containing each chunk of data that was emitted, or rejects if the stream + emits `error`. Note that this consumes the stream data. +* `concat()` - Same as `collect()`, but concatenates the data into a single + Buffer object. Will reject the returned promise if the stream is in + objectMode, or if it goes into objectMode by the end of the data. * `read(n)` - Consume `n` bytes of data out of the buffer. If `n` is not provided, then consume all of it. If `n` bytes are not available, then it returns null. **Note** consuming streams in this way is less @@ -421,8 +422,8 @@ mp.concat().then(onebigchunk => { ### iteration -You can iterate over streams synchronously or asynchronously in -platforms that support it. +You can iterate over streams synchronously or asynchronously in platforms +that support it. Synchronous iteration will end when the currently available data is consumed, even if the `end` event has not been reached. In string and @@ -430,9 +431,8 @@ buffer mode, the data is concatenated, so unless multiple writes are occurring in the same tick as the `read()`, sync iteration loops will generally only have a single iteration. -To consume chunks in this way exactly as they have been written, with -no flattening, create the stream with the `{ objectMode: true }` -option. +To consume chunks in this way exactly as they have been written, with no +flattening, create the stream with the `{ objectMode: true }` option. ```js const mp = new Minipass({ objectMode: true }) diff --git a/node_modules/tar/node_modules/minipass/index.js b/node_modules/tar/node_modules/minipass/index.js index c072352d4..55ea0f3dd 100644 --- a/node_modules/tar/node_modules/minipass/index.js +++ b/node_modules/tar/node_modules/minipass/index.js @@ -1,5 +1,6 @@ 'use strict' const EE = require('events') +const Stream = require('stream') const Yallist = require('yallist') const SD = require('string_decoder').StringDecoder @@ -29,12 +30,6 @@ const ASYNCITERATOR = doIter && Symbol.asyncIterator const ITERATOR = doIter && Symbol.iterator || Symbol('iterator not implemented') -// Buffer in node 4.x < 4.5.0 doesn't have working Buffer.from -// or Buffer.alloc, and Buffer in node 10 deprecated the ctor. -// .M, this is fine .\^/M.. -const B = Buffer.alloc ? Buffer - : /* istanbul ignore next */ require('safe-buffer').Buffer - // events that mean 'the stream is over' // these are treated specially, and re-emitted // if they are listened for after emitting. @@ -49,9 +44,9 @@ const isArrayBuffer = b => b instanceof ArrayBuffer || b.constructor.name === 'ArrayBuffer' && b.byteLength >= 0 -const isArrayBufferView = b => !B.isBuffer(b) && ArrayBuffer.isView(b) +const isArrayBufferView = b => !Buffer.isBuffer(b) && ArrayBuffer.isView(b) -module.exports = class Minipass extends EE { +module.exports = class Minipass extends Stream { constructor (options) { super() this[FLOWING] = false @@ -126,11 +121,11 @@ module.exports = class Minipass extends EE { // at some point in the future, we may want to do the opposite! // leave strings and buffers as-is // anything else switches us into object mode - if (!this[OBJECTMODE] && !B.isBuffer(chunk)) { + if (!this[OBJECTMODE] && !Buffer.isBuffer(chunk)) { if (isArrayBufferView(chunk)) - chunk = B.from(chunk.buffer, chunk.byteOffset, chunk.byteLength) + chunk = Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength) else if (isArrayBuffer(chunk)) - chunk = B.from(chunk) + chunk = Buffer.from(chunk) else if (typeof chunk !== 'string') // use the setter so we throw if we have encoding set this.objectMode = true @@ -152,10 +147,10 @@ module.exports = class Minipass extends EE { if (typeof chunk === 'string' && !this[OBJECTMODE] && // unless it is a string already ready for us to use !(encoding === this[ENCODING] && !this[DECODER].lastNeed)) { - chunk = B.from(chunk, encoding) + chunk = Buffer.from(chunk, encoding) } - if (B.isBuffer(chunk) && this[ENCODING]) + if (Buffer.isBuffer(chunk) && this[ENCODING]) chunk = this[DECODER].write(chunk) try { @@ -188,7 +183,7 @@ module.exports = class Minipass extends EE { ]) else this.buffer = new Yallist([ - B.concat(Array.from(this.buffer), this[BUFFERLENGTH]) + Buffer.concat(Array.from(this.buffer), this[BUFFERLENGTH]) ]) } @@ -423,12 +418,17 @@ module.exports = class Minipass extends EE { // const all = await stream.collect() collect () { const buf = [] - buf.dataLength = 0 + if (!this[OBJECTMODE]) + buf.dataLength = 0 + // set the promise first, in case an error is raised + // by triggering the flow here. + const p = this.promise() this.on('data', c => { buf.push(c) - buf.dataLength += c.length + if (!this[OBJECTMODE]) + buf.dataLength += c.length }) - return this.promise().then(() => buf) + return p.then(() => buf) } // const data = await stream.concat() @@ -438,7 +438,7 @@ module.exports = class Minipass extends EE { : this.collect().then(buf => this[OBJECTMODE] ? Promise.reject(new Error('cannot concat in objectMode')) - : this[ENCODING] ? buf.join('') : B.concat(buf, buf.dataLength)) + : this[ENCODING] ? buf.join('') : Buffer.concat(buf, buf.dataLength)) } // stream.promise().then(() => done, er => emitted error) @@ -529,9 +529,10 @@ module.exports = class Minipass extends EE { } static isStream (s) { - return !!s && (s instanceof Minipass || s instanceof EE && ( - typeof s.pipe === 'function' || // readable - (typeof s.write === 'function' && typeof s.end === 'function') // writable - )) + return !!s && (s instanceof Minipass || s instanceof Stream || + s instanceof EE && ( + typeof s.pipe === 'function' || // readable + (typeof s.write === 'function' && typeof s.end === 'function') // writable + )) } } diff --git a/node_modules/tar/node_modules/minipass/package.json b/node_modules/tar/node_modules/minipass/package.json index aeb390253..568682bc2 100644 --- a/node_modules/tar/node_modules/minipass/package.json +++ b/node_modules/tar/node_modules/minipass/package.json @@ -1,27 +1,27 @@ { - "_from": "minipass@^2.8.6", - "_id": "minipass@2.9.0", + "_from": "minipass@^3.0.0", + "_id": "minipass@3.1.1", "_inBundle": false, - "_integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "_integrity": "sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w==", "_location": "/tar/minipass", "_phantomChildren": {}, "_requested": { "type": "range", "registry": true, - "raw": "minipass@^2.8.6", + "raw": "minipass@^3.0.0", "name": "minipass", "escapedName": "minipass", - "rawSpec": "^2.8.6", + "rawSpec": "^3.0.0", "saveSpec": null, - "fetchSpec": "^2.8.6" + "fetchSpec": "^3.0.0" }, "_requiredBy": [ "/tar" ], - "_resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "_shasum": "e713762e7d3e32fed803115cf93e04bca9fcc9a6", - "_spec": "minipass@^2.8.6", - "_where": "/Users/mperrotte/npminc/cli/node_modules/tar", + "_resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.1.tgz", + "_shasum": "7607ce778472a185ad6d89082aa2070f79cedcd5", + "_spec": "minipass@^3.0.0", + "_where": "/Users/claudiahdz/npm/cli/node_modules/tar", "author": { "name": "Isaac Z. Schlueter", "email": "i@izs.me", @@ -32,8 +32,7 @@ }, "bundleDependencies": false, "dependencies": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" + "yallist": "^4.0.0" }, "deprecated": false, "description": "minimal implementation of a PassThrough stream", @@ -42,6 +41,9 @@ "tap": "^14.6.5", "through2": "^2.0.3" }, + "engines": { + "node": ">=8" + }, "files": [ "index.js" ], @@ -59,12 +61,12 @@ }, "scripts": { "postpublish": "git push origin --follow-tags", - "postversion": "npm publish", + "postversion": "npm publish --tag=next", "preversion": "npm test", "test": "tap" }, "tap": { "check-coverage": true }, - "version": "2.9.0" + "version": "3.1.1" } diff --git a/node_modules/tar/node_modules/mkdirp/CHANGELOG.md b/node_modules/tar/node_modules/mkdirp/CHANGELOG.md new file mode 100644 index 000000000..81458380b --- /dev/null +++ b/node_modules/tar/node_modules/mkdirp/CHANGELOG.md @@ -0,0 +1,15 @@ +# Changers Lorgs! + +## 1.0 + +Full rewrite. Essentially a brand new module. + +- Return a promise instead of taking a callback. +- Use native `fs.mkdir(path, { recursive: true })` when available. +- Drop support for outdated Node.js versions. (Technically still works on + Node.js v8, but only 10 and above are officially supported.) + +## 0.x + +Original and most widely used recursive directory creation implementation +in JavaScript, dating back to 2010. diff --git a/node_modules/tar/node_modules/mkdirp/LICENSE b/node_modules/tar/node_modules/mkdirp/LICENSE new file mode 100644 index 000000000..13fcd15f0 --- /dev/null +++ b/node_modules/tar/node_modules/mkdirp/LICENSE @@ -0,0 +1,21 @@ +Copyright James Halliday (mail@substack.net) and Isaac Z. Schlueter (i@izs.me) + +This project is free software released under the MIT license: + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/node_modules/tar/node_modules/mkdirp/bin/cmd.js b/node_modules/tar/node_modules/mkdirp/bin/cmd.js new file mode 100755 index 000000000..6e0aa8dc4 --- /dev/null +++ b/node_modules/tar/node_modules/mkdirp/bin/cmd.js @@ -0,0 +1,68 @@ +#!/usr/bin/env node + +const usage = () => ` +usage: mkdirp [DIR1,DIR2..] {OPTIONS} + + Create each supplied directory including any necessary parent directories + that don't yet exist. + + If the directory already exists, do nothing. + +OPTIONS are: + + -m<mode> If a directory needs to be created, set the mode as an octal + --mode=<mode> permission string. + + -v --version Print the mkdirp version number + + -h --help Print this helpful banner + + -p --print Print the first directories created for each path provided + + --manual Use manual implementation, even if native is available +` + +const dirs = [] +const opts = {} +let print = false +let dashdash = false +let manual = false +for (const arg of process.argv.slice(2)) { + if (dashdash) + dirs.push(arg) + else if (arg === '--') + dashdash = true + else if (arg === '--manual') + manual = true + else if (/^-h/.test(arg) || /^--help/.test(arg)) { + console.log(usage()) + process.exit(0) + } else if (arg === '-v' || arg === '--version') { + console.log(require('../package.json').version) + process.exit(0) + } else if (arg === '-p' || arg === '--print') { + print = true + } else if (/^-m/.test(arg) || /^--mode=/.test(arg)) { + const mode = parseInt(arg.replace(/^(-m|--mode=)/, ''), 8) + if (isNaN(mode)) { + console.error(`invalid mode argument: ${arg}\nMust be an octal number.`) + process.exit(1) + } + opts.mode = mode + } else + dirs.push(arg) +} + +const mkdirp = require('../') +const impl = manual ? mkdirp.manual : mkdirp +if (dirs.length === 0) + console.error(usage()) + +Promise.all(dirs.map(dir => impl(dir, opts))) + .then(made => print ? made.forEach(m => m && console.log(m)) : null) + .catch(er => { + console.error(er.message) + if (er.code) + console.error(' code: ' + er.code) + process.exit(1) + }) diff --git a/node_modules/tar/node_modules/mkdirp/index.js b/node_modules/tar/node_modules/mkdirp/index.js new file mode 100644 index 000000000..ad7a16c9f --- /dev/null +++ b/node_modules/tar/node_modules/mkdirp/index.js @@ -0,0 +1,31 @@ +const optsArg = require('./lib/opts-arg.js') +const pathArg = require('./lib/path-arg.js') + +const {mkdirpNative, mkdirpNativeSync} = require('./lib/mkdirp-native.js') +const {mkdirpManual, mkdirpManualSync} = require('./lib/mkdirp-manual.js') +const {useNative, useNativeSync} = require('./lib/use-native.js') + + +const mkdirp = (path, opts) => { + path = pathArg(path) + opts = optsArg(opts) + return useNative(opts) + ? mkdirpNative(path, opts) + : mkdirpManual(path, opts) +} + +const mkdirpSync = (path, opts) => { + path = pathArg(path) + opts = optsArg(opts) + return useNativeSync(opts) + ? mkdirpNativeSync(path, opts) + : mkdirpManualSync(path, opts) +} + +mkdirp.sync = mkdirpSync +mkdirp.native = (path, opts) => mkdirpNative(pathArg(path), optsArg(opts)) +mkdirp.manual = (path, opts) => mkdirpManual(pathArg(path), optsArg(opts)) +mkdirp.nativeSync = (path, opts) => mkdirpNativeSync(pathArg(path), optsArg(opts)) +mkdirp.manualSync = (path, opts) => mkdirpManualSync(pathArg(path), optsArg(opts)) + +module.exports = mkdirp diff --git a/node_modules/tar/node_modules/mkdirp/lib/find-made.js b/node_modules/tar/node_modules/mkdirp/lib/find-made.js new file mode 100644 index 000000000..022e492c0 --- /dev/null +++ b/node_modules/tar/node_modules/mkdirp/lib/find-made.js @@ -0,0 +1,29 @@ +const {dirname} = require('path') + +const findMade = (opts, parent, path = undefined) => { + // we never want the 'made' return value to be a root directory + if (path === parent) + return Promise.resolve() + + return opts.statAsync(parent).then( + st => st.isDirectory() ? path : undefined, // will fail later + er => er.code === 'ENOENT' + ? findMade(opts, dirname(parent), parent) + : undefined + ) +} + +const findMadeSync = (opts, parent, path = undefined) => { + if (path === parent) + return undefined + + try { + return opts.statSync(parent).isDirectory() ? path : undefined + } catch (er) { + return er.code === 'ENOENT' + ? findMadeSync(opts, dirname(parent), parent) + : undefined + } +} + +module.exports = {findMade, findMadeSync} diff --git a/node_modules/tar/node_modules/mkdirp/lib/mkdirp-manual.js b/node_modules/tar/node_modules/mkdirp/lib/mkdirp-manual.js new file mode 100644 index 000000000..2eb18cd64 --- /dev/null +++ b/node_modules/tar/node_modules/mkdirp/lib/mkdirp-manual.js @@ -0,0 +1,64 @@ +const {dirname} = require('path') + +const mkdirpManual = (path, opts, made) => { + opts.recursive = false + const parent = dirname(path) + if (parent === path) { + return opts.mkdirAsync(path, opts).catch(er => { + // swallowed by recursive implementation on posix systems + // any other error is a failure + if (er.code !== 'EISDIR') + throw er + }) + } + + return opts.mkdirAsync(path, opts).then(() => made || path, er => { + if (er.code === 'ENOENT') + return mkdirpManual(parent, opts) + .then(made => mkdirpManual(path, opts, made)) + if (er.code !== 'EEXIST' && er.code !== 'EROFS') + throw er + return opts.statAsync(path).then(st => { + if (st.isDirectory()) + return made + else + throw er + }, () => { throw er }) + }) +} + +const mkdirpManualSync = (path, opts, made) => { + const parent = dirname(path) + opts.recursive = false + + if (parent === path) { + try { + return opts.mkdirSync(path, opts) + } catch (er) { + // swallowed by recursive implementation on posix systems + // any other error is a failure + if (er.code !== 'EISDIR') + throw er + else + return + } + } + + try { + opts.mkdirSync(path, opts) + return made || path + } catch (er) { + if (er.code === 'ENOENT') + return mkdirpManualSync(path, opts, mkdirpManualSync(parent, opts, made)) + if (er.code !== 'EEXIST' && er.code !== 'EROFS') + throw er + try { + if (!opts.statSync(path).isDirectory()) + throw er + } catch (_) { + throw er + } + } +} + +module.exports = {mkdirpManual, mkdirpManualSync} diff --git a/node_modules/tar/node_modules/mkdirp/lib/mkdirp-native.js b/node_modules/tar/node_modules/mkdirp/lib/mkdirp-native.js new file mode 100644 index 000000000..c7a6b6980 --- /dev/null +++ b/node_modules/tar/node_modules/mkdirp/lib/mkdirp-native.js @@ -0,0 +1,39 @@ +const {dirname} = require('path') +const {findMade, findMadeSync} = require('./find-made.js') +const {mkdirpManual, mkdirpManualSync} = require('./mkdirp-manual.js') + +const mkdirpNative = (path, opts) => { + opts.recursive = true + const parent = dirname(path) + if (parent === path) + return opts.mkdirAsync(path, opts) + + return findMade(opts, path).then(made => + opts.mkdirAsync(path, opts).then(() => made) + .catch(er => { + if (er.code === 'ENOENT') + return mkdirpManual(path, opts) + else + throw er + })) +} + +const mkdirpNativeSync = (path, opts) => { + opts.recursive = true + const parent = dirname(path) + if (parent === path) + return opts.mkdirSync(path, opts) + + const made = findMadeSync(opts, path) + try { + opts.mkdirSync(path, opts) + return made + } catch (er) { + if (er.code === 'ENOENT') + return mkdirpManualSync(path, opts) + else + throw er + } +} + +module.exports = {mkdirpNative, mkdirpNativeSync} diff --git a/node_modules/tar/node_modules/mkdirp/lib/opts-arg.js b/node_modules/tar/node_modules/mkdirp/lib/opts-arg.js new file mode 100644 index 000000000..488bd44c3 --- /dev/null +++ b/node_modules/tar/node_modules/mkdirp/lib/opts-arg.js @@ -0,0 +1,23 @@ +const { promisify } = require('util') +const fs = require('fs') +const optsArg = opts => { + if (!opts) + opts = { mode: 0o777 & (~process.umask()), fs } + else if (typeof opts === 'object') + opts = { mode: 0o777 & (~process.umask()), fs, ...opts } + else if (typeof opts === 'number') + opts = { mode: opts, fs } + else if (typeof opts === 'string') + opts = { mode: parseInt(opts, 8), fs } + else + throw new TypeError('invalid options argument') + + opts.mkdir = opts.mkdir || opts.fs.mkdir || fs.mkdir + opts.mkdirAsync = promisify(opts.mkdir) + opts.stat = opts.stat || opts.fs.stat || fs.stat + opts.statAsync = promisify(opts.stat) + opts.statSync = opts.statSync || opts.fs.statSync || fs.statSync + opts.mkdirSync = opts.mkdirSync || opts.fs.mkdirSync || fs.mkdirSync + return opts +} +module.exports = optsArg diff --git a/node_modules/tar/node_modules/mkdirp/lib/path-arg.js b/node_modules/tar/node_modules/mkdirp/lib/path-arg.js new file mode 100644 index 000000000..cc07de5a6 --- /dev/null +++ b/node_modules/tar/node_modules/mkdirp/lib/path-arg.js @@ -0,0 +1,29 @@ +const platform = process.env.__TESTING_MKDIRP_PLATFORM__ || process.platform +const { resolve, parse } = require('path') +const pathArg = path => { + if (/\0/.test(path)) { + // simulate same failure that node raises + throw Object.assign( + new TypeError('path must be a string without null bytes'), + { + path, + code: 'ERR_INVALID_ARG_VALUE', + } + ) + } + + path = resolve(path) + if (platform === 'win32') { + const badWinChars = /[*|"<>?:]/ + const {root} = parse(path) + if (badWinChars.test(path.substr(root.length))) { + throw Object.assign(new Error('Illegal characters in path.'), { + path, + code: 'EINVAL', + }) + } + } + + return path +} +module.exports = pathArg diff --git a/node_modules/tar/node_modules/mkdirp/lib/use-native.js b/node_modules/tar/node_modules/mkdirp/lib/use-native.js new file mode 100644 index 000000000..079361de1 --- /dev/null +++ b/node_modules/tar/node_modules/mkdirp/lib/use-native.js @@ -0,0 +1,10 @@ +const fs = require('fs') + +const version = process.env.__TESTING_MKDIRP_NODE_VERSION__ || process.version +const versArr = version.replace(/^v/, '').split('.') +const hasNative = +versArr[0] > 10 || +versArr[0] === 10 && +versArr[1] >= 12 + +const useNative = !hasNative ? () => false : opts => opts.mkdir === fs.mkdir +const useNativeSync = !hasNative ? () => false : opts => opts.mkdirSync === fs.mkdirSync + +module.exports = {useNative, useNativeSync} diff --git a/node_modules/tar/node_modules/mkdirp/package.json b/node_modules/tar/node_modules/mkdirp/package.json new file mode 100644 index 000000000..f6c5a817f --- /dev/null +++ b/node_modules/tar/node_modules/mkdirp/package.json @@ -0,0 +1,75 @@ +{ + "_from": "mkdirp@^1.0.3", + "_id": "mkdirp@1.0.3", + "_inBundle": false, + "_integrity": "sha512-6uCP4Qc0sWsgMLy1EOqqS/3rjDHOEnsStVr/4vtAIK2Y5i2kA7lFFejYrpIyiN9w0pYf4ckeCYT9f1r1P9KX5g==", + "_location": "/tar/mkdirp", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "mkdirp@^1.0.3", + "name": "mkdirp", + "escapedName": "mkdirp", + "rawSpec": "^1.0.3", + "saveSpec": null, + "fetchSpec": "^1.0.3" + }, + "_requiredBy": [ + "/tar" + ], + "_resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.3.tgz", + "_shasum": "4cf2e30ad45959dddea53ad97d518b6c8205e1ea", + "_spec": "mkdirp@^1.0.3", + "_where": "/Users/claudiahdz/npm/cli/node_modules/tar", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "bugs": { + "url": "https://github.com/isaacs/node-mkdirp/issues" + }, + "bundleDependencies": false, + "deprecated": false, + "description": "Recursively mkdir, like `mkdir -p`", + "devDependencies": { + "require-inject": "^1.4.4", + "tap": "^14.10.6" + }, + "engines": { + "node": ">=10" + }, + "files": [ + "bin", + "lib", + "index.js" + ], + "homepage": "https://github.com/isaacs/node-mkdirp#readme", + "keywords": [ + "mkdir", + "directory", + "make dir", + "make", + "dir", + "recursive", + "native" + ], + "license": "MIT", + "main": "index.js", + "name": "mkdirp", + "repository": { + "type": "git", + "url": "git+https://github.com/isaacs/node-mkdirp.git" + }, + "scripts": { + "postpublish": "git push origin --follow-tags", + "postversion": "npm publish", + "preversion": "npm test", + "snap": "tap", + "test": "tap" + }, + "tap": { + "check-coverage": true, + "coverage-map": "map.js" + }, + "version": "1.0.3" +} diff --git a/node_modules/tar/node_modules/mkdirp/readme.markdown b/node_modules/tar/node_modules/mkdirp/readme.markdown new file mode 100644 index 000000000..827de5905 --- /dev/null +++ b/node_modules/tar/node_modules/mkdirp/readme.markdown @@ -0,0 +1,266 @@ +# mkdirp + +Like `mkdir -p`, but in Node.js! + +Now with a modern API and no\* bugs! + +<small>\* may contain some bugs</small> + +# example + +## pow.js + +```js +const mkdirp = require('mkdirp') + +// return value is a Promise resolving to the first directory created +mkdirp('/tmp/foo/bar/baz').then(made => + console.log(`made directories, starting with ${made}`)) +``` + +Output (where `/tmp/foo` already exists) + +``` +made directories, starting with /tmp/foo/bar +``` + +Or, if you don't have time to wait around for promises: + +```js +const mkdirp = require('mkdirp') + +// return value is the first directory created +const made = mkdirp.sync('/tmp/foo/bar/baz') +console.log(`made directories, starting with ${made}`) +``` + +And now /tmp/foo/bar/baz exists, huzzah! + +# methods + +```js +const mkdirp = require('mkdirp') +``` + +## mkdirp(dir, [opts]) -> Promise<String | undefined> + +Create a new directory and any necessary subdirectories at `dir` with octal +permission string `opts.mode`. If `opts` is a string or number, it will be +treated as the `opts.mode`. + +If `opts.mode` isn't specified, it defaults to `0o777 & +(~process.umask())`. + +Promise resolves to first directory `made` that had to be created, or +`undefined` if everything already exists. Promise rejects if any errors +are encountered. Note that, in the case of promise rejection, some +directories _may_ have been created, as recursive directory creation is not +an atomic operation. + +You can optionally pass in an alternate `fs` implementation by passing in +`opts.fs`. Your implementation should have `opts.fs.mkdir(path, opts, cb)` +and `opts.fs.stat(path, cb)`. + +You can also override just one or the other of `mkdir` and `stat` by +passing in `opts.stat` or `opts.mkdir`, or providing an `fs` option that +only overrides one of these. + +## mkdirp.sync(dir, opts) -> String|null + +Synchronously create a new directory and any necessary subdirectories at +`dir` with octal permission string `opts.mode`. If `opts` is a string or +number, it will be treated as the `opts.mode`. + +If `opts.mode` isn't specified, it defaults to `0o777 & +(~process.umask())`. + +Returns the first directory that had to be created, or undefined if +everything already exists. + +You can optionally pass in an alternate `fs` implementation by passing in +`opts.fs`. Your implementation should have `opts.fs.mkdirSync(path, mode)` +and `opts.fs.statSync(path)`. + +You can also override just one or the other of `mkdirSync` and `statSync` +by passing in `opts.statSync` or `opts.mkdirSync`, or providing an `fs` +option that only overrides one of these. + +## mkdirp.manual, mkdirp.manualSync + +Use the manual implementation (not the native one). This is the default +when the native implementation is not available or the stat/mkdir +implementation is overridden. + +## mkdirp.native, mkdirp.nativeSync + +Use the native implementation (not the manual one). This is the default +when the native implementation is available and stat/mkdir are not +overridden. + +# implementation + +On Node.js v10.12.0 and above, use the native `fs.mkdir(p, +{recursive:true})` option, unless `fs.mkdir`/`fs.mkdirSync` has been +overridden by an option. + +## native implementation + +- If the path is a root directory, then pass it to the underlying + implementation and return the result/error. (In this case, it'll either + succeed or fail, but we aren't actually creating any dirs.) +- Walk up the path statting each directory, to find the first path that + will be created, `made`. +- Call `fs.mkdir(path, { recursive: true })` (or `fs.mkdirSync`) +- If error, raise it to the caller. +- Return `made`. + +## manual implementation + +- Call underlying `fs.mkdir` implementation, with `recursive: false` +- If error: + - If path is a root directory, raise to the caller and do not handle it + - If ENOENT, mkdirp parent dir, store result as `made` + - stat(path) + - If error, raise original `mkdir` error + - If directory, return `made` + - Else, raise original `mkdir` error +- else + - return `undefined` if a root dir, or `made` if set, or `path` + +## windows vs unix caveat + +On Windows file systems, attempts to create a root directory (ie, a drive +letter or root UNC path) will fail. If the root directory exists, then it +will fail with `EPERM`. If the root directory does not exist, then it will +fail with `ENOENT`. + +On posix file systems, attempts to create a root directory (in recursive +mode) will succeed silently, as it is treated like just another directory +that already exists. (In non-recursive mode, of course, it fails with +`EEXIST`.) + +In order to preserve this system-specific behavior (and because it's not as +if we can create the parent of a root directory anyway), attempts to create +a root directory are passed directly to the `fs` implementation, and any +errors encountered are not handled. + +## native error caveat + +The native implementation (as of at least Node.js v13.4.0) does not provide +appropriate errors in some cases (see +[nodejs/node#31481](https://github.com/nodejs/node/issues/31481) and +[nodejs/node#28015](https://github.com/nodejs/node/issues/28015)). + +In order to work around this issue, the native implementation will fall +back to the manual implementation if an `ENOENT` error is encountered. + +# choosing a recursive mkdir implementation + +There are a few to choose from! Use the one that suits your needs best :D + +## use `fs.mkdir(path, {recursive: true}, cb)` if: + +- You wish to optimize performance even at the expense of other factors. +- You don't need to know the first dir created. +- You are ok with getting `ENOENT` as the error when some other problem is + the actual cause. +- You can limit your platforms to Node.js v10.12 and above. +- You're ok with using callbacks instead of promises. +- You don't need/want a CLI. +- You don't need to override the `fs` methods in use. + +## use this module (mkdirp 1.x) if: + +- You need to know the first directory that was created. +- You wish to use the native implementation if available, but fall back + when it's not. +- You prefer promise-returning APIs to callback-taking APIs. +- You want more useful error messages than the native recursive mkdir + provides (at least as of Node.js v13.4), and are ok with re-trying on + `ENOENT` to achieve this. +- You need (or at least, are ok with) a CLI. +- You need to override the `fs` methods in use. + +## use [`make-dir`](http://npm.im/make-dir) if: + +- You do not need to know the first dir created (and wish to save a few + `stat` calls when using the native implementation for this reason). +- You wish to use the native implementation if available, but fall back + when it's not. +- You prefer promise-returning APIs to callback-taking APIs. +- You are ok with occasionally getting `ENOENT` errors for failures that + are actually related to something other than a missing file system entry. +- You don't need/want a CLI. +- You need to override the `fs` methods in use. + +## use mkdirp 0.x if: + +- You need to know the first directory that was created. +- You need (or at least, are ok with) a CLI. +- You need to override the `fs` methods in use. +- You're ok with using callbacks instead of promises. +- You are not running on Windows, where the root-level ENOENT errors can + lead to infinite regress. +- You think vinyl just sounds warmer and richer for some weird reason. +- You are supporting truly ancient Node.js versions, before even the advent + of a `Promise` language primitive. (Please don't. You deserve better.) + +# cli + +This package also ships with a `mkdirp` command. + +``` +$ mkdirp -h + +usage: mkdirp [DIR1,DIR2..] {OPTIONS} + + Create each supplied directory including any necessary parent directories + that don't yet exist. + + If the directory already exists, do nothing. + +OPTIONS are: + + -m<mode> If a directory needs to be created, set the mode as an octal + --mode=<mode> permission string. + + -v --version Print the mkdirp version number + + -h --help Print this helpful banner + + -p --print Print the first directories created for each path provided + + --manual Use manual implementation, even if native is available +``` + +# install + +With [npm](http://npmjs.org) do: + +``` +npm install mkdirp +``` + +to get the library locally, or + +``` +npm install -g mkdirp +``` + +to get the command everywhere, or + +``` +npx mkdirp ... +``` + +to run the command without installing it globally. + +# platform support + +This module works on node v8, but only v10 and above are officially +supported, as Node v8 reached its LTS end of life 2020-01-01, which is in +the past, as of this writing. + +# license + +MIT diff --git a/node_modules/tar/node_modules/yallist/LICENSE b/node_modules/tar/node_modules/yallist/LICENSE new file mode 100644 index 000000000..19129e315 --- /dev/null +++ b/node_modules/tar/node_modules/yallist/LICENSE @@ -0,0 +1,15 @@ +The ISC License + +Copyright (c) Isaac Z. Schlueter and Contributors + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +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. diff --git a/node_modules/tar/node_modules/yallist/README.md b/node_modules/tar/node_modules/yallist/README.md new file mode 100644 index 000000000..f58610186 --- /dev/null +++ b/node_modules/tar/node_modules/yallist/README.md @@ -0,0 +1,204 @@ +# yallist + +Yet Another Linked List + +There are many doubly-linked list implementations like it, but this +one is mine. + +For when an array would be too big, and a Map can't be iterated in +reverse order. + + +[![Build Status](https://travis-ci.org/isaacs/yallist.svg?branch=master)](https://travis-ci.org/isaacs/yallist) [![Coverage Status](https://coveralls.io/repos/isaacs/yallist/badge.svg?service=github)](https://coveralls.io/github/isaacs/yallist) + +## basic usage + +```javascript +var yallist = require('yallist') +var myList = yallist.create([1, 2, 3]) +myList.push('foo') +myList.unshift('bar') +// of course pop() and shift() are there, too +console.log(myList.toArray()) // ['bar', 1, 2, 3, 'foo'] +myList.forEach(function (k) { + // walk the list head to tail +}) +myList.forEachReverse(function (k, index, list) { + // walk the list tail to head +}) +var myDoubledList = myList.map(function (k) { + return k + k +}) +// now myDoubledList contains ['barbar', 2, 4, 6, 'foofoo'] +// mapReverse is also a thing +var myDoubledListReverse = myList.mapReverse(function (k) { + return k + k +}) // ['foofoo', 6, 4, 2, 'barbar'] + +var reduced = myList.reduce(function (set, entry) { + set += entry + return set +}, 'start') +console.log(reduced) // 'startfoo123bar' +``` + +## api + +The whole API is considered "public". + +Functions with the same name as an Array method work more or less the +same way. + +There's reverse versions of most things because that's the point. + +### Yallist + +Default export, the class that holds and manages a list. + +Call it with either a forEach-able (like an array) or a set of +arguments, to initialize the list. + +The Array-ish methods all act like you'd expect. No magic length, +though, so if you change that it won't automatically prune or add +empty spots. + +### Yallist.create(..) + +Alias for Yallist function. Some people like factories. + +#### yallist.head + +The first node in the list + +#### yallist.tail + +The last node in the list + +#### yallist.length + +The number of nodes in the list. (Change this at your peril. It is +not magic like Array length.) + +#### yallist.toArray() + +Convert the list to an array. + +#### yallist.forEach(fn, [thisp]) + +Call a function on each item in the list. + +#### yallist.forEachReverse(fn, [thisp]) + +Call a function on each item in the list, in reverse order. + +#### yallist.get(n) + +Get the data at position `n` in the list. If you use this a lot, +probably better off just using an Array. + +#### yallist.getReverse(n) + +Get the data at position `n`, counting from the tail. + +#### yallist.map(fn, thisp) + +Create a new Yallist with the result of calling the function on each +item. + +#### yallist.mapReverse(fn, thisp) + +Same as `map`, but in reverse. + +#### yallist.pop() + +Get the data from the list tail, and remove the tail from the list. + +#### yallist.push(item, ...) + +Insert one or more items to the tail of the list. + +#### yallist.reduce(fn, initialValue) + +Like Array.reduce. + +#### yallist.reduceReverse + +Like Array.reduce, but in reverse. + +#### yallist.reverse + +Reverse the list in place. + +#### yallist.shift() + +Get the data from the list head, and remove the head from the list. + +#### yallist.slice([from], [to]) + +Just like Array.slice, but returns a new Yallist. + +#### yallist.sliceReverse([from], [to]) + +Just like yallist.slice, but the result is returned in reverse. + +#### yallist.toArray() + +Create an array representation of the list. + +#### yallist.toArrayReverse() + +Create a reversed array representation of the list. + +#### yallist.unshift(item, ...) + +Insert one or more items to the head of the list. + +#### yallist.unshiftNode(node) + +Move a Node object to the front of the list. (That is, pull it out of +wherever it lives, and make it the new head.) + +If the node belongs to a different list, then that list will remove it +first. + +#### yallist.pushNode(node) + +Move a Node object to the end of the list. (That is, pull it out of +wherever it lives, and make it the new tail.) + +If the node belongs to a list already, then that list will remove it +first. + +#### yallist.removeNode(node) + +Remove a node from the list, preserving referential integrity of head +and tail and other nodes. + +Will throw an error if you try to have a list remove a node that +doesn't belong to it. + +### Yallist.Node + +The class that holds the data and is actually the list. + +Call with `var n = new Node(value, previousNode, nextNode)` + +Note that if you do direct operations on Nodes themselves, it's very +easy to get into weird states where the list is broken. Be careful :) + +#### node.next + +The next node in the list. + +#### node.prev + +The previous node in the list. + +#### node.value + +The data the node contains. + +#### node.list + +The list to which this node belongs. (Null if it does not belong to +any list.) diff --git a/node_modules/tar/node_modules/yallist/iterator.js b/node_modules/tar/node_modules/yallist/iterator.js new file mode 100644 index 000000000..d41c97a19 --- /dev/null +++ b/node_modules/tar/node_modules/yallist/iterator.js @@ -0,0 +1,8 @@ +'use strict' +module.exports = function (Yallist) { + Yallist.prototype[Symbol.iterator] = function* () { + for (let walker = this.head; walker; walker = walker.next) { + yield walker.value + } + } +} diff --git a/node_modules/tar/node_modules/yallist/package.json b/node_modules/tar/node_modules/yallist/package.json new file mode 100644 index 000000000..83e3c6b56 --- /dev/null +++ b/node_modules/tar/node_modules/yallist/package.json @@ -0,0 +1,63 @@ +{ + "_from": "yallist@^4.0.0", + "_id": "yallist@4.0.0", + "_inBundle": false, + "_integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "_location": "/tar/yallist", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "yallist@^4.0.0", + "name": "yallist", + "escapedName": "yallist", + "rawSpec": "^4.0.0", + "saveSpec": null, + "fetchSpec": "^4.0.0" + }, + "_requiredBy": [ + "/tar", + "/tar/minipass" + ], + "_resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "_shasum": "9bb92790d9c0effec63be73519e11a35019a3a72", + "_spec": "yallist@^4.0.0", + "_where": "/Users/claudiahdz/npm/cli/node_modules/tar", + "author": { + "name": "Isaac Z. Schlueter", + "email": "i@izs.me", + "url": "http://blog.izs.me/" + }, + "bugs": { + "url": "https://github.com/isaacs/yallist/issues" + }, + "bundleDependencies": false, + "dependencies": {}, + "deprecated": false, + "description": "Yet Another Linked List", + "devDependencies": { + "tap": "^12.1.0" + }, + "directories": { + "test": "test" + }, + "files": [ + "yallist.js", + "iterator.js" + ], + "homepage": "https://github.com/isaacs/yallist#readme", + "license": "ISC", + "main": "yallist.js", + "name": "yallist", + "repository": { + "type": "git", + "url": "git+https://github.com/isaacs/yallist.git" + }, + "scripts": { + "postpublish": "git push origin --all; git push origin --tags", + "postversion": "npm publish", + "preversion": "npm test", + "test": "tap test/*.js --100" + }, + "version": "4.0.0" +} diff --git a/node_modules/tar/node_modules/yallist/yallist.js b/node_modules/tar/node_modules/yallist/yallist.js new file mode 100644 index 000000000..4e83ab1c5 --- /dev/null +++ b/node_modules/tar/node_modules/yallist/yallist.js @@ -0,0 +1,426 @@ +'use strict' +module.exports = Yallist + +Yallist.Node = Node +Yallist.create = Yallist + +function Yallist (list) { + var self = this + if (!(self instanceof Yallist)) { + self = new Yallist() + } + + self.tail = null + self.head = null + self.length = 0 + + if (list && typeof list.forEach === 'function') { + list.forEach(function (item) { + self.push(item) + }) + } else if (arguments.length > 0) { + for (var i = 0, l = arguments.length; i < l; i++) { + self.push(arguments[i]) + } + } + + return self +} + +Yallist.prototype.removeNode = function (node) { + if (node.list !== this) { + throw new Error('removing node which does not belong to this list') + } + + var next = node.next + var prev = node.prev + + if (next) { + next.prev = prev + } + + if (prev) { + prev.next = next + } + + if (node === this.head) { + this.head = next + } + if (node === this.tail) { + this.tail = prev + } + + node.list.length-- + node.next = null + node.prev = null + node.list = null + + return next +} + +Yallist.prototype.unshiftNode = function (node) { + if (node === this.head) { + return + } + + if (node.list) { + node.list.removeNode(node) + } + + var head = this.head + node.list = this + node.next = head + if (head) { + head.prev = node + } + + this.head = node + if (!this.tail) { + this.tail = node + } + this.length++ +} + +Yallist.prototype.pushNode = function (node) { + if (node === this.tail) { + return + } + + if (node.list) { + node.list.removeNode(node) + } + + var tail = this.tail + node.list = this + node.prev = tail + if (tail) { + tail.next = node + } + + this.tail = node + if (!this.head) { + this.head = node + } + this.length++ +} + +Yallist.prototype.push = function () { + for (var i = 0, l = arguments.length; i < l; i++) { + push(this, arguments[i]) + } + return this.length +} + +Yallist.prototype.unshift = function () { + for (var i = 0, l = arguments.length; i < l; i++) { + unshift(this, arguments[i]) + } + return this.length +} + +Yallist.prototype.pop = function () { + if (!this.tail) { + return undefined + } + + var res = this.tail.value + this.tail = this.tail.prev + if (this.tail) { + this.tail.next = null + } else { + this.head = null + } + this.length-- + return res +} + +Yallist.prototype.shift = function () { + if (!this.head) { + return undefined + } + + var res = this.head.value + this.head = this.head.next + if (this.head) { + this.head.prev = null + } else { + this.tail = null + } + this.length-- + return res +} + +Yallist.prototype.forEach = function (fn, thisp) { + thisp = thisp || this + for (var walker = this.head, i = 0; walker !== null; i++) { + fn.call(thisp, walker.value, i, this) + walker = walker.next + } +} + +Yallist.prototype.forEachReverse = function (fn, thisp) { + thisp = thisp || this + for (var walker = this.tail, i = this.length - 1; walker !== null; i--) { + fn.call(thisp, walker.value, i, this) + walker = walker.prev + } +} + +Yallist.prototype.get = function (n) { + for (var i = 0, walker = this.head; walker !== null && i < n; i++) { + // abort out of the list early if we hit a cycle + walker = walker.next + } + if (i === n && walker !== null) { + return walker.value + } +} + +Yallist.prototype.getReverse = function (n) { + for (var i = 0, walker = this.tail; walker !== null && i < n; i++) { + // abort out of the list early if we hit a cycle + walker = walker.prev + } + if (i === n && walker !== null) { + return walker.value + } +} + +Yallist.prototype.map = function (fn, thisp) { + thisp = thisp || this + var res = new Yallist() + for (var walker = this.head; walker !== null;) { + res.push(fn.call(thisp, walker.value, this)) + walker = walker.next + } + return res +} + +Yallist.prototype.mapReverse = function (fn, thisp) { + thisp = thisp || this + var res = new Yallist() + for (var walker = this.tail; walker !== null;) { + res.push(fn.call(thisp, walker.value, this)) + walker = walker.prev + } + return res +} + +Yallist.prototype.reduce = function (fn, initial) { + var acc + var walker = this.head + if (arguments.length > 1) { + acc = initial + } else if (this.head) { + walker = this.head.next + acc = this.head.value + } else { + throw new TypeError('Reduce of empty list with no initial value') + } + + for (var i = 0; walker !== null; i++) { + acc = fn(acc, walker.value, i) + walker = walker.next + } + + return acc +} + +Yallist.prototype.reduceReverse = function (fn, initial) { + var acc + var walker = this.tail + if (arguments.length > 1) { + acc = initial + } else if (this.tail) { + walker = this.tail.prev + acc = this.tail.value + } else { + throw new TypeError('Reduce of empty list with no initial value') + } + + for (var i = this.length - 1; walker !== null; i--) { + acc = fn(acc, walker.value, i) + walker = walker.prev + } + + return acc +} + +Yallist.prototype.toArray = function () { + var arr = new Array(this.length) + for (var i = 0, walker = this.head; walker !== null; i++) { + arr[i] = walker.value + walker = walker.next + } + return arr +} + +Yallist.prototype.toArrayReverse = function () { + var arr = new Array(this.length) + for (var i = 0, walker = this.tail; walker !== null; i++) { + arr[i] = walker.value + walker = walker.prev + } + return arr +} + +Yallist.prototype.slice = function (from, to) { + to = to || this.length + if (to < 0) { + to += this.length + } + from = from || 0 + if (from < 0) { + from += this.length + } + var ret = new Yallist() + if (to < from || to < 0) { + return ret + } + if (from < 0) { + from = 0 + } + if (to > this.length) { + to = this.length + } + for (var i = 0, walker = this.head; walker !== null && i < from; i++) { + walker = walker.next + } + for (; walker !== null && i < to; i++, walker = walker.next) { + ret.push(walker.value) + } + return ret +} + +Yallist.prototype.sliceReverse = function (from, to) { + to = to || this.length + if (to < 0) { + to += this.length + } + from = from || 0 + if (from < 0) { + from += this.length + } + var ret = new Yallist() + if (to < from || to < 0) { + return ret + } + if (from < 0) { + from = 0 + } + if (to > this.length) { + to = this.length + } + for (var i = this.length, walker = this.tail; walker !== null && i > to; i--) { + walker = walker.prev + } + for (; walker !== null && i > from; i--, walker = walker.prev) { + ret.push(walker.value) + } + return ret +} + +Yallist.prototype.splice = function (start, deleteCount, ...nodes) { + if (start > this.length) { + start = this.length - 1 + } + if (start < 0) { + start = this.length + start; + } + + for (var i = 0, walker = this.head; walker !== null && i < start; i++) { + walker = walker.next + } + + var ret = [] + for (var i = 0; walker && i < deleteCount; i++) { + ret.push(walker.value) + walker = this.removeNode(walker) + } + if (walker === null) { + walker = this.tail + } + + if (walker !== this.head && walker !== this.tail) { + walker = walker.prev + } + + for (var i = 0; i < nodes.length; i++) { + walker = insert(this, walker, nodes[i]) + } + return ret; +} + +Yallist.prototype.reverse = function () { + var head = this.head + var tail = this.tail + for (var walker = head; walker !== null; walker = walker.prev) { + var p = walker.prev + walker.prev = walker.next + walker.next = p + } + this.head = tail + this.tail = head + return this +} + +function insert (self, node, value) { + var inserted = node === self.head ? + new Node(value, null, node, self) : + new Node(value, node, node.next, self) + + if (inserted.next === null) { + self.tail = inserted + } + if (inserted.prev === null) { + self.head = inserted + } + + self.length++ + + return inserted +} + +function push (self, item) { + self.tail = new Node(item, self.tail, null, self) + if (!self.head) { + self.head = self.tail + } + self.length++ +} + +function unshift (self, item) { + self.head = new Node(item, null, self.head, self) + if (!self.tail) { + self.tail = self.head + } + self.length++ +} + +function Node (value, prev, next, list) { + if (!(this instanceof Node)) { + return new Node(value, prev, next, list) + } + + this.list = list + this.value = value + + if (prev) { + prev.next = this + this.prev = prev + } else { + this.prev = null + } + + if (next) { + next.prev = this + this.next = next + } else { + this.next = null + } +} + +try { + // add if support for Symbol.iterator is present + require('./iterator.js')(Yallist) +} catch (er) {} diff --git a/node_modules/tar/package.json b/node_modules/tar/package.json index b12db0f3e..347a0799a 100644 --- a/node_modules/tar/package.json +++ b/node_modules/tar/package.json @@ -1,33 +1,28 @@ { - "_from": "tar@4.4.13", - "_id": "tar@4.4.13", + "_from": "tar@6.0.1", + "_id": "tar@6.0.1", "_inBundle": false, - "_integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", + "_integrity": "sha512-bKhKrrz2FJJj5s7wynxy/fyxpE0CmCjmOQ1KV4KkgXFWOgoIT/NbTMnB1n+LFNrNk0SSBVGGxcK5AGsyC+pW5Q==", "_location": "/tar", - "_phantomChildren": { - "safe-buffer": "5.1.2", - "yallist": "3.0.3" - }, + "_phantomChildren": {}, "_requested": { "type": "version", "registry": true, - "raw": "tar@4.4.13", + "raw": "tar@6.0.1", "name": "tar", "escapedName": "tar", - "rawSpec": "4.4.13", + "rawSpec": "6.0.1", "saveSpec": null, - "fetchSpec": "4.4.13" + "fetchSpec": "6.0.1" }, "_requiredBy": [ "#USER", - "/", - "/node-gyp", - "/pacote" + "/" ], - "_resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", - "_shasum": "43b364bc52888d555298637b10d60790254ab525", - "_spec": "tar@4.4.13", - "_where": "/Users/mperrotte/npminc/cli", + "_resolved": "https://registry.npmjs.org/tar/-/tar-6.0.1.tgz", + "_shasum": "7b3bd6c313cb6e0153770108f8d70ac298607efa", + "_spec": "tar@6.0.1", + "_where": "/Users/claudiahdz/npm/cli", "author": { "name": "Isaac Z. Schlueter", "email": "i@izs.me", @@ -38,32 +33,31 @@ }, "bundleDependencies": false, "dependencies": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" + "chownr": "^1.1.3", + "fs-minipass": "^2.0.0", + "minipass": "^3.0.0", + "minizlib": "^2.1.0", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" }, "deprecated": false, "description": "tar for node", "devDependencies": { "chmodr": "^1.2.0", - "end-of-stream": "^1.4.1", + "end-of-stream": "^1.4.3", "events-to-array": "^1.1.2", "mutate-fs": "^2.1.1", - "rimraf": "^2.6.3", - "tap": "^14.6.5", + "rimraf": "^2.7.1", + "tap": "^14.9.2", "tar-fs": "^1.16.3", "tar-stream": "^1.6.2" }, "engines": { - "node": ">=4.5" + "node": ">= 10" }, "files": [ "index.js", - "lib/" + "lib/*.js" ], "homepage": "https://github.com/npm/node-tar#readme", "license": "ISC", @@ -84,5 +78,5 @@ "coverage-map": "map.js", "check-coverage": true }, - "version": "4.4.13" + "version": "6.0.1" } |