Skip to content

Commit 0c757d5

Browse files
committed
Add TAR_* error codes
This adds error codes to all of the warnings emitted by tar operations, tests for several error conditions, and handling for errors raised by close(2). BREAKING CHANGES: - The `warn` event now emits with 3 arguments (code, message, data) rather than 2 (message, data). - The `data` argument to the warn event handler is always an object, (either an Error or a plain old JavaScript object) rather than sometimes being a string or undefined. - Failures from `fs.close()` are tracked and emitted.
1 parent 3905fed commit 0c757d5

File tree

125 files changed

+815
-870
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

125 files changed

+815
-870
lines changed

README.md

Lines changed: 109 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -63,23 +63,93 @@ that all of the data is immediately available by calling
6363
`stream.read()`. For writable streams, it will be acted upon as soon
6464
as it is provided, but this can be at any time.
6565

66-
### Warnings
67-
68-
Some things cause tar to emit a warning, but should usually not cause
69-
the entire operation to fail. There are three ways to handle
70-
warnings:
71-
72-
1. **Ignore them** (default) Invalid entries won't be put in the
73-
archive, and invalid entries won't be unpacked. This is usually
74-
fine, but can hide failures that you might care about.
75-
2. **Notice them** Add an `onwarn` function to the options, or listen
76-
to the `'warn'` event on any tar stream. The function will get
77-
called as `onwarn(message, data)`. Handle as appropriate.
78-
3. **Explode them.** Set `strict: true` in the options object, and
79-
`warn` messages will be emitted as `'error'` events instead. If
80-
there's no `error` handler, this causes the program to crash. If
81-
used with a promise-returning/callback-taking method, then it'll
82-
send the error to the promise/callback.
66+
### Warnings and Errors
67+
68+
Tar emits warnings and errors for recoverable and unrecoverable situations,
69+
respectively. In many cases, a warning only affects a single entry in an
70+
archive, or is simply informing you that it's modifying an entry to comply
71+
with the settings provided.
72+
73+
Unrecoverable warnings will always raise an error (ie, emit `'error'` on
74+
streaming actions, throw for non-streaming sync actions, reject the
75+
returned Promise for non-streaming async operations, or call a provided
76+
callback with an `Error` as the first argument). Recoverable errors will
77+
raise an error only if `strict: true` is set in the options.
78+
79+
Respond to (recoverable) warnings by listening to the `warn` event.
80+
Handlers receive 3 arguments:
81+
82+
- `code` String. One of the error codes below. This may not match
83+
`data.code`, which preserves the original error code from fs and zlib.
84+
- `message` String. More details about the error.
85+
- `data` Metadata about the error. An `Error` object for errors raised by
86+
fs and zlib. All fields are attached to errors raisd by tar. Typically
87+
contains the following fields, as relevant:
88+
- `tarCode` The tar error code.
89+
- `code` Either the tar error code, or the error code set by the
90+
underlying system.
91+
- `file` The archive file being read or written.
92+
- `cwd` Working directory for creation and extraction operations.
93+
- `entry` The entry object (if it could be created) for `TAR_ENTRY_INFO`,
94+
`TAR_ENTRY_INVALID`, and `TAR_ENTRY_ERROR` warnings.
95+
- `header` The header object (if it could be created, and the entry could
96+
not be created) for `TAR_ENTRY_INFO` and `TAR_ENTRY_INVALID` warnings.
97+
- `recoverable` Boolean. If `false`, then the warning will emit an
98+
`error`, even in non-strict mode.
99+
100+
#### Error Codes
101+
102+
* `TAR_ENTRY_INFO` An informative error indicating that an entry is being
103+
modified, but otherwise processed normally. For example, removing `/` or
104+
`C:\` from absolute paths if `preservePaths` is not set.
105+
106+
* `TAR_ENTRY_INVALID` An indication that a given entry is not a valid tar
107+
archive entry, and will be skipped. This occurs when:
108+
- a checksum fails,
109+
- a `linkpath` is missing for a link type, or
110+
- a `linkpath` is provided for a non-link type.
111+
112+
If every entry in a parsed archive raises an `TAR_ENTRY_INVALID` error,
113+
then the archive is presumed to be unrecoverably broken, and
114+
`TAR_BAD_ARCHIVE` will be raised.
115+
116+
* `TAR_ENTRY_ERROR` The entry appears to be a valid tar archive entry, but
117+
encountered an error which prevented it from being unpacked. This occurs
118+
when:
119+
- an unrecoverable fs error happens during unpacking,
120+
- an entry has `..` in the path and `preservePaths` is not set, or
121+
- an entry is extracting through a symbolic link, when `preservePaths` is
122+
not set.
123+
124+
* `TAR_ENTRY_UNSUPPORTED` An indication that a given entry is
125+
a valid archive entry, but of a type that is unsupported, and so will be
126+
skipped in archive creation or extracting.
127+
128+
* `TAR_ABORT` When parsing gzipped-encoded archives, the parser will
129+
abort the parse process raise a warning for any zlib errors encountered.
130+
Aborts are considered unrecoverable for both parsing and unpacking.
131+
132+
* `TAR_BAD_ARCHIVE` The archive file is totally hosed. This can happen for
133+
a number of reasons, and always occurs at the end of a parse or extract:
134+
135+
- An entry body was truncated before seeing the full number of bytes.
136+
- The archive contained only invalid entries, indicating that it is
137+
likely not an archive, or at least, not an archive this library can
138+
parse.
139+
140+
`TAR_BAD_ARCHIVE` is considered informative for parse operations, but
141+
unrecoverable for extraction. Note that, if encountered at the end of an
142+
extraction, tar WILL still have extracted as much it could from the
143+
archive, so there may be some garbage files to clean up.
144+
145+
Errors that occur deeper in the system (ie, either the filesystem or zlib)
146+
will have their error codes left intact, and a `tarCode` matching one of
147+
the above will be added to the warning metadata or the raised error object.
148+
149+
Errors generated by tar will have one of the above codes set as the
150+
`error.code` field as well, but since errors originating in zlib or fs will
151+
have their original codes, it's better to read `error.tarCode` if you wish
152+
to see how tar is handling the issue.
83153

84154
### Examples
85155

@@ -201,8 +271,8 @@ The following options are supported:
201271
and a file is not provided, then the resulting stream will already
202272
have the data ready to `read` or `emit('data')` as soon as you
203273
request it.
204-
- `onwarn` A function that will get called with `(message, data)` for
205-
any warnings encountered.
274+
- `onwarn` A function that will get called with `(code, message, data)` for
275+
any warnings encountered. (See "Warnings and Errors")
206276
- `strict` Treat warnings as crash-worthy errors. Default false.
207277
- `cwd` The current working directory for creating the archive.
208278
Defaults to `process.cwd()`. [Alias: `C`]
@@ -297,8 +367,8 @@ The following options are supported:
297367
Pathnames with fewer elements will be silently skipped. Note that
298368
the pathname is edited after applying the filter, but before
299369
security checks. [Alias: `strip-components`, `stripComponents`]
300-
- `onwarn` A function that will get called with `(message, data)` for
301-
any warnings encountered.
370+
- `onwarn` A function that will get called with `(code, message, data)` for
371+
any warnings encountered. (See "Warnings and Errors")
302372
- `preserveOwner` If true, tar will set the `uid` and `gid` of
303373
extracted entries to the `uid` and `gid` fields in the archive.
304374
This defaults to true when run as root, and false otherwise. If
@@ -401,8 +471,8 @@ The following options are supported:
401471
filename. [Alias: `f`]
402472
- `sync` Act synchronously. If this is set, then any provided file
403473
will be fully written after the call to `tar.c`.
404-
- `onwarn` A function that will get called with `(message, data)` for
405-
any warnings encountered.
474+
- `onwarn` A function that will get called with `(code, message, data)` for
475+
any warnings encountered. (See "Warnings and Errors")
406476
- `strict` Treat warnings as crash-worthy errors. Default false.
407477
- `cwd` The current working directory for adding entries to the
408478
archive. Defaults to `process.cwd()`. [Alias: `C`]
@@ -452,8 +522,8 @@ The following options are supported:
452522
filename. [Alias: `f`]
453523
- `sync` Act synchronously. If this is set, then any provided file
454524
will be fully written after the call to `tar.c`.
455-
- `onwarn` A function that will get called with `(message, data)` for
456-
any warnings encountered.
525+
- `onwarn` A function that will get called with `(code, message, data)` for
526+
any warnings encountered. (See "Warnings and Errors")
457527
- `strict` Treat warnings as crash-worthy errors. Default false.
458528
- `cwd` The current working directory for adding entries to the
459529
archive. Defaults to `process.cwd()`. [Alias: `C`]
@@ -499,8 +569,8 @@ Has all the standard readable stream interface stuff. `'data'` and
499569

500570
The following options are supported:
501571

502-
- `onwarn` A function that will get called with `(message, data)` for
503-
any warnings encountered.
572+
- `onwarn` A function that will get called with `(code, message, data)` for
573+
any warnings encountered. (See "Warnings and Errors")
504574
- `strict` Treat warnings as crash-worthy errors. Default false.
505575
- `cwd` The current working directory for creating the archive.
506576
Defaults to `process.cwd()`.
@@ -595,8 +665,8 @@ Most unpack errors will cause a `warn` event to be emitted. If the
595665
Pathnames with fewer elements will be silently skipped. Note that
596666
the pathname is edited after applying the filter, but before
597667
security checks.
598-
- `onwarn` A function that will get called with `(message, data)` for
599-
any warnings encountered.
668+
- `onwarn` A function that will get called with `(code, message, data)` for
669+
any warnings encountered. (See "Warnings and Errors")
600670
- `umask` Filter the modes of entries like `process.umask()`.
601671
- `dmode` Default mode for directories
602672
- `fmode` Default mode for files
@@ -634,8 +704,8 @@ Most unpack errors will cause a `warn` event to be emitted. If the
634704
- `strict` Treat warnings as crash-worthy errors. Default false.
635705
- `onentry` A function that gets called with `(entry)` for each entry
636706
that passes the filter.
637-
- `onwarn` A function that will get called with `(message, data)` for
638-
any warnings encountered.
707+
- `onwarn` A function that will get called with `(code, message, data)` for
708+
any warnings encountered. (See "Warnings and Errors")
639709

640710
### class tar.Unpack.Sync
641711

@@ -674,13 +744,13 @@ The following options are supported:
674744
archive, or `false` to skip it.
675745
- `onentry` A function that gets called with `(entry)` for each entry
676746
that passes the filter.
677-
- `onwarn` A function that will get called with `(message, data)` for
678-
any warnings encountered.
747+
- `onwarn` A function that will get called with `(code, message, data)` for
748+
any warnings encountered. (See "Warnings and Errors")
679749

680-
#### abort(message, error)
750+
#### abort(error)
681751

682752
Stop all parsing activities. This is called when there are zlib
683-
errors. It also emits a warning with the message and error provided.
753+
errors. It also emits an unrecoverable warning with the error provided.
684754

685755
### class tar.ReadEntry extends [MiniPass](http://npm.im/minipass)
686756

@@ -781,8 +851,8 @@ The following options are supported:
781851
- `strict` Treat warnings as crash-worthy errors. Default false.
782852
- `win32` True if on a windows platform. Causes behavior where paths
783853
replace `\` with `/`.
784-
- `onwarn` A function that will get called with `(message, data)` for
785-
any warnings encountered.
854+
- `onwarn` A function that will get called with `(code, message, data)` for
855+
any warnings encountered. (See "Warnings and Errors")
786856
- `noMtime` Set to true to omit writing `mtime` values for entries.
787857
Note that this prevents using other mtime-based features like
788858
`tar.update` or the `keepNewer` option with the resulting tar archive.
@@ -818,8 +888,8 @@ The following options are supported:
818888
- `preservePaths` Allow absolute paths. By default, `/` is stripped
819889
from absolute paths.
820890
- `strict` Treat warnings as crash-worthy errors. Default false.
821-
- `onwarn` A function that will get called with `(message, data)` for
822-
any warnings encountered.
891+
- `onwarn` A function that will get called with `(code, message, data)` for
892+
any warnings encountered. (See "Warnings and Errors")
823893
- `noMtime` Set to true to omit writing `mtime` values for entries.
824894
Note that this prevents using other mtime-based features like
825895
`tar.update` or the `keepNewer` option with the resulting tar archive.

lib/pack.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ const Pack = warner(class Pack extends MiniPass {
6262
super(opt)
6363
opt = opt || Object.create(null)
6464
this.opt = opt
65+
this.file = opt.file || ''
6566
this.cwd = opt.cwd || process.cwd()
6667
this.maxReadSize = opt.maxReadSize
6768
this.preservePaths = !!opt.preservePaths
@@ -285,9 +286,7 @@ const Pack = warner(class Pack extends MiniPass {
285286

286287
[ENTRYOPT] (job) {
287288
return {
288-
onwarn: (msg, data) => {
289-
this.warn(msg, data)
290-
},
289+
onwarn: (code, msg, data) => this.warn(code, msg, data),
291290
noPax: this.noPax,
292291
cwd: this.cwd,
293292
absolute: job.absolute,

0 commit comments

Comments
 (0)