Skip to content

Commit

Permalink
Merge branch 'v5'
Browse files Browse the repository at this point in the history
Typically we don't do merge commits on this library, but in this case,
some bugfix patches were already landed on v4, which aren't relevant or
necessary on the v5 codebase, prior to v5 being released.  A merge
commit is the cleanest way to do this without having to roll back the
publish or break the continuity of the default branch.
  • Loading branch information
isaacs committed Sep 25, 2019
2 parents 65edb39 + 7bc7c20 commit eea7dd7
Show file tree
Hide file tree
Showing 142 changed files with 1,140 additions and 993 deletions.
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* @npm/cli-team
148 changes: 109 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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`]
Expand Down Expand Up @@ -297,8 +367,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
Expand Down Expand Up @@ -401,8 +471,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`]
Expand Down Expand Up @@ -452,8 +522,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`]
Expand Down Expand Up @@ -499,8 +569,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()`.
Expand Down Expand Up @@ -595,8 +665,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
Expand Down Expand Up @@ -634,8 +704,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

Expand Down Expand Up @@ -674,13 +744,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)

Expand Down Expand Up @@ -781,8 +851,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.
Expand Down Expand Up @@ -818,8 +888,8 @@ The following options are supported:
- `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.
Expand Down
11 changes: 0 additions & 11 deletions lib/buffer.js

This file was deleted.

1 change: 0 additions & 1 deletion lib/header.js
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand Down
6 changes: 3 additions & 3 deletions lib/large-numbers.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
}
Expand Down
2 changes: 0 additions & 2 deletions lib/list.js
Original file line number Diff line number Diff line change
@@ -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?

Expand Down
7 changes: 2 additions & 5 deletions lib/pack.js
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -285,9 +284,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,
Expand Down
Loading

0 comments on commit eea7dd7

Please sign in to comment.