Security update to Drupal 8.4.6
[yaffs-website] / node_modules / yauzl / README.md
1 # yauzl
2
3 [![Build Status](https://travis-ci.org/thejoshwolfe/yauzl.svg?branch=master)](https://travis-ci.org/thejoshwolfe/yauzl)
4 [![Coverage Status](https://img.shields.io/coveralls/thejoshwolfe/yauzl.svg)](https://coveralls.io/r/thejoshwolfe/yauzl)
5
6 yet another unzip library for node. For zipping, see
7 [yazl](https://github.com/thejoshwolfe/yazl).
8
9 Design principles:
10
11  * Follow the spec.
12    Don't scan for local file headers.
13    Read the central directory for file metadata.
14    (see [No Streaming Unzip API](#no-streaming-unzip-api)).
15  * Don't block the JavaScript thread.
16    Use and provide async APIs.
17  * Keep memory usage under control.
18    Don't attempt to buffer entire files in RAM at once.
19  * Never crash (if used properly).
20    Don't let malformed zip files bring down client applications who are trying to catch errors.
21  * Catch unsafe filenames entries.
22    A zip file entry throws an error if its file name starts with `"/"` or `/[A-Za-z]:\//`
23    or if it contains `".."` path segments or `"\\"` (per the spec).
24
25 ## Usage
26
27 ```js
28 var yauzl = require("yauzl");
29 var fs = require("fs");
30 var path = require("path");
31 var mkdirp = require("mkdirp"); // or similar
32
33 yauzl.open("path/to/file.zip", {lazyEntries: true}, function(err, zipfile) {
34   if (err) throw err;
35   zipfile.readEntry();
36   zipfile.on("entry", function(entry) {
37     if (/\/$/.test(entry.fileName)) {
38       // directory file names end with '/'
39       mkdirp(entry.fileName, function(err) {
40         if (err) throw err;
41         zipfile.readEntry();
42       });
43     } else {
44       // file entry
45       zipfile.openReadStream(entry, function(err, readStream) {
46         if (err) throw err;
47         // ensure parent directory exists
48         mkdirp(path.dirname(entry.fileName), function(err) {
49           if (err) throw err;
50           readStream.pipe(fs.createWriteStream(entry.fileName));
51           readStream.on("end", function() {
52             zipfile.readEntry();
53           });
54         });
55       });
56     }
57   });
58 });
59 ```
60
61 ## API
62
63 The default for every optional `callback` parameter is:
64
65 ```js
66 function defaultCallback(err) {
67   if (err) throw err;
68 }
69 ```
70
71 ### open(path, [options], [callback])
72
73 Calls `fs.open(path, "r")` and gives the `fd`, `options`, and `callback` to `fromFd()` below.
74
75 `options` may be omitted or `null`. The defaults are `{autoClose: true, lazyEntries: false}`.
76
77 `autoClose` is effectively equivalent to:
78
79 ```js
80 zipfile.once("end", function() {
81   zipfile.close();
82 });
83 ```
84
85 `lazyEntries` indicates that entries should be read only when `readEntry()` is called.
86 If `lazyEntries` is `false`, `entry` events will be emitted as fast as possible to allow `pipe()`ing
87 file data from all entries in parallel.
88 This is not recommended, as it can lead to out of control memory usage for zip files with many entries.
89 See [issue #22](https://github.com/thejoshwolfe/yauzl/issues/22).
90 If `lazyEntries` is `true`, an `entry` or `end` event will be emitted in response to each call to `readEntry()`.
91 This allows processing of one entry at a time, and will keep memory usage under control for zip files with many entries.
92
93 ### fromFd(fd, [options], [callback])
94
95 Reads from the fd, which is presumed to be an open .zip file.
96 Note that random access is required by the zip file specification,
97 so the fd cannot be an open socket or any other fd that does not support random access.
98
99 The `callback` is given the arguments `(err, zipfile)`.
100 An `err` is provided if the End of Central Directory Record Signature cannot be found in the file,
101 which indicates that the fd is not a zip file.
102 `zipfile` is an instance of `ZipFile`.
103
104 `options` may be omitted or `null`. The defaults are `{autoClose: false, lazyEntries: false}`.
105 See `open()` for the meaning of the options.
106
107 ### fromBuffer(buffer, [options], [callback])
108
109 Like `fromFd()`, but reads from a RAM buffer instead of an open file.
110 `buffer` is a `Buffer`.
111 `callback` is effectively passed directly to `fromFd()`.
112
113 If a `ZipFile` is acquired from this method,
114 it will never emit the `close` event,
115 and calling `close()` is not necessary.
116
117 `options` may be omitted or `null`. The defaults are `{lazyEntries: false}`.
118 See `open()` for the meaning of the options.
119 The `autoClose` option is ignored for this method.
120
121 ### fromRandomAccessReader(reader, totalSize, [options], [callback])
122
123 This method of creating a zip file allows clients to implement their own back-end file system.
124 For example, a client might translate read calls into network requests.
125
126 The `reader` parameter must be of a type that is a subclass of
127 [RandomAccessReader](#class-randomaccessreader) that implements the required methods.
128 The `totalSize` is a Number and indicates the total file size of the zip file.
129
130 `options` may be omitted or `null`. The defaults are `{autoClose: true, lazyEntries: false}`.
131 See `open()` for the meaning of the options.
132
133 ### dosDateTimeToDate(date, time)
134
135 Converts MS-DOS `date` and `time` data into a JavaScript `Date` object.
136 Each parameter is a `Number` treated as an unsigned 16-bit integer.
137 Note that this format does not support timezones,
138 so the returned object will use the local timezone.
139
140 ### Class: ZipFile
141
142 The constructor for the class is not part of the public API.
143 Use `open()`, `fromFd()`, `fromBuffer()`, or `fromRandomAccessReader()` instead.
144
145 #### Event: "entry"
146
147 Callback gets `(entry)`, which is an `Entry`.
148 See `open()` and `readEntry()` for when this event is emitted.
149
150 #### Event: "end"
151
152 Emitted after the last `entry` event has been emitted.
153 See `open()` and `readEntry()` for more info on when this event is emitted.
154
155 #### Event: "close"
156
157 Emitted after the fd is actually closed.
158 This is after calling `close()` (or after the `end` event when `autoClose` is `true`),
159 and after all stream pipelines created from `openReadStream()` have finished reading data from the fd.
160
161 If this `ZipFile` was acquired from `fromRandomAccessReader()`,
162 the "fd" in the previous paragraph refers to the `RandomAccessReader` implemented by the client.
163
164 If this `ZipFile` was acquired from `fromBuffer()`, this event is never emitted.
165
166 #### Event: "error"
167
168 Emitted in the case of errors with reading the zip file.
169 (Note that other errors can be emitted from the streams created from `openReadStream()` as well.)
170 After this event has been emitted, no further `entry`, `end`, or `error` events will be emitted,
171 but the `close` event may still be emitted.
172
173 #### readEntry()
174
175 Causes this `ZipFile` to emit an `entry` or `end` event (or an `error` event).
176 This method must only be called when this `ZipFile` was created with the `lazyEntries` option set to `true` (see `open()`).
177 When this `ZipFile` was created with the `lazyEntries` option set to `true`,
178 `entry` and `end` events are only ever emitted in response to this method call.
179
180 The event that is emitted in response to this method will not be emitted until after this method has returned,
181 so it is safe to call this method before attaching event listeners.
182
183 After calling this method, calling this method again before the response event has been emitted will cause undefined behavior.
184 Calling this method after the `end` event has been emitted will cause undefined behavior.
185 Calling this method after calling `close()` will cause undefined behavior.
186
187 #### openReadStream(entry, callback)
188
189 `entry` must be an `Entry` object from this `ZipFile`.
190 `callback` gets `(err, readStream)`, where `readStream` is a `Readable Stream`.
191 If the entry is compressed (with a supported compression method),
192 the read stream provides the decompressed data.
193 If this zipfile is already closed (see `close()`), the `callback` will receive an `err`.
194
195 It's possible for the `readStream` it to emit errors for several reasons.
196 For example, if zlib cannot decompress the data, the zlib error will be emitted from the `readStream`.
197 Two more error cases are if the decompressed data has too many or too few actual bytes
198 compared to the reported byte count from the entry's `uncompressedSize` field.
199 yauzl notices this false information and emits an error from the `readStream`
200 after some number of bytes have already been piped through the stream.
201
202 Because of this check, clients can always trust the `uncompressedSize` field in `Entry` objects.
203 Guarding against [zip bomb](http://en.wikipedia.org/wiki/Zip_bomb) attacks can be accomplished by
204 doing some heuristic checks on the size metadata and then watching out for the above errors.
205 Such heuristics are outside the scope of this library,
206 but enforcing the `uncompressedSize` is implemented here as a security feature.
207
208 It is possible to destroy the `readStream` before it has piped all of its data.
209 To do this, call `readStream.destroy()`.
210 You must `unpipe()` the `readStream` from any destination before calling `readStream.destroy()`.
211 If this zipfile was created using `fromRandomAccessReader()`, the `RandomAccessReader` implementation
212 must provide readable streams that implement a `.destroy()` method (see `randomAccessReader._readStreamForRange()`)
213 in order for calls to `readStream.destroy()` to work in this context.
214
215 #### close()
216
217 Causes all future calls to `openReadStream()` to fail,
218 and closes the fd after all streams created by `openReadStream()` have emitted their `end` events.
219
220 If the `autoClose` option is set to `true` (see `open()`),
221 this function will be called automatically effectively in response to this object's `end` event.
222
223 If the `lazyEntries` option is set to `false` (see `open()`) and this object's `end` event has not been emitted yet,
224 this function causes undefined behavior.
225 If the `lazyEntries` option is set to `true`,
226 you can call this function instead of calling `readEntry()` to abort reading the entries of a zipfile.
227
228 It is safe to call this function multiple times; after the first call, successive calls have no effect.
229 This includes situations where the `autoClose` option effectively calls this function for you.
230
231 #### isOpen
232
233 `Boolean`. `true` until `close()` is called; then it's `false`.
234
235 #### entryCount
236
237 `Number`. Total number of central directory records.
238
239 #### comment
240
241 `String`. Always decoded with `CP437` per the spec.
242
243 ### Class: Entry
244
245 Objects of this class represent Central Directory Records.
246 Refer to the zipfile specification for more details about these fields.
247
248 These fields are of type `Number`:
249
250  * `versionMadeBy`
251  * `versionNeededToExtract`
252  * `generalPurposeBitFlag`
253  * `compressionMethod`
254  * `lastModFileTime` (MS-DOS format, see `getLastModDateTime`)
255  * `lastModFileDate` (MS-DOS format, see `getLastModDateTime`)
256  * `crc32`
257  * `compressedSize`
258  * `uncompressedSize`
259  * `fileNameLength` (bytes)
260  * `extraFieldLength` (bytes)
261  * `fileCommentLength` (bytes)
262  * `internalFileAttributes`
263  * `externalFileAttributes`
264  * `relativeOffsetOfLocalHeader`
265
266 #### fileName
267
268 `String`.
269 Following the spec, the bytes for the file name are decoded with
270 `UTF-8` if `generalPurposeBitFlag & 0x800`, otherwise with `CP437`.
271
272 If `fileName` would contain unsafe characters, such as an absolute path or
273 a relative directory, yauzl emits an error instead of an entry.
274
275 #### extraFields
276
277 `Array` with each entry in the form `{id: id, data: data}`,
278 where `id` is a `Number` and `data` is a `Buffer`.
279 This library looks for and reads the ZIP64 Extended Information Extra Field (0x0001)
280 in order to support ZIP64 format zip files.
281 None of the other fields are considered significant by this library.
282
283 #### comment
284
285 `String` decoded with the same charset as used for `fileName`.
286
287 #### getLastModDate()
288
289 Effectively implemented as:
290
291 ```js
292 return dosDateTimeToDate(this.lastModFileDate, this.lastModFileTime);
293 ```
294
295 ### Class: RandomAccessReader
296
297 This class is meant to be subclassed by clients and instantiated for the `fromRandomAccessReader()` function.
298
299 An example implementation can be found in `test/test.js`.
300
301 #### randomAccessReader._readStreamForRange(start, end)
302
303 Subclasses *must* implement this method.
304
305 `start` and `end` are Numbers and indicate byte offsets from the start of the file.
306 `end` is exclusive, so `_readStreamForRange(0x1000, 0x2000)` would indicate to read `0x1000` bytes.
307 `end - start` will always be at least `1`.
308
309 This method should return a readable stream which will be `pipe()`ed into another stream.
310 It is expected that the readable stream will provide data in several chunks if necessary.
311 If the readable stream provides too many or too few bytes, an error will be emitted.
312 Any errors emitted on the readable stream will be handled and re-emitted on the client-visible stream
313 (returned from `zipfile.openReadStream()`) or provided as the `err` argument to the appropriate callback
314 (for example, for `fromRandomAccessReader()`).
315
316 The returned stream *must* implement a method `.destroy()`
317 if you call `readStream.destroy()` on streams you get from `openReadStream()`.
318 If you never call `readStream.destroy()`, then streams returned from this method do not need to implement a method `.destroy()`.
319 `.destroy()` should abort any streaming that is in progress and clean up any associated resources.
320 `.destroy()` will only be called after the stream has been `unpipe()`d from its destination.
321
322 Note that the stream returned from this method might not be the same object that is provided by `openReadStream()`.
323 The stream returned from this method might be `pipe()`d through one or more filter streams (for example, a zlib inflate stream).
324
325 #### randomAccessReader.read(buffer, offset, length, position, callback)
326
327 Subclasses may implement this method.
328 The default implementation uses `createReadStream()` to fill the `buffer`.
329
330 This method should behave like `fs.read()`.
331
332 #### randomAccessReader.close(callback)
333
334 Subclasses may implement this method.
335 The default implementation is effectively `setImmediate(callback);`.
336
337 `callback` takes parameters `(err)`.
338
339 This method is called once the all streams returned from `_readStreamForRange()` have ended,
340 and no more `_readStreamForRange()` or `read()` requests will be issued to this object.
341
342 ## How to Avoid Crashing
343
344 When a malformed zipfile is encountered, the default behavior is to crash (throw an exception).
345 If you want to handle errors more gracefully than this,
346 be sure to do the following:
347
348  * Provide `callback` parameters where they are allowed, and check the `err` parameter.
349  * Attach a listener for the `error` event on any `ZipFile` object you get from `open()`, `fromFd()`, `fromBuffer()`, or `fromRandomAccessReader()`.
350  * Attach a listener for the `error` event on any stream you get from `openReadStream()`.
351
352 ## Limitations
353
354 ### No Streaming Unzip API
355
356 Due to the design of the .zip file format, it's impossible to interpret a .zip file from start to finish
357 (such as from a readable stream) without sacrificing correctness.
358 The Central Directory, which is the authority on the contents of the .zip file, is at the end of a .zip file, not the beginning.
359 A streaming API would need to either buffer the entire .zip file to get to the Central Directory before interpreting anything
360 (defeating the purpose of a streaming interface), or rely on the Local File Headers which are interspersed through the .zip file.
361 However, the Local File Headers are explicitly denounced in the spec as being unreliable copies of the Central Directory,
362 so trusting them would be a violation of the spec.
363
364 Any library that offers a streaming unzip API must make one of the above two compromises,
365 which makes the library either dishonest or nonconformant (usually the latter).
366 This library insists on correctness and adherence to the spec, and so does not offer a streaming API.
367
368 ### Limitted ZIP64 Support
369
370 For ZIP64, only zip files smaller than `8PiB` are supported,
371 not the full `16EiB` range that a 64-bit integer should be able to index.
372 This is due to the JavaScript Number type being an IEEE 754 double precision float.
373
374 The Node.js `fs` module probably has this same limitation.
375
376 ### ZIP64 Extensible Data Sector Is Ignored
377
378 The spec does not allow zip file creators to put arbitrary data here,
379 but rather reserves its use for PKWARE and mentions something about Z390.
380 This doesn't seem useful to expose in this library, so it is ignored.
381
382 ### No Multi-Disk Archive Support
383
384 This library does not support multi-disk zip files.
385 The multi-disk fields in the zipfile spec were intended for a zip file to span multiple floppy disks,
386 which probably never happens now.
387 If the "number of this disk" field in the End of Central Directory Record is not `0`,
388 the `open()`, `fromFd()`, `fromBuffer()`, or `fromRandomAccessReader()` `callback` will receive an `err`.
389 By extension the following zip file fields are ignored by this library and not provided to clients:
390
391  * Disk where central directory starts
392  * Number of central directory records on this disk
393  * Disk number where file starts
394
395 ### No Encryption Support
396
397 Currently, the presence of encryption is not even checked,
398 and encrypted zip files will cause undefined behavior.
399
400 ### Local File Headers Are Ignored
401
402 Many unzip libraries mistakenly read the Local File Header data in zip files.
403 This data is officially defined to be redundant with the Central Directory information,
404 and is not to be trusted.
405 Aside from checking the signature, yauzl ignores the content of the Local File Header.
406
407 ### No CRC-32 Checking
408
409 This library provides the `crc32` field of `Entry` objects read from the Central Directory.
410 However, this field is not used for anything in this library.
411
412 ### versionNeededToExtract Is Ignored
413
414 The field `versionNeededToExtract` is ignored,
415 because this library doesn't support the complete zip file spec at any version,
416
417 ### No Support For Obscure Compression Methods
418
419 Regarding the `compressionMethod` field of `Entry` objects,
420 only method `0` (stored with no compression)
421 and method `8` (deflated) are supported.
422 Any of the other 15 official methods will cause the `openReadStream()` `callback` to receive an `err`.
423
424 ### Data Descriptors Are Ignored
425
426 There may or may not be Data Descriptor sections in a zip file.
427 This library provides no support for finding or interpreting them.
428
429 ### Archive Extra Data Record Is Ignored
430
431 There may or may not be an Archive Extra Data Record section in a zip file.
432 This library provides no support for finding or interpreting it.
433
434 ### No Language Encoding Flag Support
435
436 Zip files officially support charset encodings other than CP437 and UTF-8,
437 but the zip file spec does not specify how it works.
438 This library makes no attempt to interpret the Language Encoding Flag.
439
440 ## Change History
441
442  * 2.4.1
443    * Fix error handling.
444  * 2.4.0
445    * Add ZIP64 support. [issue #6](https://github.com/thejoshwolfe/yazl/issues/6)
446    * Add `lazyEntries` option. [issue #22](https://github.com/thejoshwolfe/yazl/issues/22)
447    * Add `readStream.destroy()` method. [issue #26](https://github.com/thejoshwolfe/yazl/issues/26)
448    * Add `fromRandomAccessReader()`. [issue #14](https://github.com/thejoshwolfe/yazl/issues/14)
449    * Add `examples/unzip.js`.
450  * 2.3.1
451    * Documentation updates.
452  * 2.3.0
453    * Check that `uncompressedSize` is correct, or else emit an error. [issue #13](https://github.com/thejoshwolfe/yazl/issues/13)
454  * 2.2.1
455    * Update dependencies.
456  * 2.2.0
457    * Update dependencies.
458  * 2.1.0
459    * Remove dependency on `iconv`.
460  * 2.0.3
461    * Fix crash when trying to read a 0-byte file.
462  * 2.0.2
463    * Fix event behavior after errors.
464  * 2.0.1
465    * Fix bug with using `iconv`.
466  * 2.0.0
467    * Initial release.