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
6yet another unzip library for node. For zipping, see
7[yazl](https://github.com/thejoshwolfe/yazl).
8
9Design 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 file names.
22   See `validateFileName()`.
23
24## Usage
25
26```js
27var yauzl = require("yauzl");
28
29yauzl.open("path/to/file.zip", {lazyEntries: true}, function(err, zipfile) {
30  if (err) throw err;
31  zipfile.readEntry();
32  zipfile.on("entry", function(entry) {
33    if (/\/$/.test(entry.fileName)) {
34      // Directory file names end with '/'.
35      // Note that entires for directories themselves are optional.
36      // An entry's fileName implicitly requires its parent directories to exist.
37      zipfile.readEntry();
38    } else {
39      // file entry
40      zipfile.openReadStream(entry, function(err, readStream) {
41        if (err) throw err;
42        readStream.on("end", function() {
43          zipfile.readEntry();
44        });
45        readStream.pipe(somewhere);
46      });
47    }
48  });
49});
50```
51
52See also `examples/` for more usage examples.
53
54## API
55
56The default for every optional `callback` parameter is:
57
58```js
59function defaultCallback(err) {
60  if (err) throw err;
61}
62```
63
64### open(path, [options], [callback])
65
66Calls `fs.open(path, "r")` and reads the `fd` effectively the same as `fromFd()` would.
67
68`options` may be omitted or `null`. The defaults are `{autoClose: true, lazyEntries: false, decodeStrings: true, validateEntrySizes: true, strictFileNames: false}`.
69
70`autoClose` is effectively equivalent to:
71
72```js
73zipfile.once("end", function() {
74  zipfile.close();
75});
76```
77
78`lazyEntries` indicates that entries should be read only when `readEntry()` is called.
79If `lazyEntries` is `false`, `entry` events will be emitted as fast as possible to allow `pipe()`ing
80file data from all entries in parallel.
81This is not recommended, as it can lead to out of control memory usage for zip files with many entries.
82See [issue #22](https://github.com/thejoshwolfe/yauzl/issues/22).
83If `lazyEntries` is `true`, an `entry` or `end` event will be emitted in response to each call to `readEntry()`.
84This allows processing of one entry at a time, and will keep memory usage under control for zip files with many entries.
85
86`decodeStrings` is the default and causes yauzl to decode strings with `CP437` or `UTF-8` as required by the spec.
87The exact effects of turning this option off are:
88
89* `zipfile.comment`, `entry.fileName`, and `entry.fileComment` will be `Buffer` objects instead of `String`s.
90* Any Info-ZIP Unicode Path Extra Field will be ignored. See `extraFields`.
91* Automatic file name validation will not be performed. See `validateFileName()`.
92
93`validateEntrySizes` is the default and ensures that an entry's reported uncompressed size matches its actual uncompressed size.
94This check happens as early as possible, which is either before emitting each `"entry"` event (for entries with no compression),
95or during the `readStream` piping after calling `openReadStream()`.
96See `openReadStream()` for more information on defending against zip bomb attacks.
97
98When `strictFileNames` is `false` (the default) and `decodeStrings` is `true`,
99all backslash (`\`) characters in each `entry.fileName` are replaced with forward slashes (`/`).
100The spec forbids file names with backslashes,
101but Microsoft's `System.IO.Compression.ZipFile` class in .NET versions 4.5.0 until 4.6.1
102creates non-conformant zipfiles with backslashes in file names.
103`strictFileNames` is `false` by default so that clients can read these
104non-conformant zipfiles without knowing about this Microsoft-specific bug.
105When `strictFileNames` is `true` and `decodeStrings` is `true`,
106entries with backslashes in their file names will result in an error. See `validateFileName()`.
107When `decodeStrings` is `false`, `strictFileNames` has no effect.
108
109The `callback` is given the arguments `(err, zipfile)`.
110An `err` is provided if the End of Central Directory Record cannot be found, or if its metadata appears malformed.
111This kind of error usually indicates that this is not a zip file.
112Otherwise, `zipfile` is an instance of `ZipFile`.
113
114### fromFd(fd, [options], [callback])
115
116Reads from the fd, which is presumed to be an open .zip file.
117Note that random access is required by the zip file specification,
118so the fd cannot be an open socket or any other fd that does not support random access.
119
120`options` may be omitted or `null`. The defaults are `{autoClose: false, lazyEntries: false, decodeStrings: true, validateEntrySizes: true, strictFileNames: false}`.
121
122See `open()` for the meaning of the options and callback.
123
124### fromBuffer(buffer, [options], [callback])
125
126Like `fromFd()`, but reads from a RAM buffer instead of an open file.
127`buffer` is a `Buffer`.
128
129If a `ZipFile` is acquired from this method,
130it will never emit the `close` event,
131and calling `close()` is not necessary.
132
133`options` may be omitted or `null`. The defaults are `{lazyEntries: false, decodeStrings: true, validateEntrySizes: true, strictFileNames: false}`.
134
135See `open()` for the meaning of the options and callback.
136The `autoClose` option is ignored for this method.
137
138### fromRandomAccessReader(reader, totalSize, [options], [callback])
139
140This method of reading a zip file allows clients to implement their own back-end file system.
141For example, a client might translate read calls into network requests.
142
143The `reader` parameter must be of a type that is a subclass of
144[RandomAccessReader](#class-randomaccessreader) that implements the required methods.
145The `totalSize` is a Number and indicates the total file size of the zip file.
146
147`options` may be omitted or `null`. The defaults are `{autoClose: true, lazyEntries: false, decodeStrings: true, validateEntrySizes: true, strictFileNames: false}`.
148
149See `open()` for the meaning of the options and callback.
150
151### dosDateTimeToDate(date, time)
152
153Converts MS-DOS `date` and `time` data into a JavaScript `Date` object.
154Each parameter is a `Number` treated as an unsigned 16-bit integer.
155Note that this format does not support timezones,
156so the returned object will use the local timezone.
157
158### validateFileName(fileName)
159
160Returns `null` or a `String` error message depending on the validity of `fileName`.
161If `fileName` starts with `"/"` or `/[A-Za-z]:\//` or if it contains `".."` path segments or `"\\"`,
162this function returns an error message appropriate for use like this:
163
164```js
165var errorMessage = yauzl.validateFileName(fileName);
166if (errorMessage != null) throw new Error(errorMessage);
167```
168
169This function is automatically run for each entry, as long as `decodeStrings` is `true`.
170See `open()`, `strictFileNames`, and `Event: "entry"` for more information.
171
172### Class: ZipFile
173
174The constructor for the class is not part of the public API.
175Use `open()`, `fromFd()`, `fromBuffer()`, or `fromRandomAccessReader()` instead.
176
177#### Event: "entry"
178
179Callback gets `(entry)`, which is an `Entry`.
180See `open()` and `readEntry()` for when this event is emitted.
181
182If `decodeStrings` is `true`, entries emitted via this event have already passed file name validation.
183See `validateFileName()` and `open()` for more information.
184
185If `validateEntrySizes` is `true` and this entry's `compressionMethod` is `0` (stored without compression),
186this entry has already passed entry size validation.
187See `open()` for more information.
188
189#### Event: "end"
190
191Emitted after the last `entry` event has been emitted.
192See `open()` and `readEntry()` for more info on when this event is emitted.
193
194#### Event: "close"
195
196Emitted after the fd is actually closed.
197This is after calling `close()` (or after the `end` event when `autoClose` is `true`),
198and after all stream pipelines created from `openReadStream()` have finished reading data from the fd.
199
200If this `ZipFile` was acquired from `fromRandomAccessReader()`,
201the "fd" in the previous paragraph refers to the `RandomAccessReader` implemented by the client.
202
203If this `ZipFile` was acquired from `fromBuffer()`, this event is never emitted.
204
205#### Event: "error"
206
207Emitted in the case of errors with reading the zip file.
208(Note that other errors can be emitted from the streams created from `openReadStream()` as well.)
209After this event has been emitted, no further `entry`, `end`, or `error` events will be emitted,
210but the `close` event may still be emitted.
211
212#### readEntry()
213
214Causes this `ZipFile` to emit an `entry` or `end` event (or an `error` event).
215This method must only be called when this `ZipFile` was created with the `lazyEntries` option set to `true` (see `open()`).
216When this `ZipFile` was created with the `lazyEntries` option set to `true`,
217`entry` and `end` events are only ever emitted in response to this method call.
218
219The event that is emitted in response to this method will not be emitted until after this method has returned,
220so it is safe to call this method before attaching event listeners.
221
222After calling this method, calling this method again before the response event has been emitted will cause undefined behavior.
223Calling this method after the `end` event has been emitted will cause undefined behavior.
224Calling this method after calling `close()` will cause undefined behavior.
225
226#### openReadStream(entry, [options], callback)
227
228`entry` must be an `Entry` object from this `ZipFile`.
229`callback` gets `(err, readStream)`, where `readStream` is a `Readable Stream` that provides the file data for this entry.
230If this zipfile is already closed (see `close()`), the `callback` will receive an `err`.
231
232`options` may be omitted or `null`, and has the following defaults:
233
234```js
235{
236  decompress: entry.isCompressed() ? true : null,
237  decrypt: null,
238  start: 0,                  // actually the default is null, see below
239  end: entry.compressedSize, // actually the default is null, see below
240}
241```
242
243If the entry is compressed (with a supported compression method),
244and the `decompress` option is `true` (or omitted),
245the read stream provides the decompressed data.
246Omitting the `decompress` option is what most clients should do.
247
248The `decompress` option must be `null` (or omitted) when the entry is not compressed (see `isCompressed()`),
249and either `true` (or omitted) or `false` when the entry is compressed.
250Specifying `decompress: false` for a compressed entry causes the read stream
251to provide the raw compressed file data without going through a zlib inflate transform.
252
253If the entry is encrypted (see `isEncrypted()`), clients may want to avoid calling `openReadStream()` on the entry entirely.
254Alternatively, clients may call `openReadStream()` for encrypted entries and specify `decrypt: false`.
255If the entry is also compressed, clients must *also* specify `decompress: false`.
256Specifying `decrypt: false` for an encrypted entry causes the read stream to provide the raw, still-encrypted file data.
257(This data includes the 12-byte header described in the spec.)
258
259The `decrypt` option must be `null` (or omitted) for non-encrypted entries, and `false` for encrypted entries.
260Omitting the `decrypt` option (or specifying it as `null`) for an encrypted entry
261will result in the `callback` receiving an `err`.
262This default behavior is so that clients not accounting for encrypted files aren't surprised by bogus file data.
263
264The `start` (inclusive) and `end` (exclusive) options are byte offsets into this entry's file data,
265and can be used to obtain part of an entry's file data rather than the whole thing.
266If either of these options are specified and non-`null`,
267then the above options must be used to obain the file's raw data.
268Speficying `{start: 0, end: entry.compressedSize}` will result in the complete file,
269which is effectively the default values for these options,
270but note that unlike omitting the options, when you specify `start` or `end` as any non-`null` value,
271the above requirement is still enforced that you must also pass the appropriate options to get the file's raw data.
272
273It's possible for the `readStream` provided to the `callback` to emit errors for several reasons.
274For example, if zlib cannot decompress the data, the zlib error will be emitted from the `readStream`.
275Two more error cases (when `validateEntrySizes` is `true`) are if the decompressed data has too many
276or too few actual bytes compared to the reported byte count from the entry's `uncompressedSize` field.
277yauzl notices this false information and emits an error from the `readStream`
278after some number of bytes have already been piped through the stream.
279
280This check allows clients to trust the `uncompressedSize` field in `Entry` objects.
281Guarding against [zip bomb](http://en.wikipedia.org/wiki/Zip_bomb) attacks can be accomplished by
282doing some heuristic checks on the size metadata and then watching out for the above errors.
283Such heuristics are outside the scope of this library,
284but enforcing the `uncompressedSize` is implemented here as a security feature.
285
286It is possible to destroy the `readStream` before it has piped all of its data.
287To do this, call `readStream.destroy()`.
288You must `unpipe()` the `readStream` from any destination before calling `readStream.destroy()`.
289If this zipfile was created using `fromRandomAccessReader()`, the `RandomAccessReader` implementation
290must provide readable streams that implement a `.destroy()` method (see `randomAccessReader._readStreamForRange()`)
291in order for calls to `readStream.destroy()` to work in this context.
292
293#### close()
294
295Causes all future calls to `openReadStream()` to fail,
296and closes the fd, if any, after all streams created by `openReadStream()` have emitted their `end` events.
297
298If the `autoClose` option is set to `true` (see `open()`),
299this function will be called automatically effectively in response to this object's `end` event.
300
301If the `lazyEntries` option is set to `false` (see `open()`) and this object's `end` event has not been emitted yet,
302this function causes undefined behavior.
303If the `lazyEntries` option is set to `true`,
304you can call this function instead of calling `readEntry()` to abort reading the entries of a zipfile.
305
306It is safe to call this function multiple times; after the first call, successive calls have no effect.
307This includes situations where the `autoClose` option effectively calls this function for you.
308
309If `close()` is never called, then the zipfile is "kept open".
310For zipfiles created with `fromFd()`, this will leave the `fd` open, which may be desirable.
311For zipfiles created with `open()`, this will leave the underlying `fd` open, thereby "leaking" it, which is probably undesirable.
312For zipfiles created with `fromRandomAccessReader()`, the reader's `close()` method will never be called.
313For zipfiles created with `fromBuffer()`, the `close()` function has no effect whether called or not.
314
315Regardless of how this `ZipFile` was created, there are no resources other than those listed above that require cleanup from this function.
316This means it may be desirable to never call `close()` in some usecases.
317
318#### isOpen
319
320`Boolean`. `true` until `close()` is called; then it's `false`.
321
322#### entryCount
323
324`Number`. Total number of central directory records.
325
326#### comment
327
328`String`. Always decoded with `CP437` per the spec.
329
330If `decodeStrings` is `false` (see `open()`), this field is the undecoded `Buffer` instead of a decoded `String`.
331
332### Class: Entry
333
334Objects of this class represent Central Directory Records.
335Refer to the zipfile specification for more details about these fields.
336
337These fields are of type `Number`:
338
339 * `versionMadeBy`
340 * `versionNeededToExtract`
341 * `generalPurposeBitFlag`
342 * `compressionMethod`
343 * `lastModFileTime` (MS-DOS format, see `getLastModDateTime`)
344 * `lastModFileDate` (MS-DOS format, see `getLastModDateTime`)
345 * `crc32`
346 * `compressedSize`
347 * `uncompressedSize`
348 * `fileNameLength` (bytes)
349 * `extraFieldLength` (bytes)
350 * `fileCommentLength` (bytes)
351 * `internalFileAttributes`
352 * `externalFileAttributes`
353 * `relativeOffsetOfLocalHeader`
354
355#### fileName
356
357`String`.
358Following the spec, the bytes for the file name are decoded with
359`UTF-8` if `generalPurposeBitFlag & 0x800`, otherwise with `CP437`.
360Alternatively, this field may be populated from the Info-ZIP Unicode Path Extra Field
361(see `extraFields`).
362
363This field is automatically validated by `validateFileName()` before yauzl emits an "entry" event.
364If this field would contain unsafe characters, yauzl emits an error instead of an entry.
365
366If `decodeStrings` is `false` (see `open()`), this field is the undecoded `Buffer` instead of a decoded `String`.
367Therefore, `generalPurposeBitFlag` and any Info-ZIP Unicode Path Extra Field are ignored.
368Furthermore, no automatic file name validation is performed for this file name.
369
370#### extraFields
371
372`Array` with each entry in the form `{id: id, data: data}`,
373where `id` is a `Number` and `data` is a `Buffer`.
374
375This library looks for and reads the ZIP64 Extended Information Extra Field (0x0001)
376in order to support ZIP64 format zip files.
377
378This library also looks for and reads the Info-ZIP Unicode Path Extra Field (0x7075)
379in order to support some zipfiles that use it instead of General Purpose Bit 11
380to convey `UTF-8` file names.
381When the field is identified and verified to be reliable (see the zipfile spec),
382the the file name in this field is stored in the `fileName` property,
383and the file name in the central directory record for this entry is ignored.
384Note that when `decodeStrings` is false, all Info-ZIP Unicode Path Extra Fields are ignored.
385
386None of the other fields are considered significant by this library.
387Fields that this library reads are left unalterned in the `extraFields` array.
388
389#### fileComment
390
391`String` decoded with the charset indicated by `generalPurposeBitFlag & 0x800` as with the `fileName`.
392(The Info-ZIP Unicode Path Extra Field has no effect on the charset used for this field.)
393
394If `decodeStrings` is `false` (see `open()`), this field is the undecoded `Buffer` instead of a decoded `String`.
395
396Prior to yauzl version 2.7.0, this field was erroneously documented as `comment` instead of `fileComment`.
397For compatibility with any code that uses the field name `comment`,
398yauzl creates an alias field named `comment` which is identical to `fileComment`.
399
400#### getLastModDate()
401
402Effectively implemented as:
403
404```js
405return dosDateTimeToDate(this.lastModFileDate, this.lastModFileTime);
406```
407
408#### isEncrypted()
409
410Returns is this entry encrypted with "Traditional Encryption".
411Effectively implemented as:
412
413```js
414return (this.generalPurposeBitFlag & 0x1) !== 0;
415```
416
417See `openReadStream()` for the implications of this value.
418
419Note that "Strong Encryption" is not supported, and will result in an `"error"` event emitted from the `ZipFile`.
420
421#### isCompressed()
422
423Effectively implemented as:
424
425```js
426return this.compressionMethod === 8;
427```
428
429See `openReadStream()` for the implications of this value.
430
431### Class: RandomAccessReader
432
433This class is meant to be subclassed by clients and instantiated for the `fromRandomAccessReader()` function.
434
435An example implementation can be found in `test/test.js`.
436
437#### randomAccessReader._readStreamForRange(start, end)
438
439Subclasses *must* implement this method.
440
441`start` and `end` are Numbers and indicate byte offsets from the start of the file.
442`end` is exclusive, so `_readStreamForRange(0x1000, 0x2000)` would indicate to read `0x1000` bytes.
443`end - start` will always be at least `1`.
444
445This method should return a readable stream which will be `pipe()`ed into another stream.
446It is expected that the readable stream will provide data in several chunks if necessary.
447If the readable stream provides too many or too few bytes, an error will be emitted.
448(Note that `validateEntrySizes` has no effect on this check,
449because this is a low-level API that should behave correctly regardless of the contents of the file.)
450Any errors emitted on the readable stream will be handled and re-emitted on the client-visible stream
451(returned from `zipfile.openReadStream()`) or provided as the `err` argument to the appropriate callback
452(for example, for `fromRandomAccessReader()`).
453
454The returned stream *must* implement a method `.destroy()`
455if you call `readStream.destroy()` on streams you get from `openReadStream()`.
456If you never call `readStream.destroy()`, then streams returned from this method do not need to implement a method `.destroy()`.
457`.destroy()` should abort any streaming that is in progress and clean up any associated resources.
458`.destroy()` will only be called after the stream has been `unpipe()`d from its destination.
459
460Note that the stream returned from this method might not be the same object that is provided by `openReadStream()`.
461The stream returned from this method might be `pipe()`d through one or more filter streams (for example, a zlib inflate stream).
462
463#### randomAccessReader.read(buffer, offset, length, position, callback)
464
465Subclasses may implement this method.
466The default implementation uses `createReadStream()` to fill the `buffer`.
467
468This method should behave like `fs.read()`.
469
470#### randomAccessReader.close(callback)
471
472Subclasses may implement this method.
473The default implementation is effectively `setImmediate(callback);`.
474
475`callback` takes parameters `(err)`.
476
477This method is called once the all streams returned from `_readStreamForRange()` have ended,
478and no more `_readStreamForRange()` or `read()` requests will be issued to this object.
479
480## How to Avoid Crashing
481
482When a malformed zipfile is encountered, the default behavior is to crash (throw an exception).
483If you want to handle errors more gracefully than this,
484be sure to do the following:
485
486 * Provide `callback` parameters where they are allowed, and check the `err` parameter.
487 * Attach a listener for the `error` event on any `ZipFile` object you get from `open()`, `fromFd()`, `fromBuffer()`, or `fromRandomAccessReader()`.
488 * Attach a listener for the `error` event on any stream you get from `openReadStream()`.
489
490Minor version updates to yauzl will not add any additional requirements to this list.
491
492## Limitations
493
494### No Streaming Unzip API
495
496Due to the design of the .zip file format, it's impossible to interpret a .zip file from start to finish
497(such as from a readable stream) without sacrificing correctness.
498The Central Directory, which is the authority on the contents of the .zip file, is at the end of a .zip file, not the beginning.
499A streaming API would need to either buffer the entire .zip file to get to the Central Directory before interpreting anything
500(defeating the purpose of a streaming interface), or rely on the Local File Headers which are interspersed through the .zip file.
501However, the Local File Headers are explicitly denounced in the spec as being unreliable copies of the Central Directory,
502so trusting them would be a violation of the spec.
503
504Any library that offers a streaming unzip API must make one of the above two compromises,
505which makes the library either dishonest or nonconformant (usually the latter).
506This library insists on correctness and adherence to the spec, and so does not offer a streaming API.
507
508Here is a way to create a spec-conformant .zip file using the `zip` command line program (Info-ZIP)
509available in most unix-like environments, that is (nearly) impossible to parse correctly with a streaming parser:
510
511```
512$ echo -ne '\x50\x4b\x07\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' > file.txt
513$ zip -q0 - file.txt | cat > out.zip
514```
515
516This .zip file contains a single file entry that uses General Purpose Bit 3,
517which means the Local File Header doesn't know the size of the file.
518Any streaming parser that encounters this situation will either immediately fail,
519or attempt to search for the Data Descriptor after the file's contents.
520The file's contents is a sequence of 16-bytes crafted to exactly mimic a valid Data Descriptor for an empty file,
521which will fool any parser that gets this far into thinking that the file is empty rather than containing 16-bytes.
522What follows the file's real contents is the file's real Data Descriptor,
523which will likely cause some kind of signature mismatch error for a streaming parser (if one hasn't occurred already).
524
525By using General Purpose Bit 3 (and compression method 0),
526it's possible to create arbitrarily ambiguous .zip files that
527distract parsers with file contents that contain apparently valid .zip file metadata.
528
529### Limitted ZIP64 Support
530
531For ZIP64, only zip files smaller than `8PiB` are supported,
532not the full `16EiB` range that a 64-bit integer should be able to index.
533This is due to the JavaScript Number type being an IEEE 754 double precision float.
534
535The Node.js `fs` module probably has this same limitation.
536
537### ZIP64 Extensible Data Sector Is Ignored
538
539The spec does not allow zip file creators to put arbitrary data here,
540but rather reserves its use for PKWARE and mentions something about Z390.
541This doesn't seem useful to expose in this library, so it is ignored.
542
543### No Multi-Disk Archive Support
544
545This library does not support multi-disk zip files.
546The multi-disk fields in the zipfile spec were intended for a zip file to span multiple floppy disks,
547which probably never happens now.
548If the "number of this disk" field in the End of Central Directory Record is not `0`,
549the `open()`, `fromFd()`, `fromBuffer()`, or `fromRandomAccessReader()` `callback` will receive an `err`.
550By extension the following zip file fields are ignored by this library and not provided to clients:
551
552 * Disk where central directory starts
553 * Number of central directory records on this disk
554 * Disk number where file starts
555
556### Limited Encryption Handling
557
558You can detect when a file entry is encrypted with "Traditional Encryption" via `isEncrypted()`,
559but yauzl will not help you decrypt it.
560See `openReadStream()`.
561
562If a zip file contains file entries encrypted with "Strong Encryption", yauzl emits an error.
563
564If the central directory is encrypted or compressed, yauzl emits an error.
565
566### Local File Headers Are Ignored
567
568Many unzip libraries mistakenly read the Local File Header data in zip files.
569This data is officially defined to be redundant with the Central Directory information,
570and is not to be trusted.
571Aside from checking the signature, yauzl ignores the content of the Local File Header.
572
573### No CRC-32 Checking
574
575This library provides the `crc32` field of `Entry` objects read from the Central Directory.
576However, this field is not used for anything in this library.
577
578### versionNeededToExtract Is Ignored
579
580The field `versionNeededToExtract` is ignored,
581because this library doesn't support the complete zip file spec at any version,
582
583### No Support For Obscure Compression Methods
584
585Regarding the `compressionMethod` field of `Entry` objects,
586only method `0` (stored with no compression)
587and method `8` (deflated) are supported.
588Any of the other 15 official methods will cause the `openReadStream()` `callback` to receive an `err`.
589
590### Data Descriptors Are Ignored
591
592There may or may not be Data Descriptor sections in a zip file.
593This library provides no support for finding or interpreting them.
594
595### Archive Extra Data Record Is Ignored
596
597There may or may not be an Archive Extra Data Record section in a zip file.
598This library provides no support for finding or interpreting it.
599
600### No Language Encoding Flag Support
601
602Zip files officially support charset encodings other than CP437 and UTF-8,
603but the zip file spec does not specify how it works.
604This library makes no attempt to interpret the Language Encoding Flag.
605
606## Change History
607
608 * 2.10.0
609   * Added support for non-conformant zipfiles created by Microsoft, and added option `strictFileNames` to disable the workaround. [issue #66](https://github.com/thejoshwolfe/yauzl/issues/66), [issue #88](https://github.com/thejoshwolfe/yauzl/issues/88)
610 * 2.9.2
611   * Removed `tools/hexdump-zip.js` and `tools/hex2bin.js`. Those tools are now located here: [thejoshwolfe/hexdump-zip](https://github.com/thejoshwolfe/hexdump-zip) and [thejoshwolfe/hex2bin](https://github.com/thejoshwolfe/hex2bin)
612   * Worked around performance problem with zlib when using `fromBuffer()` and `readStream.destroy()` for large compressed files. [issue #87](https://github.com/thejoshwolfe/yauzl/issues/87)
613 * 2.9.1
614   * Removed `console.log()` accidentally introduced in 2.9.0. [issue #64](https://github.com/thejoshwolfe/yauzl/issues/64)
615 * 2.9.0
616   * Throw an exception if `readEntry()` is called without `lazyEntries:true`. Previously this caused undefined behavior. [issue #63](https://github.com/thejoshwolfe/yauzl/issues/63)
617 * 2.8.0
618   * Added option `validateEntrySizes`. [issue #53](https://github.com/thejoshwolfe/yauzl/issues/53)
619   * Added `examples/promises.js`
620   * Added ability to read raw file data via `decompress` and `decrypt` options. [issue #11](https://github.com/thejoshwolfe/yauzl/issues/11), [issue #38](https://github.com/thejoshwolfe/yauzl/issues/38), [pull #39](https://github.com/thejoshwolfe/yauzl/pull/39)
621   * Added `start` and `end` options to `openReadStream()`. [issue #38](https://github.com/thejoshwolfe/yauzl/issues/38)
622 * 2.7.0
623   * Added option `decodeStrings`. [issue #42](https://github.com/thejoshwolfe/yauzl/issues/42)
624   * Fixed documentation for `entry.fileComment` and added compatibility alias. [issue #47](https://github.com/thejoshwolfe/yauzl/issues/47)
625 * 2.6.0
626   * Support Info-ZIP Unicode Path Extra Field, used by WinRAR for Chinese file names. [issue #33](https://github.com/thejoshwolfe/yauzl/issues/33)
627 * 2.5.0
628   * Ignore malformed Extra Field that is common in Android .apk files. [issue #31](https://github.com/thejoshwolfe/yauzl/issues/31)
629 * 2.4.3
630   * Fix crash when parsing malformed Extra Field buffers. [issue #31](https://github.com/thejoshwolfe/yauzl/issues/31)
631 * 2.4.2
632   * Remove .npmignore and .travis.yml from npm package.
633 * 2.4.1
634   * Fix error handling.
635 * 2.4.0
636   * Add ZIP64 support. [issue #6](https://github.com/thejoshwolfe/yauzl/issues/6)
637   * Add `lazyEntries` option. [issue #22](https://github.com/thejoshwolfe/yauzl/issues/22)
638   * Add `readStream.destroy()` method. [issue #26](https://github.com/thejoshwolfe/yauzl/issues/26)
639   * Add `fromRandomAccessReader()`. [issue #14](https://github.com/thejoshwolfe/yauzl/issues/14)
640   * Add `examples/unzip.js`.
641 * 2.3.1
642   * Documentation updates.
643 * 2.3.0
644   * Check that `uncompressedSize` is correct, or else emit an error. [issue #13](https://github.com/thejoshwolfe/yauzl/issues/13)
645 * 2.2.1
646   * Update dependencies.
647 * 2.2.0
648   * Update dependencies.
649 * 2.1.0
650   * Remove dependency on `iconv`.
651 * 2.0.3
652   * Fix crash when trying to read a 0-byte file.
653 * 2.0.2
654   * Fix event behavior after errors.
655 * 2.0.1
656   * Fix bug with using `iconv`.
657 * 2.0.0
658   * Initial release.
659