pax_global_header00006660000000000000000000000064152112651610014512gustar00rootroot0000000000000052 comment=f5798e15204ffbb9a428b00217e4659684a41b0f yauzl-3.4.0/000077500000000000000000000000001521126516100126625ustar00rootroot00000000000000yauzl-3.4.0/.github/000077500000000000000000000000001521126516100142225ustar00rootroot00000000000000yauzl-3.4.0/.github/workflows/000077500000000000000000000000001521126516100162575ustar00rootroot00000000000000yauzl-3.4.0/.github/workflows/test.yml000066400000000000000000000010111521126516100177520ustar00rootroot00000000000000on: push: branches: - master pull_request: branches: - master jobs: test: strategy: matrix: node-version: - 12 - 14 - 16 - 18 - 20 - 24 - 26 runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} - run: npm install - run: node test/test.js yauzl-3.4.0/.gitignore000066400000000000000000000000431521126516100146470ustar00rootroot00000000000000/coverage /node_modules /test/.tmp yauzl-3.4.0/CONTRIBUTING.md000066400000000000000000000051111521126516100151110ustar00rootroot00000000000000# Contributing to yauzl ## Intro Thanks for your interest in contributing to this project! I'm a team of one person reviewing issues and PRs and publishing updates to this code. I appreciate your patience, as I might take weeks-to-months to respond. This project is "funded" strictly by my enthusiasm, and many aspects of its design are optimized for maintainer joy: correctness, precision, test coverage, performance, thoroughly documented API, etc. The best way that you, prospective contributor, can support the project is honestly just having a warm attitude. We're all here making open source software to make the world a better place, and I appreciate you joining me on this journey! â�¤ï¸� ## AI Policy Using the model proposed in https://www.visidata.org/blog/2026/ai/ , PRs submitted to this project are limited to Levels 0-5, meaning you need to fully understand everything you are presenting regardless of how it got written. I am always operating at Level 0. I don't have any accounts with AI companies, because LLM-assisted code authoring takes the fun out of it for me. I insist on understanding all the code I ship, and I ask that you respect my level of effort before asking me to review your code. ## When to open an Issue vs a PR Simple typo fixes are pretty trivial to fully understand, but complex fixes or features are much harder. If you don't fully understand the PR you're drafting, consider just filing a bug report or feature request instead. I don't expect you to have full context on this project's history and nuances, so come on over to the issues section and let's discuss it! I'd much prefer you ask for help than propose a change with misplaced confidence in an LLM. Even if you do achieve full understanding of a complex PR, I may review your code and decide to rewrite it all in my own style anyway. That doesn't mean you wasted your time! Showing interest in this project contributes directly to the "funding" mentioned above; I appreciate it! However, if you don't like the idea of your code getting thrown away, let's have a design discussion in the issues before you invest your time in any code changes. ## Software engineering fundamentals I won't articulate the fundamentals of how to open good bug reports, feature requests, or change requests in this guide. These are skills that apply to any open source repo, so you should be able to find resources elsewhere (for example, bug reports should include steps to reproduce). If you wish there were helpful links listed here and you've found some you like, feel free to open an issue or PR with suggestions! ## Thank You! -Josh yauzl-3.4.0/LICENSE000066400000000000000000000020651521126516100136720ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2014 Josh Wolfe 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. yauzl-3.4.0/README.md000066400000000000000000001553061521126516100141530ustar00rootroot00000000000000# yauzl yet another unzip library for node. For zipping, see [yazl](https://github.com/thejoshwolfe/yazl). Design principles: * Follow the spec. Don't scan for local file headers. Read the central directory for file metadata. (see [No Streaming Unzip API](#no-streaming-unzip-api)). * Don't block the JavaScript thread. Use and provide async APIs. * Keep memory usage under control. Don't attempt to buffer entire files in RAM at once. * Never crash (if used properly). Don't let malformed zip files bring down client applications who are trying to catch errors. * Catch unsafe file names. See `validateFileName()`. ## Usage Using `await`: ```js const yauzl = require("yauzl"); (async () => { try { const zipfile = await yauzl.openPromise("path/to/file.zip"); for await (let entry of zipfile.eachEntry()) { if (entry.fileName.endsWith("/")) { // Directory file names end with '/'. // Note that entries for directories themselves are optional. // An entry's fileName implicitly requires its parent directories to exist. continue; } else { // file entry const readStream = await zipfile.openReadStreamPromise(entry); await stream.promises.pipeline(readStream, somewhere); } } } catch (err) { // Indicates a malformed zipfile or I/O error. throw err; } })(); ``` Using callbacks: ```js var yauzl = require("yauzl"); yauzl.open("path/to/file.zip", {lazyEntries: true}, function(err, zipfile) { if (err) throw err; zipfile.readEntry(); zipfile.on("entry", function(entry) { if (entry.fileName.endsWith("/")) { // Ignore directory entry. zipfile.readEntry(); } else { // file entry zipfile.openReadStream(entry, function(err, readStream) { if (err) throw err; readStream.on("end", function() { zipfile.readEntry(); }); readStream.pipe(somewhere); }); } }); }); ``` See also `examples/` for more usage examples. ## API The default for every optional `callback` parameter is: ```js function defaultCallback(err) { if (err) throw err; } ``` ### open(path, [options], [callback]) Calls `fs.open(path, "r")` and reads the `fd` effectively the same as `fromFd()` would. See also `openPromise()` to get `Promise` semantics. `options` may be omitted or `null`. The defaults are `{autoClose: true, lazyEntries: false, decodeStrings: true, validateEntrySizes: true, strictFileNames: false}`. `autoClose` is effectively equivalent to: ```js zipfile.once("end", function() { zipfile.close(); }); ``` `lazyEntries` indicates that entries should be read only when `readEntry()` is called. If `lazyEntries` is `false`, `entry` events will be emitted as fast as possible to allow `pipe()`ing file data from all entries in parallel. This is not recommended, as it can lead to out of control memory usage for zip files with many entries. See [issue #22](https://github.com/thejoshwolfe/yauzl/issues/22). If `lazyEntries` is `true`, an `entry` or `end` event will be emitted in response to each call to `readEntry()`. This allows processing of one entry at a time, and will keep memory usage under control for zip files with many entries. `decodeStrings` is the default and causes yauzl to decode strings with `CP437` or `UTF-8` as required by the spec. The exact effects of turning this option off are: * `zipfile.comment`, `entry.fileName`, and `entry.fileComment` will be `Buffer` objects instead of `String`s. * Any Info-ZIP Unicode Path Extra Field will be ignored. See `extraFields`. * Automatic file name validation will not be performed. See `validateFileName()`. `validateEntrySizes` is the default and ensures that an entry's reported uncompressed size matches its actual uncompressed size. This check happens as early as possible, which is either before emitting each `"entry"` event (for entries with no compression), or during the `readStream` piping after calling `openReadStream()`. See `openReadStream()` for more information on defending against zip bomb attacks. When `strictFileNames` is `false` (the default) and `decodeStrings` is `true`, all backslash (`\`) characters in each `entry.fileName` are replaced with forward slashes (`/`). The spec forbids file names with backslashes, but Microsoft's `System.IO.Compression.ZipFile` class in .NET versions 4.5.0 until 4.6.1 creates non-conformant zipfiles with backslashes in file names. `strictFileNames` is `false` by default so that clients can read these non-conformant zipfiles without knowing about this Microsoft-specific bug. When `strictFileNames` is `true` and `decodeStrings` is `true`, entries with backslashes in their file names will result in an error. See `validateFileName()`. When `decodeStrings` is `false`, `strictFileNames` has no effect. The `callback` is given the arguments `(err, zipfile)`. An `err` is provided if the End of Central Directory Record cannot be found, or if its metadata appears malformed. This kind of error usually indicates that this is not a zip file. Otherwise, `zipfile` is an instance of `ZipFile`. ### fromFd(fd, [options], [callback]) Reads from the fd, which is presumed to be an open .zip file. Note that random access is required by the zip file specification, so the fd cannot be an open socket or any other fd that does not support random access. See also `fromFdPromise()` to get `Promise` semantics. `options` may be omitted or `null`. The defaults are `{autoClose: false, lazyEntries: false, decodeStrings: true, validateEntrySizes: true, strictFileNames: false}`. See `open()` for the meaning of the options and callback. ### fromBuffer(buffer, [options], [callback]) Like `fromFd()`, but reads from a RAM buffer instead of an open file. `buffer` is a `Buffer`. See also `fromBufferPromise()` to get `Promise` semantics. If a `ZipFile` is acquired from this method, it will never emit the `close` event, and calling `close()` is not necessary. `options` may be omitted or `null`. The defaults are `{lazyEntries: false, decodeStrings: true, validateEntrySizes: true, strictFileNames: false}`. See `open()` for the meaning of the options and callback. The `autoClose` option is ignored for this method. ### fromRandomAccessReader(reader, totalSize, [options], [callback]) This method of reading a zip file allows clients to implement their own back-end file system. For example, a client might translate read calls into network requests. See also `fromRandomAccessReaderPromise()` to get `Promise` semantics. The `reader` parameter must be of a type that is a subclass of [RandomAccessReader](#class-randomaccessreader) that implements the required methods. The `totalSize` is a Number and indicates the total file size of the zip file. `options` may be omitted or `null`. The defaults are `{autoClose: true, lazyEntries: false, decodeStrings: true, validateEntrySizes: true, strictFileNames: false}`. See `open()` for the meaning of the options and callback. ### openPromise(path, [options]) Wraps `open()` with `Promise` semantics. The returned promise is rejected if the `callback` for `open()` receives an `err`, otherwise the promise is resolved with the `zipfile`. `options` may be omitted or `null`, and `path` and `options` are passed to `open()`. `options.lazyEntries` is always set to `true`, overriding any value you pass in. This is required for using `zipfile.eachEntry()`, which you probably also want to use. ### fromFdPromise(fd, [options]) Wraps `fromFd()` with `Promise` semantics. The returned promise is rejected if the `callback` for `fromFd()` receives an `err`, otherwise the promise is resolved with the `zipfile`. `options` may be omitted or `null`, and `fd` and `options` are passed to `fromFd()`. `options.lazyEntries` is always set to `true`, overriding any value you pass in. This is required for using `zipfile.eachEntry()`, which you probably also want to use. ### fromBufferPromise(buffer, [options]) Wraps `fromBuffer()` with `Promise` semantics. The returned promise is rejected if the `callback` for `fromBuffer()` receives an `err`, otherwise the promise is resolved with the `zipfile`. `options` may be omitted or `null`, and `buffer` and `options` are passed to `fromBuffer()`. `options.lazyEntries` is always set to `true`, overriding any value you pass in. This is required for using `zipfile.eachEntry()`, which you probably also want to use. ### fromRandomAccessReaderPromise(reader, totalSize, [options]) Wraps `fromRandomAccessReader()` with `Promise` semantics. The returned promise is rejected if the `callback` for `fromRandomAccessReader()` receives an `err`, otherwise the promise is resolved with the `zipfile`. `options` may be omitted or `null`, and `reader`, `totalSize`, and `options` are passed to `fromRandomAccessReader()`. `options.lazyEntries` is always set to `true`, overriding any value you pass in. This is required for using `zipfile.eachEntry()`, which you probably also want to use. ### dosDateTimeToDate(date, time) *Deprecated*. Since yauzl 3.2.0, it is highly recommended to call [`entry.getLastModDate()`](#getlastmoddateoptions) instead of this function due to enhanced support for reading third-party extra fields. If you ever have a use case for calling this function directly please [open an issue against yauzl](https://github.com/thejoshwolfe/yauzl/issues/new) requesting that this function be properly supported again. This function only remains exported in order to maintain compatibility with older versions of yauzl. It will be removed in yauzl 4.0.0 unless someone asks for it to remain supported. ### getFileNameLowLevel(generalPurposeBitFlag, fileNameBuffer, extraFields, strictFileNames) If you are setting `decodeStrings` to `false`, then this function can be used to decode the file name yourself. This function is effectively used internally by yauzl to populate the `entry.fileName` field when `decodeStrings` is `true`. WARNING: This method of getting the file name bypasses the security checks in [`validateFileName()`](#validatefilename-filename). You should call that function yourself to be sure to guard against malicious file paths. `generalPurposeBitFlag` can be found on an [`Entry`](#class-entry) or [`LocalFileHeader`](#class-localfileheader). Only General Purpose Bit 11 is used, and only when an Info-ZIP Unicode Path Extra Field cannot be found in `extraFields`. `fileNameBuffer` is a `Buffer` representing the file name field of the entry. This is `entry.fileNameRaw` or `localFileHeader.fileName`. `extraFields` is the parsed extra fields array from `entry.extraFields` or `parseExtraFields()`. `strictFileNames` is a boolean, the same as the option of the same name in `open()`. When `false`, backslash characters (`\`) will be replaced with forward slash characters (`/`). This function always returns a string, although it may not be a valid file name. See `validateFileName()`. ### validateFileName(fileName) Returns `null` or a `String` error message depending on the validity of `fileName`. If `fileName` starts with `"/"` or `/[A-Za-z]:\//` or if it contains `".."` path segments or `"\\"`, this function returns an error message appropriate for use like this: ```js var errorMessage = yauzl.validateFileName(fileName); if (errorMessage != null) throw new Error(errorMessage); ``` This function is automatically run for each entry, as long as `decodeStrings` is `true`. See `open()`, `strictFileNames`, and `Event: "entry"` for more information. ### parseExtraFields(extraFieldBuffer) This function is used internally by yauzl to compute [`entry.extraFields`](#extrafields). It is exported in case you want to call it on [`localFileHeader.extraField`](#class-localfileheader). `extraFieldBuffer` is a `Buffer`, such as `localFileHeader.extraField`. Returns an `Array` with each item in the form `{id: id, data: data}`, where `id` is a `Number` and `data` is a `Buffer`. Throws an `Error` if the data encodes an item with a size that exceeds the bounds of the buffer. You may want to surround calls to this function with `try { ... } catch (err) { ... }` to handle the error. ### Class: ZipFile The constructor for the class is not part of the public API. Use `open()`, `fromFd()`, `fromBuffer()`, or `fromRandomAccessReader()` instead. #### Event: "entry" Callback gets `(entry)`, which is an `Entry`. See `open()` and `readEntry()` for when this event is emitted. See also `eachEntry()` for an async iterator alternative to this event. If `decodeStrings` is `true`, entries emitted via this event have already passed file name validation. See `validateFileName()` and `open()` for more information. If `validateEntrySizes` is `true` and this entry's `compressionMethod` is `0` (stored without compression), this entry has already passed entry size validation. See `open()` for more information. #### Event: "end" Emitted after the last `entry` event has been emitted. See `open()` and `readEntry()` for more info on when this event is emitted. See also `eachEntry()` for an async iterator alternative to this event. #### Event: "close" Emitted after the fd is actually closed. This is after calling `close()` (or after the `end` event when `autoClose` is `true`), and after all stream pipelines created from `openReadStream()` have finished reading data from the fd. If this `ZipFile` was acquired from `fromRandomAccessReader()`, the "fd" in the previous paragraph refers to the `RandomAccessReader` implemented by the client. If this `ZipFile` was acquired from `fromBuffer()`, this event is never emitted. #### Event: "error" Emitted in the case of errors with reading the zip file. (Note that other errors can be emitted from the streams created from `openReadStream()` as well.) After this event has been emitted, no further `entry`, `end`, or `error` events will be emitted, but the `close` event may still be emitted. See also `eachEntry()` for an async iterator alternative to this event. #### readEntry() Causes this `ZipFile` to emit an `entry` or `end` event (or an `error` event). This method must only be called when this `ZipFile` was created with the `lazyEntries` option set to `true` (see `open()`), and must not be called if you are using `eachEntry()`. When this `ZipFile` was created with the `lazyEntries` option set to `true`, `entry` and `end` events are only ever emitted in response to this method call. See also `eachEntry()` for an async iterator alternative to this method. The event that is emitted in response to this method will not be emitted until after this method has returned, so it is safe to call this method before attaching event listeners. After calling this method, calling this method again before the response event has been emitted will cause undefined behavior. Calling this method after the `end` event has been emitted will cause undefined behavior. Calling this method after calling `close()` will cause undefined behavior. #### eachEntry() Returns an async iterable/iterator that yields each entry in this `ZipFile`. This allows using `for await (let entry of zipfile.eachEntry()) { ... }` to iterate through the `Entry` objects that would otherwise be emitted via `Event: "entry"`. The object returned from `eachEntry()` implements `next()`, `return()`, and `throw()` satisfying the async iterator API, and implements `[Symbol.asyncIterator]()`, which simply returns `this`, satisfying the async iterable API. `next()` returns a promise which is eventually either rejected with an error, or resolves to one of: * `{value: entry}` with the next `Entry`, analogous to `Event: "entry"`, or * `{done: true}` signaling the end of iteration, analogous to `Event: "end"`. You must abstain from calling `next()` again until the promise returned from the previous call to `next()` has resolved. This is how `for await...of` and `Array.fromAsync()` work. If `autoClose` is `true`, this `ZipFile` is closed at the end of iteration, or when iteration is interrupted by `return()`, which is called implicitly when exiting a `for await...of` loop with `break`, `return`, etc. If you want to still call `openReadStream()` after iteration has ended (such as when using `Array.fromAsync()` to collect entries all ahead of time), set `autoClose` to `false`, and call `close()` manually when you are done with the `ZipFile`. There is no supported way to resume iteration if it is interrupted with `return()`. Using `eachEntry()` is incompatible with older styles of accessing this `ZipFile`. If you use `eachEntry()`: * `lazyEntries` must be `true` (see `open()`). (Some APIs set this automatically for you.) * You must never call `readEntry()` on this `ZipFile`. * It is not recommend to listen for `Event: "entry"` or `Event: "end"`, because that information is fully provided by the async iterator instead. * It is not recommended to listen for `Event: "error"` on this `ZipFile`, but rather handle errors conveyed through the `Promise` API, such as with a `try...catch` block around the `for await...of` expression, or with the `catch()` method on each promise returned by `next()`, etc. * You must not call `eachEntry()` more than once. The iteration state is maintained in the `ZipFile` object itself, not in the iterator, and it is not possible to reset iteration to get the same `Entry` objects more than once. See `examples/promises.js` for an example using this method. #### openReadStream(entry, [options], callback) `entry` must be an `Entry` object from this `ZipFile`. `callback` gets `(err, readStream)`, where `readStream` is a `Readable Stream` that provides the file data for this entry. If this zipfile is already closed (see `close()`), the `callback` will receive an `err`. See also `openReadStreamPromise()` to get `Promise` semantics. `options` may be omitted or `null`, and has the following defaults: ```js { decodeFileData: true, start: 0, // actually the default is null, see below end: entry.compressedSize, // actually the default is null, see below decompress: null, // deprecated decrypt: null, // deprecated } ``` When `decodeFileData` is `true` (or `null` or omitted), yauzl will attempt to decode the file data using a zlib inflate transform when appropriate. Setting `decodeFileData` to `false` will provide the bytes of the entry's contents exactly as-is in the archive. When `compressionMethod` is `0` (stored with no compression) and the entry is not encrypted, `decodeFileData` has no effect. If `canDecodeFileData()` returns `false`, then `decodeFileData` must be set to `false`, or else `callback` will receive an error. It is up to the caller to make sense of any file data with encryption and/or an uncommon compression method. The `start` (inclusive) and `end` (exclusive) options are byte offsets into this entry's file data, and can be used to obtain part of an entry's file data rather than the whole thing. When specifying `start` and/or `end`, it is recommended to unconditionally set `decodeFileData` to `false`. If either `start` and/or `end` are specified and non-`null`, then either `decodeFileData` must be set to `false`, or both `isEncrypted()` must return `false` and `compressionMethod` must be `0`. Specifying `{start: 0, end: entry.compressedSize}` will result in the complete file. For compatibility with versions of yauzl prior to 3.3.x, `start` and `end` can also be used when the deprecated `decompress` and `decrypt` options are used appropriately. This is no longer documented, but an archive of the documentation can be found here: https://github.com/thejoshwolfe/yauzl/blob/c4695215b05c6adffda613b9051a2a85429b33fe/README.md#openreadstreamentry-options-callback It's possible for the `readStream` provided to the `callback` to emit errors for several reasons. For example, if zlib cannot decompress the data, the zlib error will be emitted from the `readStream`. Two more error cases (when `validateEntrySizes` is `true`) are if the decompressed data has too many or too few actual bytes compared to the reported byte count from the entry's `uncompressedSize` field. yauzl notices this false information and emits an error from the `readStream` after some number of bytes have already been piped through the stream. This check allows clients to trust the `uncompressedSize` field in `Entry` objects. Guarding against [zip bomb](http://en.wikipedia.org/wiki/Zip_bomb) attacks can be accomplished by doing some heuristic checks on the size metadata and then watching out for the above errors. Such heuristics are outside the scope of this library, but enforcing the `uncompressedSize` is implemented here as a security feature. It is possible to destroy the `readStream` before it has piped all of its data. To do this, call `readStream.destroy()`. You must `unpipe()` the `readStream` from any destination before calling `readStream.destroy()`. If this zipfile was created using `fromRandomAccessReader()`, the `RandomAccessReader` implementation must provide readable streams that implement a `._destroy()` method according to https://nodejs.org/api/stream.html#writable_destroyerr-callback (see `randomAccessReader._readStreamForRange()`) in order for calls to `readStream.destroy()` to work in this context. #### readLocalFileHeader(entry, [options], callback) This is a low-level function you probably don't need to call. The intended use case is either preparing to call `openReadStreamLowLevel()` or simply examining the content of the local file header out of curiosity or for debugging zip file structure issues. `entry` is an entry obtained from `Event: "entry"`. An `entry` in this library is a file's metadata from a Central Directory Header, and this function gives the corresponding redundant data in a Local File Header. `options` may be omitted or `null`, and has the following defaults: ```js { minimal: false, } ``` If `minimal` is `false` (or omitted or `null`), the callback receives a full [`LocalFileHeader`](#class-localfileheader). If `minimal` is `true`, the callback receives an object with a single property and no prototype `{fileDataStart: fileDataStart}`. For typical zipfile reading usecases, this field is the only one you need, and yauzl internally effectively uses the `{minimal: true}` option as part of `openReadStream()`. The `callback` receives `(err, localFileHeaderOrAnObjectWithJustOneFieldDependingOnTheMinimalOption)`, where the type of the second parameter is described in the above discussion of the `minimal` option. #### openReadStreamLowLevel(fileDataStart, compressedSize, relativeStart, relativeEnd, decompress, uncompressedSize, callback) This is a low-level function available for advanced use cases. You probably want `openReadStream()` instead. See also `openReadStreamLowLevelPromise()` to get `Promise` semantics. The intended use case for this function is calling `readEntry()` and `readLocalFileHeader()` with `{minimal: true}` first, and then opening the read stream at a later time, possibly after closing and reopening the entire zipfile, possibly even in a different process. The parameters are all integers and booleans, which are friendly to serialization. * `fileDataStart` - from `localFileHeader.fileDataStart` * `compressedSize` - from `entry.compressedSize` * `relativeStart` - the resolved value of `options.start` from `openReadStream()`. Must be a non-negative integer, not `null`. Typically `0` to start at the beginning of the data. * `relativeEnd` - the resolved value of `options.end` from `openReadStream()`. Must be a non-negative integer, not `null`. Typically `entry.compressedSize` to include all the data. * `decompress` - boolean indicating whether the data should be piped through a zlib inflate stream. * `uncompressedSize` - from `entry.uncompressedSize`. Only used when `validateEntrySizes` is `true`. If `validateEntrySizes` is `false`, this value is ignored, but must still be present, not omitted, in the arguments; you have to give it some value, even if it's `null`. * `callback` - receives `(err, readStream)`, the same as for `openReadStream()` This low-level function does not read any metadata from the underlying storage before opening the read stream. This is both a performance feature and a safety hazard. None of the integer parameters are bounds checked. None of the validation from `openReadStream()` with respect to compression and encryption is done here either. Only the bounds checks from `validateEntrySizes` are done, because that is part of processing the stream data. #### openReadStreamPromise(entry, [options]) Wraps `openReadStream()` with `Promise` semantics. The returned promise is rejected if the `callback` for `openReadStream()` receives an `err`, otherwise the promise is resolved with the `readStream`. `entry` and `options` are passed directly to `openReadStream()`. #### readLocalFileHeaderPromise(entry, [options]) Wraps `readLocalFileHeader()` with `Promise` semantics. The returned promise is rejected if the `callback` for `readLocalFileHeader()` receives an `err`, otherwise the promise is resolved with the `readStream`. `entry` and `options` are passed directly to `readLocalFileHeader()`. #### openReadStreamLowLevelPromise(fileDataStart, compressedSize, relativeStart, relativeEnd, decompress, uncompressedSize) Wraps `openReadStreamLowLevel()` with `Promise` semantics. The returned promise is rejected if the `callback` for `openReadStreamLowLevel()` receives an `err`, otherwise the promise is resolved with the `readStream`. All arguments, `fileDataStart`, `compressedSize`, `relativeStart`, `relativeEnd`, `decompress`, and `uncompressedSize`, are passed directly to `openReadStreamLowLevel()`. #### close() Causes all future calls to `openReadStream()` to fail, and closes the fd, if any, after all streams created by `openReadStream()` have emitted their `end` events. If the `autoClose` option is set to `true` (see `open()`), this function will be called automatically effectively in response to this object's `end` event. If the `lazyEntries` option is set to `false` (see `open()`) and this object's `end` event has not been emitted yet, this function causes undefined behavior. If the `lazyEntries` option is set to `true`, you can call this function instead of calling `readEntry()` to abort reading the entries of a zipfile. It is safe to call this function multiple times; after the first call, successive calls have no effect. This includes situations where the `autoClose` option effectively calls this function for you. If `close()` is never called, then the zipfile is "kept open". For zipfiles created with `fromFd()`, this will leave the `fd` open, which may be desirable. For zipfiles created with `open()`, this will leave the underlying `fd` open, thereby "leaking" it, which is probably undesirable. For zipfiles created with `fromRandomAccessReader()`, the reader's `close()` method will never be called. For zipfiles created with `fromBuffer()`, the `close()` function has no effect on resource usage. Regardless of how this `ZipFile` was created, there are no resources other than those listed above that require cleanup from this function. This means it may be desirable to never call `close()` in some usecases. #### isOpen `Boolean`. `true` until `close()` is called; then it's `false`. #### entryCount `Number`. Total number of central directory records. #### comment `String`. Always decoded with `CP437` per the spec. If `decodeStrings` is `false` (see `open()`), this field is the undecoded `Buffer` instead of a decoded `String`. ### Class: Entry Objects of this class represent Central Directory Records. Refer to the zipfile specification for more details about these fields. These fields are of type `Number`: * `versionMadeBy` * `versionNeededToExtract` * `generalPurposeBitFlag` * `compressionMethod` * `lastModFileTime` (MS-DOS format, see [`getLastModDate()`](#getlastmoddateoptions)) * `lastModFileDate` (MS-DOS format, see [`getLastModDate()`](#getlastmoddateoptions)) * `crc32` * `compressedSize` * `uncompressedSize` * `fileNameLength` (in bytes) * `extraFieldLength` (in bytes) * `fileCommentLength` (in bytes) * `internalFileAttributes` * `externalFileAttributes` * `relativeOffsetOfLocalHeader` These fields are of type `Buffer`, and represent variable-length bytes before being processed: * `fileNameRaw` * `extraFieldRaw` * `fileCommentRaw` There are additional fields described below: `fileName`, `extraFields`, `fileComment`. These are the processed versions of the `*Raw` fields listed above. See their own sections below. (Note the inconsistency in pluralization of "field" vs "fields" in `extraField`, `extraFields`, and `extraFieldRaw`. Sorry about that.) The `new Entry()` constructor is available for clients to call, but it's usually not useful. The constructor takes no parameters and does nothing; no fields will exist. #### fileName `String`. Following the spec, the bytes for the file name are decoded with `UTF-8` if `generalPurposeBitFlag & 0x800`, otherwise with `CP437`. Alternatively, this field may be populated from the Info-ZIP Unicode Path Extra Field (see `extraFields`). This field is automatically validated by `validateFileName()` before yauzl emits an "entry" event. If this field would contain unsafe characters, yauzl emits an error instead of an entry. If `decodeStrings` is `false` (see `open()`), this field is the undecoded `Buffer` instead of a decoded `String`. Therefore, `generalPurposeBitFlag` and any Info-ZIP Unicode Path Extra Field are ignored. Furthermore, no automatic file name validation is performed for this file name. #### extraFields `Array` with each item in the form `{id: id, data: data}`, where `id` is a `Number` and `data` is a `Buffer`. This library looks for and reads the ZIP64 Extended Information Extra Field (0x0001) in order to support ZIP64 format zip files. This library also looks for and reads the Info-ZIP Unicode Path Extra Field (0x7075) in order to support some zipfiles that use it instead of General Purpose Bit 11 to convey `UTF-8` file names. When the field is identified and verified to be reliable (see the zipfile spec), the file name in this field is stored in the `fileName` property, and the file name in the central directory record for this entry is ignored. Note that when `decodeStrings` is false, all Info-ZIP Unicode Path Extra Fields are ignored. See also [`getLastModDate()`](#getlastmoddateoptions) for additional extra fields that are recognized by this library. #### fileComment `String` decoded with the charset indicated by `generalPurposeBitFlag & 0x800` as with the `fileName`. (The Info-ZIP Unicode Path Extra Field has no effect on the charset used for this field.) If `decodeStrings` is `false` (see `open()`), this field is the undecoded `Buffer` instead of a decoded `String`. Prior to yauzl version 2.7.0, this field was erroneously documented as `comment` instead of `fileComment`. For compatibility with any code that uses the field name `comment`, yauzl creates an alias field named `comment` which is identical to `fileComment`. #### getLastModDate([options]) Returns the modification time of the file as a JavaScript `Date` object. The timezone situation is a mess due to both ZIP issues and JavaScript issues; read on to learn more. Due to the zip file specification having lackluster support for specifying timestamps natively, there are several third-party extensions that add better support in the `extraFields`. yauzl supports these encodings: 1. Info-ZIP "universal timestamp" extended field (`0x5455` aka `"UT"`): signed 32-bit seconds since `1970-01-01 00:00:00Z`, which supports the years 1901-2038 (partially inclusive) with 1-second precision. The value is timezone agnostic, i.e. always UTC. 2. NTFS extended field (`0x000a`): 64-bit signed 100-nanoseconds since `1601-01-01 00:00:00Z`, which supports the approximate years 20,000BCE-20,000CE with precision rounded to 1-millisecond (due to the JavaScript `Date` type). The value is timezone agnostic, i.e. always UTC. 3. DOS `lastModFileDate` and `lastModFileTime`: supports the years 1980-2108 (inclusive) with 2-second precision. Timezone is interpreted either as the local timezone or UTC depending on the `timezone` option documented below. If both the Info-ZIP "universal timestamp" and NTFS extended fields are found, yauzl uses one of them, but which one is unspecified. If neither are found, yauzl falls back to the built-in DOS `lastModFileDate` and `lastModFileTime`. Every possible bit pattern of every encoding can be represented by a JavaScript `Date` object, meaning this function cannot fail (barring parameter validation), and will never return an `Invalid Date` object. `options` may be omitted or `null`, and has the following defaults: ```js { timezone: "local", // or "UTC" forceDosFormat: false, } ``` Set `forceDosFormat` to `true` (and do not set `timezone`) to enable pre-yauzl 3.2.0 behavior where the Info-ZIP "universal timestamp" and NTFS extended fields are ignored. The `timezone` option is only used in the DOS fallback. If `timezone` is `"local"` (or omitted or `null`), the `lastModFileDate` and `lastModFileTime` are interpreted in the system's current timezone (using `new Date(year, ...)`). If `timezone` is `"UTC"`, the interpretation is in UTC+00:00 (using `new Date(Date.UTC(year, ...))`). The JavaScript `Date` object, has several inherent limitations surrounding timezones. There is an ECMAScript proposal to add better timezone support to JavaScript called the `Temporal` API. Last I checked, it was at stage 4. https://github.com/tc39/proposal-temporal Once that new API is available and stable, better timezone handling should be possible here somehow. If you notice that the new API has become widely available, please open a feature request against this library to add support for it. #### canDecodeFileData() Returns `true` if and only if the metadata for this entry specifies an encoding that yauzl can automatically decode as part of `openReadStream()`. This considers compression method and encryption. Only compression methods `0` (stored with no compression) and `8` (deflated) are supported, and neither traditional encryption nor strong encryption is supported. See also `openReadStream()`. #### isEncrypted() Note that "Strong Encryption" is not supported, and will result in an `"error"` event emitted from the `ZipFile`. This method is effectively implemented as `return (this.generalPurposeBitFlag & 0x1) !== 0`. yauzl provides no functionality to decrypt file data. #### isCompressed() *DEPRECATED*: use `canDecodeFileData()` instead, and/or manually check `compressionMethod`. This method is effectively implemented as `return this.compressionMethod === 8`, which misleadingly returns `false` for entries that are compressed using a compression method other than `8`. This implementation is maintained for backward compatibility with yauzl versions prior to 3.3.x. ### Class: LocalFileHeader This is a trivial class that has no methods and only the following properties. The constructor is available to call, but it doesn't do anything. See `readLocalFileHeader()`. See the zipfile spec for what these fields mean. * `fileDataStart` - `Number`: inferred from `fileNameLength`, `extraFieldLength`, and this struct's position in the zipfile. * `versionNeededToExtract` - `Number` * `generalPurposeBitFlag` - `Number` * `compressionMethod` - `Number` * `lastModFileTime` - `Number` * `lastModFileDate` - `Number` * `crc32` - `Number` * `compressedSize` - `Number` * `uncompressedSize` - `Number` * `fileNameLength` - `Number` * `extraFieldLength` - `Number` * `fileName` - `Buffer` * `extraField` - `Buffer` Note that unlike `Class: Entry`, the `fileName` and `extraField` are completely unprocessed. This notably lacks Unicode and ZIP64 handling as well as any kind of safety validation on the file name. See also [`parseExtraFields()`](#parseextrafields-extrafieldbuffer). Also note that if your object is missing some of these fields, make sure to read the docs on the `minimal` option in `readLocalFileHeader()`. ### Class: RandomAccessReader This class is meant to be subclassed by clients and instantiated for the `fromRandomAccessReader()` function. An example implementation can be found in `test/test.js`. #### randomAccessReader._readStreamForRange(start, end) Subclasses *must* implement this method. `start` and `end` are Numbers and indicate byte offsets from the start of the file. `end` is exclusive, so `_readStreamForRange(0x1000, 0x2000)` would indicate to read `0x1000` bytes. `end - start` will always be at least `1`. This method should return a readable stream which will be `pipe()`ed into another stream. It is expected that the readable stream will provide data in several chunks if necessary. If the readable stream provides too many or too few bytes, an error will be emitted. (Note that `validateEntrySizes` has no effect on this check, because this is a low-level API that should behave correctly regardless of the contents of the file.) Any errors emitted on the readable stream will be handled and re-emitted on the client-visible stream (returned from `zipfile.openReadStream()`) or provided as the `err` argument to the appropriate callback (for example, for `fromRandomAccessReader()`). If you call `readStream.destroy()` on streams you get from `openReadStream()`, the returned stream *must* implement a method `._destroy()` according to https://nodejs.org/api/stream.html#writable_destroyerr-callback . If you never call `readStream.destroy()`, then streams returned from this method do not need to implement a method `._destroy()`. `._destroy()` should abort any streaming that is in progress and clean up any associated resources. `._destroy()` will only be called after the stream has been `unpipe()`d from its destination. Note that the stream returned from this method might not be the same object that is provided by `openReadStream()`. The stream returned from this method might be `pipe()`d through one or more filter streams (for example, a zlib inflate stream). #### randomAccessReader.read(buffer, offset, length, position, callback) Subclasses may implement this method. The default implementation uses `createReadStream()` to fill the `buffer`. This method should behave like `fs.read()`. #### randomAccessReader.close(callback) Subclasses may implement this method. The default implementation is effectively `setImmediate(callback);`. `callback` takes parameters `(err)`. This method is called once the all streams returned from `_readStreamForRange()` have ended, and no more `_readStreamForRange()` or `read()` requests will be issued to this object. ## How to Avoid Crashing When a malformed zipfile is encountered, the default behavior is to crash (throw an exception). If you want to handle errors more gracefully than this, be sure to do the following: * When using an API with a `callback` parameter, check the `err` parameter. * When using an API that returns a `Promise`, check for promise rejection. * When accessing entries via `Event: "entry"` and `Event: "end"`, attach a listener for `Event: "error"` on the `ZipFile`. * When accessing entires via `eachEntry()`, check for promise rejection on each returned promise. (When using `await` or `for await...of`, rejections will be thrown by those language constructs and must be caught with `try...catch`.) * Read streams for entries (such as from `openReadStream()`) can produce errors. Either attach a listen for `Event: "error"` on the read stream, or handle the error some other way. ## Limitations The automated tests for this project run on node versions 12 and up. Older versions of node are not supported. ### Files corrupted by the Mac Archive Utility are not my problem For a lengthy discussion, see [issue #69](https://github.com/thejoshwolfe/yauzl/issues/69). In summary, the Mac Archive Utility is buggy when creating large zip files, and this library does not make any effort to work around the bugs. This library will attempt to interpret the zip file data at face value, which may result in errors, or even silently incomplete data. If this bothers you, that's good! Please complain to Apple. :) I have accepted that this library will simply not support that nonsense. ### No Streaming Unzip API Due to the design of the .zip file format, it's impossible to interpret a .zip file from start to finish (such as from a readable stream) without sacrificing correctness. 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. A streaming API would need to either buffer the entire .zip file to get to the Central Directory before interpreting anything (defeating the purpose of a streaming interface), or rely on the Local File Headers which are interspersed through the .zip file. However, the Local File Headers are explicitly denounced in the spec as being unreliable copies of the Central Directory, so trusting them would be a violation of the spec. Any library that offers a streaming unzip API must make one of the above two compromises, which makes the library either dishonest or nonconformant (usually the latter). This library insists on correctness and adherence to the spec, and so does not offer a streaming API. Here is a way to create a spec-conformant .zip file using the `zip` command line program (Info-ZIP) available in most unix-like environments, that is (nearly) impossible to parse correctly with a streaming parser: ``` $ echo -ne '\x50\x4b\x07\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' > file.txt $ zip -q0 - file.txt | cat > out.zip ``` This .zip file contains a single file entry that uses General Purpose Bit 3, which means the Local File Header doesn't know the size of the file. Any streaming parser that encounters this situation will either immediately fail, or attempt to search for the Data Descriptor after the file's contents. The file's contents is a sequence of 16-bytes crafted to exactly mimic a valid Data Descriptor for an empty file, which will fool any parser that gets this far into thinking that the file is empty rather than containing 16-bytes. What follows the file's real contents is the file's real Data Descriptor, which will likely cause some kind of signature mismatch error for a streaming parser (if one hasn't occurred already). By using General Purpose Bit 3 (and compression method 0), it's possible to create arbitrarily ambiguous .zip files that distract parsers with file contents that contain apparently valid .zip file metadata. ### Limited ZIP64 Support For ZIP64, only zip files smaller than `8PiB` are supported, not the full `16EiB` range that a 64-bit integer should be able to index. This is due to the JavaScript Number type being an IEEE 754 double precision float. The Node.js `fs` module probably has this same limitation. ### ZIP64 Extensible Data Sector Is Ignored The spec does not allow zip file creators to put arbitrary data here, but rather reserves its use for PKWARE and mentions something about Z390. This doesn't seem useful to expose in this library, so it is ignored. ### No Multi-Disk Archive Support This library does not support multi-disk zip files. The multi-disk fields in the zipfile spec were intended for a zip file to span multiple floppy disks, which probably never happens now. If the "number of this disk" field in the End of Central Directory Record is not `0`, the `open()`, `fromFd()`, `fromBuffer()`, or `fromRandomAccessReader()` `callback` will receive an `err`. By extension the following zip file fields are ignored by this library and not provided to clients: * Disk where central directory starts * Number of central directory records on this disk * Disk number where file starts ### Limited Encryption Handling You can detect when a file entry is encrypted with "Traditional Encryption" via `generalPurposeBitFlag`, but yauzl will not help you decrypt it. See the `openReadStream()` option `decodeFileData`. If a zip file contains file entries encrypted with "Strong Encryption", yauzl emits an error. If the central directory is encrypted or compressed, yauzl emits an error. ### Local File Headers Are Ignored Many unzip libraries mistakenly read the Local File Header data in zip files. This data is officially defined to be redundant with the Central Directory information, and is not to be trusted. Aside from checking the signature, yauzl ignores the content of the Local File Header. ### No CRC-32 Checking This library provides the `crc32` field of `Entry` objects read from the Central Directory. However, this field is not used for anything in this library. ### versionNeededToExtract Is Ignored The field `versionNeededToExtract` is ignored, because this library doesn't support the complete zip file spec at any version, ### No Support For Obscure Compression Methods Regarding the `compressionMethod` field of `Entry` objects, only method `0` (stored with no compression) and method `8` (deflated) are supported. Any of the other 15 official methods will cause the `openReadStream()` `callback` to receive an `err`. ### Data Descriptors Are Ignored There may or may not be Data Descriptor sections in a zip file. This library provides no support for finding or interpreting them. ### Archive Extra Data Record Is Ignored There may or may not be an Archive Extra Data Record section in a zip file. This library provides no support for finding or interpreting it. ### No Language Encoding Flag Support Zip files officially support charset encodings other than CP437 and UTF-8, but the zip file spec does not specify how it works. This library makes no attempt to interpret the Language Encoding Flag. ### How Ambiguities Are Handled The zip file specification has several ambiguities inherent in its design. Yikes! * The `.ZIP file comment` must not contain the `end of central dir signature` bytes `50 4b 05 06`. This corresponds to the text `"PK☺☻"` in CP437. While this is allowed by the specification, yauzl will hopefully reject this situation with an "Invalid comment length" error. However, in some situations unpredictable incorrect behavior will ensue, which will probably manifest in either an invalid signature error or some kind of bounds check error, such as "Unexpected EOF". * In non-ZIP64 files, the last central directory header must not have the bytes `50 4b 06 07` (`"PK♠•"` in CP437) exactly 20 bytes from its end, which might be in the `file name`, the `extra field`, or the `file comment`. The presence of these bytes indicates that this is a ZIP64 file. ## Change History * 3.4.0 * Add wrapper functions that give Promise semantics: `openPromise()`, `fromFdPromise()`, `fromBufferPromise()`, `fromRandomAccessReaderPromise()`, `openReadStreamPromise()`, `readLocalFileHeaderPromise()`, `openReadStreamLowLevelPromise()`. [pull #171](https://github.com/thejoshwolfe/yauzl/pull/171) * Add `eachEntry()`, which gives async iterator semantics as an alternative to `readEntry()`, `Event: "entry"`, `Event: "end"`, and `Event: "error"`. * Added more modern examples to `README.md` and `examples/` using `await` on the new APIs. * Added a `CONTRIBUTING.md`. * 3.3.2 * Vendor and simplify `buffer-crc` dependency and prefer `zlib.crc32()` when available. [issue #172](https://github.com/thejoshwolfe/yauzl/issues/172) [pull #173](https://github.com/thejoshwolfe/yauzl/pull/173) * Fixed typo in error handling for obscure IO errors. Raised in [issue #174](https://github.com/thejoshwolfe/yauzl/issues/174). * 3.3.1 * Fixed bugs related to interrupting streams with `destroy()` and with async iteration on read streams. [issue #169](https://github.com/thejoshwolfe/yauzl/issues/169) [pull #170](https://github.com/thejoshwolfe/yauzl/pull/170) * 3.3.0 * Added `entry.canDecodeFileData()` and option `decodeFileData` for `entry.openReadStream()`, and marked as deprecated `isCompressed()` and options `decompress` and `decrypt`. [issue #80](https://github.com/thejoshwolfe/yauzl/issues/80) [pull #81](https://github.com/thejoshwolfe/yauzl/pull/81) [pull #82](https://github.com/thejoshwolfe/yauzl/pull/82) [issue #166](https://github.com/thejoshwolfe/yauzl/issues/166) * 3.2.1 * Fix crash when reading certain corrupted NTFS timestamp extra fields. Thanks to CodeAnt AI Code Reviewer ( https://www.codeant.ai/ai-code-review ) for finding the bug. * 3.2.0 * Added support for reading third-party extensions for timestamps: Info-ZIP "universal timestamp" extra field and NTFS extra field. [pull #160](https://github.com/thejoshwolfe/yauzl/pull/160) * `entry.getLastModDate()` takes options `forceDosFormat` to revert the above change, and `timezone` to allow UTC interpretation of DOS timestamps. * Documented `dosDateTimeToDate()` as now deprecated. * 3.1.3 * Fixed a crash when using `fromBuffer()` to read corrupt zip files that specify out of bounds file offsets. [issue #156](https://github.com/thejoshwolfe/yauzl/pull/156) * Enahnced the test suite to run the error tests through `fromBuffer()` and `fromRandomAccessReader()` in addition to `open()`, which would have caught the above. * 3.1.2 * Fixed handling non-64 bit entries (similar to the version 3.1.1 fix) that actually have exactly 0xffffffff values in the fields. This fixes erroneous "expected zip64 extended information extra field" errors. [issue #109](https://github.com/thejoshwolfe/yauzl/pull/109) * 3.1.1 * Fixed handling non-64 bit files that actually have exactly 0xffff or 0xffffffff values in End of Central Directory Record. This fixes erroneous "invalid zip64 end of central directory locator signature" errors. [issue #108](https://github.com/thejoshwolfe/yauzl/pull/108) * Fixed handling of 64-bit zip files that put 0xffff or 0xffffffff in every field overridden in the Zip64 end of central directory record even if the value would have fit without overflow. In particular, this fixes an incorrect "multi-disk zip files are not supported" error. [pull #118](https://github.com/thejoshwolfe/yauzl/pull/118) * 3.1.0 * Added `readLocalFileHeader()` and `Class: LocalFileHeader`. * Added `openReadStreamLowLevel()`. * Added `getFileNameLowLevel()` and `parseExtraFields()`. Added fields to `Class: Entry`: `fileNameRaw`, `extraFieldRaw`, `fileCommentRaw`. * Added `examples/compareCentralAndLocalHeaders.js` that demonstrate many of these low level APIs. * Noted dropped support of node versions before 12 in the `"engines"` field of `package.json`. * Fixed a crash when calling `openReadStream()` with an explicitly `null` options parameter (as opposed to omitted). * 3.0.0 * BREAKING CHANGE: implementations of [RandomAccessReader](#class-randomaccessreader) that implement a `destroy` method must instead implement `_destroy` in accordance with the node standard https://nodejs.org/api/stream.html#writable_destroyerr-callback (note the error and callback parameters). If you continue to override `destory` instead, some error handling may be subtly broken. Additionally, this is required for async iterators to work correctly in some versions of node. [issue #110](https://github.com/thejoshwolfe/yauzl/issues/110) * BREAKING CHANGE: Drop support for node versions older than 12. * Maintenance: Fix buffer deprecation warning by bundling `fd-slicer` with a 1-line change, rather than depending on it. [issue #114](https://github.com/thejoshwolfe/yauzl/issues/114) * Maintenance: Upgrade `bl` dependency; add `package-lock.json`; drop deprecated istanbul dependency. This resolves all security warnings for this project. [pull #125](https://github.com/thejoshwolfe/yauzl/pull/125) * Maintenance: Replace broken Travis CI with GitHub Actions. [pull #148](https://github.com/thejoshwolfe/yauzl/pull/148) * Maintenance: Fixed a long-standing issue in the test suite where a premature exit would incorrectly signal success. * Officially gave up on supporting Mac Archive Utility corruption in order to rescue my motivation for this project. [issue #69](https://github.com/thejoshwolfe/yauzl/issues/69) * 2.10.0 * 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) * 2.9.2 * 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) * 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) * 2.9.1 * Removed `console.log()` accidentally introduced in 2.9.0. [issue #64](https://github.com/thejoshwolfe/yauzl/issues/64) * 2.9.0 * Throw an exception if `readEntry()` is called without `lazyEntries:true`. Previously this caused undefined behavior. [issue #63](https://github.com/thejoshwolfe/yauzl/issues/63) * 2.8.0 * Added option `validateEntrySizes`. [issue #53](https://github.com/thejoshwolfe/yauzl/issues/53) * Added `examples/promises.js` * 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) * Added `start` and `end` options to `openReadStream()`. [issue #38](https://github.com/thejoshwolfe/yauzl/issues/38) * 2.7.0 * Added option `decodeStrings`. [issue #42](https://github.com/thejoshwolfe/yauzl/issues/42) * Fixed documentation for `entry.fileComment` and added compatibility alias. [issue #47](https://github.com/thejoshwolfe/yauzl/issues/47) * 2.6.0 * Support Info-ZIP Unicode Path Extra Field, used by WinRAR for Chinese file names. [issue #33](https://github.com/thejoshwolfe/yauzl/issues/33) * 2.5.0 * Ignore malformed Extra Field that is common in Android .apk files. [issue #31](https://github.com/thejoshwolfe/yauzl/issues/31) * 2.4.3 * Fix crash when parsing malformed Extra Field buffers. [issue #31](https://github.com/thejoshwolfe/yauzl/issues/31) * 2.4.2 * Remove .npmignore and .travis.yml from npm package. * 2.4.1 * Fix error handling. * 2.4.0 * Add ZIP64 support. [issue #6](https://github.com/thejoshwolfe/yauzl/issues/6) * Add `lazyEntries` option. [issue #22](https://github.com/thejoshwolfe/yauzl/issues/22) * Add `readStream.destroy()` method. [issue #26](https://github.com/thejoshwolfe/yauzl/issues/26) * Add `fromRandomAccessReader()`. [issue #14](https://github.com/thejoshwolfe/yauzl/issues/14) * Add `examples/unzip.js`. * 2.3.1 * Documentation updates. * 2.3.0 * Check that `uncompressedSize` is correct, or else emit an error. [issue #13](https://github.com/thejoshwolfe/yauzl/issues/13) * 2.2.1 * Update dependencies. * 2.2.0 * Update dependencies. * 2.1.0 * Remove dependency on `iconv`. * 2.0.3 * Fix crash when trying to read a 0-byte file. * 2.0.2 * Fix event behavior after errors. * 2.0.1 * Fix bug with using `iconv`. * 2.0.0 * Initial release. ## Development One of the trickiest things in development is crafting test cases located in `test/{success,failure}/`. These are zip files that have been specifically generated or design to test certain conditions in this library. I recommend using [hexdump-zip](https://github.com/thejoshwolfe/hexdump-zip) to examine the structure of a zipfile. For making new error cases, I typically start by copying `test/success/linux-info-zip.zip`, and then editing a few bytes with a hex editor. yauzl-3.4.0/crc32.js000066400000000000000000000065521521126516100141440ustar00rootroot00000000000000// Adapted from https://github.com/brianloveswords/buffer-crc32/blob/v0.2.13/index.js const CRC_TABLE = new Int32Array([ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, ]); function crc32(buf) { let crc = -1; for (let x of buf) { crc = CRC_TABLE[(crc ^ x) & 0xff] ^ (crc >>> 8); } return (crc ^ -1) >>> 0; } module.exports = crc32; yauzl-3.4.0/examples/000077500000000000000000000000001521126516100145005ustar00rootroot00000000000000yauzl-3.4.0/examples/compareCentralAndLocalHeaders.js000066400000000000000000000111521521126516100226670ustar00rootroot00000000000000 var yauzl = require("../"); // replace with: var yauzl = require("yauzl"); function usage() { console.log( "usage: node compareCentralAndLocalHeaders.js path/to/file.zip\n" + "\n" + "Shows a table comparing the central directory metadata and local\n" + "file headers for each item in a zipfile.\n" + ""); process.exit(1); } var zipfilePath = null; var detailedExtraFieldBreakdown = true; process.argv.slice(2).forEach(function(arg) { if (/^-/.test(arg)) usage(); if (zipfilePath != null) usage(); zipfilePath = arg; }); if (zipfilePath == null) usage(); yauzl.open(zipfilePath, {lazyEntries: true, decodeStrings: false}, function(err, zipfile) { if (err) throw err; zipfile.on("error", function(err) { throw err; }); zipfile.readEntry(); zipfile.on("entry", function(entry) { zipfile.readLocalFileHeader(entry, function(err, localFileHeader) { if (err) throw err; compare(entry, localFileHeader); zipfile.readEntry(); }); }); }) function compare(entry, localFileHeader) { console.log(yauzl.getFileNameLowLevel(entry.generalPurposeBitFlag, entry.fileNameRaw, entry.extraFields, false)); // Compare integers var integerFields = [ "versionMadeBy", "versionNeededToExtract", "generalPurposeBitFlag", "compressionMethod", "lastModFileTime", "lastModFileDate", "crc32", "compressedSize", "uncompressedSize", "fileNameLength", "extraFieldLength", "fileCommentLength", "internalFileAttributes", "externalFileAttributes", "relativeOffsetOfLocalHeader", ]; function formatNumber(numberOrNull) { if (numberOrNull == null) return "-"; return "0x" + numberOrNull.toString(16); } var rows = [["field", "central", "local", "diff"]]; rows.push(...integerFields.map(function(name) { var a = entry[name]; var b = localFileHeader[name]; var diff = a == null || b == null ? "" : a === b ? "" : "x"; return [name, formatNumber(a), formatNumber(b), diff] })); var columnWidths = [0, 1, 2, 3].map(function(i) { return Math.max(...rows.map(row => row[i].length)); }); var formatFunctions = ["padEnd", "padStart", "padStart", "padEnd"]; console.log("┌" + columnWidths.map(w => "─".repeat(w)).join("┬") + "â”�"); for (var i = 0; i < rows.length; i++) { console.log("│" + rows[i].map((x, j) => x[formatFunctions[j]](columnWidths[j])).join("│") + "│"); if (i === 0) { console.log("├" + columnWidths.map(w => "─".repeat(w)).join("┼") + "┤"); } } console.log("â””" + columnWidths.map(w => "─".repeat(w)).join("â”´") + "┘"); // Compare variable length data. console.log("central.fileName:", entry.fileNameRaw.toString("hex")); if (entry.fileNameRaw.equals(localFileHeader.fileName)) { console.log("(local matches)"); } else { console.log(" local.fileName:", localFileHeader.fileName.toString("hex")); } console.log("central.extraField:", entry.extraFieldRaw.toString("hex")); if (entry.extraFieldRaw.equals(localFileHeader.extraField)) { console.log("(local matches)"); } else { console.log(" local.extraField:", localFileHeader.extraField.toString("hex")); } if (detailedExtraFieldBreakdown) { var centralExtraFieldMap = extraFieldsToMap(entry.extraFields); var localExtraFieldMap = extraFieldsToMap(yauzl.parseExtraFields(localFileHeader.extraField)); for (var key in centralExtraFieldMap) { var centralData = centralExtraFieldMap[key]; var localData = localExtraFieldMap[key]; delete localExtraFieldMap[key]; // to isolate unhandled keys. console.log(" [" + key + "]central:", centralData.toString("hex")); if (localData != null && centralData.equals(localData)) { console.log(" [" + key + "](local matches)"); } else if (localData != null) { console.log(" [" + key + "] local:", localData.toString("hex")); } else { console.log(" [" + key + "] local: "); } } // Any keys left here don't match anything. for (var key in localExtraFieldMap) { var localData = localExtraFieldMap[key]; console.log(" [" + key + "]central: "); console.log(" [" + key + "] local:", localData.toString("hex")); } } console.log("central.comment:", entry.fileCommentRaw.toString("hex")); console.log(""); } function extraFieldsToMap(extraFields) { var map = {}; extraFields.forEach(({id, data}) => { var key = "0x" + id.toString(16).padStart(4, "0"); var baseKey = key; var i = 1; while (key in map) { key = baseKey + "." + i; i++; } map[key] = data; }); return map; } yauzl-3.4.0/examples/dump.js000066400000000000000000000013631521126516100160060ustar00rootroot00000000000000 var yauzl = require("../"); // replace with: var yauzl = require("yauzl"); var paths = []; var dumpContents = true; process.argv.slice(2).forEach(function(arg) { if (arg === "--no-contents") { dumpContents = false; } else { paths.push(arg); } }); paths.forEach(function(path) { yauzl.open(path, function(err, zipfile) { if (err) throw err; zipfile.on("error", function(err) { throw err; }); zipfile.on("entry", function(entry) { console.log(entry); console.log(entry.getLastModDate()); if (!dumpContents || /\/$/.exec(entry)) return; zipfile.openReadStream(entry, function(err, readStream) { if (err) throw err; readStream.pipe(process.stdout); }); }); }); }); yauzl-3.4.0/examples/promises.js000066400000000000000000000035351521126516100167050ustar00rootroot00000000000000const yauzl = require("../"); // replace with: const yauzl = require("yauzl"); // Parse CLI args. const paths = []; let dumpContents = true; let shouldReadStream = true; process.argv.slice(2).forEach(function(arg) { if (arg === "--no-contents") { dumpContents = false; } else if (arg === "--no-readStream") { shouldReadStream = false; } else { paths.push(arg); } }); // Read each arg .zip and dump its contents to stdout. (async () => { for (let path of paths) { try { const zipfile = await yauzl.openPromise(path); for await (let entry of zipfile.eachEntry()) { console.log(entry); if (!shouldReadStream || entry.fileName.endsWith("/")) continue; const readStream = await zipfile.openReadStreamPromise(entry); // You should just use readStream.pipe(process.stdout) if you don't care about individual chunks. // This example demonstrates detailed involvement in the piping process. let chunksSeen = 0; for await (let chunk of readStream) { console.log("seeing chunk:", chunksSeen); chunksSeen++; if (chunksSeen === 10) { console.log("interrupting the read stream"); readStream.destroy(); break; } if (dumpContents) { await writeToStream(process.stdout, chunk); } } console.log(`readStream completed in ${chunksSeen} chunks`); } } catch (err) { // yauzl errors get thrown by `await` expressions and end up here. throw err; } } })(); function writeToStream(stream, chunk) { // As of 2023, you have to write this function in your own code. // https://github.com/nodejs/node/issues/49658 return new Promise(resolve => { if (!stream.write(chunk)) { stream.once('drain', resolve); } else { resolve(); } }); } yauzl-3.4.0/examples/unzip.js000066400000000000000000000154631521126516100162140ustar00rootroot00000000000000 var yauzl = require("../"); // replace with: var yauzl = require("yauzl"); var path = require("path"); var fs = require("fs"); var util = require("util"); var Transform = require("stream").Transform; var zipFilePath; var offsetArg; var lenArg; var endArg; var args = process.argv.slice(2); for (var i = 0; i < args.length; i++) { var arg = args[i]; if (arg === "--offset") { i += 1; offsetArg = parseInt(args[i]); if (isNaN(offsetArg)) throw new Error("--offset argument not parsable as an int"); } else if (arg === "--len") { i += 1; lenArg = parseInt(args[i]); if (isNaN(lenArg)) throw new Error("--len argument not parsable as an int"); } else if (arg === "--end") { i += 1; endArg = parseInt(args[i]); if (isNaN(endArg)) throw new Error("--end argument not parsable as an int"); } else if (["-h", "--help"].indexOf(arg) !== -1) { // print help zipFilePath = null; break; } else if (/^--/.test(arg)) { throw new Error("unrecognized option: " + arg); } else { if (zipFilePath != null) throw new Error("too many arguments"); zipFilePath = arg; } } if (zipFilePath == null || /^-/.test(zipFilePath) || (lenArg != null && endArg != null)) { console.log( "usage: node unzip.js [options] path/to/file.zip\n" + "\n" + "unzips the specified zip file into the current directory\n" + "\n" + "options:\n" + " --offset START\n" + " --len LEN\n" + " --end END\n" + " interprets the middle of the specified file as a zipfile.\n" + " starting START number of bytes in from the beginning (default 0).\n" + " end with length of LEN (default is all the way to the end of the file).\n" + " or end at byte offset END (exclusive) (default is the end of the file).\n" + " end can be negative to count backwards from the end of the file\n" + " (example, `--end -1` excludes the last byte of the file).\n" + ""); process.exit(1); } function mkdirp(dir, cb) { if (dir === ".") return cb(); fs.stat(dir, function(err) { if (err == null) return cb(); // already exists var parent = path.dirname(dir); mkdirp(parent, function() { process.stdout.write(dir.replace(/\/$/, "") + "/\n"); fs.mkdir(dir, cb); }); }); } if (offsetArg != null || lenArg != null || endArg != null) { openMiddleOfFile(zipFilePath, {lazyEntries: true}, offsetArg, lenArg, endArg, handleZipFile); } else { yauzl.open(zipFilePath, {lazyEntries: true}, handleZipFile); } function openMiddleOfFile(zipFilePath, options, offsetArg, lenArg, endArg, handleZipFile) { fs.open(zipFilePath, "r", function(err, fd) { if (err != null) throw err; fs.fstat(fd, function(err, stats) { // resolve optional parameters if (offsetArg == null) offsetArg = 0; if (lenArg == null && endArg == null) endArg = stats.size; if (endArg == null) endArg = lenArg + offsetArg; else if (endArg < 0) endArg = stats.size + endArg; // validate parameters if (offsetArg < 0) throw new Error("--offset < 0"); if (lenArg < 0) throw new Error("--len < 0"); if (offsetArg > endArg) throw new Error("--offset > --end"); if (endArg > stats.size) throw new Error("--end/--len goes past EOF"); function adjustOffset(n) { return n + offsetArg; } // extend RandomAccessReader function MiddleOfFileReader() { yauzl.RandomAccessReader.call(this); } util.inherits(MiddleOfFileReader, yauzl.RandomAccessReader); // implement required and option methods MiddleOfFileReader.prototype._readStreamForRange = function(start, end) { return fs.createReadStream(null, { fd: fd, // shift the start and end offsets start: start + offsetArg, end: end + offsetArg - 1, // the -1 is because fs.createReadStream()'s end option is inclusive autoClose: false, }); }; MiddleOfFileReader.prototype.read = function(buffer, offset, length, position, callback) { // shift the position fs.read(fd, buffer, offset, length, position + offsetArg, callback); }; MiddleOfFileReader.prototype.close = function(callback) { fs.close(fd, callback); }; yauzl.fromRandomAccessReader(new MiddleOfFileReader(), endArg - offsetArg, options, handleZipFile); }); }); } function handleZipFile(err, zipfile) { if (err) throw err; // track when we've closed all our file handles var handleCount = 0; function incrementHandleCount() { handleCount++; } function decrementHandleCount() { handleCount--; if (handleCount === 0) { console.log("all input and output handles closed"); } } incrementHandleCount(); zipfile.on("close", function() { console.log("closed input file"); decrementHandleCount(); }); zipfile.readEntry(); zipfile.on("entry", function(entry) { if (/\/$/.test(entry.fileName)) { // directory file names end with '/' mkdirp(entry.fileName, function() { if (err) throw err; zipfile.readEntry(); }); } else { // ensure parent directory exists mkdirp(path.dirname(entry.fileName), function() { zipfile.openReadStream(entry, function(err, readStream) { if (err) throw err; // report progress through large files var byteCount = 0; var totalBytes = entry.uncompressedSize; var lastReportedString = byteCount + "/" + totalBytes + " 0%"; process.stdout.write(entry.fileName + "..." + lastReportedString); function reportString(msg) { var clearString = ""; for (var i = 0; i < lastReportedString.length; i++) { clearString += "\b"; if (i >= msg.length) { clearString += " \b"; } } process.stdout.write(clearString + msg); lastReportedString = msg; } // report progress at 60Hz var progressInterval = setInterval(function() { reportString(byteCount + "/" + totalBytes + " " + ((byteCount / totalBytes * 100) | 0) + "%"); }, 1000 / 60); var filter = new Transform(); filter._transform = function(chunk, encoding, cb) { byteCount += chunk.length; cb(null, chunk); }; filter._flush = function(cb) { clearInterval(progressInterval); reportString(""); // delete the "..." process.stdout.write("\b \b\b \b\b \b\n"); cb(); zipfile.readEntry(); }; // pump file contents var writeStream = fs.createWriteStream(entry.fileName); incrementHandleCount(); writeStream.on("close", decrementHandleCount); readStream.pipe(filter).pipe(writeStream); }); }); } }); } yauzl-3.4.0/fd-slicer.js000066400000000000000000000120471521126516100150740ustar00rootroot00000000000000// This was adapted from https://github.com/andrewrk/node-fd-slicer by Andrew Kelley under the MIT License. var fs = require('fs'); var util = require('util'); var stream = require('stream'); var Readable = stream.Readable; var PassThrough = stream.PassThrough; var Pend = require('pend'); var EventEmitter = require('events').EventEmitter; exports.BufferSlicer = BufferSlicer; exports.FdSlicer = FdSlicer; util.inherits(FdSlicer, EventEmitter); function FdSlicer(fd) { EventEmitter.call(this); this.fd = fd; this.pend = new Pend(); this.pend.max = 1; this.refCount = 0; } FdSlicer.prototype.read = function(buffer, offset, length, position, callback) { var self = this; self.pend.go(function(cb) { fs.read(self.fd, buffer, offset, length, position, function(err, bytesRead, buffer) { cb(); callback(err, bytesRead, buffer); }); }); }; FdSlicer.prototype.createReadStream = function(options) { return new ReadStream(this, options); }; FdSlicer.prototype.ref = function() { this.refCount += 1; }; FdSlicer.prototype.unref = function() { var self = this; self.refCount -= 1; if (self.refCount < 0) throw new Error("invalid unref"); if (self.refCount > 0) return; fs.close(self.fd, onCloseDone); function onCloseDone(err) { if (err) { self.emit('error', err); } else { self.emit('close'); } } }; util.inherits(ReadStream, Readable); function ReadStream(context, options) { options = options || {}; Readable.call(this, options); this.context = context; this.context.ref(); this.start = options.start || 0; this.endOffset = options.end; this.pos = this.start; } ReadStream.prototype._read = function(n) { var self = this; var toRead = Math.min(self._readableState.highWaterMark, n); if (self.endOffset != null) { toRead = Math.min(toRead, self.endOffset - self.pos); } if (toRead <= 0) { self.push(null); this._cleanup(); return; } self.context.pend.go(function(cb) { var buffer = Buffer.allocUnsafe(toRead); fs.read(self.context.fd, buffer, 0, toRead, self.pos, function(err, bytesRead) { if (err) { self.destroy(err); } else if (bytesRead === 0) { self.push(null); self._cleanup(); } else { self.pos += bytesRead; self.push(buffer.slice(0, bytesRead)); } cb(); }); }); }; ReadStream.prototype._destroy = function(err, cb) { // Node 14+ calls this automatically at EOF. this._cleanup(); cb(err); }; ReadStream.prototype._cleanup = function() { if (this.context != null) { this.context.unref(); this.context = null; } }; util.inherits(BufferSlicer, EventEmitter); function BufferSlicer(buffer) { EventEmitter.call(this); this.refCount = 0; this.buffer = buffer; } BufferSlicer.prototype.read = function(buffer, offset, length, position, callback) { if (!(0 <= offset && offset <= buffer.length)) throw new RangeError("offset outside buffer: 0 <= " + offset + " <= " + buffer.length); if (position < 0) throw new RangeError("position is negative: " + position); if (offset + length > buffer.length) { // The caller's buffer can't hold all the bytes they're trying to read. // Clamp the length instead of giving an error. // The callback will be informed of fewer than expected bytes written. length = buffer.length - offset; } if (position + length > this.buffer.length) { // Clamp any attempt to read past the end of the source buffer. length = this.buffer.length - position; } if (length <= 0) { // After any clamping, we're fully out of bounds or otherwise have nothing to do. // This isn't an error; it's just zero bytes written. setImmediate(function() { callback(null, 0); }); return; } this.buffer.copy(buffer, offset, position, position + length); setImmediate(function() { callback(null, length); }); }; BufferSlicer.prototype.createReadStream = function(options) { options = options || {}; var readStream = new PassThrough(options); readStream.start = options.start || 0; readStream.endOffset = options.end; // by the time this function returns, we'll be done. readStream.pos = readStream.endOffset || this.buffer.length; var entireSlice = this.buffer.slice(readStream.start, readStream.pos); // Cut the buffer into smaller slices for better memory usage when streaming into a zlib inflate stream. // See https://github.com/thejoshwolfe/yauzl/issues/87 var maxChunkSize = 0x10000; var offset = 0; while (true) { var nextOffset = offset + maxChunkSize; if (nextOffset >= entireSlice.length) { // last chunk if (offset < entireSlice.length) { readStream.write(entireSlice.slice(offset, entireSlice.length)); } break; } readStream.write(entireSlice.slice(offset, nextOffset)); offset = nextOffset; } readStream.end(); return readStream; }; BufferSlicer.prototype.ref = function() { this.refCount += 1; }; BufferSlicer.prototype.unref = function() { this.refCount -= 1; if (this.refCount < 0) { throw new Error("invalid unref"); } }; yauzl-3.4.0/index.js000066400000000000000000001247071521126516100143420ustar00rootroot00000000000000var fs = require("fs"); var zlib = require("zlib"); var fd_slicer = require("./fd-slicer"); var util = require("util"); var EventEmitter = require("events").EventEmitter; var Transform = require("stream").Transform; var PassThrough = require("stream").PassThrough; var Writable = require("stream").Writable; // Node 20 added zlib.crc32. const crc32 = typeof zlib.crc32 === "function" ? zlib.crc32 : require("./crc32"); exports.open = open; exports.fromFd = fromFd; exports.fromBuffer = fromBuffer; exports.fromRandomAccessReader = fromRandomAccessReader; exports.openPromise = openPromise; exports.fromFdPromise = fromFdPromise; exports.fromBufferPromise = fromBufferPromise; exports.fromRandomAccessReaderPromise = fromRandomAccessReaderPromise; exports.dosDateTimeToDate = dosDateTimeToDate; exports.getFileNameLowLevel = getFileNameLowLevel; exports.validateFileName = validateFileName; exports.parseExtraFields = parseExtraFields; exports.ZipFile = ZipFile; exports.Entry = Entry; exports.LocalFileHeader = LocalFileHeader; exports.RandomAccessReader = RandomAccessReader; function openPromise(path, options) { return new Promise((resolve, reject) => { open(path, {...options, lazyEntries: true}, function(err, zipfile) { if (err) return reject(err); resolve(zipfile); }); }); } function fromFdPromise(fd, options) { return new Promise((resolve, reject) => { fromFd(fd, {...options, lazyEntries: true}, function(err, zipfile) { if (err) return reject(err); resolve(zipfile); }); }); } function fromBufferPromise(buffer, options) { return new Promise((resolve, reject) => { fromBuffer(buffer, {...options, lazyEntries: true}, function(err, zipfile) { if (err) return reject(err); resolve(zipfile); }); }); } function fromRandomAccessReaderPromise(reader, totalSize, options) { return new Promise((resolve, reject) => { fromRandomAccessReader(reader, totalSize, {...options, lazyEntries: true}, function(err, zipfile) { if (err) return reject(err); resolve(zipfile); }); }); } function open(path, options, callback) { if (typeof options === "function") { callback = options; options = null; } if (options == null) options = {}; if (options.autoClose == null) options.autoClose = true; if (options.lazyEntries == null) options.lazyEntries = false; if (options.decodeStrings == null) options.decodeStrings = true; if (options.validateEntrySizes == null) options.validateEntrySizes = true; if (options.strictFileNames == null) options.strictFileNames = false; if (callback == null) callback = defaultCallback; fs.open(path, "r", function(err, fd) { if (err) return callback(err); fromFd(fd, options, function(err, zipfile) { if (err) fs.close(fd, defaultCallback); callback(err, zipfile); }); }); } function fromFd(fd, options, callback) { if (typeof options === "function") { callback = options; options = null; } if (options == null) options = {}; if (options.autoClose == null) options.autoClose = false; if (options.lazyEntries == null) options.lazyEntries = false; if (options.decodeStrings == null) options.decodeStrings = true; if (options.validateEntrySizes == null) options.validateEntrySizes = true; if (options.strictFileNames == null) options.strictFileNames = false; if (callback == null) callback = defaultCallback; fs.fstat(fd, function(err, stats) { if (err) return callback(err); var reader = new fd_slicer.FdSlicer(fd); fromRandomAccessReader(reader, stats.size, options, callback); }); } function fromBuffer(buffer, options, callback) { if (typeof options === "function") { callback = options; options = null; } if (options == null) options = {}; options.autoClose = false; if (options.lazyEntries == null) options.lazyEntries = false; if (options.decodeStrings == null) options.decodeStrings = true; if (options.validateEntrySizes == null) options.validateEntrySizes = true; if (options.strictFileNames == null) options.strictFileNames = false; var reader = new fd_slicer.BufferSlicer(buffer); fromRandomAccessReader(reader, buffer.length, options, callback); } function fromRandomAccessReader(reader, totalSize, options, callback) { if (typeof options === "function") { callback = options; options = null; } if (options == null) options = {}; if (options.autoClose == null) options.autoClose = true; if (options.lazyEntries == null) options.lazyEntries = false; if (options.decodeStrings == null) options.decodeStrings = true; var decodeStrings = !!options.decodeStrings; if (options.validateEntrySizes == null) options.validateEntrySizes = true; if (options.strictFileNames == null) options.strictFileNames = false; if (callback == null) callback = defaultCallback; if (typeof totalSize !== "number") throw new Error("expected totalSize parameter to be a number"); if (totalSize > Number.MAX_SAFE_INTEGER) { throw new Error("zip file too large. only file sizes up to 2^52 are supported due to JavaScript's Number type being an IEEE 754 double."); } // the matching unref() call is in zipfile.close() reader.ref(); // eocdr means End of Central Directory Record. // search backwards for the eocdr signature. // the last field of the eocdr is a variable-length comment. // the comment size is encoded in a 2-byte field in the eocdr, which we can't find without trudging backwards through the comment to find it. // as a consequence of this design decision, it's possible to have ambiguous zip file metadata if a coherent eocdr was in the comment. // we search backwards for a eocdr signature, and hope that whoever made the zip file was smart enough to forbid the eocdr signature in the comment. var eocdrWithoutCommentSize = 22; var zip64EocdlSize = 20; // Zip64 end of central directory locator var maxCommentSize = 0xffff; // 2-byte size var bufferSize = Math.min(zip64EocdlSize + eocdrWithoutCommentSize + maxCommentSize, totalSize); var buffer = newBuffer(bufferSize); var bufferReadStart = totalSize - buffer.length; readAndAssertNoEof(reader, buffer, 0, bufferSize, bufferReadStart, function(err) { if (err) return callback(err); for (var i = bufferSize - eocdrWithoutCommentSize; i >= 0; i -= 1) { if (buffer.readUInt32LE(i) !== 0x06054b50) continue; // found eocdr var eocdrBuffer = buffer.subarray(i); // 0 - End of central directory signature = 0x06054b50 // 4 - Number of this disk var diskNumber = eocdrBuffer.readUInt16LE(4); // 6 - Disk where central directory starts // 8 - Number of central directory records on this disk // 10 - Total number of central directory records var entryCount = eocdrBuffer.readUInt16LE(10); // 12 - Size of central directory (bytes) // 16 - Offset of start of central directory, relative to start of archive var centralDirectoryOffset = eocdrBuffer.readUInt32LE(16); // 20 - Comment length var commentLength = eocdrBuffer.readUInt16LE(20); var expectedCommentLength = eocdrBuffer.length - eocdrWithoutCommentSize; if (commentLength !== expectedCommentLength) { return callback(new Error("Invalid comment length. Expected: " + expectedCommentLength + ". Found: " + commentLength + ". Are there extra bytes at the end of the file? Or is the end of central dir signature `PK☺☻` in the comment?")); } // 22 - Comment // the encoding is always cp437. var comment = decodeStrings ? decodeBuffer(eocdrBuffer.subarray(22), false) : eocdrBuffer.subarray(22); // Look for a Zip64 end of central directory locator if (i - zip64EocdlSize >= 0 && buffer.readUInt32LE(i - zip64EocdlSize) === 0x07064b50) { // ZIP64 format var zip64EocdlBuffer = buffer.subarray(i - zip64EocdlSize, i - zip64EocdlSize + zip64EocdlSize); // 0 - zip64 end of central dir locator signature = 0x07064b50 // 4 - number of the disk with the start of the zip64 end of central directory // 8 - relative offset of the zip64 end of central directory record var zip64EocdrOffset = readUInt64LE(zip64EocdlBuffer, 8); // 16 - total number of disks // ZIP64 end of central directory record var zip64EocdrBuffer = newBuffer(56); return readAndAssertNoEof(reader, zip64EocdrBuffer, 0, zip64EocdrBuffer.length, zip64EocdrOffset, function(err) { if (err) return callback(err); // 0 - zip64 end of central dir signature 4 bytes (0x06064b50) if (zip64EocdrBuffer.readUInt32LE(0) !== 0x06064b50) { return callback(new Error("invalid zip64 end of central directory record signature")); } // 4 - size of zip64 end of central directory record 8 bytes // 12 - version made by 2 bytes // 14 - version needed to extract 2 bytes // 16 - number of this disk 4 bytes diskNumber = zip64EocdrBuffer.readUInt32LE(16); if (diskNumber !== 0) { // Check this only after zip64 overrides. See #118. return callback(new Error("multi-disk zip files are not supported: found disk number: " + diskNumber)); } // 20 - number of the disk with the start of the central directory 4 bytes // 24 - total number of entries in the central directory on this disk 8 bytes // 32 - total number of entries in the central directory 8 bytes entryCount = readUInt64LE(zip64EocdrBuffer, 32); // 40 - size of the central directory 8 bytes // 48 - offset of start of central directory with respect to the starting disk number 8 bytes centralDirectoryOffset = readUInt64LE(zip64EocdrBuffer, 48); // 56 - zip64 extensible data sector (variable size) return callback(null, new ZipFile(reader, centralDirectoryOffset, totalSize, entryCount, comment, options.autoClose, options.lazyEntries, decodeStrings, options.validateEntrySizes, options.strictFileNames)); }); } // Not ZIP64 format if (diskNumber !== 0) { return callback(new Error("multi-disk zip files are not supported: found disk number: " + diskNumber)); } return callback(null, new ZipFile(reader, centralDirectoryOffset, totalSize, entryCount, comment, options.autoClose, options.lazyEntries, decodeStrings, options.validateEntrySizes, options.strictFileNames)); } // Not a zip file. callback(new Error("End of central directory record signature not found. Either not a zip file, or file is truncated.")); }); } util.inherits(ZipFile, EventEmitter); function ZipFile(reader, centralDirectoryOffset, fileSize, entryCount, comment, autoClose, lazyEntries, decodeStrings, validateEntrySizes, strictFileNames) { var self = this; EventEmitter.call(self); self.reader = reader; // forward close events self.reader.on("error", function(err) { // error closing the fd emitError(self, err); }); self.reader.once("close", function() { self.emit("close"); }); self.readEntryCursor = centralDirectoryOffset; self.fileSize = fileSize; self.entryCount = entryCount; self.comment = comment; self.entriesRead = 0; self.autoClose = !!autoClose; self.lazyEntries = !!lazyEntries; self.decodeStrings = !!decodeStrings; self.validateEntrySizes = !!validateEntrySizes; self.strictFileNames = !!strictFileNames; self.isOpen = true; self.emittedError = false; self.hasEachEntryBeenCalled = false; if (!self.lazyEntries) self._readEntry(); } ZipFile.prototype.close = function() { if (!this.isOpen) return; this.isOpen = false; this.reader.unref(); }; function emitErrorAndAutoClose(self, err) { if (self.autoClose) self.close(); emitError(self, err); } function emitError(self, err) { if (self.emittedError) return; self.emittedError = true; self.emit("error", err); } ZipFile.prototype.readEntry = function() { if (!this.lazyEntries) throw new Error("readEntry() called without lazyEntries:true"); this._readEntry(); }; ZipFile.prototype._readEntry = function() { var self = this; if (self.entryCount === self.entriesRead) { // done with metadata setImmediate(function() { if (self.autoClose) self.close(); if (self.emittedError) return; self.emit("end"); }); return; } if (self.emittedError) return; var buffer = newBuffer(46); readAndAssertNoEof(self.reader, buffer, 0, buffer.length, self.readEntryCursor, function(err) { if (err) return emitErrorAndAutoClose(self, err); if (self.emittedError) return; var entry = new Entry(); // 0 - Central directory file header signature var signature = buffer.readUInt32LE(0); if (signature !== 0x02014b50) return emitErrorAndAutoClose(self, new Error("invalid central directory file header signature: 0x" + signature.toString(16))); // 4 - Version made by entry.versionMadeBy = buffer.readUInt16LE(4); // 6 - Version needed to extract (minimum) entry.versionNeededToExtract = buffer.readUInt16LE(6); // 8 - General purpose bit flag entry.generalPurposeBitFlag = buffer.readUInt16LE(8); // 10 - Compression method entry.compressionMethod = buffer.readUInt16LE(10); // 12 - File last modification time entry.lastModFileTime = buffer.readUInt16LE(12); // 14 - File last modification date entry.lastModFileDate = buffer.readUInt16LE(14); // 16 - CRC-32 entry.crc32 = buffer.readUInt32LE(16); // 20 - Compressed size entry.compressedSize = buffer.readUInt32LE(20); // 24 - Uncompressed size entry.uncompressedSize = buffer.readUInt32LE(24); // 28 - File name length (n) entry.fileNameLength = buffer.readUInt16LE(28); // 30 - Extra field length (m) entry.extraFieldLength = buffer.readUInt16LE(30); // 32 - File comment length (k) entry.fileCommentLength = buffer.readUInt16LE(32); // 34 - Disk number where file starts // 36 - Internal file attributes entry.internalFileAttributes = buffer.readUInt16LE(36); // 38 - External file attributes entry.externalFileAttributes = buffer.readUInt32LE(38); // 42 - Relative offset of local file header entry.relativeOffsetOfLocalHeader = buffer.readUInt32LE(42); if (entry.generalPurposeBitFlag & 0x40) return emitErrorAndAutoClose(self, new Error("strong encryption is not supported")); self.readEntryCursor += 46; buffer = newBuffer(entry.fileNameLength + entry.extraFieldLength + entry.fileCommentLength); readAndAssertNoEof(self.reader, buffer, 0, buffer.length, self.readEntryCursor, function(err) { if (err) return emitErrorAndAutoClose(self, err); if (self.emittedError) return; // 46 - File name entry.fileNameRaw = buffer.subarray(0, entry.fileNameLength); // 46+n - Extra field var fileCommentStart = entry.fileNameLength + entry.extraFieldLength; entry.extraFieldRaw = buffer.subarray(entry.fileNameLength, fileCommentStart); // 46+n+m - File comment entry.fileCommentRaw = buffer.subarray(fileCommentStart, fileCommentStart + entry.fileCommentLength); // Parse the extra fields, which we need for processing other fields. try { entry.extraFields = parseExtraFields(entry.extraFieldRaw); } catch (err) { return emitErrorAndAutoClose(self, err); } // Interpret strings according to bit flags, extra fields, and options. if (self.decodeStrings) { var isUtf8 = (entry.generalPurposeBitFlag & 0x800) !== 0; entry.fileComment = decodeBuffer(entry.fileCommentRaw, isUtf8); entry.fileName = getFileNameLowLevel(entry.generalPurposeBitFlag, entry.fileNameRaw, entry.extraFields, self.strictFileNames); var errorMessage = validateFileName(entry.fileName); if (errorMessage != null) return emitErrorAndAutoClose(self, new Error(errorMessage)); } else { entry.fileComment = entry.fileCommentRaw; entry.fileName = entry.fileNameRaw; } // Maintain API compatibility. See https://github.com/thejoshwolfe/yauzl/issues/47 entry.comment = entry.fileComment; self.readEntryCursor += buffer.length; self.entriesRead += 1; // Check for the Zip64 Extended Information Extra Field. for (var i = 0; i < entry.extraFields.length; i++) { var extraField = entry.extraFields[i]; if (extraField.id !== 0x0001) continue; // Found it. var zip64EiefBuffer = extraField.data; var index = 0; // 0 - Original Size 8 bytes if (entry.uncompressedSize === 0xffffffff) { if (index + 8 > zip64EiefBuffer.length) { return emitErrorAndAutoClose(self, new Error("zip64 extended information extra field does not include uncompressed size")); } entry.uncompressedSize = readUInt64LE(zip64EiefBuffer, index); index += 8; } // 8 - Compressed Size 8 bytes if (entry.compressedSize === 0xffffffff) { if (index + 8 > zip64EiefBuffer.length) { return emitErrorAndAutoClose(self, new Error("zip64 extended information extra field does not include compressed size")); } entry.compressedSize = readUInt64LE(zip64EiefBuffer, index); index += 8; } // 16 - Relative Header Offset 8 bytes if (entry.relativeOffsetOfLocalHeader === 0xffffffff) { if (index + 8 > zip64EiefBuffer.length) { return emitErrorAndAutoClose(self, new Error("zip64 extended information extra field does not include relative header offset")); } entry.relativeOffsetOfLocalHeader = readUInt64LE(zip64EiefBuffer, index); index += 8; } // 24 - Disk Start Number 4 bytes break; } // validate file size if (self.validateEntrySizes && entry.compressionMethod === 0) { var expectedCompressedSize = entry.uncompressedSize; if (entry.isEncrypted()) { // traditional encryption prefixes the file data with a header expectedCompressedSize += 12; } if (entry.compressedSize !== expectedCompressedSize) { var msg = "compressed/uncompressed size mismatch for stored file: " + entry.compressedSize + " != " + entry.uncompressedSize; return emitErrorAndAutoClose(self, new Error(msg)); } } self.emit("entry", entry); if (!self.lazyEntries) self._readEntry(); }); }); }; ZipFile.prototype.eachEntry = function() { const self = this; if (!self.lazyEntries) throw new Error("eachEntry() requires lazyEntries: true"); if (self.hasEachEntryBeenCalled) throw new Error("eachEntry() must only be called once per ZipFile"); self.hasEachEntryBeenCalled = true; let pendingResolveReject = null; self.on("entry", onEntry); self.on("end", onEnd); self.on("error", onError); function cleanup() { self.removeListener("entry", onEntry); self.removeListener("end", onEnd); self.removeListener("error", onError); if (self.autoClose) self.close(); } function onEntry(entry) { let {resolve} = pendingResolveReject; pendingResolveReject = null; resolve({value: entry}); } function onEnd() { let {resolve} = pendingResolveReject; pendingResolveReject = null; cleanup(); resolve({done: true}); } function onError(err) { let {reject} = pendingResolveReject; pendingResolveReject = null; cleanup(); reject(err); } return { [Symbol.asyncIterator]() { // Called once by `for await...of`. return this; }, next() { // Called on each iteration in a `for await...of`. const promise = new Promise((resolve, reject) => { if (pendingResolveReject != null) throw new Error("next() called before previous Promise was resolved."); pendingResolveReject = {resolve, reject}; }); self.readEntry(); return promise; }, return(value) { // Called when breaking, returning, throwing out of a `for await...of`. cleanup(); return Promise.resolve({done: true, value}); }, throw(value) { // Almost never called. Something about `yield*` maybe? cleanup(); return Promise.reject(value); }, }; }; ZipFile.prototype.openReadStream = function(entry, options, callback) { var self = this; // parameter validation var relativeStart = 0; var relativeEnd = entry.compressedSize; if (callback == null) { callback = options; options = null; } if (options == null) { options = {}; } else { if (options.decodeFileData === false) { // new, simple option if (options.decrypt != null) { throw new Error("cannot use options.decrypt when options.decodeFileData === false"); } if (options.decompress != null) { throw new Error("cannot use options.decompress when options.decodeFileData === false"); } // start and end are allowed } else { // old, complicated options if (options.decrypt != null) { if (!entry.isEncrypted()) { throw new Error("options.decrypt can only be specified for encrypted entries. See also option decodeFileData."); } if (options.decrypt !== false) throw new Error("invalid options.decrypt value: " + options.decrypt); if (entry.isCompressed()) { if (options.decompress !== false) throw new Error("entry is encrypted and compressed, and options.decompress !== false. See also option decodeFileData."); } } if (options.decompress != null) { if (!entry.isCompressed()) { throw new Error("options.decompress can only be specified for compressed entries. See also option decodeFileData."); } if (!(options.decompress === false || options.decompress === true)) { throw new Error("invalid options.decompress value: " + options.decompress); } decompress = options.decompress; } } if (options.start != null) { relativeStart = options.start; if (relativeStart < 0) throw new Error("options.start < 0"); if (relativeStart > entry.compressedSize) throw new Error("options.start > entry.compressedSize"); } if (options.end != null) { relativeEnd = options.end; if (relativeEnd < 0) throw new Error("options.end < 0"); if (relativeEnd > entry.compressedSize) throw new Error("options.end > entry.compressedSize"); if (relativeEnd < relativeStart) throw new Error("options.end < options.start"); } } var rawMode = ( options.decodeFileData === false || // Explicitly requested raw. ( (entry.compressionMethod === 0 || // Naturally without compression. (entry.compressionMethod === 8 && options.decompress === false) // Deprecated compression bypass option. ) && (!entry.isEncrypted() || // Naturally without encryption. options.decrypt === false // Deprecated encryption bypass option. ) ) ); if (options.start != null || options.end != null) { // Ensure slicing deals with raw data. if (!rawMode) throw new Error("start/end range require options.decodeFileData === false for non-trivial encoded entries."); } // any further errors can either be caused by the zipfile, // or were introduced in a minor version of yauzl, // so should be passed to the client rather than thrown. if (!self.isOpen) return callback(new Error("closed")); if (entry.isEncrypted() && !rawMode) { if (options.decrypt !== false) return callback(new Error("entry is encrypted, and options.decodeFileData !== false")); } var decompress; if (rawMode) { decompress = false; } else if (entry.compressionMethod === 8) { // 8 - The file is Deflated decompress = options.decodeFileData !== true; } else { return callback(new Error("unsupported compression method: " + entry.compressionMethod)); } self.readLocalFileHeader(entry, {minimal: true}, function(err, localFileHeader) { if (err) return callback(err); self.openReadStreamLowLevel( localFileHeader.fileDataStart, entry.compressedSize, relativeStart, relativeEnd, decompress, entry.uncompressedSize, callback); }); }; ZipFile.prototype.openReadStreamLowLevel = function(fileDataStart, compressedSize, relativeStart, relativeEnd, decompress, uncompressedSize, callback) { var self = this; var fileDataEnd = fileDataStart + compressedSize; var readStream = self.reader.createReadStream({ start: fileDataStart + relativeStart, end: fileDataStart + relativeEnd, }); var endpointStream = readStream; if (decompress) { var destroyed = false; var inflateFilter = zlib.createInflateRaw(); readStream.on("error", function(err) { // setImmediate here because errors can be emitted during the first call to pipe() setImmediate(function() { if (!destroyed) inflateFilter.emit("error", err); }); }); readStream.pipe(inflateFilter); if (self.validateEntrySizes) { endpointStream = new AssertByteCountStream(uncompressedSize); inflateFilter.on("error", function(err) { // forward zlib errors to the client-visible stream setImmediate(function() { if (!destroyed) endpointStream.emit("error", err); }); }); inflateFilter.pipe(endpointStream); } else { // the zlib filter is the client-visible stream endpointStream = inflateFilter; } // this is part of yauzl's API, so implement this function on the client-visible stream installDestroyFn(endpointStream, function() { destroyed = true; if (inflateFilter !== endpointStream) inflateFilter.unpipe(endpointStream); readStream.unpipe(inflateFilter); // TODO: the inflateFilter may cause a memory leak. see Issue #27. readStream.destroy(); }); } callback(null, endpointStream); }; ZipFile.prototype.readLocalFileHeader = function(entry, options, callback) { var self = this; if (callback == null) { callback = options; options = null; } if (options == null) options = {}; self.reader.ref(); var buffer = newBuffer(30); readAndAssertNoEof(self.reader, buffer, 0, buffer.length, entry.relativeOffsetOfLocalHeader, function(err) { try { if (err) return callback(err); // 0 - Local file header signature = 0x04034b50 var signature = buffer.readUInt32LE(0); if (signature !== 0x04034b50) { return callback(new Error("invalid local file header signature: 0x" + signature.toString(16))); } var fileNameLength = buffer.readUInt16LE(26); var extraFieldLength = buffer.readUInt16LE(28); var fileDataStart = entry.relativeOffsetOfLocalHeader + 30 + fileNameLength + extraFieldLength; // We now have enough information to do this bounds check. if (fileDataStart + entry.compressedSize > self.fileSize) { return callback(new Error("file data overflows file bounds: " + fileDataStart + " + " + entry.compressedSize + " > " + self.fileSize)); } if (options.minimal) { return callback(null, {fileDataStart: fileDataStart}); } var localFileHeader = new LocalFileHeader(); localFileHeader.fileDataStart = fileDataStart; // 4 - Version needed to extract (minimum) localFileHeader.versionNeededToExtract = buffer.readUInt16LE(4); // 6 - General purpose bit flag localFileHeader.generalPurposeBitFlag = buffer.readUInt16LE(6); // 8 - Compression method localFileHeader.compressionMethod = buffer.readUInt16LE(8); // 10 - File last modification time localFileHeader.lastModFileTime = buffer.readUInt16LE(10); // 12 - File last modification date localFileHeader.lastModFileDate = buffer.readUInt16LE(12); // 14 - CRC-32 localFileHeader.crc32 = buffer.readUInt32LE(14); // 18 - Compressed size localFileHeader.compressedSize = buffer.readUInt32LE(18); // 22 - Uncompressed size localFileHeader.uncompressedSize = buffer.readUInt32LE(22); // 26 - File name length (n) localFileHeader.fileNameLength = fileNameLength; // 28 - Extra field length (m) localFileHeader.extraFieldLength = extraFieldLength; // 30 - File name // 30+n - Extra field buffer = newBuffer(fileNameLength + extraFieldLength); self.reader.ref(); readAndAssertNoEof(self.reader, buffer, 0, buffer.length, entry.relativeOffsetOfLocalHeader + 30, function(err) { try { if (err) return callback(err); localFileHeader.fileName = buffer.subarray(0, fileNameLength); localFileHeader.extraField = buffer.subarray(fileNameLength); return callback(null, localFileHeader); } finally { self.reader.unref(); } }); } finally { self.reader.unref(); } }); }; ZipFile.prototype.openReadStreamPromise = function(entry, options) { return new Promise((resolve, reject) => { this.openReadStream(entry, options, function(err, readStream) { if (err) return reject(err); resolve(readStream); }); }); }; ZipFile.prototype.openReadStreamLowLevelPromise = function(fileDataStart, compressedSize, relativeStart, relativeEnd, decompress, uncompressedSize) { return new Promise((resolve, reject) => { this.openReadStream(fileDataStart, compressedSize, relativeStart, relativeEnd, decompress, uncompressedSize, function(err, readStream) { if (err) return reject(err); resolve(readStream); }); }); }; ZipFile.prototype.readLocalFileHeaderPromise = function(entry, options) { return new Promise((resolve, reject) => { this.readLocalFileHeader(entry, options, function(err, localFileHeader) { if (err) return reject(err); resolve(localFileHeader); }); }); }; function Entry() { } Entry.prototype.getLastModDate = function(options) { if (options == null) options = {}; if (!options.forceDosFormat) { // Check extended fields. for (var i = 0; i < this.extraFields.length; i++) { var extraField = this.extraFields[i]; if (extraField.id === 0x5455) { // Info-ZIP "universal timestamp" extended field (`0x5455` aka `"UT"`). // See the Info-ZIP source code unix/unix.c:set_extra_field() and zipfile.c:ef_scan_ut_time(). var data = extraField.data; if (data.length < 5) continue; // Too short. // The flags define which of the three fields are present: mtime, atime, ctime. // We only care about mtime. // Also, ctime is never included in practice. // And also, atime is only included in the local file header for some reason // despite the flags lying about its inclusion in the central header. var flags = data[0]; var HAS_MTIME = 1; if (!(flags & HAS_MTIME)) continue; // This will realistically never happen. // Although the positions of all of the fields shift around depending on the presence of other fields, // mtime is always first if present, and that's the only one we care about. var posixTimestamp = data.readInt32LE(1); return new Date(posixTimestamp * 1000); } else if (extraField.id === 0x000a) { var data = extraField.data; if (data.length !== 32) continue; // The length is always the same. // 4 bytes reserved // 2 bytes Tag if (data.readUInt16LE(4) !== 1) continue; // Tag1 is actually the only defined Tag. // 2 bytes Size if (data.readUInt16LE(6) !== 24) continue; // Size is always 24. // 8 bytes Mtime var hundredNanoSecondsSince1601 = data.readUInt32LE(8) + 4294967296 * data.readInt32LE(12); // Convert from NTFS to POSIX milliseconds. // The big number below is the milliseconds between year 1601 and year 1970 // (i.e. the negative POSIX timestamp of 1601-01-01 00:00:00Z) var millisecondsSince1970 = hundredNanoSecondsSince1601 / 10000 - 11644473600000; // Note on numeric precision: JavaScript Number objects lose precision above Number.MAX_SAFE_INTEGER, // and NTFS timestamps are typically much bigger than that limit. // (MAX_SAFE_INTEGER would represent 1629-07-17T23:58:45.475Z.) // However, we're losing precision in the conversion from 100nanosecond units to millisecond units anyway, // and the time at which we also lose 1-millisecond precision is year 275760, the JavaScript Date limit (by design). // Up through the year 2057, this conversion only drops 4 bits of precision, // which is well under the 13-14 bits ratio between the milliseconds and 100nanoseconds. return new Date(millisecondsSince1970); } } } // Fallback to non-extended encoding. return dosDateTimeToDate(this.lastModFileDate, this.lastModFileTime, options.timezone); }; Entry.prototype.canDecodeFileData = function() { return ( !this.isEncrypted() && (this.compressionMethod === 0 || this.compressionMethod === 8) ); }; Entry.prototype.isEncrypted = function() { return (this.generalPurposeBitFlag & 0x1) !== 0; }; Entry.prototype.isCompressed = function() { return this.compressionMethod === 8; }; function LocalFileHeader() { } function dosDateTimeToDate(date, time, timezone) { var day = date & 0x1f; // 1-31 var month = (date >> 5 & 0xf) - 1; // 1-12, 0-11 var year = (date >> 9 & 0x7f) + 1980; // 0-128, 1980-2108 var millisecond = 0; var second = (time & 0x1f) * 2; // 0-29, 0-58 (even numbers) var minute = time >> 5 & 0x3f; // 0-59 var hour = time >> 11 & 0x1f; // 0-23 if (timezone == null || timezone === "local") { return new Date(year, month, day, hour, minute, second, millisecond); } else if (timezone === "UTC") { return new Date(Date.UTC(year, month, day, hour, minute, second, millisecond)); } else { throw new Error("unrecognized options.timezone: " + options.timezone); } } function getFileNameLowLevel(generalPurposeBitFlag, fileNameBuffer, extraFields, strictFileNames) { var fileName = null; // check for Info-ZIP Unicode Path Extra Field (0x7075) // see https://github.com/thejoshwolfe/yauzl/issues/33 for (var i = 0; i < extraFields.length; i++) { var extraField = extraFields[i]; if (extraField.id === 0x7075) { if (extraField.data.length < 6) { // too short to be meaningful continue; } // Version 1 byte version of this extra field, currently 1 if (extraField.data.readUInt8(0) !== 1) { // > Changes may not be backward compatible so this extra // > field should not be used if the version is not recognized. continue; } // NameCRC32 4 bytes File Name Field CRC32 Checksum var oldNameCrc32 = extraField.data.readUInt32LE(1); if (crc32(fileNameBuffer) !== oldNameCrc32) { // > If the CRC check fails, this UTF-8 Path Extra Field should be // > ignored and the File Name field in the header should be used instead. continue; } // UnicodeName Variable UTF-8 version of the entry File Name fileName = decodeBuffer(extraField.data.subarray(5), true); break; } } if (fileName == null) { // The typical case. var isUtf8 = (generalPurposeBitFlag & 0x800) !== 0; fileName = decodeBuffer(fileNameBuffer, isUtf8); } if (!strictFileNames) { // Allow backslash. fileName = fileName.replace(/\\/g, "/"); } return fileName; } function validateFileName(fileName) { if (fileName.indexOf("\\") !== -1) { return "invalid characters in fileName: " + fileName; } if (/^[a-zA-Z]:/.test(fileName) || /^\//.test(fileName)) { return "absolute path: " + fileName; } if (fileName.split("/").indexOf("..") !== -1) { return "invalid relative path: " + fileName; } // all good return null; } function parseExtraFields(extraFieldBuffer) { var extraFields = []; var i = 0; while (i < extraFieldBuffer.length - 3) { var headerId = extraFieldBuffer.readUInt16LE(i + 0); var dataSize = extraFieldBuffer.readUInt16LE(i + 2); var dataStart = i + 4; var dataEnd = dataStart + dataSize; if (dataEnd > extraFieldBuffer.length) throw new Error("extra field length exceeds extra field buffer size"); var dataBuffer = extraFieldBuffer.subarray(dataStart, dataEnd); extraFields.push({ id: headerId, data: dataBuffer, }); i = dataEnd; } return extraFields; } function readAndAssertNoEof(reader, buffer, offset, length, position, callback) { if (length === 0) { // fs.read will throw an out-of-bounds error if you try to read 0 bytes from a 0 byte file return setImmediate(function() { callback(null, newBuffer(0)); }); } reader.read(buffer, offset, length, position, function(err, bytesRead) { if (err) return callback(err); if (bytesRead < length) { return callback(new Error("unexpected EOF")); } callback(); }); } util.inherits(AssertByteCountStream, Transform); function AssertByteCountStream(byteCount) { Transform.call(this); this.actualByteCount = 0; this.expectedByteCount = byteCount; } AssertByteCountStream.prototype._transform = function(chunk, encoding, cb) { this.actualByteCount += chunk.length; if (this.actualByteCount > this.expectedByteCount) { var msg = "too many bytes in the stream. expected " + this.expectedByteCount + ". got at least " + this.actualByteCount; return cb(new Error(msg)); } cb(null, chunk); }; AssertByteCountStream.prototype._flush = function(cb) { if (this.actualByteCount < this.expectedByteCount) { var msg = "not enough bytes in the stream. expected " + this.expectedByteCount + ". got only " + this.actualByteCount; return cb(new Error(msg)); } cb(); }; util.inherits(RandomAccessReader, EventEmitter); function RandomAccessReader() { EventEmitter.call(this); this.refCount = 0; } RandomAccessReader.prototype.ref = function() { this.refCount += 1; }; RandomAccessReader.prototype.unref = function() { var self = this; self.refCount -= 1; if (self.refCount > 0) return; if (self.refCount < 0) throw new Error("invalid unref"); self.close(onCloseDone); function onCloseDone(err) { if (err) return self.emit('error', err); self.emit('close'); } }; RandomAccessReader.prototype.createReadStream = function(options) { if (options == null) options = {}; var start = options.start; var end = options.end; if (start === end) { var emptyStream = new PassThrough(); setImmediate(function() { emptyStream.end(); }); return emptyStream; } var stream = this._readStreamForRange(start, end); var destroyed = false; var refUnrefFilter = new RefUnrefFilter(this); stream.on("error", function(err) { setImmediate(function() { if (!destroyed) refUnrefFilter.emit("error", err); }); }); installDestroyFn(refUnrefFilter, function() { stream.unpipe(refUnrefFilter); refUnrefFilter.unref(); stream.destroy(); }); var byteCounter = new AssertByteCountStream(end - start); refUnrefFilter.on("error", function(err) { setImmediate(function() { if (!destroyed) byteCounter.emit("error", err); }); }); installDestroyFn(byteCounter, function() { destroyed = true; refUnrefFilter.unpipe(byteCounter); refUnrefFilter.destroy(); }); return stream.pipe(refUnrefFilter).pipe(byteCounter); }; RandomAccessReader.prototype._readStreamForRange = function(start, end) { throw new Error("not implemented"); }; RandomAccessReader.prototype.read = function(buffer, offset, length, position, callback) { var readStream = this.createReadStream({start: position, end: position + length}); var writeStream = new Writable(); var written = 0; writeStream._write = function(chunk, encoding, cb) { chunk.copy(buffer, offset + written, 0, chunk.length); written += chunk.length; cb(); }; writeStream.on("finish", callback); readStream.on("error", function(error) { callback(error); }); readStream.pipe(writeStream); }; RandomAccessReader.prototype.close = function(callback) { setImmediate(callback); }; util.inherits(RefUnrefFilter, PassThrough); function RefUnrefFilter(context) { PassThrough.call(this); this.context = context; this.context.ref(); this.unreffedYet = false; } RefUnrefFilter.prototype._flush = function(cb) { this.unref(); cb(); }; RefUnrefFilter.prototype.unref = function(cb) { if (this.unreffedYet) return; this.unreffedYet = true; this.context.unref(); }; var cp437 = '\u0000☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→â†�∟↔▲▼ !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿âŒ�¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗â•�╜╛â”�└┴┬├─┼╞╟╚╔╩╦╠â•�╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌â–�▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√â�¿Â²â– Â '; function decodeBuffer(buffer, isUtf8) { if (isUtf8) { return buffer.toString("utf8"); } else { var result = ""; for (var i = 0; i < buffer.length; i++) { result += cp437[buffer[i]]; } return result; } } function readUInt64LE(buffer, offset) { // There is no native function for this, because we can't actually store 64-bit integers precisely. // after 53 bits, JavaScript's Number type (IEEE 754 double) can't store individual integers anymore. // but since 53 bits is a whole lot more than 32 bits, we do our best anyway. // As of 2020, Node has added support for BigInt, which obviates this whole function, // but yauzl hasn't been updated to depend on BigInt (yet?). var lower32 = buffer.readUInt32LE(offset); var upper32 = buffer.readUInt32LE(offset + 4); // we can't use bitshifting here, because JavaScript bitshifting only works on 32-bit integers. return upper32 * 0x100000000 + lower32; // as long as we're bounds checking the result of this function against the total file size, // we'll catch any overflow errors, because we already made sure the total file size was within reason. } // Node 10 deprecated new Buffer(). var newBuffer; if (typeof Buffer.allocUnsafe === "function") { newBuffer = function(len) { return Buffer.allocUnsafe(len); }; } else { newBuffer = function(len) { return new Buffer(len); }; } // Node 8 introduced a proper destroy() implementation on writable streams. function installDestroyFn(stream, fn) { if (typeof stream.destroy === "function") { // New API. stream._destroy = function(err, cb) { fn(); if (cb != null) cb(err); }; } else { // Old API. stream.destroy = fn; } } function defaultCallback(err) { if (err) throw err; } yauzl-3.4.0/package-lock.json000066400000000000000000000166431521126516100161100ustar00rootroot00000000000000{ "name": "yauzl", "version": "3.4.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "yauzl", "version": "3.4.0", "license": "MIT", "dependencies": { "pend": "~1.2.0" }, "devDependencies": { "bl": "^6.0.11" }, "engines": { "node": ">=12" } }, "node_modules/@types/node": { "version": "20.11.17", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.17.tgz", "integrity": "sha512-QmgQZGWu1Yw9TDyAP9ZzpFJKynYNeOvwMJmaxABfieQoVoiVOS6MN1WSpqpRcbeA5+RW82kraAVxCCJg+780Qw==", "dev": true, "dependencies": { "undici-types": "~5.26.4" } }, "node_modules/@types/readable-stream": { "version": "4.0.10", "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.10.tgz", "integrity": "sha512-AbUKBjcC8SHmImNi4yK2bbjogQlkFSg7shZCcicxPQapniOlajG8GCc39lvXzCWX4lLRRs7DM3VAeSlqmEVZUA==", "dev": true, "dependencies": { "@types/node": "*", "safe-buffer": "~5.1.1" } }, "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", "dev": true, "dependencies": { "event-target-shim": "^5.0.0" }, "engines": { "node": ">=6.5" } }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ] }, "node_modules/bl": { "version": "6.0.11", "resolved": "https://registry.npmjs.org/bl/-/bl-6.0.11.tgz", "integrity": "sha512-Ok/NWrEA0mlEEbWzckkZVLq6Nv1m2xZ+i9Jq5hZ9Ph/YEcP5dExqls9wUzpluhQRPzdeT8oZNOXAytta6YN8pQ==", "dev": true, "dependencies": { "@types/readable-stream": "^4.0.0", "buffer": "^6.0.3", "inherits": "^2.0.4", "readable-stream": "^4.2.0" } }, "node_modules/buffer": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ], "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "node_modules/event-target-shim": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "dev": true, "engines": { "node": ">=0.8.x" } }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ] }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==" }, "node_modules/process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", "dev": true, "engines": { "node": ">= 0.6.0" } }, "node_modules/readable-stream": { "version": "4.5.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", "dev": true, "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", "process": "^0.11.10", "string_decoder": "^1.3.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, "dependencies": { "safe-buffer": "~5.2.0" } }, "node_modules/string_decoder/node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/feross" }, { "type": "patreon", "url": "https://www.patreon.com/feross" }, { "type": "consulting", "url": "https://feross.org/support" } ] }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", "dev": true } } } yauzl-3.4.0/package.json000066400000000000000000000013721521126516100151530ustar00rootroot00000000000000{ "name": "yauzl", "version": "3.4.0", "description": "yet another unzip library for node", "engines": { "node": ">=12" }, "main": "index.js", "scripts": { "test": "node test/test.js" }, "repository": { "type": "git", "url": "git+https://github.com/thejoshwolfe/yauzl.git" }, "keywords": [ "unzip", "zip", "stream", "archive", "file" ], "author": "Josh Wolfe ", "license": "MIT", "bugs": { "url": "https://github.com/thejoshwolfe/yauzl/issues" }, "homepage": "https://github.com/thejoshwolfe/yauzl", "dependencies": { "pend": "~1.2.0" }, "devDependencies": { "bl": "^6.0.11" }, "files": [ "crc32.js", "fd-slicer.js", "index.js" ] } yauzl-3.4.0/test/000077500000000000000000000000001521126516100136415ustar00rootroot00000000000000yauzl-3.4.0/test/errors.js000066400000000000000000000125361521126516100155220ustar00rootroot00000000000000// Test I/O errors coming from the random access reader at any given moment. // The .zip file being tested has a variety of features, such as a large central directory, // and somewhat large compressed and uncompressed files. const yauzl = require("../"); const path = require("path"); const fs = require("fs"); const stream = require("stream"); exports.runTest = runTest; let ArrayFromAsync = Array.fromAsync; if (typeof ArrayFromAsync !== "function") { ArrayFromAsync = async function(items) { // This is not a general-purpose polyfill. // It just does enough for what we want here. const result = []; for await (let item of items) { result.push(item); } return result; }; } class EventuallyFailRandomAccessReader extends yauzl.RandomAccessReader { constructor(successCount, buffer) { super(); this.successCount = successCount; this.buffer = buffer; } isItTimeToFail() { if (this.successCount <= 0) return true; this.successCount--; return false; } _readStreamForRange(start, end) { const self = this; const reader = new stream.Readable(); reader._read = function(size) { if (self.isItTimeToFail()) return this.emit("error", new TheErrorWeExpect("i've decided to fail now")); const clampedEnd = Math.min(start + size, end); const chunk = self.buffer.slice(start, clampedEnd); start = clampedEnd; this.push(chunk); if (start >= end) { return this.push(null); // EOF } }; return reader; } close(cb) { this.buffer = null; cb(); } } class TheErrorWeExpect extends Error {} const stopAtEntryFileName = "a/b/020"; function runTest(cb) { const buffer = fs.readFileSync(path.join(__dirname, "success", "everything.zip")); testErrorsWithCallbacks(buffer, async function() { await testErrorsWithPromises(buffer); await testErrorsWithPromisesGreedy(buffer); cb(); }); } function testErrorsWithCallbacks(buffer, cb) { const prefix = "test every error with callbacks: "; let successCount = 0; giveItAGo(function handleResult(reachedEnd) { if (reachedEnd) return cb(); successCount++; giveItAGo(handleResult); }); function giveItAGo(cb) { function handleError(err) { if (err instanceof TheErrorWeExpect) return cb(false); throw err; } const reader = new EventuallyFailRandomAccessReader(successCount, buffer); yauzl.fromRandomAccessReader(reader, buffer.length, {lazyEntries:true}, function(err, zipfile) { if (err) return handleError(err); zipfile.readEntry(); zipfile.on("error", handleError); zipfile.on("entry", function(entry) { if (entry.fileName === stopAtEntryFileName) { // We've seen enough. Don't need to fully process each small entry. return done(); } zipfile.openReadStream(entry, function(err, readStream) { if (err) return handleError(err); readStream.on("error", handleError); const sink = new stream.Writable(); sink._write = function(chunk, encoding, callback) { callback(); }; sink.on("finish", function() { zipfile.readEntry(); }); readStream.pipe(sink); }); }); zipfile.on("end", function() { throw new Error("expected to interrupt before reaching the end"); }); function done() { console.log(prefix + `done after ${successCount} read() calls`); cb(true); } }); } } async function testErrorsWithPromises(buffer) { const prefix = "test every error with promises: "; for (var successCount = 0;; successCount++) { const reader = new EventuallyFailRandomAccessReader(successCount, buffer); try { const zipfile = await yauzl.fromRandomAccessReaderPromise(reader, buffer.length); for await (let entry of zipfile.eachEntry()) { if (entry.fileName == stopAtEntryFileName) break; const readStream = await zipfile.openReadStreamPromise(entry); for await (let chunk of readStream) { // Do nothing. } } } catch (err) { handleError(err); continue; } break; } console.log(prefix + `done after ${successCount} read() calls`); function handleError(err) { if (err instanceof TheErrorWeExpect) return; throw err; } } async function testErrorsWithPromisesGreedy(buffer) { const prefix = "test almost every error with greedy promises: "; for (var successCount = 0;; successCount += Math.max(1, successCount >> 2)) { var reader = new EventuallyFailRandomAccessReader(successCount, buffer); try { const zipfile = await yauzl.fromRandomAccessReaderPromise(reader, buffer.length, {autoClose: false}); try { // All entries are read first, then all read streams are opened afterward. const entries = await ArrayFromAsync(zipfile.eachEntry()); for (let entry of entries) { const readStream = await zipfile.openReadStreamPromise(entry); for await (let chunk of readStream) { // Do nothing. } } } finally { zipfile.close(); } } catch (err) { handleError(err); continue; } break; } console.log(prefix + `done after ${successCount - reader.successCount} read() calls`); function handleError(err) { if (err instanceof TheErrorWeExpect) return; throw err; } } yauzl-3.4.0/test/failure/000077500000000000000000000000001521126516100152705ustar00rootroot00000000000000End of central directory record signature not found Either not a zip file or file is truncated.zip000066400000000000000000000004641521126516100372450ustar00rootroot00000000000000yauzl-3.4.0/test/failurePK ÛKEQàV‡a.txtUT >*òS>*òSux èèasdf PK ÛKE�šöÀb.txtUT >*òS>*òSux èèbsdf PK ÛKEQàV‡¤�a.txtUT>*òSux èèPK ÛKE�šöÀ¤�Db.txtUT>*òSux èèPK–ˆEnd of central directory record signature not found Either not a zip file or file is truncated_1.zip000066400000000000000000000000001521126516100374470ustar00rootroot00000000000000yauzl-3.4.0/test/failure64cca97da08d4c96c19675cedb5284a402d60867.paxheader00006660000000000000000000000262152112651610020450xustar00rootroot00000000000000178 path=yauzl-3.4.0/test/failure/Invalid comment length Expected 1 Found 0 Are there extra bytes at the end of the file Or is the end of central dir signature PK in the com.zip 64cca97da08d4c96c19675cedb5284a402d60867.data000066400000000000000000000004651521126516100173130ustar00rootroot00000000000000PK ÛKEQàV‡a.txtUT >*òS>*òSux èèasdf PK ÛKE�šöÀb.txtUT >*òS>*òSux èèbsdf PK ÛKEQàV‡¤�a.txtUT>*òSux èèPK ÛKE�šöÀ¤�Db.txtUT>*òSux èèPK–ˆyauzl-3.4.0/test/failure/absolute path C xt.zip000066400000000000000000000004641521126516100213320ustar00rootroot00000000000000PK ÛKEQàV‡a.txtUT >*òS>*òSux èèasdf PK ÛKE�šöÀb.txtUT >*òS>*òSux èèbsdf PK ÛKEQàV‡¤�C:/xtUT>*òSux èèPK ÛKE�šöÀ¤�Db.txtUT>*òSux èèPK–ˆyauzl-3.4.0/test/failure/absolute path atxt.zip000066400000000000000000000004641521126516100215140ustar00rootroot00000000000000PK ÛKEQàV‡a.txtUT >*òS>*òSux èèasdf PK ÛKE�šöÀb.txtUT >*òS>*òSux èèbsdf PK ÛKEQàV‡¤�/atxtUT>*òSux èèPK ÛKE�šöÀ¤�Db.txtUT>*òSux èèPK–ˆyauzl-3.4.0/test/failure/compressed uncompressed size mismatch for stored file 2147483647 5.zip000066400000000000000000000004641521126516100315300ustar00rootroot00000000000000PK ÛKEQàV‡a.txtUT >*òS>*òSux èèasdf PK ÛKE�šöÀb.txtUT >*òS>*òSux èèbsdf PK ÛKEQàV‡ÿÿÿ¤�a.txtUT>*òSux èèPK ÛKE�šöÀ¤�Db.txtUT>*òSux èèPK–ˆyauzl-3.4.0/test/failure/extra field length exceeds extra field buffer size.zip000066400000000000000000000004641521126516100274070ustar00rootroot00000000000000PK ÛKEQàV‡a.txtUT >*òS>*òSux èèasdf PK ÛKE�šöÀb.txtUT >*òS>*òSux èèbsdf PK ÛKEQàV‡¤�a.txtUT>*òSux èèPK ÛKE�šöÀ¤�Db.txtUT>*òSux èèPK–ˆyauzl-3.4.0/test/failure/file data overflows file bounds 63 2147483647 308.zip000066400000000000000000000004641521126516100255750ustar00rootroot00000000000000PK ÛKEQàV‡a.txtUT >*òS>*òSux èèasdf PK ÛKE�šöÀb.txtUT >*òS>*òSux èèbsdf PK ÛKEQàV‡ÿÿÿÿÿÿ¤�a.txtUT>*òSux èèPK ÛKE�šöÀ¤�Db.txtUT>*òSux èèPK–ˆyauzl-3.4.0/test/failure/invalid central directory file header signature 0x1014b50.zip000066400000000000000000000004641521126516100302640ustar00rootroot00000000000000PK ÛKEQàV‡a.txtUT >*òS>*òSux èèasdf PK ÛKE�šöÀb.txtUT >*òS>*òSux èèbsdf PK ÛKEQàV‡¤�a.txtUT>*òSux èèPK ÛKE�šöÀ¤�Db.txtUT>*òSux èèPK–ˆyauzl-3.4.0/test/failure/invalid characters in fileName a txt.zip000066400000000000000000000004641521126516100246370ustar00rootroot00000000000000PK ÛKEQàV‡a.txtUT >*òS>*òSux èèasdf PK ÛKE�šöÀb.txtUT >*òS>*òSux èèbsdf PK ÛKEQàV‡¤�a\txtUT>*òSux èèPK ÛKE�šöÀ¤�Db.txtUT>*òSux èèPK–ˆyauzl-3.4.0/test/failure/invalid code lengths set.zip000066400000000000000000000056611521126516100225460ustar00rootroot00000000000000PK Eˆ Á)index.jsUT •WôS±WôSux èèÝú[oÛÈ~÷¯˜ÕC#Á’¬Ûº†UoÑØÎv�\I¶Zô�"‡Ò $‡åŲ6ðï9sã 9”ìdŸj ‘Í9sΙï܇z —ä†ô¿5+èp—ƒÑúìž¿‰>%,¤…³MJñ‰Î..H‘ ¹¥YU ¹š°âÅA®¾%ò‘†¼ˆ�‚rIsŸE„Çý¤g<§ÙpPѲºÛ=Ë&,‹ùäw–Oáß`Lâ: +Ƴ!-Š1�g1Kèˆ|=#„ÅŸŽHµ+øžÀ¯kxò¬ä �&|; \FËë�Ù:U�>Ò4`˶ÃÑ·}¡4ÿHƒH<ÁZ°»"KÑý ÉÍÍ ™�Ûª.²µØ¡© àt;C÷dÈå Ù÷� ìóÉMzE‹@LQáOK%QȬ72�I%ÖŽiÎr:Ì Ò²œ–UÄëÊ(ñd~ë ªŸÎðó,åQ�ð=漨J¡5ø#~¬Ï øÂ?ò Ú�I$É&¿4Æ×Oo’ÕI2"ÍÑ8¨“êV=&•R¿AÑq¯8² ,��64ŒÅCy˜XðŠ££>êðùaÂK*6µô3°Ù’f~ðÿS¿X·lÔüCŒË*¨<§ÆÇå Ð{ Å¡”4(Â8 AŠ}PD%è\€ R•FJ¶ÍàCj/$\M‚²"1£‰È1 =+I@ ͱ`“ÐIB³mµƒ°ISˆ„©Í@=¿SÜE³�G4",‹ÉæPQÅžþc²ß±pGöÀ È^¡ �åö¬ÚA�ª¨£­{ ¦z»sDV\nc�Fª�Ñ 4¡òP VDøY x�aÓ«’ä¼,Yí‚J‚tö5¯Kt‚^CRZQP`�±•>ižÐ±�´£ª"AÛƒxuÊ6TpPi$�…bV”UÛNÀ޶Çš ¼8{“4ˆ¨ØeD©eÀ"“qd½a‘Ïþ^±ž ºJ ÜÊÅOhÓ²X¬ U<º‹³Çù ~ÖxHent³aSÇ1-ñ;HÓ”�»÷;o P11E–£u‹)0Ìèž¼ AB™È¡‹”V¹<•î-waŠ~Ïïy,âSŒÉlldÜfëÆ±'iõ‡0^0D]hg¡5é³È(àñsrCæí⣅ùí—¬Z.ÞÞÙˆü€õôqv9ûqµù +DIŲš6Õɤ“˜×à{ÒqÀõx—´º&0ϰ�è9a£‘ÅC{Òkm"¥Žè‹@(Zškkno_Áö÷uºA&ÐYùÅÑ(š[5ÐüZYg@­]?Ø�HcCt½û¢àÅp�BŠgÜb¢òè�qHŒuŽÅ…F×Dâ*è2Á[bÚȲ‘„ã]Âñî�z�iƇš ´·\9ˆtw¢g, Ït�æ´ðªqÖÌ2Jñ>J5}�Ê aei�ŽºÞ âÏü^‘ú%]6’°ßþ™f¡Èë"Ç ¿ÁºŸ[‹ýV’ü*)^³ê ¬÷p¿j¸ÏU‹™c�d(ôy‘Å8l߉µ¦¦íÖ-7†¿¼ýIyÄb"÷V,¥{$xÇ#$þ +}ÌóU?ó(¨z˜ßÁJsË®¢õ¿ýx;Y.l Šp¹èñ÷¹e«…�&�š{ J©Û ¿……ã�ú[ör¬³çñ´N¸¸Òðeà­Ôafû*Ú{X5s�¶…åFK1f£K««8ÍÖ opý(㥅ÀÒxR«£~i+Üže¼¬-?Z®ôð«æP9‹$c�½H‰N,h��¹ *H1›&GK ¦HPß¿‚>U,¿Y^IøN  �Ï Œ¾´ì³B?êY•›Ñ6á¡(óª%L�¶²Ãý¿EÚ¿Ëìë—¸ZèË·™Ríòù Y]*_ÍôúÞyŸïœ÷™~Ô\³¹¥W(õœÒëÓþ»nàЗvØ©ç²,‡<’ ×±Lþ'(sW³ù+ÔU|5 0ÚeÈØÀòùÃ݇kÐ$O‚\—Å•7¹ýuµü3©K”³«ª¼¼¾¸ØÂB½Á¤t±É8LZ»š•�è„…<{°ÚØÆ*�åM•ÕHúlØÜÈ Î37WXXX¶Ô·©/rе�«Yó_ú�;8ݼ-°3´@¦Ç6üÙïÐÔCFþÒQD�ÚVûŽÛeüý‚åµ³ÃI Žß¾ÏÁ×*ÿŸÞ¼ðmVpãúª»Œ7¨7ṑإ}í mMmIîè)®(Â�ŒÄ±VÃæÐ6‰µì &]`ÇÖsdvmiÛ¬=Y˜:3ˆm&)וÏÓV}êDÍ­™øû§íuÝ'GÓ�’Ù—t=ï ±}ç„sg±ïâ¡s•cFN=àZ·2@Þ�ÝWßö8¨Þ‚Ÿœ ûÆ.Õ:|Gî?Yû¾ySóÖÛvÉm¿…XÍ–æ-Äw\ŠÙèè¤Õé¾aºöò¾¿ÜñÀ (¢:‹­ ìÔФf¬£“�šŽzÆ=ÝœšCNÌ+f¤Ð£‡5࣫ž–_ß(ûÛw\½<Öˆërxº ¿lõöGÚp·.¾¬»w{ñÔ[ÉQ†p(Ü CFV�Ó]幌ðw·î{+¾ˆ¾¾iU¾\ûÚämñj§:}ôØŠƒ«òœXÛ%b­›¶#×ufÞÃÙl”Gª×~Ím¶cù;«,w]wh%ÊîζH9%6{ ; ;9f^ žo}C髊®] ˜0£k[]@[õÁú*“]Ì•¬~5œ‚–ÁV}/Çþ•^p¯úý/Ó¹ºò×IR«Ä—2ÜÊ˶gîu¯„ÅkC„ç%@¼<×û 5Ô�àQ·Òï¸Èý‡7æÅG ]©¼õ2ÄÈ-…Ý*øl¸´oÐþOk]ò6EÞ÷µ»§³ÿPK Eˆ Á)´�index.jsUT•WôSux èèPKNM yauzl-3.4.0/test/failure/invalid local file header signature 0x3034b50.zip000066400000000000000000000004641521126516100257450ustar00rootroot00000000000000PK ÛKEQàV‡a.txtUT >*òS>*òSux èèasdf PK ÛKE�šöÀb.txtUT >*òS>*òSux èèbsdf PK ÛKEQàV‡¤�a.txtUT>*òSux èèPK ÛKE�šöÀ¤�Db.txtUT>*òSux èèPK–ˆyauzl-3.4.0/test/failure/invalid relative path xt.zip000066400000000000000000000004641521126516100225730ustar00rootroot00000000000000PK ÛKEQàV‡a.txtUT >*òS>*òSux èèasdf PK ÛKE�šöÀb.txtUT >*òS>*òSux èèbsdf PK ÛKEQàV‡¤�../xtUT>*òSux èèPK ÛKE�šöÀ¤�Db.txtUT>*òSux èèPK–ˆyauzl-3.4.0/test/failure/invalid zip64 end of central directory record signature.zip000066400000000000000000000001421521126516100303270ustar00rootroot00000000000000PK,?-PKPKÿÿÿÿÿÿÿÿÿÿÿÿyauzl-3.4.0/test/failure/multi-disk zip files are not supported found disk number 1.zip000066400000000000000000000004641521126516100306700ustar00rootroot00000000000000PK ÛKEQàV‡a.txtUT >*òS>*òSux èèasdf PK ÛKE�šöÀb.txtUT >*òS>*òSux èèbsdf PK ÛKEQàV‡¤�a.txtUT>*òSux èèPK ÛKE�šöÀ¤�Db.txtUT>*òSux èèPK–ˆyauzl-3.4.0/test/failure/not enough bytes in the stream expected 2048576 got only 1000000.zip000066400000000000000000000022011521126516100304670ustar00rootroot00000000000000PKG‰œFžËyÙ@B zeros.binUT e!@U\!@Uux èèíÁ‚ ÿ¯nH@¯PKG‰œFžËyÙ@B ´�zeros.binUTe!@Uux èèPKOyauzl-3.4.0/test/failure/strong encryption is not supported.zip000066400000000000000000000003021521126516100246610ustar00rootroot00000000000000PK û‰’J 0:6a.txtUT :¬öXE¬öXux èèš(=þ0þ•¼ŸÓX Ý&]b\PK 0:6PK Iû‰’J 0:6´�a.txtUT:¬öXux èèPKKayauzl-3.4.0/test/failure/too many bytes in the stream expected 82496 got at least 98304.zip000066400000000000000000000022011521126516100304070ustar00rootroot00000000000000PKG‰œFžËyÙ@B zeros.binUT e!@U\!@Uux èèíÁ‚ ÿ¯nH@¯PKG‰œFžËyÙ@B ´�zeros.binUTe!@Uux èèPKOyauzl-3.4.0/test/failure/too many length or distance symbols.zip000066400000000000000000000056611521126516100246410ustar00rootroot00000000000000PK Eˆ Á)index.jsUT •WôS±WôSux èèýZ[oÛÈ~÷¯˜ÕC#Á’¬Ûº†UoÑØÎv�\I¶Zô�"‡Ò $‡åŲ6ðï9sã 9”ìdŸj ‘Í9sΙï܇z —ä†ô¿5+èp—ƒÑúìž¿‰>%,¤…³MJñ‰Î..H‘ ¹¥YU ¹š°âÅA®¾%ò‘†¼ˆ�‚rIsŸE„Çý¤g<§ÙpPѲºÛ=Ë&,‹ùäw–Oáß`Lâ: +Ƴ!-Š1�g1Kèˆ|=#„ÅŸŽHµ+øžÀ¯kxò¬ä �&|; \FËë�Ù:U�>Ò4`˶ÃÑ·}¡4ÿHƒH<ÁZ°»"KÑý ÉÍÍ ™�Ûª.²µØ¡© àt;C÷dÈå Ù÷� ìóÉMzE‹@LQáOK%QȬ72�I%ÖŽiÎr:Ì Ò²œ–UÄëÊ(ñd~ë ªŸÎðó,åQ�ð=漨J¡5ø#~¬Ï øÂ?ò Ú�I$É&¿4Æ×Oo’ÕI2"ÍÑ8¨“êV=&•R¿AÑq¯8² ,��64ŒÅCy˜XðŠ££>êðùaÂK*6µô3°Ù’f~ðÿS¿X·lÔüCŒË*¨<§ÆÇå Ð{ Å¡”4(Â8 AŠ}PD%è\€ R•FJ¶ÍàCj/$\M‚²"1£‰È1 =+I@ ͱ`“ÐIB³mµƒ°ISˆ„©Í@=¿SÜE³�G4",‹ÉæPQÅžþc²ß±pGöÀ È^¡ �åö¬ÚA�ª¨£­{ ¦z»sDV\nc�Fª�Ñ 4¡òP VDøY x�aÓ«’ä¼,Yí‚J‚tö5¯Kt‚^CRZQP`�±•>ižÐ±�´£ª"AÛƒxuÊ6TpPi$�…bV”UÛNÀ޶Çš ¼8{“4ˆ¨ØeD©eÀ"“qd½a‘Ïþ^±ž ºJ ÜÊÅOhÓ²X¬ U<º‹³Çù ~ÖxHent³aSÇ1-ñ;HÓ”�»÷;o P11E–£u‹)0Ìèž¼ AB™È¡‹”V¹<•î-waŠ~Ïïy,âSŒÉlldÜfëÆ±'iõ‡0^0D]hg¡5é³È(àñsrCæí⣅ùí—¬Z.ÞÞÙˆü€õôqv9ûqµù +DIŲš6Õɤ“˜×à{ÒqÀõx—´º&0ϰ�è9a£‘ÅC{Òkm"¥Žè‹@(Zškkno_Áö÷uºA&ÐYùÅÑ(š[5ÐüZYg@­]?Ø�HcCt½û¢àÅp�BŠgÜb¢òè�qHŒuŽÅ…F×Dâ*è2Á[bÚȲ‘„ã]Âñî�z�iƇš ´·\9ˆtw¢g, Ït�æ´ðªqÖÌ2Jñ>J5}�Ê aei�ŽºÞ âÏü^‘ú%]6’°ßþ™f¡Èë"Ç ¿ÁºŸ[‹ýV’ü*)^³ê ¬÷p¿j¸ÏU‹™c�d(ôy‘Å8l߉µ¦¦íÖ-7†¿¼ýIyÄb"÷V,¥{$xÇ#$þ +}ÌóU?ó(¨z˜ßÁJsË®¢õ¿ýx;Y.l Šp¹èñ÷¹e«…�&�š{ J©Û ¿……ã�ú[ör¬³çñ´N¸¸Òðeà­Ôafû*Ú{X5s�¶…åFK1f£K««8ÍÖ opý(㥅ÀÒxR«£~i+Üže¼¬-?Z®ôð«æP9‹$c�½H‰N,h��¹ *H1›&GK ¦HPß¿‚>U,¿Y^IøN  �Ï Œ¾´ì³B?êY•›Ñ6á¡(óª%L�¶²Ãý¿EÚ¿Ëìë—¸ZèË·™Ríòù Y]*_ÍôúÞyŸïœ÷™~Ô\³¹¥W(õœÒëÓþ»nàЗvØ©ç²,‡<’ ×±Lþ'(sW³ù+ÔU|5 0ÚeÈØÀòùÃ݇kÐ$O‚\—Å•7¹ýuµü3©K”³«ª¼¼¾¸ØÂB½Á¤t±É8LZ»š•�è„…<{°ÚØÆ*�åM•ÕHúlØÜÈ Î37WXXX¶Ô·©/rе�«Yó_ú�;8ݼ-°3´@¦Ç6üÙïÐÔCFþÒQD�ÚVûŽÛeüý‚åµ³ÃI Žß¾ÏÁ×*ÿŸÞ¼ðmVpãúª»Œ7¨7ṑإ}í mMmIîè)®(Â�ŒÄ±VÃæÐ6‰µì &]`ÇÖsdvmiÛ¬=Y˜:3ˆm&)וÏÓV}êDÍ­™øû§íuÝ'GÓ�’Ù—t=ï ±}ç„sg±ïâ¡s•cFN=àZ·2@Þ�ÝWßö8¨Þ‚Ÿœ ûÆ.Õ:|Gî?Yû¾ySóÖÛvÉm¿…XÍ–æ-Äw\ŠÙèè¤Õé¾aºöò¾¿ÜñÀ (¢:‹­ ìÔФf¬£“�šŽzÆ=ÝœšCNÌ+f¤Ð£‡5࣫ž–_ß(ûÛw\½<Öˆërxº ¿lõöGÚp·.¾¬»w{ñÔ[ÉQ†p(Ü CFV�Ó]幌ðw·î{+¾ˆ¾¾iU¾\ûÚämñj§:}ôØŠƒ«òœXÛ%b­›¶#×ufÞÃÙl”Gª×~Ím¶cù;«,w]wh%ÊîζH9%6{ ; ;9f^ žo}C髊®] ˜0£k[]@[õÁú*“]Ì•¬~5œ‚–ÁV}/Çþ•^p¯úý/Ó¹ºò×IR«Ä—2ÜÊ˶gîu¯„ÅkC„ç%@¼<×û 5Ô�àQ·Òï¸Èý‡7æÅG ]©¼õ2ÄÈ-…Ý*øl¸´oÐþOk]ò6EÞ÷µ»§³ÿPK Eˆ Á)´�index.jsUT•WôSux èèPKNM yauzl-3.4.0/test/failure/unexpected EOF.zip000066400000000000000000000003641521126516100205550ustar00rootroot00000000000000PK-fÒH empty.txtPKPK?-fÒHÿÿÿÿÿÿÿÿ ´�ÿÿÿÿempty.txtPK,?-S?PK’PKÿÿÿÿÿÿÿÿÿÿÿÿyauzl-3.4.0/test/failure/unsupported compression method 1.zip000066400000000000000000000004641521126516100243140ustar00rootroot00000000000000PK ÛKEQàV‡a.txtUT >*òS>*òSux èèasdf PK ÛKE�šöÀb.txtUT >*òS>*òSux èèbsdf PK ÛKEQàV‡¤�a.txtUT>*òSux èèPK ÛKE�šöÀ¤�Db.txtUT>*òSux èèPK–ˆyauzl-3.4.0/test/failure/zip64 extended information extra field does not include compressed size.zip000066400000000000000000000003641521126516100334120ustar00rootroot00000000000000PK-c ÒH empty.txtPKPK?-c ÒHÿÿÿÿÿÿÿÿ ´�ÿÿÿÿempty.txtPK,?-S?PK’PKÿÿÿÿÿÿÿÿÿÿÿÿzip64 extended information extra field does not include relative header offset.zip000066400000000000000000000003641521126516100345270ustar00rootroot00000000000000yauzl-3.4.0/test/failurePK-c ÒH empty.txtPKPK?-c ÒHÿÿÿÿÿÿÿÿ ´�ÿÿÿÿempty.txtPK,?-S?PK’PKÿÿÿÿÿÿÿÿÿÿÿÿzip64 extended information extra field does not include uncompressed size.zip000066400000000000000000000003641521126516100336760ustar00rootroot00000000000000yauzl-3.4.0/test/failurePK-c ÒH empty.txtPKPK?-c ÒHÿÿÿÿÿÿÿÿ ´�ÿÿÿÿempty.txtPK,?-S?PK’PKÿÿÿÿÿÿÿÿÿÿÿÿyauzl-3.4.0/test/forAwait.js000066400000000000000000000023021521126516100157500ustar00rootroot00000000000000// Test for this bug: https://github.com/thejoshwolfe/yauzl/issues/169 const yauzl = require("../"); const fs = require("fs"); const path = require("path"); const paths = process.argv.slice(2); if (paths.length === 0) throw new Error("give a path to a zipfile as an arg"); let done = false; yauzl.open(paths[0], {lazyEntries: true}, function(err, zipfile) { if (err) throw err; zipfile.on("error", function(err) { throw err; }); zipfile.once("close", function() { done = true; }); zipfile.readEntry(); zipfile.once("entry", function(entry) { zipfile.openReadStream(entry, function(err, readStream) { if (err) throw err; (async function() { let bytesSeen = 0; console.log("starting..."); for await (let chunk of readStream) { if (bytesSeen === 0) console.log(" ...iterating"); bytesSeen += chunk.length; } console.log("...closing after bytes:", bytesSeen); zipfile.close(); })().catch(function(err) { throw err; }); }); }); }); process.on("exit", function(code) { if (code === 0 && !done) { throw new Error("premature exit. probably means an event never got fired."); } }); yauzl-3.4.0/test/range-test.js000066400000000000000000000145371521126516100162620ustar00rootroot00000000000000var yauzl = require("../"); var PassThrough = require("stream").PassThrough; var util = require("util"); var Pend = require("pend"); var BufferList = require("bl"); exports.runTest = runTest; // zipfile obtained via: // $ echo -n 'aaabaaabaaabaaab' > stored.txt // $ cp stored.txt compressed.txt // $ cp stored.txt encrypted.txt // $ cp stored.txt encrypted-and-compressed.txt // $ rm -f out.zip // $ zip out.zip -0 stored.txt // $ zip out.zip compressed.txt // $ zip out.zip -e0 encrypted.txt // $ zip out.zip -e encrypted-and-compressed.txt var zipfileBuffer = hexToBuffer("" + "504b03040a00000000006a54954ab413389510000000100000000a001c007374" + "6f7265642e7478745554090003d842fa5842c5f75875780b000104e803000004" + "e803000061616162616161626161616261616162504b03041400000008007554" + "954ab413389508000000100000000e001c00636f6d707265737365642e747874" + "5554090003ed42fa58ed42fa5875780b000104e803000004e80300004b4c4c4c" + "4a44c200504b03040a00090000008454954ab41338951c000000100000000d00" + "1c00656e637279707465642e74787455540900030743fa580743fa5875780b00" + "0104e803000004e8030000f72e7bb915142131c934f01b163fcadb2a8db7cdaf" + "d0a6f4dd1694c0504b0708b41338951c00000010000000504b03041400090008" + "008a54954ab413389514000000100000001c001c00656e637279707465642d61" + "6e642d636f6d707265737365642e74787455540900031343fa581343fa587578" + "0b000104e803000004e80300007c4d3ea0d9754b470d3eb32ada5741bfc848f4" + "19504b0708b41338951400000010000000504b01021e030a00000000006a5495" + "4ab413389510000000100000000a0018000000000000000000b4810000000073" + "746f7265642e7478745554050003d842fa5875780b000104e803000004e80300" + "00504b01021e031400000008007554954ab413389508000000100000000e0018" + "000000000001000000b48154000000636f6d707265737365642e747874555405" + "0003ed42fa5875780b000104e803000004e8030000504b01021e030a00090000" + "008454954ab41338951c000000100000000d0018000000000000000000b481a4" + "000000656e637279707465642e74787455540500030743fa5875780b000104e8" + "03000004e8030000504b01021e031400090008008a54954ab413389514000000" + "100000001c0018000000000001000000b48117010000656e637279707465642d" + "616e642d636f6d707265737365642e74787455540500031343fa5875780b0001" + "04e803000004e8030000504b0506000000000400040059010000910100000000" + ""); // the same file in all 4 supported forms: // [0b00]: stored // [0b01]: compressed // [0b10]: encrypted // [0b11]: encrypted and compressed function shouldBeCompressed(index) { return (index & 1) !== 0; } function shouldBeEncrypted (index) { return (index & 2) !== 0; } var expectedFileDatas = [ hexToBuffer("61616162616161626161616261616162"), hexToBuffer("4b4c4c4c4a44c200"), hexToBuffer("f72e7bb915142131c934f01b163fcadb2a8db7cdafd0a6f4dd1694c0"), hexToBuffer("7c4d3ea0d9754b470d3eb32ada5741bfc848f419"), ]; function runTest(cb) { util.inherits(StingyRandomAccessReader, yauzl.RandomAccessReader); function StingyRandomAccessReader(buffer) { yauzl.RandomAccessReader.call(this); this.buffer = buffer; this.upcomingByteCounts = []; } StingyRandomAccessReader.prototype._readStreamForRange = function(start, end) { if (this.upcomingByteCounts.length > 0) { var expectedByteCount = this.upcomingByteCounts.shift(); if (expectedByteCount != null) { if (expectedByteCount !== end - start) { throw new Error("expected " + expectedByteCount + " got " + (end - start) + " bytes"); } } } var result = new PassThrough(); result.write(this.buffer.slice(start, end)); result.end(); return result; }; var zipfileReader = new StingyRandomAccessReader(zipfileBuffer); var options = {lazyEntries: true, autoClose: false}; yauzl.fromRandomAccessReader(zipfileReader, zipfileBuffer.length, options, function(err, zipfile) { var entries = []; zipfile.readEntry(); zipfile.on("entry", function(entry) { var index = entries.length; // asser the structure of the zipfile is what we expect if (entry.isCompressed() !== shouldBeCompressed(index)) throw new Error("assertion failure"); if (entry.isEncrypted() !== shouldBeEncrypted(index)) throw new Error("assertion failure"); entries.push(entry); zipfile.readEntry(); }); zipfile.on("end", function() { // now we get to the testing var pend = new Pend(); // 1 thing at a time for better determinism/reproducibility pend.max = 1; [null, 0, 2].forEach(function(start) { [null, 3, 5].forEach(function(end) { entries.forEach(function(entry, index) { var expectedFileData = expectedFileDatas[index]; pend.go(function(cb) { var effectiveStart = start != null ? start : 0; var effectiveEnd = end != null ? end : expectedFileData.length; var expectedSlice = expectedFileData.slice(effectiveStart, effectiveEnd); // the next read will be to check the local file header. // then we assert that yauzl is asking for just the bytes we asked for. zipfileReader.upcomingByteCounts = [null, expectedSlice.length]; var options = {}; if (start != null) options.start = start; if (end != null) options.end = end; if (entry.isCompressed()) options.decompress = false; if (entry.isEncrypted()) options.decrypt = false; zipfile.openReadStream(entry, options, function(err, readStream) { if (err) throw err; readStream.pipe(BufferList(function(err, data) { var prefix = "openReadStream with range(" + start + "," + end + "," + index + "): "; if (!buffersEqual(data, expectedSlice)) { throw new Error(prefix + "contents mismatch"); } console.log(prefix + "pass"); cb(); })); }); }); }); }); }); pend.wait(cb); }); }); } function hexToBuffer(hexString) { var buffer = Buffer.allocUnsafe(hexString.length / 2); for (var i = 0; i < buffer.length; i++) { buffer[i] = parseInt(hexString.substr(i * 2, 2), 16); } return buffer; } function buffersEqual(a, b) { if (a.length !== b.length) return false; for (var i = 0; i < a.length; i++) { if (a[i] !== b[i]) return false; } return true; } if (require.main === module) runTest(function() {}); yauzl-3.4.0/test/success/000077500000000000000000000000001521126516100153115ustar00rootroot00000000000000yauzl-3.4.0/test/success/NtfsTimestamp.zip000066400000000000000000000002541521126516100206340ustar00rootroot00000000000000PK-£ C*$a €Û0H”ÜPK?-£ C*$´�a €Û0H”ÜPKSCyauzl-3.4.0/test/success/NtfsTimestamp/000077500000000000000000000000001521126516100201075ustar00rootroot00000000000000yauzl-3.4.0/test/success/NtfsTimestamp/a000066400000000000000000000000001521126516100202400ustar00rootroot00000000000000yauzl-3.4.0/test/success/big-compression.zip000066400000000000000000000004671521126516100211440ustar00rootroot00000000000000PKÍHµ\Pü»‚“0x21000UT QjQjux èdíÁ‚ ÿ¯nH@/PKÍHµ\Pü»‚“¤�0x21000UTQjux èdPKMÔyauzl-3.4.0/test/success/big-compression/000077500000000000000000000000001521126516100204115ustar00rootroot00000000000000yauzl-3.4.0/test/success/big-compression/0x21000000066400000000000000000004100001521126516100212410ustar00rootroot00000000000000yauzl-3.4.0/test/success/big-uncompressed.zip000066400000000000000000004102441521126516100213100ustar00rootroot00000000000000PK �Fµ\Pü»‚0x21000UT jjux èdPK �Fµ\Pü»‚¤�0x21000UTjux èdPKMAyauzl-3.4.0/test/success/big-uncompressed/000077500000000000000000000000001521126516100205575ustar00rootroot00000000000000yauzl-3.4.0/test/success/big-uncompressed/0x21000000066400000000000000000004100001521126516100214070ustar00rootroot00000000000000yauzl-3.4.0/test/success/bogus-compression-method.zip000066400000000000000000000056611521126516100230010ustar00rootroot00000000000000PK Eˆ Á)index.jsUT •WôS±WôSux èèÝZ[oÛÈ~÷¯˜ÕC#Á’¬Ûº†UoÑØÎv�\I¶Zô�"‡Ò $‡åŲ6ðï9sã 9”ìdŸj ‘Í9sΙï܇z —ä†ô¿5+èp—ƒÑúìž¿‰>%,¤…³MJñ‰Î..H‘ ¹¥YU ¹š°âÅA®¾%ò‘†¼ˆ�‚rIsŸE„Çý¤g<§ÙpPѲºÛ=Ë&,‹ùäw–Oáß`Lâ: +Ƴ!-Š1�g1Kèˆ|=#„ÅŸŽHµ+øžÀ¯kxò¬ä �&|; \FËë�Ù:U�>Ò4`˶ÃÑ·}¡4ÿHƒH<ÁZ°»"KÑý ÉÍÍ ™�Ûª.²µØ¡© àt;C÷dÈå Ù÷� ìóÉMzE‹@LQáOK%QȬ72�I%ÖŽiÎr:Ì Ò²œ–UÄëÊ(ñd~ë ªŸÎðó,åQ�ð=漨J¡5ø#~¬Ï øÂ?ò Ú�I$É&¿4Æ×Oo’ÕI2"ÍÑ8¨“êV=&•R¿AÑq¯8² ,��64ŒÅCy˜XðŠ££>êðùaÂK*6µô3°Ù’f~ðÿS¿X·lÔüCŒË*¨<§ÆÇå Ð{ Å¡”4(Â8 AŠ}PD%è\€ R•FJ¶ÍàCj/$\M‚²"1£‰È1 =+I@ ͱ`“ÐIB³mµƒ°ISˆ„©Í@=¿SÜE³�G4",‹ÉæPQÅžþc²ß±pGöÀ È^¡ �åö¬ÚA�ª¨£­{ ¦z»sDV\nc�Fª�Ñ 4¡òP VDøY x�aÓ«’ä¼,Yí‚J‚tö5¯Kt‚^CRZQP`�±•>ižÐ±�´£ª"AÛƒxuÊ6TpPi$�…bV”UÛNÀ޶Çš ¼8{“4ˆ¨ØeD©eÀ"“qd½a‘Ïþ^±ž ºJ ÜÊÅOhÓ²X¬ U<º‹³Çù ~ÖxHent³aSÇ1-ñ;HÓ”�»÷;o P11E–£u‹)0Ìèž¼ AB™È¡‹”V¹<•î-waŠ~Ïïy,âSŒÉlldÜfëÆ±'iõ‡0^0D]hg¡5é³È(àñsrCæí⣅ùí—¬Z.ÞÞÙˆü€õôqv9ûqµù +DIŲš6Õɤ“˜×à{ÒqÀõx—´º&0ϰ�è9a£‘ÅC{Òkm"¥Žè‹@(Zškkno_Áö÷uºA&ÐYùÅÑ(š[5ÐüZYg@­]?Ø�HcCt½û¢àÅp�BŠgÜb¢òè�qHŒuŽÅ…F×Dâ*è2Á[bÚȲ‘„ã]Âñî�z�iƇš ´·\9ˆtw¢g, Ït�æ´ðªqÖÌ2Jñ>J5}�Ê aei�ŽºÞ âÏü^‘ú%]6’°ßþ™f¡Èë"Ç ¿ÁºŸ[‹ýV’ü*)^³ê ¬÷p¿j¸ÏU‹™c�d(ôy‘Å8l߉µ¦¦íÖ-7†¿¼ýIyÄb"÷V,¥{$xÇ#$þ +}ÌóU?ó(¨z˜ßÁJsË®¢õ¿ýx;Y.l Šp¹èñ÷¹e«…�&�š{ J©Û ¿……ã�ú[ör¬³çñ´N¸¸Òðeà­Ôafû*Ú{X5s�¶…åFK1f£K««8ÍÖ opý(㥅ÀÒxR«£~i+Üže¼¬-?Z®ôð«æP9‹$c�½H‰N,h��¹ *H1›&GK ¦HPß¿‚>U,¿Y^IøN  �Ï Œ¾´ì³B?êY•›Ñ6á¡(óª%L�¶²Ãý¿EÚ¿Ëìë—¸ZèË·™Ríòù Y]*_ÍôúÞyŸïœ÷™~Ô\³¹¥W(õœÒëÓþ»nàЗvØ©ç²,‡<’ ×±Lþ'(sW³ù+ÔU|5 0ÚeÈØÀòùÃ݇kÐ$O‚\—Å•7¹ýuµü3©K”³«ª¼¼¾¸ØÂB½Á¤t±É8LZ»š•�è„…<{°ÚØÆ*�åM•ÕHúlØÜÈ Î37WXXX¶Ô·©/rе�«Yó_ú�;8ݼ-°3´@¦Ç6üÙïÐÔCFþÒQD�ÚVûŽÛeüý‚åµ³ÃI Žß¾ÏÁ×*ÿŸÞ¼ðmVpãúª»Œ7¨7ṑإ}í mMmIîè)®(Â�ŒÄ±VÃæÐ6‰µì &]`ÇÖsdvmiÛ¬=Y˜:3ˆm&)וÏÓV}êDÍ­™øû§íuÝ'GÓ�’Ù—t=ï ±}ç„sg±ïâ¡s•cFN=àZ·2@Þ�ÝWßö8¨Þ‚Ÿœ ûÆ.Õ:|Gî?Yû¾ySóÖÛvÉm¿…XÍ–æ-Äw\ŠÙèè¤Õé¾aºöò¾¿ÜñÀ (¢:‹­ ìÔФf¬£“�šŽzÆ=ÝœšCNÌ+f¤Ð£‡5࣫ž–_ß(ûÛw\½<Öˆërxº ¿lõöGÚp·.¾¬»w{ñÔ[ÉQ†p(Ü CFV�Ó]幌ðw·î{+¾ˆ¾¾iU¾\ûÚämñj§:}ôØŠƒ«òœXÛ%b­›¶#×ufÞÃÙl”Gª×~Ím¶cù;«,w]wh%ÊîζH9%6{ ; ;9f^ žo}C髊®] ˜0£k[]@[õÁú*“]Ì•¬~5œ‚–ÁV}/Çþ•^p¯úý/Ó¹ºò×IR«Ä—2ÜÊ˶gîu¯„ÅkC„ç%@¼<×û 5Ô�àQ·Òï¸Èý‡7æÅG ]©¼õ2ÄÈ-…Ý*øl¸´oÐþOk]ò6EÞ÷µ»§³ÿPK Eˆ Á)´�index.jsUT•WôSux èèPKNM yauzl-3.4.0/test/success/bogus-compression-method/000077500000000000000000000000001521126516100222455ustar00rootroot00000000000000yauzl-3.4.0/test/success/bogus-compression-method/index.js000066400000000000000000000054131521126516100237150ustar00rootroot00000000000000ÝZ[oÛÈ~÷¯˜ÕC#Á’¬Ûº†UoÑØÎv�\I¶Zô�"‡Ò $‡åŲ6ðï9sã 9”ìdŸj ‘Í9sΙï܇z —ä†ô¿5+èp—ƒÑúìž¿‰>%,¤…³MJñ‰Î..H‘ ¹¥YU ¹š°âÅA®¾%ò‘†¼ˆ�‚rIsŸE„Çý¤g<§ÙpPѲºÛ=Ë&,‹ùäw–Oáß`Lâ: +Ƴ!-Š1�g1Kèˆ|=#„ÅŸŽHµ+øžÀ¯kxò¬ä �&|; \FËë�Ù:U�>Ò4`˶ÃÑ·}¡4ÿHƒH<ÁZ°»"KÑý ÉÍÍ ™�Ûª.²µØ¡© àt;C÷dÈå Ù÷� ìóÉMzE‹@LQáOK%QȬ72�I%ÖŽiÎr:Ì Ò²œ–UÄëÊ(ñd~ë ªŸÎðó,åQ�ð=漨J¡5ø#~¬Ï øÂ?ò Ú�I$É&¿4Æ×Oo’ÕI2"ÍÑ8¨“êV=&•R¿AÑq¯8² ,��64ŒÅCy˜XðŠ££>êðùaÂK*6µô3°Ù’f~ðÿS¿X·lÔüCŒË*¨<§ÆÇå Ð{ Å¡”4(Â8 AŠ}PD%è\€ R•FJ¶ÍàCj/$\M‚²"1£‰È1 =+I@ ͱ`“ÐIB³mµƒ°ISˆ„©Í@=¿SÜE³�G4",‹ÉæPQÅžþc²ß±pGöÀ È^¡ �åö¬ÚA�ª¨£­{ ¦z»sDV\nc�Fª�Ñ 4¡òP VDøY x�aÓ«’ä¼,Yí‚J‚tö5¯Kt‚^CRZQP`�±•>ižÐ±�´£ª"AÛƒxuÊ6TpPi$�…bV”UÛNÀ޶Çš ¼8{“4ˆ¨ØeD©eÀ"“qd½a‘Ïþ^±ž ºJ ÜÊÅOhÓ²X¬ U<º‹³Çù ~ÖxHent³aSÇ1-ñ;HÓ”�»÷;o P11E–£u‹)0Ìèž¼ AB™È¡‹”V¹<•î-waŠ~Ïïy,âSŒÉlldÜfëÆ±'iõ‡0^0D]hg¡5é³È(àñsrCæí⣅ùí—¬Z.ÞÞÙˆü€õôqv9ûqµù +DIŲš6Õɤ“˜×à{ÒqÀõx—´º&0ϰ�è9a£‘ÅC{Òkm"¥Žè‹@(Zškkno_Áö÷uºA&ÐYùÅÑ(š[5ÐüZYg@­]?Ø�HcCt½û¢àÅp�BŠgÜb¢òè�qHŒuŽÅ…F×Dâ*è2Á[bÚȲ‘„ã]Âñî�z�iƇš ´·\9ˆtw¢g, Ït�æ´ðªqÖÌ2Jñ>J5}�Ê aei�ŽºÞ âÏü^‘ú%]6’°ßþ™f¡Èë"Ç ¿ÁºŸ[‹ýV’ü*)^³ê ¬÷p¿j¸ÏU‹™c�d(ôy‘Å8l߉µ¦¦íÖ-7†¿¼ýIyÄb"÷V,¥{$xÇ#$þ +}ÌóU?ó(¨z˜ßÁJsË®¢õ¿ýx;Y.l Šp¹èñ÷¹e«…�&�š{ J©Û ¿……ã�ú[ör¬³çñ´N¸¸Òðeà­Ôafû*Ú{X5s�¶…åFK1f£K««8ÍÖ opý(㥅ÀÒxR«£~i+Üže¼¬-?Z®ôð«æP9‹$c�½H‰N,h��¹ *H1›&GK ¦HPß¿‚>U,¿Y^IøN  �Ï Œ¾´ì³B?êY•›Ñ6á¡(óª%L�¶²Ãý¿EÚ¿Ëìë—¸ZèË·™Ríòù Y]*_ÍôúÞyŸïœ÷™~Ô\³¹¥W(õœÒëÓþ»nàЗvØ©ç²,‡<’ ×±Lþ'(sW³ù+ÔU|5 0ÚeÈØÀòùÃ݇kÐ$O‚\—Å•7¹ýuµü3©K”³«ª¼¼¾¸ØÂB½Á¤t±É8LZ»š•�è„…<{°ÚØÆ*�åM•ÕHúlØÜÈ Î37WXXX¶Ô·©/rе�«Yó_ú�;8ݼ-°3´@¦Ç6üÙïÐÔCFþÒQD�ÚVûŽÛeüý‚åµ³ÃI Žß¾ÏÁ×*ÿŸÞ¼ðmVpãúª»Œ7¨7ṑإ}í mMmIîè)®(Â�ŒÄ±VÃæÐ6‰µì &]`ÇÖsdvmiÛ¬=Y˜:3ˆm&)וÏÓV}êDÍ­™øû§íuÝ'GÓ�’Ù—t=ï ±}ç„sg±ïâ¡s•cFN=àZ·2@Þ�ÝWßö8¨Þ‚Ÿœ ûÆ.Õ:|Gî?Yû¾ySóÖÛvÉm¿…XÍ–æ-Äw\ŠÙèè¤Õé¾aºöò¾¿ÜñÀ (¢:‹­ ìÔФf¬£“�šŽzÆ=ÝœšCNÌ+f¤Ð£‡5࣫ž–_ß(ûÛw\½<Öˆërxº ¿lõöGÚp·.¾¬»w{ñÔ[ÉQ†p(Ü CFV�Ó]幌ðw·î{+¾ˆ¾¾iU¾\ûÚämñj§:}ôØŠƒ«òœXÛ%b­›¶#×ufÞÃÙl”Gª×~Ím¶cù;«,w]wh%ÊîζH9%6{ ; ;9f^ žo}C髊®] ˜0£k[]@[õÁú*“]Ì•¬~5œ‚–ÁV}/Çþ•^p¯úý/Ó¹ºò×IR«Ä—2ÜÊ˶gîu¯„ÅkC„ç%@¼<×û 5Ô�àQ·Òï¸Èý‡7æÅG ]©¼õ2ÄÈ-…Ý*øl¸´oÐþOk]ò6EÞ÷µ»§³ÿyauzl-3.4.0/test/success/cygwin-info-zip.zip000066400000000000000000000004641521126516100210720ustar00rootroot00000000000000PK ÛKEQàV‡a.txtUT =*òS=*òSux Ò+z+asdf PK ÛKE�šöÀb.txtUT =*òS=*òSux Ò+z+bsdf PK ÛKEQàV‡¤�a.txtUT=*òSux Ò+z+PK ÛKE�šöÀ¤�Db.txtUT=*òSux Ò+z+PK–ˆyauzl-3.4.0/test/success/cygwin-info-zip/000077500000000000000000000000001521126516100203425ustar00rootroot00000000000000yauzl-3.4.0/test/success/cygwin-info-zip/a.txt000066400000000000000000000000051521126516100213160ustar00rootroot00000000000000asdf yauzl-3.4.0/test/success/cygwin-info-zip/b.txt000066400000000000000000000000051521126516100213170ustar00rootroot00000000000000bsdf yauzl-3.4.0/test/success/deflate.zip000066400000000000000000000056611521126516100174510ustar00rootroot00000000000000PK Eˆ Á)index.jsUT •WôS±WôSux èèÝZ[oÛÈ~÷¯˜ÕC#Á’¬Ûº†UoÑØÎv�\I¶Zô�"‡Ò $‡åŲ6ðï9sã 9”ìdŸj ‘Í9sΙï܇z —ä†ô¿5+èp—ƒÑúìž¿‰>%,¤…³MJñ‰Î..H‘ ¹¥YU ¹š°âÅA®¾%ò‘†¼ˆ�‚rIsŸE„Çý¤g<§ÙpPѲºÛ=Ë&,‹ùäw–Oáß`Lâ: +Ƴ!-Š1�g1Kèˆ|=#„ÅŸŽHµ+øžÀ¯kxò¬ä �&|; \FËë�Ù:U�>Ò4`˶ÃÑ·}¡4ÿHƒH<ÁZ°»"KÑý ÉÍÍ ™�Ûª.²µØ¡© àt;C÷dÈå Ù÷� ìóÉMzE‹@LQáOK%QȬ72�I%ÖŽiÎr:Ì Ò²œ–UÄëÊ(ñd~ë ªŸÎðó,åQ�ð=漨J¡5ø#~¬Ï øÂ?ò Ú�I$É&¿4Æ×Oo’ÕI2"ÍÑ8¨“êV=&•R¿AÑq¯8² ,��64ŒÅCy˜XðŠ££>êðùaÂK*6µô3°Ù’f~ðÿS¿X·lÔüCŒË*¨<§ÆÇå Ð{ Å¡”4(Â8 AŠ}PD%è\€ R•FJ¶ÍàCj/$\M‚²"1£‰È1 =+I@ ͱ`“ÐIB³mµƒ°ISˆ„©Í@=¿SÜE³�G4",‹ÉæPQÅžþc²ß±pGöÀ È^¡ �åö¬ÚA�ª¨£­{ ¦z»sDV\nc�Fª�Ñ 4¡òP VDøY x�aÓ«’ä¼,Yí‚J‚tö5¯Kt‚^CRZQP`�±•>ižÐ±�´£ª"AÛƒxuÊ6TpPi$�…bV”UÛNÀ޶Çš ¼8{“4ˆ¨ØeD©eÀ"“qd½a‘Ïþ^±ž ºJ ÜÊÅOhÓ²X¬ U<º‹³Çù ~ÖxHent³aSÇ1-ñ;HÓ”�»÷;o P11E–£u‹)0Ìèž¼ AB™È¡‹”V¹<•î-waŠ~Ïïy,âSŒÉlldÜfëÆ±'iõ‡0^0D]hg¡5é³È(àñsrCæí⣅ùí—¬Z.ÞÞÙˆü€õôqv9ûqµù +DIŲš6Õɤ“˜×à{ÒqÀõx—´º&0ϰ�è9a£‘ÅC{Òkm"¥Žè‹@(Zškkno_Áö÷uºA&ÐYùÅÑ(š[5ÐüZYg@­]?Ø�HcCt½û¢àÅp�BŠgÜb¢òè�qHŒuŽÅ…F×Dâ*è2Á[bÚȲ‘„ã]Âñî�z�iƇš ´·\9ˆtw¢g, Ït�æ´ðªqÖÌ2Jñ>J5}�Ê aei�ŽºÞ âÏü^‘ú%]6’°ßþ™f¡Èë"Ç ¿ÁºŸ[‹ýV’ü*)^³ê ¬÷p¿j¸ÏU‹™c�d(ôy‘Å8l߉µ¦¦íÖ-7†¿¼ýIyÄb"÷V,¥{$xÇ#$þ +}ÌóU?ó(¨z˜ßÁJsË®¢õ¿ýx;Y.l Šp¹èñ÷¹e«…�&�š{ J©Û ¿……ã�ú[ör¬³çñ´N¸¸Òðeà­Ôafû*Ú{X5s�¶…åFK1f£K««8ÍÖ opý(㥅ÀÒxR«£~i+Üže¼¬-?Z®ôð«æP9‹$c�½H‰N,h��¹ *H1›&GK ¦HPß¿‚>U,¿Y^IøN  �Ï Œ¾´ì³B?êY•›Ñ6á¡(óª%L�¶²Ãý¿EÚ¿Ëìë—¸ZèË·™Ríòù Y]*_ÍôúÞyŸïœ÷™~Ô\³¹¥W(õœÒëÓþ»nàЗvØ©ç²,‡<’ ×±Lþ'(sW³ù+ÔU|5 0ÚeÈØÀòùÃ݇kÐ$O‚\—Å•7¹ýuµü3©K”³«ª¼¼¾¸ØÂB½Á¤t±É8LZ»š•�è„…<{°ÚØÆ*�åM•ÕHúlØÜÈ Î37WXXX¶Ô·©/rе�«Yó_ú�;8ݼ-°3´@¦Ç6üÙïÐÔCFþÒQD�ÚVûŽÛeüý‚åµ³ÃI Žß¾ÏÁ×*ÿŸÞ¼ðmVpãúª»Œ7¨7ṑإ}í mMmIîè)®(Â�ŒÄ±VÃæÐ6‰µì &]`ÇÖsdvmiÛ¬=Y˜:3ˆm&)וÏÓV}êDÍ­™øû§íuÝ'GÓ�’Ù—t=ï ±}ç„sg±ïâ¡s•cFN=àZ·2@Þ�ÝWßö8¨Þ‚Ÿœ ûÆ.Õ:|Gî?Yû¾ySóÖÛvÉm¿…XÍ–æ-Äw\ŠÙèè¤Õé¾aºöò¾¿ÜñÀ (¢:‹­ ìÔФf¬£“�šŽzÆ=ÝœšCNÌ+f¤Ð£‡5࣫ž–_ß(ûÛw\½<Öˆërxº ¿lõöGÚp·.¾¬»w{ñÔ[ÉQ†p(Ü CFV�Ó]幌ðw·î{+¾ˆ¾¾iU¾\ûÚämñj§:}ôØŠƒ«òœXÛ%b­›¶#×ufÞÃÙl”Gª×~Ím¶cù;«,w]wh%ÊîζH9%6{ ; ;9f^ žo}C髊®] ˜0£k[]@[õÁú*“]Ì•¬~5œ‚–ÁV}/Çþ•^p¯úý/Ó¹ºò×IR«Ä—2ÜÊ˶gîu¯„ÅkC„ç%@¼<×û 5Ô�àQ·Òï¸Èý‡7æÅG ]©¼õ2ÄÈ-…Ý*øl¸´oÐþOk]ò6EÞ÷µ»§³ÿPK Eˆ Á)´�index.jsUT•WôSux èèPKNM yauzl-3.4.0/test/success/deflate/000077500000000000000000000000001521126516100167155ustar00rootroot00000000000000yauzl-3.4.0/test/success/deflate/index.js000066400000000000000000000247011521126516100203660ustar00rootroot00000000000000var fs = require("fs"); var FdSlicer = require("fd-slicer"); // cd - Central Directory // cdr - Central Directory Record // eocdr - End of Central Directory Record open("test/cygwin-info-zip.zip", function(err, zipfile) { if (err) throw err; console.log("entries:", zipfile.entriesRemaining()); keepReading(); function keepReading() { if (zipfile.entriesRemaining() === 0) return; zipfile.readEntry(function(err, entry) { if (err) throw err; console.log(entry); zipfile.openReadStream(entry, function(err, readStream) { if (err) throw err; readStream.pipe(process.stdout); }); keepReading(); }); } }); module.exports.open = open; function open(path, callback) { if (callback == null) callback = defaultCallback; fs.open(path, "r", function(err, fd) { if (err) return callback(err); fopen(fd, function(err, zipfile) { if (err) fs.close(fd, defaultCallback); callback(err, zipfile); }); }); } module.exports.fopen = fopen; function fopen(fd, callback) { if (callback == null) callback = defaultCallback; fs.fstat(fd, function(err, stats) { if (err) return callback(err); verbose("searching backwards for the eocdr signature"); // the last field of the eocdr is a variable-length comment. // the comment size is encoded in a 2-byte field in the eocdr, which we can't find without trudging backwards through the comment to find it. // as a consequence of this design decision, it's possible to have ambiguous zip file metadata if, for example, a coherent eocdr was in the comment. // we search backwards for the first eocdr signature, and hope that whoever made the zip file was smart enough to forbid the eocdr signature in the comment. var eocdrWithoutCommentSize = 22; var maxCommentSize = 0x10000; // 2-byte size var bufferSize = Math.min(eocdrWithoutCommentSize + maxCommentSize, stats.size); var buffer = new Buffer(bufferSize); var bufferReadStart = stats.size - buffer.length; readNoEof(fd, buffer, 0, bufferSize, bufferReadStart, function(err) { if (err) return callback(err); for (var i = bufferSize - eocdrWithoutCommentSize; i >= 0; i -= 1) { if (buffer.readUInt32LE(i) !== 0x06054b50) continue; verbose("found eocdr at offset: " + (bufferReadStart + i)); var eocdrBuffer = buffer.slice(i); // 0 - End of central directory signature = 0x06054b50 // 4 - Number of this disk var diskNumber = eocdrBuffer.readUInt16LE(4); if (diskNumber !== 0) return callback(new Error("multi-disk zip files are not supported: found disk number: " + diskNumber)); // 6 - Disk where central directory starts // 8 - Number of central directory records on this disk // 10 - Total number of central directory records var entryCount = eocdrBuffer.readUInt16LE(10); // 12 - Size of central directory (bytes) // 16 - Offset of start of central directory, relative to start of archive var cdOffset = eocdrBuffer.readUInt32LE(16); // 20 - Comment length var commentLength = eocdrBuffer.readUInt16LE(20); var expectedCommentLength = eocdrBuffer.length - eocdrWithoutCommentSize; if (commentLength !== expectedCommentLength) { return callback(new Error("invalid comment length. expected: " + expectedCommentLength + ". found: " + commentLength)); } // 22 - Comment var comment = new Buffer(commentLength); // the comment length is typcially 0. // copy from the original buffer to make sure we're not pinning it from being GC'ed. eocdrBuffer.copy(comment, 0, 22, eocdrBuffer.length); return callback(null, new ZipFile(fd, cdOffset, entryCount, comment)); } callback(new Error("end of central directory record signature not found")); }); }); } function ZipFile(fd, cdOffset, entryCount, comment) { this.fdSlicer = new FdSlicer(fd); this.readEntryCursor = cdOffset; this.entryCount = entryCount; this.comment = comment; this.entriesRead = 0; this.isReadingEntry = false; } ZipFile.prototype.close = function(callback) { if (callback == null) callback = defaultCallback; fs.close(this.fdSlicer.fd, callback); }; ZipFile.prototype.readEntries = function(callback) { var self = this; if (callback == null) callback = defaultCallback; var entries = []; keepReading(); function keepReading() { self.readEntry(function(err, entry) { if (err) return callback(err); entries.push(entry); if (self.entriesRemaining() > 0) { keepReading(); } else { callback(null, entries); } }); } }; ZipFile.prototype.entriesRemaining = function() { return this.entryCount - this.entriesRead; }; ZipFile.prototype.readEntry = function(callback) { var self = this; if (self.isReadingEntry) throw new Error("readEntry already in progress"); self.isReadingEntry = true; if (callback == null) callback = defaultCallback; var buffer = new Buffer(46); readFdSlicerNoEof(this.fdSlicer, buffer, 0, buffer.length, this.readEntryCursor, function(err) { if (err) return callback(err); var entry = {}; // 0 - Central directory file header signature var signature = buffer.readUInt32LE(0); if (signature !== 0x02014b50) return callback(new Error("invalid central directory file header signature: 0x" + signature.toString(16))); // 4 - Version made by entry.versionMadeBy = buffer.readUInt16LE(4); // 6 - Version needed to extract (minimum) entry.versionNeededToExtract = buffer.readUInt16LE(6); // 8 - General purpose bit flag entry.generalPurposeBitFlag = buffer.readUInt16LE(8); // 10 - Compression method entry.compressionMethod = buffer.readUInt16LE(10); // 12 - File last modification time entry.lastModFileTime = buffer.readUInt16LE(12); // 14 - File last modification date entry.lastModFileDate = buffer.readUInt16LE(14); // 16 - CRC-32 entry.crc32 = buffer.readUInt32LE(16); // 20 - Compressed size entry.compressedSize = buffer.readUInt32LE(20); // 24 - Uncompressed size entry.uncompressedSize = buffer.readUInt32LE(24); // 28 - File name length (n) entry.fileNameLength = buffer.readUInt16LE(28); // 30 - Extra field length (m) entry.extraFieldLength = buffer.readUInt16LE(30); // 32 - File comment length (k) entry.fileCommentLength = buffer.readUInt16LE(32); // 34 - Disk number where file starts // 36 - Internal file attributes entry.internalFileAttributes = buffer.readUInt16LE(36); // 38 - External file attributes entry.externalFileAttributes = buffer.readUInt32LE(38); // 42 - Relative offset of local file header entry.relativeOffsetOfLocalHeader = buffer.readUInt32LE(42); self.readEntryCursor += 46; buffer = new Buffer(entry.fileNameLength + entry.extraFieldLength + entry.fileCommentLength); readFdSlicerNoEof(self.fdSlicer, buffer, 0, buffer.length, self.readEntryCursor, function(err) { if (err) return callback(err); // 46 - File name var encoding = entry.generalPurposeBitFlag & 0x800 ? "utf8" : "ascii"; // TODO: replace ascii with CP437 using https://github.com/bnoordhuis/node-iconv entry.fileName = buffer.toString(encoding, 0, entry.fileNameLength); // 46+n - Extra field var fileCommentStart = entry.fileNameLength + entry.extraFieldLength; var extraFieldBuffer = buffer.slice(entry.fileNameLength, fileCommentStart); entry.extraFields = []; var i = 0; while (i < extraFieldBuffer.length) { var headerId = extraFieldBuffer.readUInt16LE(i + 0); var dataSize = extraFieldBuffer.readUInt16LE(i + 2); var dataStart = i + 4; var dataEnd = dataStart + dataSize; var dataBuffer = new Buffer(dataSize); extraFieldBuffer.copy(dataBuffer, 0, dataStart, dataEnd); entry.extraFields.push({ id: headerId, data: dataBuffer, }); i = dataEnd; } // 46+n+m - File comment entry.fileComment = buffer.toString(encoding, fileCommentStart, fileCommentStart + entry.fileCommentLength); self.readEntryCursor += buffer.length; self.entriesRead += 1; self.isReadingEntry = false; callback(null, entry); }); }); }; ZipFile.prototype.openReadStream = function(entry, callback) { var self = this; var buffer = new Buffer(30); readFdSlicerNoEof(self.fdSlicer, buffer, 0, buffer.length, entry.relativeOffsetOfLocalHeader, function(err) { if (err) return callback(err); // 0 - Local file header signature = 0x04034b50 var signature = buffer.readUInt32LE(0); if (signature !== 0x04034b50) callback(new Error("invalid local file header signature: 0x" + signature.toString(16))); // all this should be redundant // 4 - Version needed to extract (minimum) // 6 - General purpose bit flag // 8 - Compression method // 10 - File last modification time // 12 - File last modification date // 14 - CRC-32 // 18 - Compressed size // 22 - Uncompressed size // 26 - File name length (n) var fileNameLength = buffer.readUInt16LE(26); // 28 - Extra field length (m) var extraFieldLength = buffer.readUInt16LE(28); // 30 - File name // 30+n - Extra field var localFileHeaderEnd = entry.relativeOffsetOfLocalHeader + buffer.length + fileNameLength + extraFieldLength; if (entry.compressionMethod === 0) { // 0 - The file is stored (no compression) } else { return callback(new Error("unsupported compression method: " + entry.compressionMethod)); } var fileDataStart = localFileHeaderEnd; var fileDataEnd = fileDataStart + entry.compressedSize; var readStream = self.fdSlicer.createReadStream({start: fileDataStart, end: fileDataEnd}); callback(null, readStream); }); }; function verbose(message) { console.log(message); } function readNoEof(fd, buffer, offset, length, position, callback) { fs.read(fd, buffer, offset, length, position, function(err, bytesRead) { if (err) return callback(err); if (bytesRead < length) return callback(new Error("unexpected EOF")); callback(null, buffer); }); } function readFdSlicerNoEof(fdSlicer, buffer, offset, length, position, callback) { fdSlicer.read(buffer, offset, length, position, function(err, bytesRead) { if (err) return callback(err); if (bytesRead < length) return callback(new Error("unexpected EOF")); callback(null, buffer); }); } function defaultCallback(err) { if (err) throw err; } yauzl-3.4.0/test/success/directories.zip000066400000000000000000000006541521126516100203560ustar00rootroot00000000000000PK ä­Ea/UT ÌøSøSux èèPK ä­Ea/a.txtUT ÌøSøSux èèPK »Eb/UT ¯3øS´3øSux èèPK ä­EýAa/UTÌøSux èèPK ä­E´�<a/a.txtUTÌøSux èèPK »EýA}b/UT¯3øSux èèPKݹyauzl-3.4.0/test/success/directories/000077500000000000000000000000001521126516100176255ustar00rootroot00000000000000yauzl-3.4.0/test/success/directories/a/000077500000000000000000000000001521126516100200455ustar00rootroot00000000000000yauzl-3.4.0/test/success/directories/a/a.txt000066400000000000000000000000001521126516100210140ustar00rootroot00000000000000yauzl-3.4.0/test/success/directories/b/000077500000000000000000000000001521126516100200465ustar00rootroot00000000000000yauzl-3.4.0/test/success/directories/b/.git_please_make_this_directory000066400000000000000000000000001521126516100262610ustar00rootroot00000000000000yauzl-3.4.0/test/success/empty.zip000066400000000000000000000000261521126516100171710ustar00rootroot00000000000000PKyauzl-3.4.0/test/success/empty/000077500000000000000000000000001521126516100164475ustar00rootroot00000000000000yauzl-3.4.0/test/success/empty/.git_please_make_this_directory000066400000000000000000000000001521126516100246620ustar00rootroot00000000000000yauzl-3.4.0/test/success/everything.zip000066400000000000000000010374671521126516100202430ustar00rootroot00000000000000PK ¶]¸\Pü»‚0x21000UT (j>jux èdPK á]¸\a/UT ujˆjux èdPK á]¸\Oa/longlonglonglonglonglonglonglonglonglonglonglonglonglonglongkindalongname.txtUT ujäjux èdPK ^¸\a/b/UT ½j¾jux èdPK Ã]¸\a/b/c/UT >jäjux èdPKÃ]¸\Pü»‚“ a/b/c/0x21000UT >jäjux èdíÁ‚ ÿ¯nH@/PK ^¸\a/b/000UT »jäjux èdPK ^¸\a/b/001UT »jäjux èdPK ^¸\a/b/002UT »jäjux èdPK ^¸\a/b/003UT »jäjux èdPK ^¸\a/b/004UT »jäjux èdPK ^¸\a/b/005UT »jäjux èdPK ^¸\a/b/006UT »jäjux èdPK ^¸\a/b/007UT »jäjux èdPK ^¸\a/b/008UT »jäjux èdPK ^¸\a/b/009UT »jäjux èdPK ^¸\a/b/010UT »jäjux èdPK ^¸\a/b/011UT »jäjux èdPK ^¸\a/b/012UT »jäjux èdPK ^¸\a/b/013UT »jäjux èdPK ^¸\a/b/014UT »jäjux èdPK ^¸\a/b/015UT »jäjux èdPK ^¸\a/b/016UT »jäjux èdPK ^¸\a/b/017UT »jäjux èdPK ^¸\a/b/018UT »jäjux èdPK ^¸\a/b/019UT »jäjux èdPK ^¸\a/b/020UT »jäjux èdPK ^¸\a/b/021UT »jäjux èdPK ^¸\a/b/022UT »jäjux èdPK ^¸\a/b/023UT »jäjux èdPK ^¸\a/b/024UT »jäjux èdPK ^¸\a/b/025UT »jäjux èdPK ^¸\a/b/026UT »jäjux èdPK ^¸\a/b/027UT »jäjux èdPK ^¸\a/b/028UT »jäjux èdPK ^¸\a/b/029UT »jäjux èdPK ^¸\a/b/030UT »jäjux èdPK ^¸\a/b/031UT »jäjux èdPK ^¸\a/b/032UT »jäjux èdPK ^¸\a/b/033UT »jäjux èdPK ^¸\a/b/034UT »jäjux èdPK ^¸\a/b/035UT »jäjux èdPK ^¸\a/b/036UT »jäjux èdPK ^¸\a/b/037UT »jäjux èdPK ^¸\a/b/038UT »jäjux èdPK ^¸\a/b/039UT »jäjux èdPK ^¸\a/b/040UT »jäjux èdPK ^¸\a/b/041UT »jäjux èdPK ^¸\a/b/042UT »jäjux èdPK ^¸\a/b/043UT »jäjux èdPK ^¸\a/b/044UT »jäjux èdPK ^¸\a/b/045UT »jäjux èdPK ^¸\a/b/046UT »jäjux èdPK ^¸\a/b/047UT »jäjux èdPK ^¸\a/b/048UT »jäjux èdPK ^¸\a/b/049UT »jäjux èdPK ^¸\a/b/050UT »jäjux èdPK ^¸\a/b/051UT »jäjux èdPK ^¸\a/b/052UT »jäjux èdPK ^¸\a/b/053UT »jäjux èdPK ^¸\a/b/054UT »jäjux èdPK ^¸\a/b/055UT »jäjux èdPK ^¸\a/b/056UT »jäjux èdPK ^¸\a/b/057UT »jäjux èdPK ^¸\a/b/058UT »jäjux èdPK ^¸\a/b/059UT »jäjux èdPK ^¸\a/b/060UT »jäjux èdPK ^¸\a/b/061UT »jäjux èdPK ^¸\a/b/062UT »jäjux èdPK ^¸\a/b/063UT »jäjux èdPK ^¸\a/b/064UT »jäjux èdPK ^¸\a/b/065UT »jäjux èdPK ^¸\a/b/066UT »jäjux èdPK ^¸\a/b/067UT »jäjux èdPK ^¸\a/b/068UT »jäjux èdPK ^¸\a/b/069UT »jäjux èdPK ^¸\a/b/070UT »jäjux èdPK ^¸\a/b/071UT »jäjux èdPK ^¸\a/b/072UT »jäjux èdPK ^¸\a/b/073UT »jäjux èdPK ^¸\a/b/074UT »jäjux èdPK ^¸\a/b/075UT »jäjux èdPK ^¸\a/b/076UT »jäjux èdPK ^¸\a/b/077UT »jäjux èdPK ^¸\a/b/078UT »jäjux èdPK ^¸\a/b/079UT »jäjux èdPK ^¸\a/b/080UT »jäjux èdPK ^¸\a/b/081UT »jäjux èdPK ^¸\a/b/082UT »jäjux èdPK ^¸\a/b/083UT »jäjux èdPK ^¸\a/b/084UT »jäjux èdPK ^¸\a/b/085UT »jäjux èdPK ^¸\a/b/086UT »jäjux èdPK ^¸\a/b/087UT »jäjux èdPK ^¸\a/b/088UT »jäjux èdPK ^¸\a/b/089UT »jäjux èdPK ^¸\a/b/090UT »jäjux èdPK ^¸\a/b/091UT »jäjux èdPK ^¸\a/b/092UT »jäjux èdPK ^¸\a/b/093UT »jäjux èdPK ^¸\a/b/094UT »jäjux èdPK ^¸\a/b/095UT »jäjux èdPK ^¸\a/b/096UT »jäjux èdPK ^¸\a/b/097UT »jäjux èdPK ^¸\a/b/098UT »jäjux èdPK ^¸\a/b/099UT »jäjux èdPK ^¸\a/b/100UT »jäjux èdPK ^¸\a/b/101UT »jäjux èdPK ^¸\a/b/102UT »jäjux èdPK ^¸\a/b/103UT »jäjux èdPK ^¸\a/b/104UT »jäjux èdPK ^¸\a/b/105UT »jäjux èdPK ^¸\a/b/106UT »jäjux èdPK ^¸\a/b/107UT »jäjux èdPK ^¸\a/b/108UT »jäjux èdPK ^¸\a/b/109UT »jäjux èdPK ^¸\a/b/110UT »jäjux èdPK ^¸\a/b/111UT »jäjux èdPK ^¸\a/b/112UT »jäjux èdPK ^¸\a/b/113UT »jäjux èdPK ^¸\a/b/114UT »jäjux èdPK ^¸\a/b/115UT »jäjux èdPK ^¸\a/b/116UT »jäjux èdPK ^¸\a/b/117UT »jäjux èdPK ^¸\a/b/118UT »jäjux èdPK ^¸\a/b/119UT »jäjux èdPK ^¸\a/b/120UT »jäjux èdPK ^¸\a/b/121UT »jäjux èdPK ^¸\a/b/122UT »jäjux èdPK ^¸\a/b/123UT »jäjux èdPK ^¸\a/b/124UT »jäjux èdPK ^¸\a/b/125UT »jäjux èdPK ^¸\a/b/126UT »jäjux èdPK ^¸\a/b/127UT »jäjux èdPK ^¸\a/b/128UT »jäjux èdPK ^¸\a/b/129UT »jäjux èdPK ^¸\a/b/130UT »jäjux èdPK ^¸\a/b/131UT »jäjux èdPK ^¸\a/b/132UT »jäjux èdPK ^¸\a/b/133UT »jäjux èdPK ^¸\a/b/134UT »jäjux èdPK ^¸\a/b/135UT »jäjux èdPK ^¸\a/b/136UT »jäjux èdPK ^¸\a/b/137UT »jäjux èdPK ^¸\a/b/138UT »jäjux èdPK ^¸\a/b/139UT »jäjux èdPK ^¸\a/b/140UT »jäjux èdPK ^¸\a/b/141UT »jäjux èdPK ^¸\a/b/142UT »jäjux èdPK ^¸\a/b/143UT »jäjux èdPK ^¸\a/b/144UT »jäjux èdPK ^¸\a/b/145UT »jäjux èdPK ^¸\a/b/146UT »jäjux èdPK ^¸\a/b/147UT »jäjux èdPK ^¸\a/b/148UT »jäjux èdPK ^¸\a/b/149UT »jäjux èdPK ^¸\a/b/150UT »jäjux èdPK ^¸\a/b/151UT »jäjux èdPK ^¸\a/b/152UT »jäjux èdPK ^¸\a/b/153UT »jäjux èdPK ^¸\a/b/154UT »jäjux èdPK ^¸\a/b/155UT »jäjux èdPK ^¸\a/b/156UT »jäjux èdPK ^¸\a/b/157UT »jäjux èdPK ^¸\a/b/158UT »jäjux èdPK ^¸\a/b/159UT »jäjux èdPK ^¸\a/b/160UT »jäjux èdPK ^¸\a/b/161UT »jäjux èdPK ^¸\a/b/162UT »jäjux èdPK ^¸\a/b/163UT »jäjux èdPK ^¸\a/b/164UT »jäjux èdPK ^¸\a/b/165UT »jäjux èdPK ^¸\a/b/166UT »jäjux èdPK ^¸\a/b/167UT »jäjux èdPK ^¸\a/b/168UT »jäjux èdPK ^¸\a/b/169UT »jäjux èdPK ^¸\a/b/170UT »jäjux èdPK ^¸\a/b/171UT »jäjux èdPK ^¸\a/b/172UT »jäjux èdPK ^¸\a/b/173UT »jäjux èdPK ^¸\a/b/174UT »jäjux èdPK ^¸\a/b/175UT »jäjux èdPK ^¸\a/b/176UT »jäjux èdPK ^¸\a/b/177UT »jäjux èdPK ^¸\a/b/178UT »jäjux èdPK ^¸\a/b/179UT »jäjux èdPK ^¸\a/b/180UT »jäjux èdPK ^¸\a/b/181UT »jäjux èdPK ^¸\a/b/182UT »jäjux èdPK ^¸\a/b/183UT »jäjux èdPK ^¸\a/b/184UT »jäjux èdPK ^¸\a/b/185UT »jäjux èdPK ^¸\a/b/186UT »jäjux èdPK ^¸\a/b/187UT »jäjux èdPK ^¸\a/b/188UT »jäjux èdPK ^¸\a/b/189UT »jäjux èdPK ^¸\a/b/190UT »jäjux èdPK ^¸\a/b/191UT »jäjux èdPK ^¸\a/b/192UT »jäjux èdPK ^¸\a/b/193UT »jäjux èdPK ^¸\a/b/194UT »jäjux èdPK ^¸\a/b/195UT »jäjux èdPK ^¸\a/b/196UT »jäjux èdPK ^¸\a/b/197UT »jäjux èdPK ^¸\a/b/198UT »jäjux èdPK ^¸\a/b/199UT »jäjux èdPK ^¸\a/b/200UT »jäjux èdPK ^¸\a/b/201UT »jäjux èdPK ^¸\a/b/202UT »jäjux èdPK ^¸\a/b/203UT »jäjux èdPK ^¸\a/b/204UT »jäjux èdPK ^¸\a/b/205UT »jäjux èdPK ^¸\a/b/206UT »jäjux èdPK ^¸\a/b/207UT »jäjux èdPK ^¸\a/b/208UT »jäjux èdPK ^¸\a/b/209UT »jäjux èdPK ^¸\a/b/210UT »jäjux èdPK ^¸\a/b/211UT »jäjux èdPK ^¸\a/b/212UT »jäjux èdPK ^¸\a/b/213UT »jäjux èdPK ^¸\a/b/214UT »jäjux èdPK ^¸\a/b/215UT »jäjux èdPK ^¸\a/b/216UT »jäjux èdPK ^¸\a/b/217UT »jäjux èdPK ^¸\a/b/218UT »jäjux èdPK ^¸\a/b/219UT »jäjux èdPK ^¸\a/b/220UT »jäjux èdPK ^¸\a/b/221UT »jäjux èdPK ^¸\a/b/222UT »jäjux èdPK ^¸\a/b/223UT »jäjux èdPK ^¸\a/b/224UT »jäjux èdPK ^¸\a/b/225UT »jäjux èdPK ^¸\a/b/226UT »jäjux èdPK ^¸\a/b/227UT »jäjux èdPK ^¸\a/b/228UT »jäjux èdPK ^¸\a/b/229UT »jäjux èdPK ^¸\a/b/230UT »jäjux èdPK ^¸\a/b/231UT »jäjux èdPK ^¸\a/b/232UT »jäjux èdPK ^¸\a/b/233UT »jäjux èdPK ^¸\a/b/234UT »jäjux èdPK ^¸\a/b/235UT »jäjux èdPK ^¸\a/b/236UT »jäjux èdPK ^¸\a/b/237UT »jäjux èdPK ^¸\a/b/238UT »jäjux èdPK ^¸\a/b/239UT »jäjux èdPK ^¸\a/b/240UT »jäjux èdPK ^¸\a/b/241UT »jäjux èdPK ^¸\a/b/242UT »jäjux èdPK ^¸\a/b/243UT »jäjux èdPK ^¸\a/b/244UT »jäjux èdPK ^¸\a/b/245UT »jäjux èdPK ^¸\a/b/246UT »jäjux èdPK ^¸\a/b/247UT »jäjux èdPK ^¸\a/b/248UT »jäjux èdPK ^¸\a/b/249UT »jäjux èdPK ^¸\a/b/250UT »jäjux èdPK ^¸\a/b/251UT »jäjux èdPK ^¸\a/b/252UT »jäjux èdPK ^¸\a/b/253UT »jäjux èdPK ^¸\a/b/254UT »jäjux èdPK ^¸\a/b/255UT »jäjux èdPK ^¸\a/b/256UT »jäjux èdPK ^¸\a/b/257UT »jäjux èdPK ^¸\a/b/258UT »jäjux èdPK ^¸\a/b/259UT »jäjux èdPK ^¸\a/b/260UT »jäjux èdPK ^¸\a/b/261UT »jäjux èdPK ^¸\a/b/262UT »jäjux èdPK ^¸\a/b/263UT »jäjux èdPK ^¸\a/b/264UT »jäjux èdPK ^¸\a/b/265UT »jäjux èdPK ^¸\a/b/266UT »jäjux èdPK ^¸\a/b/267UT ¼jäjux èdPK ^¸\a/b/268UT ¼jäjux èdPK ^¸\a/b/269UT ¼jäjux èdPK ^¸\a/b/270UT ¼jäjux èdPK ^¸\a/b/271UT ¼jäjux èdPK ^¸\a/b/272UT ¼jäjux èdPK ^¸\a/b/273UT ¼jäjux èdPK ^¸\a/b/274UT ¼jäjux èdPK ^¸\a/b/275UT ¼jäjux èdPK ^¸\a/b/276UT ¼jäjux èdPK ^¸\a/b/277UT ¼jäjux èdPK ^¸\a/b/278UT ¼jäjux èdPK ^¸\a/b/279UT ¼jäjux èdPK ^¸\a/b/280UT ¼jäjux èdPK ^¸\a/b/281UT ¼jäjux èdPK ^¸\a/b/282UT ¼jäjux èdPK ^¸\a/b/283UT ¼jäjux èdPK ^¸\a/b/284UT ¼jäjux èdPK ^¸\a/b/285UT ¼jäjux èdPK ^¸\a/b/286UT ¼jäjux èdPK ^¸\a/b/287UT ¼jäjux èdPK ^¸\a/b/288UT ¼jäjux èdPK ^¸\a/b/289UT ¼jäjux èdPK ^¸\a/b/290UT ¼jäjux èdPK ^¸\a/b/291UT ¼jäjux èdPK ^¸\a/b/292UT ¼jäjux èdPK ^¸\a/b/293UT ¼jäjux èdPK ^¸\a/b/294UT ¼jäjux èdPK ^¸\a/b/295UT ¼jäjux èdPK ^¸\a/b/296UT ¼jäjux èdPK ^¸\a/b/297UT ¼jäjux èdPK ^¸\a/b/298UT ¼jäjux èdPK ^¸\a/b/299UT ¼jäjux èdPK ^¸\a/b/300UT ¼jäjux èdPK ^¸\a/b/301UT ¼jäjux èdPK ^¸\a/b/302UT ¼jäjux èdPK ^¸\a/b/303UT ¼jäjux èdPK ^¸\a/b/304UT ¼jäjux èdPK ^¸\a/b/305UT ¼jäjux èdPK ^¸\a/b/306UT ¼jäjux èdPK ^¸\a/b/307UT ¼jäjux èdPK ^¸\a/b/308UT ¼jäjux èdPK ^¸\a/b/309UT ¼jäjux èdPK ^¸\a/b/310UT ¼jäjux èdPK ^¸\a/b/311UT ¼jäjux èdPK ^¸\a/b/312UT ¼jäjux èdPK ^¸\a/b/313UT ¼jäjux èdPK ^¸\a/b/314UT ¼jäjux èdPK ^¸\a/b/315UT ¼jäjux èdPK ^¸\a/b/316UT ¼jäjux èdPK ^¸\a/b/317UT ¼jäjux èdPK ^¸\a/b/318UT ¼jäjux èdPK ^¸\a/b/319UT ¼jäjux èdPK ^¸\a/b/320UT ¼jäjux èdPK ^¸\a/b/321UT ¼jäjux èdPK ^¸\a/b/322UT ¼jäjux èdPK ^¸\a/b/323UT ¼jäjux èdPK ^¸\a/b/324UT ¼jäjux èdPK ^¸\a/b/325UT ¼jäjux èdPK ^¸\a/b/326UT ¼jäjux èdPK ^¸\a/b/327UT ¼jäjux èdPK ^¸\a/b/328UT ¼jäjux èdPK ^¸\a/b/329UT ¼jäjux èdPK ^¸\a/b/330UT ¼jäjux èdPK ^¸\a/b/331UT ¼jäjux èdPK ^¸\a/b/332UT ¼jäjux èdPK ^¸\a/b/333UT ¼jäjux èdPK ^¸\a/b/334UT ¼jäjux èdPK ^¸\a/b/335UT ¼jäjux èdPK ^¸\a/b/336UT ¼jäjux èdPK ^¸\a/b/337UT ¼jäjux èdPK ^¸\a/b/338UT ¼jäjux èdPK ^¸\a/b/339UT ¼jäjux èdPK ^¸\a/b/340UT ¼jäjux èdPK ^¸\a/b/341UT ¼jäjux èdPK ^¸\a/b/342UT ¼jäjux èdPK ^¸\a/b/343UT ¼jäjux èdPK ^¸\a/b/344UT ¼jäjux èdPK ^¸\a/b/345UT ¼jäjux èdPK ^¸\a/b/346UT ¼jäjux èdPK ^¸\a/b/347UT ¼jäjux èdPK ^¸\a/b/348UT ¼jäjux èdPK ^¸\a/b/349UT ¼jäjux èdPK ^¸\a/b/350UT ¼jäjux èdPK ^¸\a/b/351UT ¼jäjux èdPK ^¸\a/b/352UT ¼jäjux èdPK ^¸\a/b/353UT ¼jäjux èdPK ^¸\a/b/354UT ¼jäjux èdPK ^¸\a/b/355UT ¼jäjux èdPK ^¸\a/b/356UT ¼jäjux èdPK ^¸\a/b/357UT ¼jäjux èdPK ^¸\a/b/358UT ¼jäjux èdPK ^¸\a/b/359UT ¼jäjux èdPK ^¸\a/b/360UT ¼jäjux èdPK ^¸\a/b/361UT ¼jäjux èdPK ^¸\a/b/362UT ¼jäjux èdPK ^¸\a/b/363UT ¼jäjux èdPK ^¸\a/b/364UT ¼jäjux èdPK ^¸\a/b/365UT ¼jäjux èdPK ^¸\a/b/366UT ¼jäjux èdPK ^¸\a/b/367UT ¼jäjux èdPK ^¸\a/b/368UT ¼jäjux èdPK ^¸\a/b/369UT ¼jäjux èdPK ^¸\a/b/370UT ¼jäjux èdPK ^¸\a/b/371UT ¼jäjux èdPK ^¸\a/b/372UT ¼jäjux èdPK ^¸\a/b/373UT ¼jäjux èdPK ^¸\a/b/374UT ¼jäjux èdPK ^¸\a/b/375UT ¼jäjux èdPK ^¸\a/b/376UT ¼jäjux èdPK ^¸\a/b/377UT ¼jäjux èdPK ^¸\a/b/378UT ¼jäjux èdPK ^¸\a/b/379UT ¼jäjux èdPK ^¸\a/b/380UT ¼jäjux èdPK ^¸\a/b/381UT ¼jäjux èdPK ^¸\a/b/382UT ¼jäjux èdPK ^¸\a/b/383UT ¼jäjux èdPK ^¸\a/b/384UT ¼jäjux èdPK ^¸\a/b/385UT ¼jäjux èdPK ^¸\a/b/386UT ¼jäjux èdPK ^¸\a/b/387UT ¼jäjux èdPK ^¸\a/b/388UT ¼jäjux èdPK ^¸\a/b/389UT ¼jäjux èdPK ^¸\a/b/390UT ¼jäjux èdPK ^¸\a/b/391UT ¼jäjux èdPK ^¸\a/b/392UT ¼jäjux èdPK ^¸\a/b/393UT ¼jäjux èdPK ^¸\a/b/394UT ¼jäjux èdPK ^¸\a/b/395UT ¼jäjux èdPK ^¸\a/b/396UT ¼jäjux èdPK ^¸\a/b/397UT ¼jäjux èdPK ^¸\a/b/398UT ¼jäjux èdPK ^¸\a/b/399UT ¼jäjux èdPK ^¸\a/b/400UT ¼jäjux èdPK ^¸\a/b/401UT ¼jäjux èdPK ^¸\a/b/402UT ¼jäjux èdPK ^¸\a/b/403UT ¼jäjux èdPK ^¸\a/b/404UT ¼jäjux èdPK ^¸\a/b/405UT ¼jäjux èdPK ^¸\a/b/406UT ¼jäjux èdPK ^¸\a/b/407UT ¼jäjux èdPK ^¸\a/b/408UT ¼jäjux èdPK ^¸\a/b/409UT ¼jäjux èdPK ^¸\a/b/410UT ¼jäjux èdPK ^¸\a/b/411UT ¼jäjux èdPK ^¸\a/b/412UT ¼jäjux èdPK ^¸\a/b/413UT ¼jäjux èdPK ^¸\a/b/414UT ¼jäjux èdPK ^¸\a/b/415UT ¼jäjux èdPK ^¸\a/b/416UT ¼jäjux èdPK ^¸\a/b/417UT ¼jäjux èdPK ^¸\a/b/418UT ¼jäjux èdPK ^¸\a/b/419UT ¼jäjux èdPK ^¸\a/b/420UT ¼jäjux èdPK ^¸\a/b/421UT ¼jäjux èdPK ^¸\a/b/422UT ¼jäjux èdPK ^¸\a/b/423UT ¼jäjux èdPK ^¸\a/b/424UT ¼jäjux èdPK ^¸\a/b/425UT ¼jäjux èdPK ^¸\a/b/426UT ¼jäjux èdPK ^¸\a/b/427UT ¼jäjux èdPK ^¸\a/b/428UT ¼jäjux èdPK ^¸\a/b/429UT ¼jäjux èdPK ^¸\a/b/430UT ¼jäjux èdPK ^¸\a/b/431UT ¼jäjux èdPK ^¸\a/b/432UT ¼jäjux èdPK ^¸\a/b/433UT ¼jäjux èdPK ^¸\a/b/434UT ¼jäjux èdPK ^¸\a/b/435UT ¼jäjux èdPK ^¸\a/b/436UT ¼jäjux èdPK ^¸\a/b/437UT ¼jäjux èdPK ^¸\a/b/438UT ¼jäjux èdPK ^¸\a/b/439UT ¼jäjux èdPK ^¸\a/b/440UT ¼jäjux èdPK ^¸\a/b/441UT ¼jäjux èdPK ^¸\a/b/442UT ¼jäjux èdPK ^¸\a/b/443UT ¼jäjux èdPK ^¸\a/b/444UT ¼jäjux èdPK ^¸\a/b/445UT ¼jäjux èdPK ^¸\a/b/446UT ¼jäjux èdPK ^¸\a/b/447UT ¼jäjux èdPK ^¸\a/b/448UT ¼jäjux èdPK ^¸\a/b/449UT ¼jäjux èdPK ^¸\a/b/450UT ¼jäjux èdPK ^¸\a/b/451UT ¼jäjux èdPK ^¸\a/b/452UT ¼jäjux èdPK ^¸\a/b/453UT ¼jäjux èdPK ^¸\a/b/454UT ¼jäjux èdPK ^¸\a/b/455UT ¼jäjux èdPK ^¸\a/b/456UT ¼jäjux èdPK ^¸\a/b/457UT ¼jäjux èdPK ^¸\a/b/458UT ¼jäjux èdPK ^¸\a/b/459UT ¼jäjux èdPK ^¸\a/b/460UT ¼jäjux èdPK ^¸\a/b/461UT ¼jäjux èdPK ^¸\a/b/462UT ¼jäjux èdPK ^¸\a/b/463UT ¼jäjux èdPK ^¸\a/b/464UT ¼jäjux èdPK ^¸\a/b/465UT ¼jäjux èdPK ^¸\a/b/466UT ¼jäjux èdPK ^¸\a/b/467UT ¼jäjux èdPK ^¸\a/b/468UT ¼jäjux èdPK ^¸\a/b/469UT ¼jäjux èdPK ^¸\a/b/470UT ¼jäjux èdPK ^¸\a/b/471UT ¼jäjux èdPK ^¸\a/b/472UT ¼jäjux èdPK ^¸\a/b/473UT ¼jäjux èdPK ^¸\a/b/474UT ¼jäjux èdPK ^¸\a/b/475UT ¼jäjux èdPK ^¸\a/b/476UT ¼jäjux èdPK ^¸\a/b/477UT ¼jäjux èdPK ^¸\a/b/478UT ¼jäjux èdPK ^¸\a/b/479UT ¼jäjux èdPK ^¸\a/b/480UT ¼jäjux èdPK ^¸\a/b/481UT ¼jäjux èdPK ^¸\a/b/482UT ¼jäjux èdPK ^¸\a/b/483UT ¼jäjux èdPK ^¸\a/b/484UT ¼jäjux èdPK ^¸\a/b/485UT ¼jäjux èdPK ^¸\a/b/486UT ¼jäjux èdPK ^¸\a/b/487UT ¼jäjux èdPK ^¸\a/b/488UT ¼jäjux èdPK ^¸\a/b/489UT ¼jäjux èdPK ^¸\a/b/490UT ¼jäjux èdPK ^¸\a/b/491UT ¼jäjux èdPK ^¸\a/b/492UT ¼jäjux èdPK ^¸\a/b/493UT ¼jäjux èdPK ^¸\a/b/494UT ¼jäjux èdPK ^¸\a/b/495UT ¼jäjux èdPK ^¸\a/b/496UT ¼jäjux èdPK ^¸\a/b/497UT ¼jäjux èdPK ^¸\a/b/498UT ¼jäjux èdPK ^¸\a/b/499UT ¼jäjux èdPK ^¸\a/b/500UT ¼jäjux èdPK ^¸\a/b/501UT ¼jäjux èdPK ^¸\a/b/502UT ¼jäjux èdPK ^¸\a/b/503UT ¼jäjux èdPK ^¸\a/b/504UT ¼jäjux èdPK ^¸\a/b/505UT ¼jäjux èdPK ^¸\a/b/506UT ¼jäjux èdPK ^¸\a/b/507UT ¼jäjux èdPK ^¸\a/b/508UT ¼jäjux èdPK ^¸\a/b/509UT ¼jäjux èdPK ^¸\a/b/510UT ¼jäjux èdPK ^¸\a/b/511UT ¼jäjux èdPK ^¸\a/b/512UT ¼jäjux èdPK ^¸\a/b/513UT ¼jäjux èdPK ^¸\a/b/514UT ¼jäjux èdPK ^¸\a/b/515UT ¼jäjux èdPK ^¸\a/b/516UT ¼jäjux èdPK ^¸\a/b/517UT ¼jäjux èdPK ^¸\a/b/518UT ¼jäjux èdPK ^¸\a/b/519UT ¼jäjux èdPK ^¸\a/b/520UT ¼jäjux èdPK ^¸\a/b/521UT ¼jäjux èdPK ^¸\a/b/522UT ¼jäjux èdPK ^¸\a/b/523UT ¼jäjux èdPK ^¸\a/b/524UT ¼jäjux èdPK ^¸\a/b/525UT ¼jäjux èdPK ^¸\a/b/526UT ¼jäjux èdPK ^¸\a/b/527UT ¼jäjux èdPK ^¸\a/b/528UT ¼jäjux èdPK ^¸\a/b/529UT ¼jäjux èdPK ^¸\a/b/530UT ¼jäjux èdPK ^¸\a/b/531UT ¼jäjux èdPK ^¸\a/b/532UT ¼jäjux èdPK ^¸\a/b/533UT ¼jäjux èdPK ^¸\a/b/534UT ¼jäjux èdPK ^¸\a/b/535UT ¼jäjux èdPK ^¸\a/b/536UT ¼jäjux èdPK ^¸\a/b/537UT ¼jäjux èdPK ^¸\a/b/538UT ¼jäjux èdPK ^¸\a/b/539UT ¼jäjux èdPK ^¸\a/b/540UT ¼jäjux èdPK ^¸\a/b/541UT ¼jäjux èdPK ^¸\a/b/542UT ¼jäjux èdPK ^¸\a/b/543UT ¼jäjux èdPK ^¸\a/b/544UT ¼jäjux èdPK ^¸\a/b/545UT ¼jäjux èdPK ^¸\a/b/546UT ¼jäjux èdPK ^¸\a/b/547UT ¼jäjux èdPK ^¸\a/b/548UT ¼jäjux èdPK ^¸\a/b/549UT ¼jäjux èdPK ^¸\a/b/550UT ¼jäjux èdPK ^¸\a/b/551UT ¼jäjux èdPK ^¸\a/b/552UT ¼jäjux èdPK ^¸\a/b/553UT ¼jäjux èdPK ^¸\a/b/554UT ¼jäjux èdPK ^¸\a/b/555UT ¼jäjux èdPK ^¸\a/b/556UT ¼jäjux èdPK ^¸\a/b/557UT ¼jäjux èdPK ^¸\a/b/558UT ¼jäjux èdPK ^¸\a/b/559UT ¼jäjux èdPK ^¸\a/b/560UT ¼jäjux èdPK ^¸\a/b/561UT ¼jäjux èdPK ^¸\a/b/562UT ¼jäjux èdPK ^¸\a/b/563UT ¼jäjux èdPK ^¸\a/b/564UT ¼jäjux èdPK ^¸\a/b/565UT ¼jäjux èdPK ^¸\a/b/566UT ¼jäjux èdPK ^¸\a/b/567UT ¼jäjux èdPK ^¸\a/b/568UT ¼jäjux èdPK ^¸\a/b/569UT ¼jäjux èdPK ^¸\a/b/570UT ¼jäjux èdPK ^¸\a/b/571UT ¼jäjux èdPK ^¸\a/b/572UT ¼jäjux èdPK ^¸\a/b/573UT ¼jäjux èdPK ^¸\a/b/574UT ¼jäjux èdPK ^¸\a/b/575UT ¼jäjux èdPK ^¸\a/b/576UT ¼jäjux èdPK ^¸\a/b/577UT ¼jäjux èdPK ^¸\a/b/578UT ¼jäjux èdPK ^¸\a/b/579UT ¼jäjux èdPK ^¸\a/b/580UT ¼jäjux èdPK ^¸\a/b/581UT ¼jäjux èdPK ^¸\a/b/582UT ¼jäjux èdPK ^¸\a/b/583UT ¼jäjux èdPK ^¸\a/b/584UT ¼jäjux èdPK ^¸\a/b/585UT ¼jäjux èdPK ^¸\a/b/586UT ¼jäjux èdPK ^¸\a/b/587UT ¼jäjux èdPK ^¸\a/b/588UT ¼jäjux èdPK ^¸\a/b/589UT ¼jäjux èdPK ^¸\a/b/590UT ¼jäjux èdPK ^¸\a/b/591UT ¼jäjux èdPK ^¸\a/b/592UT ¼jäjux èdPK ^¸\a/b/593UT ¼jäjux èdPK ^¸\a/b/594UT ¼jäjux èdPK ^¸\a/b/595UT ¼jäjux èdPK ^¸\a/b/596UT ¼jäjux èdPK ^¸\a/b/597UT ¼jäjux èdPK ^¸\a/b/598UT ¼jäjux èdPK ^¸\a/b/599UT ¼jäjux èdPK ^¸\a/b/600UT ¼jäjux èdPK ^¸\a/b/601UT ¼jäjux èdPK ^¸\a/b/602UT ¼jäjux èdPK ^¸\a/b/603UT ¼jäjux èdPK ^¸\a/b/604UT ¼jäjux èdPK ^¸\a/b/605UT ¼jäjux èdPK ^¸\a/b/606UT ¼jäjux èdPK ^¸\a/b/607UT ¼jäjux èdPK ^¸\a/b/608UT ¼jäjux èdPK ^¸\a/b/609UT ¼jäjux èdPK ^¸\a/b/610UT ¼jäjux èdPK ^¸\a/b/611UT ¼jäjux èdPK ^¸\a/b/612UT ½jäjux èdPK ^¸\a/b/613UT ½jäjux èdPK ^¸\a/b/614UT ½jäjux èdPK ^¸\a/b/615UT ½jäjux èdPK ^¸\a/b/616UT ½jäjux èdPK ^¸\a/b/617UT ½jäjux èdPK ^¸\a/b/618UT ½jäjux èdPK ^¸\a/b/619UT ½jäjux èdPK ^¸\a/b/620UT ½jäjux èdPK ^¸\a/b/621UT ½jäjux èdPK ^¸\a/b/622UT ½jäjux èdPK ^¸\a/b/623UT ½jäjux èdPK ^¸\a/b/624UT ½jäjux èdPK ^¸\a/b/625UT ½jäjux èdPK ^¸\a/b/626UT ½jäjux èdPK ^¸\a/b/627UT ½jäjux èdPK ^¸\a/b/628UT ½jäjux èdPK ^¸\a/b/629UT ½jäjux èdPK ^¸\a/b/630UT ½jäjux èdPK ^¸\a/b/631UT ½jäjux èdPK ^¸\a/b/632UT ½jäjux èdPK ^¸\a/b/633UT ½jäjux èdPK ^¸\a/b/634UT ½jäjux èdPK ^¸\a/b/635UT ½jäjux èdPK ^¸\a/b/636UT ½jäjux èdPK ^¸\a/b/637UT ½jäjux èdPK ^¸\a/b/638UT ½jäjux èdPK ^¸\a/b/639UT ½jäjux èdPK ^¸\a/b/640UT ½jäjux èdPK ^¸\a/b/641UT ½jäjux èdPK ^¸\a/b/642UT ½jäjux èdPK ^¸\a/b/643UT ½jäjux èdPK ^¸\a/b/644UT ½jäjux èdPK ^¸\a/b/645UT ½jäjux èdPK ^¸\a/b/646UT ½jäjux èdPK ^¸\a/b/647UT ½jäjux èdPK ^¸\a/b/648UT ½jäjux èdPK ^¸\a/b/649UT ½jäjux èdPK ^¸\a/b/650UT ½jäjux èdPK ^¸\a/b/651UT ½jäjux èdPK ^¸\a/b/652UT ½jäjux èdPK ^¸\a/b/653UT ½jäjux èdPK ^¸\a/b/654UT ½jäjux èdPK ^¸\a/b/655UT ½jäjux èdPK ^¸\a/b/656UT ½jäjux èdPK ^¸\a/b/657UT ½jäjux èdPK ^¸\a/b/658UT ½jäjux èdPK ^¸\a/b/659UT ½jäjux èdPK ^¸\a/b/660UT ½jäjux èdPK ^¸\a/b/661UT ½jäjux èdPK ^¸\a/b/662UT ½jäjux èdPK ^¸\a/b/663UT ½jäjux èdPK ^¸\a/b/664UT ½jäjux èdPK ^¸\a/b/665UT ½jäjux èdPK ^¸\a/b/666UT ½jäjux èdPK ^¸\a/b/667UT ½jäjux èdPK ^¸\a/b/668UT ½jäjux èdPK ^¸\a/b/669UT ½jäjux èdPK ^¸\a/b/670UT ½jäjux èdPK ^¸\a/b/671UT ½jäjux èdPK ^¸\a/b/672UT ½jäjux èdPK ^¸\a/b/673UT ½jäjux èdPK ^¸\a/b/674UT ½jäjux èdPK ^¸\a/b/675UT ½jäjux èdPK ^¸\a/b/676UT ½jäjux èdPK ^¸\a/b/677UT ½jäjux èdPK ^¸\a/b/678UT ½jäjux èdPK ^¸\a/b/679UT ½jäjux èdPK ^¸\a/b/680UT ½jäjux èdPK ^¸\a/b/681UT ½jäjux èdPK ^¸\a/b/682UT ½jäjux èdPK ^¸\a/b/683UT ½jäjux èdPK ^¸\a/b/684UT ½jäjux èdPK ^¸\a/b/685UT ½jäjux èdPK ^¸\a/b/686UT ½jäjux èdPK ^¸\a/b/687UT ½jäjux èdPK ^¸\a/b/688UT ½jäjux èdPK ^¸\a/b/689UT ½jäjux èdPK ^¸\a/b/690UT ½jäjux èdPK ^¸\a/b/691UT ½jäjux èdPK ^¸\a/b/692UT ½jäjux èdPK ^¸\a/b/693UT ½jäjux èdPK ^¸\a/b/694UT ½jäjux èdPK ^¸\a/b/695UT ½jäjux èdPK ^¸\a/b/696UT ½jäjux èdPK ^¸\a/b/697UT ½jäjux èdPK ^¸\a/b/698UT ½jäjux èdPK ^¸\a/b/699UT ½jäjux èdPK ^¸\a/b/700UT ½jäjux èdPK ^¸\a/b/701UT ½jäjux èdPK ^¸\a/b/702UT ½jäjux èdPK ^¸\a/b/703UT ½jäjux èdPK ^¸\a/b/704UT ½jäjux èdPK ^¸\a/b/705UT ½jäjux èdPK ^¸\a/b/706UT ½jäjux èdPK ^¸\a/b/707UT ½jäjux èdPK ^¸\a/b/708UT ½jäjux èdPK ^¸\a/b/709UT ½jäjux èdPK ^¸\a/b/710UT ½jäjux èdPK ^¸\a/b/711UT ½jäjux èdPK ^¸\a/b/712UT ½jäjux èdPK ^¸\a/b/713UT ½jäjux èdPK ^¸\a/b/714UT ½jäjux èdPK ^¸\a/b/715UT ½jäjux èdPK ^¸\a/b/716UT ½jäjux èdPK ^¸\a/b/717UT ½jäjux èdPK ^¸\a/b/718UT ½jäjux èdPK ^¸\a/b/719UT ½jäjux èdPK ^¸\a/b/720UT ½jäjux èdPK ^¸\a/b/721UT ½jäjux èdPK ^¸\a/b/722UT ½jäjux èdPK ^¸\a/b/723UT ½jäjux èdPK ^¸\a/b/724UT ½jäjux èdPK ^¸\a/b/725UT ½jäjux èdPK ^¸\a/b/726UT ½jäjux èdPK ^¸\a/b/727UT ½jäjux èdPK ^¸\a/b/728UT ½jäjux èdPK ^¸\a/b/729UT ½jäjux èdPK ^¸\a/b/730UT ½jäjux èdPK ^¸\a/b/731UT ½jäjux èdPK ^¸\a/b/732UT ½jäjux èdPK ^¸\a/b/733UT ½jäjux èdPK ^¸\a/b/734UT ½jäjux èdPK ^¸\a/b/735UT ½jäjux èdPK ^¸\a/b/736UT ½jäjux èdPK ^¸\a/b/737UT ½jäjux èdPK ^¸\a/b/738UT ½jäjux èdPK ^¸\a/b/739UT ½jäjux èdPK ^¸\a/b/740UT ½jäjux èdPK ^¸\a/b/741UT ½jäjux èdPK ^¸\a/b/742UT ½jäjux èdPK ^¸\a/b/743UT ½jäjux èdPK ^¸\a/b/744UT ½jäjux èdPK ^¸\a/b/745UT ½jäjux èdPK ^¸\a/b/746UT ½jäjux èdPK ^¸\a/b/747UT ½jäjux èdPK ^¸\a/b/748UT ½jäjux èdPK ^¸\a/b/749UT ½jäjux èdPK ^¸\a/b/750UT ½jäjux èdPK ^¸\a/b/751UT ½jäjux èdPK ^¸\a/b/752UT ½jäjux èdPK ^¸\a/b/753UT ½jäjux èdPK ^¸\a/b/754UT ½jäjux èdPK ^¸\a/b/755UT ½jäjux èdPK ^¸\a/b/756UT ½jäjux èdPK ^¸\a/b/757UT ½jäjux èdPK ^¸\a/b/758UT ½jäjux èdPK ^¸\a/b/759UT ½jäjux èdPK ^¸\a/b/760UT ½jäjux èdPK ^¸\a/b/761UT ½jäjux èdPK ^¸\a/b/762UT ½jäjux èdPK ^¸\a/b/763UT ½jäjux èdPK ^¸\a/b/764UT ½jäjux èdPK ^¸\a/b/765UT ½jäjux èdPK ^¸\a/b/766UT ½jäjux èdPK ^¸\a/b/767UT ½jäjux èdPK ^¸\a/b/768UT ½jäjux èdPK ^¸\a/b/769UT ½jäjux èdPK ^¸\a/b/770UT ½jäjux èdPK ^¸\a/b/771UT ½jäjux èdPK ^¸\a/b/772UT ½jäjux èdPK ^¸\a/b/773UT ½jäjux èdPK ^¸\a/b/774UT ½jäjux èdPK ^¸\a/b/775UT ½jäjux èdPK ^¸\a/b/776UT ½jäjux èdPK ^¸\a/b/777UT ½jäjux èdPK ^¸\a/b/778UT ½jäjux èdPK ^¸\a/b/779UT ½jäjux èdPK ^¸\a/b/780UT ½jäjux èdPK ^¸\a/b/781UT ½jäjux èdPK ^¸\a/b/782UT ½jäjux èdPK ^¸\a/b/783UT ½jäjux èdPK ^¸\a/b/784UT ½jäjux èdPK ^¸\a/b/785UT ½jäjux èdPK ^¸\a/b/786UT ½jäjux èdPK ^¸\a/b/787UT ½jäjux èdPK ^¸\a/b/788UT ½jäjux èdPK ^¸\a/b/789UT ½jäjux èdPK ^¸\a/b/790UT ½jäjux èdPK ^¸\a/b/791UT ½jäjux èdPK ^¸\a/b/792UT ½jäjux èdPK ^¸\a/b/793UT ½jäjux èdPK ^¸\a/b/794UT ½jäjux èdPK ^¸\a/b/795UT ½jäjux èdPK ^¸\a/b/796UT ½jäjux èdPK ^¸\a/b/797UT ½jäjux èdPK ^¸\a/b/798UT ½jäjux èdPK ^¸\a/b/799UT ½jäjux èdPK ^¸\a/b/800UT ½jäjux èdPK ^¸\a/b/801UT ½jäjux èdPK ^¸\a/b/802UT ½jäjux èdPK ^¸\a/b/803UT ½jäjux èdPK ^¸\a/b/804UT ½jäjux èdPK ^¸\a/b/805UT ½jäjux èdPK ^¸\a/b/806UT ½jäjux èdPK ^¸\a/b/807UT ½jäjux èdPK ^¸\a/b/808UT ½jäjux èdPK ^¸\a/b/809UT ½jäjux èdPK ^¸\a/b/810UT ½jäjux èdPK ^¸\a/b/811UT ½jäjux èdPK ^¸\a/b/812UT ½jäjux èdPK ^¸\a/b/813UT ½jäjux èdPK ^¸\a/b/814UT ½jäjux èdPK ^¸\a/b/815UT ½jäjux èdPK ^¸\a/b/816UT ½jäjux èdPK ^¸\a/b/817UT ½jäjux èdPK ^¸\a/b/818UT ½jäjux èdPK ^¸\a/b/819UT ½jäjux èdPK ^¸\a/b/820UT ½jäjux èdPK ^¸\a/b/821UT ½jäjux èdPK ^¸\a/b/822UT ½jäjux èdPK ^¸\a/b/823UT ½jäjux èdPK ^¸\a/b/824UT ½jäjux èdPK ^¸\a/b/825UT ½jäjux èdPK ^¸\a/b/826UT ½jäjux èdPK ^¸\a/b/827UT ½jäjux èdPK ^¸\a/b/828UT ½jäjux èdPK ^¸\a/b/829UT ½jäjux èdPK ^¸\a/b/830UT ½jäjux èdPK ^¸\a/b/831UT ½jäjux èdPK ^¸\a/b/832UT ½jäjux èdPK ^¸\a/b/833UT ½jäjux èdPK ^¸\a/b/834UT ½jäjux èdPK ^¸\a/b/835UT ½jäjux èdPK ^¸\a/b/836UT ½jäjux èdPK ^¸\a/b/837UT ½jäjux èdPK ^¸\a/b/838UT ½jäjux èdPK ^¸\a/b/839UT ½jäjux èdPK ^¸\a/b/840UT ½jäjux èdPK ^¸\a/b/841UT ½jäjux èdPK ^¸\a/b/842UT ½jäjux èdPK ^¸\a/b/843UT ½jäjux èdPK ^¸\a/b/844UT ½jäjux èdPK ^¸\a/b/845UT ½jäjux èdPK ^¸\a/b/846UT ½jäjux èdPK ^¸\a/b/847UT ½jäjux èdPK ^¸\a/b/848UT ½jäjux èdPK ^¸\a/b/849UT ½jäjux èdPK ^¸\a/b/850UT ½jäjux èdPK ^¸\a/b/851UT ½jäjux èdPK ^¸\a/b/852UT ½jäjux èdPK ^¸\a/b/853UT ½jäjux èdPK ^¸\a/b/854UT ½jäjux èdPK ^¸\a/b/855UT ½jäjux èdPK ^¸\a/b/856UT ½jäjux èdPK ^¸\a/b/857UT ½jäjux èdPK ^¸\a/b/858UT ½jäjux èdPK ^¸\a/b/859UT ½jäjux èdPK ^¸\a/b/860UT ½jäjux èdPK ^¸\a/b/861UT ½jäjux èdPK ^¸\a/b/862UT ½jäjux èdPK ^¸\a/b/863UT ½jäjux èdPK ^¸\a/b/864UT ½jäjux èdPK ^¸\a/b/865UT ½jäjux èdPK ^¸\a/b/866UT ½jäjux èdPK ^¸\a/b/867UT ½jäjux èdPK ^¸\a/b/868UT ½jäjux èdPK ^¸\a/b/869UT ½jäjux èdPK ^¸\a/b/870UT ½jäjux èdPK ^¸\a/b/871UT ½jäjux èdPK ^¸\a/b/872UT ½jäjux èdPK ^¸\a/b/873UT ½jäjux èdPK ^¸\a/b/874UT ½jäjux èdPK ^¸\a/b/875UT ½jäjux èdPK ^¸\a/b/876UT ½jäjux èdPK ^¸\a/b/877UT ½jäjux èdPK ^¸\a/b/878UT ½jäjux èdPK ^¸\a/b/879UT ½jäjux èdPK ^¸\a/b/880UT ½jäjux èdPK ^¸\a/b/881UT ½jäjux èdPK ^¸\a/b/882UT ½jäjux èdPK ^¸\a/b/883UT ½jäjux èdPK ^¸\a/b/884UT ½jäjux èdPK ^¸\a/b/885UT ½jäjux èdPK ^¸\a/b/886UT ½jäjux èdPK ^¸\a/b/887UT ½jäjux èdPK ^¸\a/b/888UT ½jäjux èdPK ^¸\a/b/889UT ½jäjux èdPK ^¸\a/b/890UT ½jäjux èdPK ^¸\a/b/891UT ½jäjux èdPK ^¸\a/b/892UT ½jäjux èdPK ^¸\a/b/893UT ½jäjux èdPK ^¸\a/b/894UT ½jäjux èdPK ^¸\a/b/895UT ½jäjux èdPK ^¸\a/b/896UT ½jäjux èdPK ^¸\a/b/897UT ½jäjux èdPK ^¸\a/b/898UT ½jäjux èdPK ^¸\a/b/899UT ½jäjux èdPK ^¸\a/b/900UT ½jäjux èdPK ^¸\a/b/901UT ½jäjux èdPK ^¸\a/b/902UT ½jäjux èdPK ^¸\a/b/903UT ½jäjux èdPK ^¸\a/b/904UT ½jäjux èdPK ^¸\a/b/905UT ½jäjux èdPK ^¸\a/b/906UT ½jäjux èdPK ^¸\a/b/907UT ½jäjux èdPK ^¸\a/b/908UT ½jäjux èdPK ^¸\a/b/909UT ½jäjux èdPK ^¸\a/b/910UT ½jäjux èdPK ^¸\a/b/911UT ½jäjux èdPK ^¸\a/b/912UT ½jäjux èdPK ^¸\a/b/913UT ½jäjux èdPK ^¸\a/b/914UT ½jäjux èdPK ^¸\a/b/915UT ½jäjux èdPK ^¸\a/b/916UT ½jäjux èdPK ^¸\a/b/917UT ½jäjux èdPK ^¸\a/b/918UT ½jäjux èdPK ^¸\a/b/919UT ½jäjux èdPK ^¸\a/b/920UT ½jäjux èdPK ^¸\a/b/921UT ½jäjux èdPK ^¸\a/b/922UT ½jäjux èdPK ^¸\a/b/923UT ½jäjux èdPK ^¸\a/b/924UT ½jäjux èdPK ^¸\a/b/925UT ½jäjux èdPK ^¸\a/b/926UT ½jäjux èdPK ^¸\a/b/927UT ½jäjux èdPK ^¸\a/b/928UT ½jäjux èdPK ^¸\a/b/929UT ½jäjux èdPK ^¸\a/b/930UT ½jäjux èdPK ^¸\a/b/931UT ½jäjux èdPK ^¸\a/b/932UT ½jäjux èdPK ^¸\a/b/933UT ½jäjux èdPK ^¸\a/b/934UT ½jäjux èdPK ^¸\a/b/935UT ½jäjux èdPK ^¸\a/b/936UT ½jäjux èdPK ^¸\a/b/937UT ½jäjux èdPK ^¸\a/b/938UT ½jäjux èdPK ^¸\a/b/939UT ½jäjux èdPK ^¸\a/b/940UT ½jäjux èdPK ^¸\a/b/941UT ½jäjux èdPK ^¸\a/b/942UT ½jäjux èdPK ^¸\a/b/943UT ½jäjux èdPK ^¸\a/b/944UT ½jäjux èdPK ^¸\a/b/945UT ½jäjux èdPK ^¸\a/b/946UT ½jäjux èdPK ^¸\a/b/947UT ½jäjux èdPK ^¸\a/b/948UT ½jäjux èdPK ^¸\a/b/949UT ½jäjux èdPK ^¸\a/b/950UT ½jäjux èdPK ^¸\a/b/951UT ½jäjux èdPK ^¸\a/b/952UT ½jäjux èdPK ^¸\a/b/953UT ½jäjux èdPK ^¸\a/b/954UT ½jäjux èdPK ^¸\a/b/955UT ½jäjux èdPK ^¸\a/b/956UT ½jäjux èdPK ^¸\a/b/957UT ½jäjux èdPK ^¸\a/b/958UT ½jäjux èdPK ^¸\a/b/959UT ½jäjux èdPK ^¸\a/b/960UT ½jäjux èdPK ^¸\a/b/961UT ½jäjux èdPK ^¸\a/b/962UT ½jäjux èdPK ^¸\a/b/963UT ½jäjux èdPK ^¸\a/b/964UT ½jäjux èdPK ^¸\a/b/965UT ½jäjux èdPK ^¸\a/b/966UT ½jäjux èdPK ^¸\a/b/967UT ½jäjux èdPK ^¸\a/b/968UT ½jäjux èdPK ^¸\a/b/969UT ½jäjux èdPK ^¸\a/b/970UT ½jäjux èdPK ^¸\a/b/971UT ½jäjux èdPK ^¸\a/b/972UT ½jäjux èdPK ^¸\a/b/973UT ½jäjux èdPK ^¸\a/b/974UT ½jäjux èdPK ^¸\a/b/975UT ½jäjux èdPK ^¸\a/b/976UT ½jäjux èdPK ^¸\a/b/977UT ½jäjux èdPK ^¸\a/b/978UT ½jäjux èdPK ^¸\a/b/979UT ½jäjux èdPK ^¸\a/b/980UT ½jäjux èdPK ^¸\a/b/981UT ½jäjux èdPK ^¸\a/b/982UT ½jäjux èdPK ^¸\a/b/983UT ½jäjux èdPK ^¸\a/b/984UT ½jäjux èdPK ^¸\a/b/985UT ½jäjux èdPK ^¸\a/b/986UT ½jäjux èdPK ^¸\a/b/987UT ½jäjux èdPK ^¸\a/b/988UT ½jäjux èdPK ^¸\a/b/989UT ½jäjux èdPK ^¸\a/b/990UT ½jäjux èdPK ^¸\a/b/991UT ½jäjux èdPK ^¸\a/b/992UT ½jäjux èdPK ^¸\a/b/993UT ½jäjux èdPK ^¸\a/b/994UT ½jäjux èdPK ^¸\a/b/995UT ½jäjux èdPK ^¸\a/b/996UT ½jäjux èdPK ^¸\a/b/997UT ½jäjux èdPK ^¸\a/b/998UT ½jäjux èdPK ^¸\a/b/999UT ½jäjux èdPK ¶]¸\Pü»‚¤�0x21000UT(jux èdPK á]¸\íAAa/UTujux èdPK á]¸\O¤�}a/longlonglonglonglonglonglonglonglonglonglonglonglonglonglongkindalongname.txtUTujux èdPK ^¸\íAa/b/UT½jux èdPK Ã]¸\íADa/b/c/UT>jux èdPKÃ]¸\Pü»‚“ ¤�„a/b/c/0x21000UT>jux èdPK ^¸\¤�^a/b/000UT»jux èdPK ^¸\¤�Ÿa/b/001UT»jux èdPK ^¸\¤�àa/b/002UT»jux èdPK ^¸\¤�!a/b/003UT»jux èdPK ^¸\¤�ba/b/004UT»jux èdPK ^¸\¤�£a/b/005UT»jux èdPK ^¸\¤�äa/b/006UT»jux èdPK ^¸\¤�%a/b/007UT»jux èdPK ^¸\¤�fa/b/008UT»jux èdPK ^¸\¤�§a/b/009UT»jux èdPK ^¸\¤�èa/b/010UT»jux èdPK ^¸\¤�)a/b/011UT»jux èdPK ^¸\¤�ja/b/012UT»jux èdPK ^¸\¤�«a/b/013UT»jux èdPK ^¸\¤�ìa/b/014UT»jux èdPK ^¸\¤�-a/b/015UT»jux èdPK ^¸\¤�na/b/016UT»jux èdPK ^¸\¤�¯a/b/017UT»jux èdPK ^¸\¤�ða/b/018UT»jux èdPK ^¸\¤�1a/b/019UT»jux èdPK ^¸\¤�ra/b/020UT»jux èdPK ^¸\¤�³a/b/021UT»jux èdPK ^¸\¤�ôa/b/022UT»jux èdPK ^¸\¤�5a/b/023UT»jux èdPK ^¸\¤�va/b/024UT»jux èdPK ^¸\¤�·a/b/025UT»jux èdPK ^¸\¤�øa/b/026UT»jux èdPK ^¸\¤�9a/b/027UT»jux èdPK ^¸\¤�za/b/028UT»jux èdPK ^¸\¤�»a/b/029UT»jux èdPK ^¸\¤�üa/b/030UT»jux èdPK ^¸\¤�=a/b/031UT»jux èdPK ^¸\¤�~a/b/032UT»jux èdPK ^¸\¤�¿a/b/033UT»jux èdPK ^¸\¤�a/b/034UT»jux èdPK ^¸\¤�Aa/b/035UT»jux èdPK ^¸\¤�‚a/b/036UT»jux èdPK ^¸\¤�Ãa/b/037UT»jux èdPK ^¸\¤�a/b/038UT»jux èdPK ^¸\¤�Ea/b/039UT»jux èdPK ^¸\¤�†a/b/040UT»jux èdPK ^¸\¤�Ça/b/041UT»jux èdPK ^¸\¤�a/b/042UT»jux èdPK ^¸\¤�Ia/b/043UT»jux èdPK ^¸\¤�Ša/b/044UT»jux èdPK ^¸\¤�Ëa/b/045UT»jux èdPK ^¸\¤� a/b/046UT»jux èdPK ^¸\¤�Ma/b/047UT»jux èdPK ^¸\¤�Ža/b/048UT»jux èdPK ^¸\¤�Ïa/b/049UT»jux èdPK ^¸\¤�a/b/050UT»jux èdPK ^¸\¤�Qa/b/051UT»jux èdPK ^¸\¤�’a/b/052UT»jux èdPK ^¸\¤�Óa/b/053UT»jux èdPK ^¸\¤� a/b/054UT»jux èdPK ^¸\¤�U a/b/055UT»jux èdPK ^¸\¤�– a/b/056UT»jux èdPK ^¸\¤�× a/b/057UT»jux èdPK ^¸\¤�!a/b/058UT»jux èdPK ^¸\¤�Y!a/b/059UT»jux èdPK ^¸\¤�š!a/b/060UT»jux èdPK ^¸\¤�Û!a/b/061UT»jux èdPK ^¸\¤�"a/b/062UT»jux èdPK ^¸\¤�]"a/b/063UT»jux èdPK ^¸\¤�ž"a/b/064UT»jux èdPK ^¸\¤�ß"a/b/065UT»jux èdPK ^¸\¤� #a/b/066UT»jux èdPK ^¸\¤�a#a/b/067UT»jux èdPK ^¸\¤�¢#a/b/068UT»jux èdPK ^¸\¤�ã#a/b/069UT»jux èdPK ^¸\¤�$$a/b/070UT»jux èdPK ^¸\¤�e$a/b/071UT»jux èdPK ^¸\¤�¦$a/b/072UT»jux èdPK ^¸\¤�ç$a/b/073UT»jux èdPK ^¸\¤�(%a/b/074UT»jux èdPK ^¸\¤�i%a/b/075UT»jux èdPK ^¸\¤�ª%a/b/076UT»jux èdPK ^¸\¤�ë%a/b/077UT»jux èdPK ^¸\¤�,&a/b/078UT»jux èdPK ^¸\¤�m&a/b/079UT»jux èdPK ^¸\¤�®&a/b/080UT»jux èdPK ^¸\¤�ï&a/b/081UT»jux èdPK ^¸\¤�0'a/b/082UT»jux èdPK ^¸\¤�q'a/b/083UT»jux èdPK ^¸\¤�²'a/b/084UT»jux èdPK ^¸\¤�ó'a/b/085UT»jux èdPK ^¸\¤�4(a/b/086UT»jux èdPK ^¸\¤�u(a/b/087UT»jux èdPK ^¸\¤�¶(a/b/088UT»jux èdPK ^¸\¤�÷(a/b/089UT»jux èdPK ^¸\¤�8)a/b/090UT»jux èdPK ^¸\¤�y)a/b/091UT»jux èdPK ^¸\¤�º)a/b/092UT»jux èdPK ^¸\¤�û)a/b/093UT»jux èdPK ^¸\¤�<*a/b/094UT»jux èdPK ^¸\¤�}*a/b/095UT»jux èdPK ^¸\¤�¾*a/b/096UT»jux èdPK ^¸\¤�ÿ*a/b/097UT»jux èdPK ^¸\¤�@+a/b/098UT»jux èdPK ^¸\¤��+a/b/099UT»jux èdPK ^¸\¤�Â+a/b/100UT»jux èdPK ^¸\¤�,a/b/101UT»jux èdPK ^¸\¤�D,a/b/102UT»jux èdPK ^¸\¤�…,a/b/103UT»jux èdPK ^¸\¤�Æ,a/b/104UT»jux èdPK ^¸\¤�-a/b/105UT»jux èdPK ^¸\¤�H-a/b/106UT»jux èdPK ^¸\¤�‰-a/b/107UT»jux èdPK ^¸\¤�Ê-a/b/108UT»jux èdPK ^¸\¤� .a/b/109UT»jux èdPK ^¸\¤�L.a/b/110UT»jux èdPK ^¸\¤��.a/b/111UT»jux èdPK ^¸\¤�Î.a/b/112UT»jux èdPK ^¸\¤�/a/b/113UT»jux èdPK ^¸\¤�P/a/b/114UT»jux èdPK ^¸\¤�‘/a/b/115UT»jux èdPK ^¸\¤�Ò/a/b/116UT»jux èdPK ^¸\¤�0a/b/117UT»jux èdPK ^¸\¤�T0a/b/118UT»jux èdPK ^¸\¤�•0a/b/119UT»jux èdPK ^¸\¤�Ö0a/b/120UT»jux èdPK ^¸\¤�1a/b/121UT»jux èdPK ^¸\¤�X1a/b/122UT»jux èdPK ^¸\¤�™1a/b/123UT»jux èdPK ^¸\¤�Ú1a/b/124UT»jux èdPK ^¸\¤�2a/b/125UT»jux èdPK ^¸\¤�\2a/b/126UT»jux èdPK ^¸\¤��2a/b/127UT»jux èdPK ^¸\¤�Þ2a/b/128UT»jux èdPK ^¸\¤�3a/b/129UT»jux èdPK ^¸\¤�`3a/b/130UT»jux èdPK ^¸\¤�¡3a/b/131UT»jux èdPK ^¸\¤�â3a/b/132UT»jux èdPK ^¸\¤�#4a/b/133UT»jux èdPK ^¸\¤�d4a/b/134UT»jux èdPK ^¸\¤�¥4a/b/135UT»jux èdPK ^¸\¤�æ4a/b/136UT»jux èdPK ^¸\¤�'5a/b/137UT»jux èdPK ^¸\¤�h5a/b/138UT»jux èdPK ^¸\¤�©5a/b/139UT»jux èdPK ^¸\¤�ê5a/b/140UT»jux èdPK ^¸\¤�+6a/b/141UT»jux èdPK ^¸\¤�l6a/b/142UT»jux èdPK ^¸\¤�­6a/b/143UT»jux èdPK ^¸\¤�î6a/b/144UT»jux èdPK ^¸\¤�/7a/b/145UT»jux èdPK ^¸\¤�p7a/b/146UT»jux èdPK ^¸\¤�±7a/b/147UT»jux èdPK ^¸\¤�ò7a/b/148UT»jux èdPK ^¸\¤�38a/b/149UT»jux èdPK ^¸\¤�t8a/b/150UT»jux èdPK ^¸\¤�µ8a/b/151UT»jux èdPK ^¸\¤�ö8a/b/152UT»jux èdPK ^¸\¤�79a/b/153UT»jux èdPK ^¸\¤�x9a/b/154UT»jux èdPK ^¸\¤�¹9a/b/155UT»jux èdPK ^¸\¤�ú9a/b/156UT»jux èdPK ^¸\¤�;:a/b/157UT»jux èdPK ^¸\¤�|:a/b/158UT»jux èdPK ^¸\¤�½:a/b/159UT»jux èdPK ^¸\¤�þ:a/b/160UT»jux èdPK ^¸\¤�?;a/b/161UT»jux èdPK ^¸\¤�€;a/b/162UT»jux èdPK ^¸\¤�Á;a/b/163UT»jux èdPK ^¸\¤�<a/b/164UT»jux èdPK ^¸\¤�C<a/b/165UT»jux èdPK ^¸\¤�„<a/b/166UT»jux èdPK ^¸\¤�Å<a/b/167UT»jux èdPK ^¸\¤�=a/b/168UT»jux èdPK ^¸\¤�G=a/b/169UT»jux èdPK ^¸\¤�ˆ=a/b/170UT»jux èdPK ^¸\¤�É=a/b/171UT»jux èdPK ^¸\¤� >a/b/172UT»jux èdPK ^¸\¤�K>a/b/173UT»jux èdPK ^¸\¤�Œ>a/b/174UT»jux èdPK ^¸\¤�Í>a/b/175UT»jux èdPK ^¸\¤�?a/b/176UT»jux èdPK ^¸\¤�O?a/b/177UT»jux èdPK ^¸\¤��?a/b/178UT»jux èdPK ^¸\¤�Ñ?a/b/179UT»jux èdPK ^¸\¤�@a/b/180UT»jux èdPK ^¸\¤�S@a/b/181UT»jux èdPK ^¸\¤�”@a/b/182UT»jux èdPK ^¸\¤�Õ@a/b/183UT»jux èdPK ^¸\¤�Aa/b/184UT»jux èdPK ^¸\¤�WAa/b/185UT»jux èdPK ^¸\¤�˜Aa/b/186UT»jux èdPK ^¸\¤�ÙAa/b/187UT»jux èdPK ^¸\¤�Ba/b/188UT»jux èdPK ^¸\¤�[Ba/b/189UT»jux èdPK ^¸\¤�œBa/b/190UT»jux èdPK ^¸\¤�ÝBa/b/191UT»jux èdPK ^¸\¤�Ca/b/192UT»jux èdPK ^¸\¤�_Ca/b/193UT»jux èdPK ^¸\¤� Ca/b/194UT»jux èdPK ^¸\¤�áCa/b/195UT»jux èdPK ^¸\¤�"Da/b/196UT»jux èdPK ^¸\¤�cDa/b/197UT»jux èdPK ^¸\¤�¤Da/b/198UT»jux èdPK ^¸\¤�åDa/b/199UT»jux èdPK ^¸\¤�&Ea/b/200UT»jux èdPK ^¸\¤�gEa/b/201UT»jux èdPK ^¸\¤�¨Ea/b/202UT»jux èdPK ^¸\¤�éEa/b/203UT»jux èdPK ^¸\¤�*Fa/b/204UT»jux èdPK ^¸\¤�kFa/b/205UT»jux èdPK ^¸\¤�¬Fa/b/206UT»jux èdPK ^¸\¤�íFa/b/207UT»jux èdPK ^¸\¤�.Ga/b/208UT»jux èdPK ^¸\¤�oGa/b/209UT»jux èdPK ^¸\¤�°Ga/b/210UT»jux èdPK ^¸\¤�ñGa/b/211UT»jux èdPK ^¸\¤�2Ha/b/212UT»jux èdPK ^¸\¤�sHa/b/213UT»jux èdPK ^¸\¤�´Ha/b/214UT»jux èdPK ^¸\¤�õHa/b/215UT»jux èdPK ^¸\¤�6Ia/b/216UT»jux èdPK ^¸\¤�wIa/b/217UT»jux èdPK ^¸\¤�¸Ia/b/218UT»jux èdPK ^¸\¤�ùIa/b/219UT»jux èdPK ^¸\¤�:Ja/b/220UT»jux èdPK ^¸\¤�{Ja/b/221UT»jux èdPK ^¸\¤�¼Ja/b/222UT»jux èdPK ^¸\¤�ýJa/b/223UT»jux èdPK ^¸\¤�>Ka/b/224UT»jux èdPK ^¸\¤�Ka/b/225UT»jux èdPK ^¸\¤�ÀKa/b/226UT»jux èdPK ^¸\¤�La/b/227UT»jux èdPK ^¸\¤�BLa/b/228UT»jux èdPK ^¸\¤�ƒLa/b/229UT»jux èdPK ^¸\¤�ÄLa/b/230UT»jux èdPK ^¸\¤�Ma/b/231UT»jux èdPK ^¸\¤�FMa/b/232UT»jux èdPK ^¸\¤�‡Ma/b/233UT»jux èdPK ^¸\¤�ÈMa/b/234UT»jux èdPK ^¸\¤� Na/b/235UT»jux èdPK ^¸\¤�JNa/b/236UT»jux èdPK ^¸\¤�‹Na/b/237UT»jux èdPK ^¸\¤�ÌNa/b/238UT»jux èdPK ^¸\¤� Oa/b/239UT»jux èdPK ^¸\¤�NOa/b/240UT»jux èdPK ^¸\¤��Oa/b/241UT»jux èdPK ^¸\¤�ÐOa/b/242UT»jux èdPK ^¸\¤�Pa/b/243UT»jux èdPK ^¸\¤�RPa/b/244UT»jux èdPK ^¸\¤�“Pa/b/245UT»jux èdPK ^¸\¤�ÔPa/b/246UT»jux èdPK ^¸\¤�Qa/b/247UT»jux èdPK ^¸\¤�VQa/b/248UT»jux èdPK ^¸\¤�—Qa/b/249UT»jux èdPK ^¸\¤�ØQa/b/250UT»jux èdPK ^¸\¤�Ra/b/251UT»jux èdPK ^¸\¤�ZRa/b/252UT»jux èdPK ^¸\¤�›Ra/b/253UT»jux èdPK ^¸\¤�ÜRa/b/254UT»jux èdPK ^¸\¤�Sa/b/255UT»jux èdPK ^¸\¤�^Sa/b/256UT»jux èdPK ^¸\¤�ŸSa/b/257UT»jux èdPK ^¸\¤�àSa/b/258UT»jux èdPK ^¸\¤�!Ta/b/259UT»jux èdPK ^¸\¤�bTa/b/260UT»jux èdPK ^¸\¤�£Ta/b/261UT»jux èdPK ^¸\¤�äTa/b/262UT»jux èdPK ^¸\¤�%Ua/b/263UT»jux èdPK ^¸\¤�fUa/b/264UT»jux èdPK ^¸\¤�§Ua/b/265UT»jux èdPK ^¸\¤�èUa/b/266UT»jux èdPK ^¸\¤�)Va/b/267UT¼jux èdPK ^¸\¤�jVa/b/268UT¼jux èdPK ^¸\¤�«Va/b/269UT¼jux èdPK ^¸\¤�ìVa/b/270UT¼jux èdPK ^¸\¤�-Wa/b/271UT¼jux èdPK ^¸\¤�nWa/b/272UT¼jux èdPK ^¸\¤�¯Wa/b/273UT¼jux èdPK ^¸\¤�ðWa/b/274UT¼jux èdPK ^¸\¤�1Xa/b/275UT¼jux èdPK ^¸\¤�rXa/b/276UT¼jux èdPK ^¸\¤�³Xa/b/277UT¼jux èdPK ^¸\¤�ôXa/b/278UT¼jux èdPK ^¸\¤�5Ya/b/279UT¼jux èdPK ^¸\¤�vYa/b/280UT¼jux èdPK ^¸\¤�·Ya/b/281UT¼jux èdPK ^¸\¤�øYa/b/282UT¼jux èdPK ^¸\¤�9Za/b/283UT¼jux èdPK ^¸\¤�zZa/b/284UT¼jux èdPK ^¸\¤�»Za/b/285UT¼jux èdPK ^¸\¤�üZa/b/286UT¼jux èdPK ^¸\¤�=[a/b/287UT¼jux èdPK ^¸\¤�~[a/b/288UT¼jux èdPK ^¸\¤�¿[a/b/289UT¼jux èdPK ^¸\¤�\a/b/290UT¼jux èdPK ^¸\¤�A\a/b/291UT¼jux èdPK ^¸\¤�‚\a/b/292UT¼jux èdPK ^¸\¤�Ã\a/b/293UT¼jux èdPK ^¸\¤�]a/b/294UT¼jux èdPK ^¸\¤�E]a/b/295UT¼jux èdPK ^¸\¤�†]a/b/296UT¼jux èdPK ^¸\¤�Ç]a/b/297UT¼jux èdPK ^¸\¤�^a/b/298UT¼jux èdPK ^¸\¤�I^a/b/299UT¼jux èdPK ^¸\¤�Š^a/b/300UT¼jux èdPK ^¸\¤�Ë^a/b/301UT¼jux èdPK ^¸\¤� _a/b/302UT¼jux èdPK ^¸\¤�M_a/b/303UT¼jux èdPK ^¸\¤�Ž_a/b/304UT¼jux èdPK ^¸\¤�Ï_a/b/305UT¼jux èdPK ^¸\¤�`a/b/306UT¼jux èdPK ^¸\¤�Q`a/b/307UT¼jux èdPK ^¸\¤�’`a/b/308UT¼jux èdPK ^¸\¤�Ó`a/b/309UT¼jux èdPK ^¸\¤�aa/b/310UT¼jux èdPK ^¸\¤�Uaa/b/311UT¼jux èdPK ^¸\¤�–aa/b/312UT¼jux èdPK ^¸\¤�×aa/b/313UT¼jux èdPK ^¸\¤�ba/b/314UT¼jux èdPK ^¸\¤�Yba/b/315UT¼jux èdPK ^¸\¤�šba/b/316UT¼jux èdPK ^¸\¤�Ûba/b/317UT¼jux èdPK ^¸\¤�ca/b/318UT¼jux èdPK ^¸\¤�]ca/b/319UT¼jux èdPK ^¸\¤�žca/b/320UT¼jux èdPK ^¸\¤�ßca/b/321UT¼jux èdPK ^¸\¤� da/b/322UT¼jux èdPK ^¸\¤�ada/b/323UT¼jux èdPK ^¸\¤�¢da/b/324UT¼jux èdPK ^¸\¤�ãda/b/325UT¼jux èdPK ^¸\¤�$ea/b/326UT¼jux èdPK ^¸\¤�eea/b/327UT¼jux èdPK ^¸\¤�¦ea/b/328UT¼jux èdPK ^¸\¤�çea/b/329UT¼jux èdPK ^¸\¤�(fa/b/330UT¼jux èdPK ^¸\¤�ifa/b/331UT¼jux èdPK ^¸\¤�ªfa/b/332UT¼jux èdPK ^¸\¤�ëfa/b/333UT¼jux èdPK ^¸\¤�,ga/b/334UT¼jux èdPK ^¸\¤�mga/b/335UT¼jux èdPK ^¸\¤�®ga/b/336UT¼jux èdPK ^¸\¤�ïga/b/337UT¼jux èdPK ^¸\¤�0ha/b/338UT¼jux èdPK ^¸\¤�qha/b/339UT¼jux èdPK ^¸\¤�²ha/b/340UT¼jux èdPK ^¸\¤�óha/b/341UT¼jux èdPK ^¸\¤�4ia/b/342UT¼jux èdPK ^¸\¤�uia/b/343UT¼jux èdPK ^¸\¤�¶ia/b/344UT¼jux èdPK ^¸\¤�÷ia/b/345UT¼jux èdPK ^¸\¤�8ja/b/346UT¼jux èdPK ^¸\¤�yja/b/347UT¼jux èdPK ^¸\¤�ºja/b/348UT¼jux èdPK ^¸\¤�ûja/b/349UT¼jux èdPK ^¸\¤�Œa/b/480UT¼jux èdPK ^¸\¤�Œa/b/481UT¼jux èdPK ^¸\¤�ÀŒa/b/482UT¼jux èdPK ^¸\¤��a/b/483UT¼jux èdPK ^¸\¤�B�a/b/484UT¼jux èdPK ^¸\¤�ƒ�a/b/485UT¼jux èdPK ^¸\¤�Ä�a/b/486UT¼jux èdPK ^¸\¤�Ža/b/487UT¼jux èdPK ^¸\¤�FŽa/b/488UT¼jux èdPK ^¸\¤�‡Ža/b/489UT¼jux èdPK ^¸\¤�ÈŽa/b/490UT¼jux èdPK ^¸\¤� �a/b/491UT¼jux èdPK ^¸\¤�J�a/b/492UT¼jux èdPK ^¸\¤�‹�a/b/493UT¼jux èdPK ^¸\¤�Ì�a/b/494UT¼jux èdPK ^¸\¤� �a/b/495UT¼jux èdPK ^¸\¤�N�a/b/496UT¼jux èdPK ^¸\¤���a/b/497UT¼jux èdPK ^¸\¤�Ð�a/b/498UT¼jux èdPK ^¸\¤�‘a/b/499UT¼jux èdPK ^¸\¤�R‘a/b/500UT¼jux èdPK ^¸\¤�“‘a/b/501UT¼jux èdPK ^¸\¤�Ô‘a/b/502UT¼jux èdPK ^¸\¤�’a/b/503UT¼jux èdPK ^¸\¤�V’a/b/504UT¼jux èdPK ^¸\¤�—’a/b/505UT¼jux èdPK ^¸\¤�Ø’a/b/506UT¼jux èdPK ^¸\¤�“a/b/507UT¼jux èdPK ^¸\¤�Z“a/b/508UT¼jux èdPK ^¸\¤�›“a/b/509UT¼jux èdPK ^¸\¤�Ü“a/b/510UT¼jux èdPK ^¸\¤�”a/b/511UT¼jux èdPK ^¸\¤�^”a/b/512UT¼jux èdPK ^¸\¤�Ÿ”a/b/513UT¼jux èdPK ^¸\¤�à”a/b/514UT¼jux èdPK ^¸\¤�!•a/b/515UT¼jux èdPK ^¸\¤�b•a/b/516UT¼jux èdPK ^¸\¤�£•a/b/517UT¼jux èdPK ^¸\¤�ä•a/b/518UT¼jux èdPK ^¸\¤�%–a/b/519UT¼jux èdPK ^¸\¤�f–a/b/520UT¼jux èdPK ^¸\¤�§–a/b/521UT¼jux èdPK ^¸\¤�è–a/b/522UT¼jux èdPK ^¸\¤�)—a/b/523UT¼jux èdPK ^¸\¤�j—a/b/524UT¼jux èdPK ^¸\¤�«—a/b/525UT¼jux èdPK ^¸\¤�ì—a/b/526UT¼jux èdPK ^¸\¤�-˜a/b/527UT¼jux èdPK ^¸\¤�n˜a/b/528UT¼jux èdPK ^¸\¤�¯˜a/b/529UT¼jux èdPK ^¸\¤�ð˜a/b/530UT¼jux èdPK ^¸\¤�1™a/b/531UT¼jux èdPK ^¸\¤�r™a/b/532UT¼jux èdPK ^¸\¤�³™a/b/533UT¼jux èdPK ^¸\¤�ô™a/b/534UT¼jux èdPK ^¸\¤�5ša/b/535UT¼jux èdPK ^¸\¤�vša/b/536UT¼jux èdPK ^¸\¤�·ša/b/537UT¼jux èdPK ^¸\¤�øša/b/538UT¼jux èdPK ^¸\¤�9›a/b/539UT¼jux èdPK ^¸\¤�z›a/b/540UT¼jux èdPK ^¸\¤�»›a/b/541UT¼jux èdPK ^¸\¤�ü›a/b/542UT¼jux èdPK ^¸\¤�=œa/b/543UT¼jux èdPK ^¸\¤�~œa/b/544UT¼jux èdPK ^¸\¤�¿œa/b/545UT¼jux èdPK ^¸\¤��a/b/546UT¼jux èdPK ^¸\¤�A�a/b/547UT¼jux èdPK ^¸\¤�‚�a/b/548UT¼jux èdPK ^¸\¤�Ã�a/b/549UT¼jux èdPK ^¸\¤�ža/b/550UT¼jux èdPK ^¸\¤�Eža/b/551UT¼jux èdPK ^¸\¤�†ža/b/552UT¼jux èdPK ^¸\¤�Çža/b/553UT¼jux èdPK ^¸\¤�Ÿa/b/554UT¼jux èdPK ^¸\¤�IŸa/b/555UT¼jux èdPK ^¸\¤�ŠŸa/b/556UT¼jux èdPK ^¸\¤�ËŸa/b/557UT¼jux èdPK ^¸\¤�  a/b/558UT¼jux èdPK ^¸\¤�M a/b/559UT¼jux èdPK ^¸\¤�Ž a/b/560UT¼jux èdPK ^¸\¤�Ï a/b/561UT¼jux èdPK ^¸\¤�¡a/b/562UT¼jux èdPK ^¸\¤�Q¡a/b/563UT¼jux èdPK ^¸\¤�’¡a/b/564UT¼jux èdPK ^¸\¤�Ó¡a/b/565UT¼jux èdPK ^¸\¤�¢a/b/566UT¼jux èdPK ^¸\¤�U¢a/b/567UT¼jux èdPK ^¸\¤�–¢a/b/568UT¼jux èdPK ^¸\¤�×¢a/b/569UT¼jux èdPK ^¸\¤�£a/b/570UT¼jux èdPK ^¸\¤�Y£a/b/571UT¼jux èdPK ^¸\¤�š£a/b/572UT¼jux èdPK ^¸\¤�Û£a/b/573UT¼jux èdPK ^¸\¤�¤a/b/574UT¼jux èdPK ^¸\¤�]¤a/b/575UT¼jux èdPK ^¸\¤�ž¤a/b/576UT¼jux èdPK ^¸\¤�ߤa/b/577UT¼jux èdPK ^¸\¤� ¥a/b/578UT¼jux èdPK ^¸\¤�a¥a/b/579UT¼jux èdPK ^¸\¤�¢¥a/b/580UT¼jux èdPK ^¸\¤�ã¥a/b/581UT¼jux èdPK ^¸\¤�$¦a/b/582UT¼jux èdPK ^¸\¤�e¦a/b/583UT¼jux èdPK ^¸\¤�¦¦a/b/584UT¼jux èdPK ^¸\¤�ç¦a/b/585UT¼jux èdPK ^¸\¤�(§a/b/586UT¼jux èdPK ^¸\¤�i§a/b/587UT¼jux èdPK ^¸\¤�ª§a/b/588UT¼jux èdPK ^¸\¤�ë§a/b/589UT¼jux èdPK ^¸\¤�,¨a/b/590UT¼jux èdPK ^¸\¤�m¨a/b/591UT¼jux èdPK ^¸\¤�®¨a/b/592UT¼jux èdPK ^¸\¤�ï¨a/b/593UT¼jux èdPK ^¸\¤�0©a/b/594UT¼jux èdPK ^¸\¤�q©a/b/595UT¼jux èdPK ^¸\¤�²©a/b/596UT¼jux èdPK ^¸\¤�ó©a/b/597UT¼jux èdPK ^¸\¤�4ªa/b/598UT¼jux èdPK ^¸\¤�uªa/b/599UT¼jux èdPK ^¸\¤�¶ªa/b/600UT¼jux èdPK ^¸\¤�÷ªa/b/601UT¼jux èdPK ^¸\¤�8«a/b/602UT¼jux èdPK ^¸\¤�y«a/b/603UT¼jux èdPK ^¸\¤�º«a/b/604UT¼jux èdPK ^¸\¤�û«a/b/605UT¼jux èdPK ^¸\¤�<¬a/b/606UT¼jux èdPK ^¸\¤�}¬a/b/607UT¼jux èdPK ^¸\¤�¾¬a/b/608UT¼jux èdPK ^¸\¤�ÿ¬a/b/609UT¼jux èdPK ^¸\¤�@­a/b/610UT¼jux èdPK ^¸\¤��­a/b/611UT¼jux èdPK ^¸\¤�­a/b/612UT½jux èdPK ^¸\¤�®a/b/613UT½jux èdPK ^¸\¤�D®a/b/614UT½jux èdPK ^¸\¤�…®a/b/615UT½jux èdPK ^¸\¤�Æ®a/b/616UT½jux èdPK ^¸\¤�¯a/b/617UT½jux èdPK ^¸\¤�H¯a/b/618UT½jux èdPK ^¸\¤�‰¯a/b/619UT½jux èdPK ^¸\¤�ʯa/b/620UT½jux èdPK ^¸\¤� °a/b/621UT½jux èdPK ^¸\¤�L°a/b/622UT½jux èdPK ^¸\¤��°a/b/623UT½jux èdPK ^¸\¤�ΰa/b/624UT½jux èdPK ^¸\¤�±a/b/625UT½jux èdPK ^¸\¤�P±a/b/626UT½jux èdPK ^¸\¤�‘±a/b/627UT½jux èdPK ^¸\¤�Ò±a/b/628UT½jux èdPK ^¸\¤�²a/b/629UT½jux èdPK ^¸\¤�T²a/b/630UT½jux èdPK ^¸\¤�•²a/b/631UT½jux èdPK ^¸\¤�Ö²a/b/632UT½jux èdPK ^¸\¤�³a/b/633UT½jux èdPK ^¸\¤�X³a/b/634UT½jux èdPK ^¸\¤�™³a/b/635UT½jux èdPK ^¸\¤�Ú³a/b/636UT½jux èdPK ^¸\¤�´a/b/637UT½jux èdPK ^¸\¤�\´a/b/638UT½jux èdPK ^¸\¤��´a/b/639UT½jux èdPK ^¸\¤�Þ´a/b/640UT½jux èdPK ^¸\¤�µa/b/641UT½jux èdPK ^¸\¤�`µa/b/642UT½jux èdPK ^¸\¤�¡µa/b/643UT½jux èdPK ^¸\¤�âµa/b/644UT½jux èdPK ^¸\¤�#¶a/b/645UT½jux èdPK ^¸\¤�d¶a/b/646UT½jux èdPK ^¸\¤�¥¶a/b/647UT½jux èdPK ^¸\¤�æ¶a/b/648UT½jux èdPK ^¸\¤�'·a/b/649UT½jux èdPK ^¸\¤�h·a/b/650UT½jux èdPK ^¸\¤�©·a/b/651UT½jux èdPK ^¸\¤�ê·a/b/652UT½jux èdPK ^¸\¤�+¸a/b/653UT½jux èdPK ^¸\¤�l¸a/b/654UT½jux èdPK ^¸\¤�­¸a/b/655UT½jux èdPK ^¸\¤�î¸a/b/656UT½jux èdPK ^¸\¤�/¹a/b/657UT½jux èdPK ^¸\¤�p¹a/b/658UT½jux èdPK ^¸\¤�±¹a/b/659UT½jux èdPK ^¸\¤�ò¹a/b/660UT½jux èdPK ^¸\¤�3ºa/b/661UT½jux èdPK ^¸\¤�tºa/b/662UT½jux èdPK ^¸\¤�µºa/b/663UT½jux èdPK ^¸\¤�öºa/b/664UT½jux èdPK ^¸\¤�7»a/b/665UT½jux èdPK ^¸\¤�x»a/b/666UT½jux èdPK ^¸\¤�¹»a/b/667UT½jux èdPK ^¸\¤�ú»a/b/668UT½jux èdPK ^¸\¤�;¼a/b/669UT½jux èdPK ^¸\¤�|¼a/b/670UT½jux èdPK ^¸\¤�½¼a/b/671UT½jux èdPK ^¸\¤�þ¼a/b/672UT½jux èdPK ^¸\¤�?½a/b/673UT½jux èdPK ^¸\¤�€½a/b/674UT½jux èdPK ^¸\¤�Á½a/b/675UT½jux èdPK ^¸\¤�¾a/b/676UT½jux èdPK ^¸\¤�C¾a/b/677UT½jux èdPK ^¸\¤�„¾a/b/678UT½jux èdPK ^¸\¤�ža/b/679UT½jux èdPK ^¸\¤�¿a/b/680UT½jux èdPK ^¸\¤�G¿a/b/681UT½jux èdPK ^¸\¤�ˆ¿a/b/682UT½jux èdPK ^¸\¤�É¿a/b/683UT½jux èdPK ^¸\¤� Àa/b/684UT½jux èdPK ^¸\¤�KÀa/b/685UT½jux èdPK ^¸\¤�ŒÀa/b/686UT½jux èdPK ^¸\¤�ÍÀa/b/687UT½jux èdPK ^¸\¤�Áa/b/688UT½jux èdPK ^¸\¤�OÁa/b/689UT½jux èdPK ^¸\¤��Áa/b/690UT½jux èdPK ^¸\¤�ÑÁa/b/691UT½jux èdPK ^¸\¤�Âa/b/692UT½jux èdPK ^¸\¤�SÂa/b/693UT½jux èdPK ^¸\¤�”Âa/b/694UT½jux èdPK ^¸\¤�ÕÂa/b/695UT½jux èdPK ^¸\¤�Ãa/b/696UT½jux èdPK ^¸\¤�WÃa/b/697UT½jux èdPK ^¸\¤�˜Ãa/b/698UT½jux èdPK ^¸\¤�ÙÃa/b/699UT½jux èdPK ^¸\¤�Äa/b/700UT½jux èdPK ^¸\¤�[Äa/b/701UT½jux èdPK ^¸\¤�œÄa/b/702UT½jux èdPK ^¸\¤�ÝÄa/b/703UT½jux èdPK ^¸\¤�Åa/b/704UT½jux èdPK ^¸\¤�_Åa/b/705UT½jux èdPK ^¸\¤� Åa/b/706UT½jux èdPK ^¸\¤�áÅa/b/707UT½jux èdPK ^¸\¤�"Æa/b/708UT½jux èdPK ^¸\¤�cÆa/b/709UT½jux èdPK ^¸\¤�¤Æa/b/710UT½jux èdPK ^¸\¤�åÆa/b/711UT½jux èdPK ^¸\¤�&Ça/b/712UT½jux èdPK ^¸\¤�gÇa/b/713UT½jux èdPK ^¸\¤�¨Ça/b/714UT½jux èdPK ^¸\¤�éÇa/b/715UT½jux èdPK ^¸\¤�*Èa/b/716UT½jux èdPK ^¸\¤�kÈa/b/717UT½jux èdPK ^¸\¤�¬Èa/b/718UT½jux èdPK ^¸\¤�íÈa/b/719UT½jux èdPK ^¸\¤�.Éa/b/720UT½jux èdPK ^¸\¤�oÉa/b/721UT½jux èdPK ^¸\¤�°Éa/b/722UT½jux èdPK ^¸\¤�ñÉa/b/723UT½jux èdPK ^¸\¤�2Êa/b/724UT½jux èdPK ^¸\¤�sÊa/b/725UT½jux èdPK ^¸\¤�´Êa/b/726UT½jux èdPK ^¸\¤�õÊa/b/727UT½jux èdPK ^¸\¤�6Ëa/b/728UT½jux èdPK ^¸\¤�wËa/b/729UT½jux èdPK ^¸\¤�¸Ëa/b/730UT½jux èdPK ^¸\¤�ùËa/b/731UT½jux èdPK ^¸\¤�:Ìa/b/732UT½jux èdPK ^¸\¤�{Ìa/b/733UT½jux èdPK ^¸\¤�¼Ìa/b/734UT½jux èdPK ^¸\¤�ýÌa/b/735UT½jux èdPK ^¸\¤�>Ía/b/736UT½jux èdPK ^¸\¤�Ía/b/737UT½jux èdPK ^¸\¤�ÀÍa/b/738UT½jux èdPK ^¸\¤�Îa/b/739UT½jux èdPK ^¸\¤�BÎa/b/740UT½jux èdPK ^¸\¤�ƒÎa/b/741UT½jux èdPK ^¸\¤�ÄÎa/b/742UT½jux èdPK ^¸\¤�Ïa/b/743UT½jux èdPK ^¸\¤�FÏa/b/744UT½jux èdPK ^¸\¤�‡Ïa/b/745UT½jux èdPK ^¸\¤�ÈÏa/b/746UT½jux èdPK ^¸\¤� Ða/b/747UT½jux èdPK ^¸\¤�JÐa/b/748UT½jux èdPK ^¸\¤�‹Ða/b/749UT½jux èdPK ^¸\¤�ÌÐa/b/750UT½jux èdPK ^¸\¤� Ña/b/751UT½jux èdPK ^¸\¤�NÑa/b/752UT½jux èdPK ^¸\¤��Ña/b/753UT½jux èdPK ^¸\¤�ÐÑa/b/754UT½jux èdPK ^¸\¤�Òa/b/755UT½jux èdPK ^¸\¤�RÒa/b/756UT½jux èdPK ^¸\¤�“Òa/b/757UT½jux èdPK ^¸\¤�ÔÒa/b/758UT½jux èdPK ^¸\¤�Óa/b/759UT½jux èdPK ^¸\¤�VÓa/b/760UT½jux èdPK ^¸\¤�—Óa/b/761UT½jux èdPK ^¸\¤�ØÓa/b/762UT½jux èdPK ^¸\¤�Ôa/b/763UT½jux èdPK ^¸\¤�ZÔa/b/764UT½jux èdPK ^¸\¤�›Ôa/b/765UT½jux èdPK ^¸\¤�ÜÔa/b/766UT½jux èdPK ^¸\¤�Õa/b/767UT½jux èdPK ^¸\¤�^Õa/b/768UT½jux èdPK ^¸\¤�ŸÕa/b/769UT½jux èdPK ^¸\¤�àÕa/b/770UT½jux èdPK ^¸\¤�!Öa/b/771UT½jux èdPK ^¸\¤�bÖa/b/772UT½jux èdPK ^¸\¤�£Öa/b/773UT½jux èdPK ^¸\¤�äÖa/b/774UT½jux èdPK ^¸\¤�%×a/b/775UT½jux èdPK ^¸\¤�f×a/b/776UT½jux èdPK ^¸\¤�§×a/b/777UT½jux èdPK ^¸\¤�è×a/b/778UT½jux èdPK ^¸\¤�)Øa/b/779UT½jux èdPK ^¸\¤�jØa/b/780UT½jux èdPK ^¸\¤�«Øa/b/781UT½jux èdPK ^¸\¤�ìØa/b/782UT½jux èdPK ^¸\¤�-Ùa/b/783UT½jux èdPK ^¸\¤�nÙa/b/784UT½jux èdPK ^¸\¤�¯Ùa/b/785UT½jux èdPK ^¸\¤�ðÙa/b/786UT½jux èdPK ^¸\¤�1Úa/b/787UT½jux èdPK ^¸\¤�rÚa/b/788UT½jux èdPK ^¸\¤�³Úa/b/789UT½jux èdPK ^¸\¤�ôÚa/b/790UT½jux èdPK ^¸\¤�5Ûa/b/791UT½jux èdPK ^¸\¤�vÛa/b/792UT½jux èdPK ^¸\¤�·Ûa/b/793UT½jux èdPK ^¸\¤�øÛa/b/794UT½jux èdPK ^¸\¤�9Üa/b/795UT½jux èdPK ^¸\¤�zÜa/b/796UT½jux èdPK ^¸\¤�»Üa/b/797UT½jux èdPK ^¸\¤�üÜa/b/798UT½jux èdPK ^¸\¤�=Ýa/b/799UT½jux èdPK ^¸\¤�~Ýa/b/800UT½jux èdPK ^¸\¤�¿Ýa/b/801UT½jux èdPK ^¸\¤�Þa/b/802UT½jux èdPK ^¸\¤�AÞa/b/803UT½jux èdPK ^¸\¤�‚Þa/b/804UT½jux èdPK ^¸\¤�ÃÞa/b/805UT½jux èdPK ^¸\¤�ßa/b/806UT½jux èdPK ^¸\¤�Eßa/b/807UT½jux èdPK ^¸\¤�†ßa/b/808UT½jux èdPK ^¸\¤�Çßa/b/809UT½jux èdPK ^¸\¤�àa/b/810UT½jux èdPK ^¸\¤�Iàa/b/811UT½jux èdPK ^¸\¤�Šàa/b/812UT½jux èdPK ^¸\¤�Ëàa/b/813UT½jux èdPK ^¸\¤� áa/b/814UT½jux èdPK ^¸\¤�Máa/b/815UT½jux èdPK ^¸\¤�Žáa/b/816UT½jux èdPK ^¸\¤�Ïáa/b/817UT½jux èdPK ^¸\¤�âa/b/818UT½jux èdPK ^¸\¤�Qâa/b/819UT½jux èdPK ^¸\¤�’âa/b/820UT½jux èdPK ^¸\¤�Óâa/b/821UT½jux èdPK ^¸\¤�ãa/b/822UT½jux èdPK ^¸\¤�Uãa/b/823UT½jux èdPK ^¸\¤�–ãa/b/824UT½jux èdPK ^¸\¤�×ãa/b/825UT½jux èdPK ^¸\¤�äa/b/826UT½jux èdPK ^¸\¤�Yäa/b/827UT½jux èdPK ^¸\¤�šäa/b/828UT½jux èdPK ^¸\¤�Ûäa/b/829UT½jux èdPK ^¸\¤�åa/b/830UT½jux èdPK ^¸\¤�]åa/b/831UT½jux èdPK ^¸\¤�žåa/b/832UT½jux èdPK ^¸\¤�ßåa/b/833UT½jux èdPK ^¸\¤� æa/b/834UT½jux èdPK ^¸\¤�aæa/b/835UT½jux èdPK ^¸\¤�¢æa/b/836UT½jux èdPK ^¸\¤�ãæa/b/837UT½jux èdPK ^¸\¤�$ça/b/838UT½jux èdPK ^¸\¤�eça/b/839UT½jux èdPK ^¸\¤�¦ça/b/840UT½jux èdPK ^¸\¤�çça/b/841UT½jux èdPK ^¸\¤�(èa/b/842UT½jux èdPK ^¸\¤�ièa/b/843UT½jux èdPK ^¸\¤�ªèa/b/844UT½jux èdPK ^¸\¤�ëèa/b/845UT½jux èdPK ^¸\¤�,éa/b/846UT½jux èdPK ^¸\¤�méa/b/847UT½jux èdPK ^¸\¤�®éa/b/848UT½jux èdPK ^¸\¤�ïéa/b/849UT½jux èdPK ^¸\¤�0êa/b/850UT½jux èdPK ^¸\¤�qêa/b/851UT½jux èdPK ^¸\¤�²êa/b/852UT½jux èdPK ^¸\¤�óêa/b/853UT½jux èdPK ^¸\¤�4ëa/b/854UT½jux èdPK ^¸\¤�uëa/b/855UT½jux èdPK ^¸\¤�¶ëa/b/856UT½jux èdPK ^¸\¤�÷ëa/b/857UT½jux èdPK ^¸\¤�8ìa/b/858UT½jux èdPK ^¸\¤�yìa/b/859UT½jux èdPK ^¸\¤�ºìa/b/860UT½jux èdPK ^¸\¤�ûìa/b/861UT½jux èdPK ^¸\¤�<ía/b/862UT½jux èdPK ^¸\¤�}ía/b/863UT½jux èdPK ^¸\¤�¾ía/b/864UT½jux èdPK ^¸\¤�ÿía/b/865UT½jux èdPK ^¸\¤�@îa/b/866UT½jux èdPK ^¸\¤��îa/b/867UT½jux èdPK ^¸\¤�Âîa/b/868UT½jux èdPK ^¸\¤�ïa/b/869UT½jux èdPK ^¸\¤�Dïa/b/870UT½jux èdPK ^¸\¤�…ïa/b/871UT½jux èdPK ^¸\¤�Æïa/b/872UT½jux èdPK ^¸\¤�ða/b/873UT½jux èdPK ^¸\¤�Hða/b/874UT½jux èdPK ^¸\¤�‰ða/b/875UT½jux èdPK ^¸\¤�Êða/b/876UT½jux èdPK ^¸\¤� ña/b/877UT½jux èdPK ^¸\¤�Lña/b/878UT½jux èdPK ^¸\¤��ña/b/879UT½jux èdPK ^¸\¤�Îña/b/880UT½jux èdPK ^¸\¤�òa/b/881UT½jux èdPK ^¸\¤�Pòa/b/882UT½jux èdPK ^¸\¤�‘òa/b/883UT½jux èdPK ^¸\¤�Òòa/b/884UT½jux èdPK ^¸\¤�óa/b/885UT½jux èdPK ^¸\¤�Tóa/b/886UT½jux èdPK ^¸\¤�•óa/b/887UT½jux èdPK ^¸\¤�Öóa/b/888UT½jux èdPK ^¸\¤�ôa/b/889UT½jux èdPK ^¸\¤�Xôa/b/890UT½jux èdPK ^¸\¤�™ôa/b/891UT½jux èdPK ^¸\¤�Úôa/b/892UT½jux èdPK ^¸\¤�õa/b/893UT½jux èdPK ^¸\¤�\õa/b/894UT½jux èdPK ^¸\¤��õa/b/895UT½jux èdPK ^¸\¤�Þõa/b/896UT½jux èdPK ^¸\¤�öa/b/897UT½jux èdPK ^¸\¤�`öa/b/898UT½jux èdPK ^¸\¤�¡öa/b/899UT½jux èdPK ^¸\¤�âöa/b/900UT½jux èdPK ^¸\¤�#÷a/b/901UT½jux èdPK ^¸\¤�d÷a/b/902UT½jux èdPK ^¸\¤�¥÷a/b/903UT½jux èdPK ^¸\¤�æ÷a/b/904UT½jux èdPK ^¸\¤�'øa/b/905UT½jux èdPK ^¸\¤�høa/b/906UT½jux èdPK ^¸\¤�©øa/b/907UT½jux èdPK ^¸\¤�êøa/b/908UT½jux èdPK ^¸\¤�+ùa/b/909UT½jux èdPK ^¸\¤�lùa/b/910UT½jux èdPK ^¸\¤�­ùa/b/911UT½jux èdPK ^¸\¤�îùa/b/912UT½jux èdPK ^¸\¤�/úa/b/913UT½jux èdPK ^¸\¤�púa/b/914UT½jux èdPK ^¸\¤�±úa/b/915UT½jux èdPK ^¸\¤�òúa/b/916UT½jux èdPK ^¸\¤�3ûa/b/917UT½jux èdPK ^¸\¤�tûa/b/918UT½jux èdPK ^¸\¤�µûa/b/919UT½jux èdPK ^¸\¤�öûa/b/920UT½jux èdPK ^¸\¤�7üa/b/921UT½jux èdPK ^¸\¤�xüa/b/922UT½jux èdPK ^¸\¤�¹üa/b/923UT½jux èdPK ^¸\¤�úüa/b/924UT½jux èdPK ^¸\¤�;ýa/b/925UT½jux èdPK ^¸\¤�|ýa/b/926UT½jux èdPK ^¸\¤�½ýa/b/927UT½jux èdPK ^¸\¤�þýa/b/928UT½jux èdPK ^¸\¤�?þa/b/929UT½jux èdPK ^¸\¤�€þa/b/930UT½jux èdPK ^¸\¤�Áþa/b/931UT½jux èdPK ^¸\¤�ÿa/b/932UT½jux èdPK ^¸\¤�Cÿa/b/933UT½jux èdPK ^¸\¤�„ÿa/b/934UT½jux èdPK ^¸\¤�Åÿa/b/935UT½jux èdPK ^¸\¤�a/b/936UT½jux èdPK ^¸\¤�Ga/b/937UT½jux èdPK ^¸\¤�ˆa/b/938UT½jux èdPK ^¸\¤�Éa/b/939UT½jux èdPK ^¸\¤� a/b/940UT½jux èdPK ^¸\¤�Ka/b/941UT½jux èdPK ^¸\¤�Œa/b/942UT½jux èdPK ^¸\¤�Ía/b/943UT½jux èdPK ^¸\¤�a/b/944UT½jux èdPK ^¸\¤�Oa/b/945UT½jux èdPK ^¸\¤��a/b/946UT½jux èdPK ^¸\¤�Ña/b/947UT½jux èdPK ^¸\¤�a/b/948UT½jux èdPK ^¸\¤�Sa/b/949UT½jux èdPK ^¸\¤�”a/b/950UT½jux èdPK ^¸\¤�Õa/b/951UT½jux èdPK ^¸\¤�a/b/952UT½jux èdPK ^¸\¤�Wa/b/953UT½jux èdPK ^¸\¤�˜a/b/954UT½jux èdPK ^¸\¤�Ùa/b/955UT½jux èdPK ^¸\¤�a/b/956UT½jux èdPK ^¸\¤�[a/b/957UT½jux èdPK ^¸\¤�œa/b/958UT½jux èdPK ^¸\¤�Ýa/b/959UT½jux èdPK ^¸\¤�a/b/960UT½jux èdPK ^¸\¤�_a/b/961UT½jux èdPK ^¸\¤� a/b/962UT½jux èdPK ^¸\¤�áa/b/963UT½jux èdPK ^¸\¤�"a/b/964UT½jux èdPK ^¸\¤�ca/b/965UT½jux èdPK ^¸\¤�¤a/b/966UT½jux èdPK ^¸\¤�åa/b/967UT½jux èdPK ^¸\¤�&a/b/968UT½jux èdPK ^¸\¤�ga/b/969UT½jux èdPK ^¸\¤�¨a/b/970UT½jux èdPK ^¸\¤�éa/b/971UT½jux èdPK ^¸\¤�* a/b/972UT½jux èdPK ^¸\¤�k a/b/973UT½jux èdPK ^¸\¤�¬ a/b/974UT½jux èdPK ^¸\¤�í a/b/975UT½jux èdPK ^¸\¤�. a/b/976UT½jux èdPK ^¸\¤�o a/b/977UT½jux èdPK ^¸\¤�° a/b/978UT½jux èdPK ^¸\¤�ñ a/b/979UT½jux èdPK ^¸\¤�2 a/b/980UT½jux èdPK ^¸\¤�s a/b/981UT½jux èdPK ^¸\¤�´ a/b/982UT½jux èdPK ^¸\¤�õ a/b/983UT½jux èdPK ^¸\¤�6 a/b/984UT½jux èdPK ^¸\¤�w a/b/985UT½jux èdPK ^¸\¤�¸ a/b/986UT½jux èdPK ^¸\¤�ù a/b/987UT½jux èdPK ^¸\¤�: a/b/988UT½jux èdPK ^¸\¤�{ a/b/989UT½jux èdPK ^¸\¤�¼ a/b/990UT½jux èdPK ^¸\¤�ý a/b/991UT½jux èdPK ^¸\¤�>a/b/992UT½jux èdPK ^¸\¤�a/b/993UT½jux èdPK ^¸\¤�Àa/b/994UT½jux èdPK ^¸\¤�a/b/995UT½jux èdPK ^¸\¤�Ba/b/996UT½jux èdPK ^¸\¤�ƒa/b/997UT½jux èdPK ^¸\¤�Äa/b/998UT½jux èdPK ^¸\¤�a/b/999UT½jux èdPKîîÛ.Fyauzl-3.4.0/test/success/everything/000077500000000000000000000000001521126516100174755ustar00rootroot00000000000000yauzl-3.4.0/test/success/everything/0x21000000066400000000000000000004100001521126516100203250ustar00rootroot00000000000000yauzl-3.4.0/test/success/everything/a/000077500000000000000000000000001521126516100177155ustar00rootroot00000000000000yauzl-3.4.0/test/success/everything/a/b/000077500000000000000000000000001521126516100201365ustar00rootroot00000000000000yauzl-3.4.0/test/success/everything/a/b/c/000077500000000000000000000000001521126516100203605ustar00rootroot00000000000000yauzl-3.4.0/test/success/everything/a/b/c/0x21000000066400000000000000000004100001521126516100212100ustar00rootroot00000000000000longlonglonglonglonglonglonglonglonglonglonglonglonglonglongkindalongname.txt000066400000000000000000000000001521126516100377140ustar00rootroot00000000000000yauzl-3.4.0/test/success/everything/ayauzl-3.4.0/test/success/linux-info-zip.zip000066400000000000000000000004641521126516100207310ustar00rootroot00000000000000PK ÛKEQàV‡a.txtUT >*òS>*òSux èèasdf PK ÛKE�šöÀb.txtUT >*òS>*òSux èèbsdf PK ÛKEQàV‡¤�a.txtUT>*òSux èèPK ÛKE�šöÀ¤�Db.txtUT>*òSux èèPK–ˆyauzl-3.4.0/test/success/linux-info-zip/000077500000000000000000000000001521126516100202015ustar00rootroot00000000000000yauzl-3.4.0/test/success/linux-info-zip/a.txt000066400000000000000000000000051521126516100211550ustar00rootroot00000000000000asdf yauzl-3.4.0/test/success/linux-info-zip/b.txt000066400000000000000000000000051521126516100211560ustar00rootroot00000000000000bsdf yauzl-3.4.0/test/success/sloppy-filenames.zip000066400000000000000000000004641521126516100213300ustar00rootroot00000000000000PK ÛKEQàV‡a.txtUT >*òS>*òSux èèasdf PK ÛKE�šöÀb.txtUT >*òS>*òSux èèbsdf PK ÛKEQàV‡¤�a\txtUT>*òSux èèPK ÛKE�šöÀ¤�Db.txtUT>*òSux èèPK–ˆyauzl-3.4.0/test/success/sloppy-filenames/000077500000000000000000000000001521126516100206005ustar00rootroot00000000000000yauzl-3.4.0/test/success/sloppy-filenames/a/000077500000000000000000000000001521126516100210205ustar00rootroot00000000000000yauzl-3.4.0/test/success/sloppy-filenames/a/.dont_expect_an_empty_dir_entry_for_this_dir000066400000000000000000000000001521126516100320310ustar00rootroot00000000000000yauzl-3.4.0/test/success/sloppy-filenames/a/txt000066400000000000000000000000051521126516100215550ustar00rootroot00000000000000asdf yauzl-3.4.0/test/success/sloppy-filenames/b.txt000066400000000000000000000000051521126516100215550ustar00rootroot00000000000000bsdf yauzl-3.4.0/test/success/streaming.zip000066400000000000000000000004241521126516100200260ustar00rootroot00000000000000PKµ3cZ test1.txtKËÏOƸPK²¸ÈOPK¹3cZ test2.txtKJ,J†¸PK4² ÎPK?µ3cZ²¸ÈO ¤�test1.txtUT§’ÅgPK?¹3cZ4² Î ¤�?test2.txtUT®’ÅgPK€~yauzl-3.4.0/test/success/streaming/000077500000000000000000000000001521126516100173025ustar00rootroot00000000000000yauzl-3.4.0/test/success/streaming/test1.txt000066400000000000000000000000311521126516100210750ustar00rootroot00000000000000foofoofoofoofoofoofoofoo yauzl-3.4.0/test/success/streaming/test2.txt000066400000000000000000000000311521126516100210760ustar00rootroot00000000000000barbarbarbarbarbarbarbar yauzl-3.4.0/test/success/traditional-encryption-and-compression.zip000066400000000000000000000003071521126516100256360ustar00rootroot00000000000000PK ·”’J€ èa.binUT i¿öXi¿öXux èèªãc.š€,ÿŒ"™s® IXù}Y`PK€ èPK ·”’J€ è´�a.binUTi¿öXux èèPKKfyauzl-3.4.0/test/success/traditional-encryption-and-compression/000077500000000000000000000000001521126516100251125ustar00rootroot00000000000000yauzl-3.4.0/test/success/traditional-encryption-and-compression/a.bin000066400000000000000000000000271521126516100260230ustar00rootroot00000000000000ªãc.š€,ÿŒ"™s® IXù}Y`yauzl-3.4.0/test/success/traditional-encryption-and-compression_deprecated.zip000066400000000000000000000003071521126516100300160ustar00rootroot00000000000000PK ·”’J€ èa.binUT i¿öXi¿öXux èèªãc.š€,ÿŒ"™s® IXù}Y`PK€ èPK ·”’J€ è´�a.binUTi¿öXux èèPKKfyauzl-3.4.0/test/success/traditional-encryption-and-compression_deprecated/000077500000000000000000000000001521126516100272725ustar00rootroot00000000000000yauzl-3.4.0/test/success/traditional-encryption-and-compression_deprecated/a.bin000066400000000000000000000000271521126516100302030ustar00rootroot00000000000000ªãc.š€,ÿŒ"™s® IXù}Y`yauzl-3.4.0/test/success/traditional-encryption.zip000066400000000000000000000003021521126516100225320ustar00rootroot00000000000000PK û‰’J 0:6a.txtUT :¬öXE¬öXux èèš(=þ0þ•¼ŸÓX Ý&]b\PK 0:6PK û‰’J 0:6´�a.txtUT:¬öXux èèPKKayauzl-3.4.0/test/success/traditional-encryption/000077500000000000000000000000001521126516100220135ustar00rootroot00000000000000yauzl-3.4.0/test/success/traditional-encryption/a.txt000066400000000000000000000000221521126516100227660ustar00rootroot00000000000000š(=þ0þ•¼ŸÓX Ý&]b\yauzl-3.4.0/test/success/traditional-encryption_deprecated.zip000066400000000000000000000003021521126516100247120ustar00rootroot00000000000000PK û‰’J 0:6a.txtUT :¬öXE¬öXux èèš(=þ0þ•¼ŸÓX Ý&]b\PK 0:6PK û‰’J 0:6´�a.txtUT:¬öXux èèPKKayauzl-3.4.0/test/success/traditional-encryption_deprecated/000077500000000000000000000000001521126516100241735ustar00rootroot00000000000000yauzl-3.4.0/test/success/traditional-encryption_deprecated/a.txt000066400000000000000000000000221521126516100251460ustar00rootroot00000000000000š(=þ0þ•¼ŸÓX Ý&]b\yauzl-3.4.0/test/success/unicode-path-extra-field.zip000066400000000000000000000003411521126516100226150ustar00rootroot00000000000000PK-%�ÎH upˆâÎÎ七个房间.txtPKPK?-%�ÎH6´� upˆâÎÎupˆâÎÎäupˆÿÿÿÿupˆâÎÎ七个房间.txtPKtWyauzl-3.4.0/test/success/unicode-path-extra-field/000077500000000000000000000000001521126516100220735ustar00rootroot00000000000000yauzl-3.4.0/test/success/unicode-path-extra-field/qi ge fangjian.txt000066400000000000000000000000001521126516100253450ustar00rootroot00000000000000yauzl-3.4.0/test/success/unicode.zip000066400000000000000000000017641521126516100174730ustar00rootroot00000000000000PK z ETurmion Kätilöt/UT èéþSêþSux èèPK E ETurmion Kätilöt/Hoitovirhe/UT �éþSêþSux èèPK � E+Turmion Kätilöt/Hoitovirhe/Rautaketju.mp3UT êþS8FþSux èèPK ¢ ETurmion Kätilöt/Pirun nyrkki/UT 0êþS1êþSux èèPK • E6Turmion Kätilöt/Pirun nyrkki/Mistä veri pakenee.mp3UT êþS:FþSux èèPK z EýATurmion Kätilöt/UTèéþSux èèPK E EýALTurmion Kätilöt/Hoitovirhe/UT�éþSux èèPK � E+´�£Turmion Kätilöt/Hoitovirhe/Rautaketju.mp3UTêþSux èèPK ¢ EýATurmion Kätilöt/Pirun nyrkki/UT0êþSux èèPK • E6´�aTurmion Kätilöt/Pirun nyrkki/Mistä veri pakenee.mp3UTêþSux èèPK Ñyauzl-3.4.0/test/success/unicode/000077500000000000000000000000001521126516100167375ustar00rootroot00000000000000yauzl-3.4.0/test/success/unicode/Turmion Katilot/000077500000000000000000000000001521126516100217645ustar00rootroot00000000000000yauzl-3.4.0/test/success/unicode/Turmion Katilot/Hoitovirhe/000077500000000000000000000000001521126516100241045ustar00rootroot00000000000000yauzl-3.4.0/test/success/unicode/Turmion Katilot/Hoitovirhe/Rautaketju.mp3000066400000000000000000000000001521126516100266320ustar00rootroot00000000000000yauzl-3.4.0/test/success/unicode/Turmion Katilot/Pirun nyrkki/000077500000000000000000000000001521126516100243515ustar00rootroot00000000000000yauzl-3.4.0/test/success/unicode/Turmion Katilot/Pirun nyrkki/Mista veri pakenee.mp3000066400000000000000000000000001521126516100303540ustar00rootroot00000000000000yauzl-3.4.0/test/success/unix-epoch.zip000066400000000000000000000002621521126516100201140ustar00rootroot00000000000000PK !unix-epoch.txtUT ™‘&gux èdPK !¤�unix-epoch.txtUTux èdPKTHyauzl-3.4.0/test/success/unix-epoch/000077500000000000000000000000001521126516100173705ustar00rootroot00000000000000yauzl-3.4.0/test/success/unix-epoch/unix-epoch.txt000066400000000000000000000000001521126516100221760ustar00rootroot00000000000000yauzl-3.4.0/test/success/windows-7-zip.zip000077500000000000000000000004241521126516100204760ustar00rootroot00000000000000PK ÛKEQàV‡a.txtasdf PK ÛKE�šöÀb.txtbsdf PK? ÛKEQàV‡$ a.txt >ÊlÇ»Ï>ÊlÇ»Ï>ÊlÇ»ÏPK? ÛKE�šöÀ$ (b.txt ®ÛmǻϞ´mǻϞ´mÇ»ÏPK®Pyauzl-3.4.0/test/success/windows-7-zip/000077500000000000000000000000001521126516100177475ustar00rootroot00000000000000yauzl-3.4.0/test/success/windows-7-zip/a.txt000066400000000000000000000000051521126516100207230ustar00rootroot00000000000000asdf yauzl-3.4.0/test/success/windows-7-zip/b.txt000066400000000000000000000000051521126516100207240ustar00rootroot00000000000000bsdf yauzl-3.4.0/test/success/windows-compressed-folder.zip000077500000000000000000000003141521126516100231430ustar00rootroot00000000000000PKÛKEQàV‡a.txtasdf PKÛKE�šöÀb.txtbsdf PKÛKEQàV‡ a.txtPKÛKE�šöÀ (b.txtPKfPyauzl-3.4.0/test/success/windows-compressed-folder/000077500000000000000000000000001521126516100224165ustar00rootroot00000000000000yauzl-3.4.0/test/success/windows-compressed-folder/a.txt000066400000000000000000000000051521126516100233720ustar00rootroot00000000000000asdf yauzl-3.4.0/test/success/windows-compressed-folder/b.txt000066400000000000000000000000051521126516100233730ustar00rootroot00000000000000bsdf yauzl-3.4.0/test/success/zip64.zip000066400000000000000000000006201521126516100170070ustar00rootroot00000000000000PK-§} I test1.txtKËÏPK!esŒPK-¯} I test2.txtKJ,PKªŒÿvPK--§} I!esŒÿÿÿÿÿÿÿÿ  ¤�test1.txtPK--¯} IªŒÿvÿÿÿÿÿÿÿÿ  ¤�Dtest2.txtDPK,--¦ˆPK.PKÿÿÿÿÿÿÿÿÿÿÿÿyauzl-3.4.0/test/success/zip64/000077500000000000000000000000001521126516100162655ustar00rootroot00000000000000yauzl-3.4.0/test/success/zip64/test1.txt000066400000000000000000000000031521126516100200570ustar00rootroot00000000000000fooyauzl-3.4.0/test/success/zip64/test2.txt000066400000000000000000000000031521126516100200600ustar00rootroot00000000000000baryauzl-3.4.0/test/test.js000066400000000000000000000545001521126516100151620ustar00rootroot00000000000000var yauzl = require("../"); var zip64 = require("./zip64"); var rangeTest = require("./range-test"); var errorsTest = require("./errors"); var fs = require("fs"); var path = require("path"); var Pend = require("pend"); var util = require("util"); var child_process = require("child_process"); var Readable = require("stream").Readable; var Writable = require("stream").Writable; if (require("../crc32")(Buffer.from("hello")) === 907060870) { console.log("crc32: pass"); } else { throw new Error("crc32 wrong"); } // This is a month before I made the example zip files and their content files, // so this timestamp will be earlier than all the ones stored in these test zip files unless otherwise noted. var earliestTimestamp = new Date(2014, 7, 18, 0, 0, 0, 0); if (Date.now() / 1000 >= 2147483648) throw new Error("The year is 2038. The Epochalypse is uppon us. Signed 32-bit POSIX timestamps have collapsed. TODO: fix."); var pend = new Pend(); // 1 thing at a time for better determinism/reproducibility pend.max = 1; var args = process.argv.slice(2); function shouldDoTest(testPath) { if (args.length === 0) return true; return args.indexOf(testPath) !== -1; } var openFunctions = [ function(zipfilePath, testId, options, callback) { yauzl.open(zipfilePath, options, callback); }, function(zipfilePath, testId, options, callback) { yauzl.fromBuffer(fs.readFileSync(zipfilePath), options, callback); }, function(zipfilePath, testId, options, callback) { openWithRandomAccess(zipfilePath, options, true, testId, callback); }, function(zipfilePath, testId, options, callback) { openWithRandomAccess(zipfilePath, options, false, testId, callback); }, ]; var openFunctionNames = [ "fd", "buffer", "randomAccess", "minimalRandomAccess", ]; // success tests listZipFiles([path.join(__dirname, "success"), path.join(__dirname, "wrong-entry-sizes")]).forEach(function(zipfilePath) { if (!shouldDoTest(zipfilePath)) return; var optionConfigurations = [ // you can find more options coverage in the failure tests. {lazyEntries: true}, {lazyEntries: true, decodeStrings: false}, ]; if (/\/wrong-entry-sizes\//.test(zipfilePath)) { optionConfigurations.forEach(function(options) { options.validateEntrySizes = false; }); } openFunctions.forEach(function(openFunction, i) { optionConfigurations.forEach(function(options, j) { var testId = zipfilePath + "(" + openFunctionNames[i] + "," + j + "): "; var expectedPathPrefix = zipfilePath.replace(/\.zip$/, ""); var expectedArchiveContents = {}; var DIRECTORY = 1; // not a string recursiveRead("."); function recursiveRead(name) { // windows support? whatever. var name = name.replace(/\\/g, "/"); var key = addUnicodeSupport(name); var realPath = path.join(expectedPathPrefix, name); if (fs.statSync(realPath).isFile()) { switch (path.basename(name)) { case ".git_please_make_this_directory": // ignore break; case ".dont_expect_an_empty_dir_entry_for_this_dir": delete expectedArchiveContents[path.dirname(name)]; break; default: // normal file expectedArchiveContents[key] = fs.readFileSync(realPath); break; } } else { if (name !== ".") expectedArchiveContents[key] = DIRECTORY; fs.readdirSync(realPath).forEach(function(child) { recursiveRead(path.join(name, child)); }); if (name === "a/b" && path.basename(zipfilePath) === "everything.zip") { // Insert 1000 expected files here that we don't want to waste git's time with. const emptyBuffer = Buffer.from([]); for (let i = 0; i < 1000; i++) { expectedArchiveContents["a/b/" + i.toString().padStart(3, "0")] = emptyBuffer; } } } } pend.go(function(zipfileCallback) { openFunction(zipfilePath, testId, options, function(err, zipfile) { if (err) throw err; zipfile.readEntry(); zipfile.on("entry", function(entry) { var fileName = entry.fileName; var fileComment = entry.fileComment; if (options.decodeStrings === false) { if (fileName.constructor !== Buffer) throw new Error(testId + "expected fileName to be a Buffer"); fileName = manuallyDecodeFileName(fileName); fileComment = manuallyDecodeFileName(fileComment); } if (fileComment !== "") throw new Error(testId + "expected empty fileComment"); var messagePrefix = testId + fileName + ": "; var timestamp = entry.getLastModDate(); if (fileName === "unix-epoch.txt") { if (timestamp.getTime() !== 0) throw new Error(messagePrefix + "expected timestamp to be 0. found: " + timestamp); var dosTimestamp = entry.getLastModDate({forceDosFormat:true}); if (dosTimestamp.getTime() === 0) throw new Error(messagePrefix + "DOS timestamp can't encode this time: " + dosTimestamp); var dosTimestampUTC = entry.getLastModDate({forceDosFormat:true, timezone: "UTC"}); // This test is only meaningful when the system's local UTC offset is not 0. if (dosTimestamp - dosTimestampUTC !== dosTimestamp.getTimezoneOffset() * 60 * 1000) { throw new Error(messagePrefix + "expected UTC timezone to be different by the current timezone offset. " + "local: " + dosTimestamp + ", UTC: " + dosTimestampUTC ); } } else { if (timestamp < earliestTimestamp) throw new Error(messagePrefix + "timestamp too early: " + timestamp); if (timestamp > new Date()) throw new Error(messagePrefix + "timestamp in the future: " + timestamp); } var fileNameKey = fileName.replace(/\/$/, ""); var expectedContents = expectedArchiveContents[fileNameKey]; if (expectedContents == null) { throw new Error(messagePrefix + "not supposed to exist"); } delete expectedArchiveContents[fileNameKey]; if (fileName !== fileNameKey) { // directory console.log(messagePrefix + "pass"); zipfile.readEntry(); } else { var isEncrypted = entry.isEncrypted(); var isCompressed = entry.isCompressed(); if (/traditional-encryption/.test(zipfilePath) !== isEncrypted) { throw new Error("expected traditional encryption in the traditional encryption test cases"); if (/traditional-encryption-and-compression/.test(zipfilePath) !== isCompressed) { throw new Error("expected traditional encryption and compression in the traditional encryption and compression test case"); } } if (/traditional-encryption/.test(zipfilePath)) { if (entry.canDecodeFileData()) throw new Error(messagePrefix + "supposed to be unable to decode this"); if (/deprecated/.test(zipfilePath)) { // Deprecated style. zipfile.openReadStream(entry, { decrypt: false, decompress: isCompressed ? false : null, }, onReadStream); } else { // New style. zipfile.openReadStream(entry, { decodeFileData: false, }, onReadStream); } } else if (/bogus-compression-method/.test(zipfilePath)) { if (entry.canDecodeFileData()) throw new Error(messagePrefix + "supposed to be unable to decode this"); zipfile.openReadStream(entry, { decodeFileData: false, }, onReadStream); } else { if (!entry.canDecodeFileData()) throw new Error(messagePrefix + "supposed to be able to decode this"); zipfile.openReadStream(entry, onReadStream); } function onReadStream(err, readStream) { if (err) throw err; var buffers = []; readStream.on("data", function(data) { buffers.push(data); }); readStream.on("end", function() { var actualContents = Buffer.concat(buffers); // uh. there's no buffer equality check? var equal = actualContents.toString("binary") === expectedContents.toString("binary"); if (!equal) { throw new Error(messagePrefix + "wrong contents"); } if (/^a\/b\/\d{3}$/.test(fileName)) { // There are 1000 of these. if (fileName === "a/b/000") { console.log(messagePrefix + "pass (and not printing for the next 999)"); } } else { console.log(messagePrefix + "pass"); } zipfile.readEntry(); }); readStream.on("error", function(err) { console.log(testId + "fail:"); throw err; }); } } }); zipfile.on("end", function() { for (var fileName in expectedArchiveContents) { throw new Error(testId + fileName + ": missing file"); } console.log(testId + "pass"); zipfileCallback(); }); zipfile.on("close", function() { console.log(testId + "closed"); }); }); }); }); }); }); // failure tests listZipFiles([path.join(__dirname, "failure")]).forEach(function(zipfilePath) { if (!shouldDoTest(zipfilePath)) return; var expectedErrorMessage = path.basename(zipfilePath).replace(/(_\d+)?\.zip$/, ""); openFunctions.forEach(function(openFunction, i) { var testId = zipfilePath + "(" + openFunctionNames[i] + "): "; var failedYet = false; var emittedError = false; pend.go(function(cb) { var operationsInProgress = 0; var options = null; if (/invalid characters in fileName/.test(zipfilePath)) { // this error can only happen when you specify an option options = {strictFileNames: true}; } openFunction(zipfilePath, testId, options, onZipFile); function onZipFile(err, zipfile) { if (err) return checkErrorMessage(err); zipfile.on("error", function(err) { noEventsAllowedAfterError(); emittedError = true; checkErrorMessage(err); }); zipfile.on("entry", function(entry) { noEventsAllowedAfterError(); // let's also try to read directories, cuz whatever. operationsInProgress += 1; zipfile.openReadStream(entry, function(err, stream) { if (err) return checkErrorMessage(err); stream.on("error", function(err) { checkErrorMessage(err); }); stream.on("data", function(data) { // ignore }); stream.on("end", function() { doneWithSomething(); }); }); }); operationsInProgress += 1; zipfile.on("end", function() { noEventsAllowedAfterError(); doneWithSomething(); }); function doneWithSomething() { operationsInProgress -= 1; if (operationsInProgress !== 0) return; if (!failedYet) { throw new Error(testId + "expected failure"); } } } function checkErrorMessage(err) { var actualMessage = err.message.replace(/[^0-9A-Za-z-]+/g, " ").trimRight(); // eCryptfs limits file names to 143 bytes. (All file names are ascii.) actualMessage = actualMessage.slice(0, 143 - ".zip".length); if (actualMessage !== expectedErrorMessage) { if (i !== 0) { // The error messages are tuned for the common case. // Sometimes other open functions give slightly different error messages, and that's ok, // as long as we're still getting some error. } else { throw new Error(testId + "wrong error message: " + actualMessage); } } console.log(testId + "pass"); failedYet = true; operationsInProgress = -Infinity; cb(); } function noEventsAllowedAfterError() { if (emittedError) throw new Error(testId + "events emitted after error event"); } }); }); }); // fromRandomAccessReader with errors pend.go(function(cb) { util.inherits(TestRandomAccessReader, yauzl.RandomAccessReader); function TestRandomAccessReader() { yauzl.RandomAccessReader.call(this); } TestRandomAccessReader.prototype._readStreamForRange = function(start, end) { var brokenator = new Readable(); brokenator._read = function(size) { brokenator.emit("error", new Error("all reads fail")); }; return brokenator; }; var reader = new TestRandomAccessReader(); yauzl.fromRandomAccessReader(reader, 0x1000, function(err, zipfile) { if (err.message === "all reads fail") { console.log("fromRandomAccessReader with errors: pass"); cb(); } else { throw err; } }); }); // read some entries, then close. pend.go(function(cb) { var prefix = "read some entries then close: "; // this zip file should have at least 3 entries in it yauzl.open(path.join(__dirname, "success/unicode.zip"), {lazyEntries: true}, function(err, zipfile) { if (err) throw err; var entryCount = 0; zipfile.readEntry(); zipfile.on("entry", function(entry) { entryCount += 1; console.log(prefix + "entryCount: " + entryCount); if (entryCount < 3) { zipfile.readEntry(); } else if (entryCount === 3) { zipfile.close(); console.log(prefix + "close()"); } else { throw new Error(prefix + "read too many entries"); } }); zipfile.on("close", function() { console.log(prefix + "closed"); if (entryCount === 3) { console.log(prefix + "pass"); cb(); } else { throw new Error(prefix + "not enough entries read before closed"); } }); zipfile.on("end", function() { throw new Error(prefix + "we weren't supposed to get to the end"); }); zipfile.on("error", function(err) { throw err; }); }); }); // Abort open read stream with several combinations of stream pipelines. // The destroy logic depends on whether there's an inflater, a byte counter, etc. ["big-compression.zip", "big-uncompressed.zip"].forEach(input => { const inputPath = path.join(__dirname, "success", input); [{}, {validateEntrySizes: false}].forEach((options, i) => { pend.go(function(cb) { yauzl.open(inputPath, {lazyEntries: true, ...options}, function(err, zipfile) { if (err) throw err; const prefix = `destroy: ${input}: open(${i}): `; testTheFile(prefix, zipfile, true, cb); }); }); pend.go(function(cb) { yauzl.fromBuffer(fs.readFileSync(inputPath), {lazyEntries: true, ...options}, function(err, zipfile) { if (err) throw err; const prefix = `destroy: ${input}: fromBuffer(${i}): `; testTheFile(prefix, zipfile, false, cb); }); }); }); function testTheFile(prefix, zipfile, canClose, cb) { console.log(prefix + "start"); var doneWithStream = false; zipfile.readEntry(); zipfile.on("entry", function(entry) { zipfile.openReadStream(entry, function(err, readStream) { var writer = new Writable(); var bytesSeen = 0; writer._write = function(chunk, encoding, callback) { bytesSeen += chunk.length; if (bytesSeen < entry.uncompressedSize / 10) { // keep piping a bit longer callback(); } else { // alright, i've seen enough. doneWithStream = true; console.log(prefix + "destroy()"); readStream.unpipe(writer); readStream.destroy(); // now keep trying to use the fd zipfile.readEntry(); } }; readStream.pipe(writer); }); }); zipfile.on("end", function() { console.log(prefix + "end"); if (!canClose) { // fromBuffer never emits "close". cleanup(); } }); zipfile.on("close", function() { console.log(prefix + "closed"); cleanup(); }); function cleanup() { if (doneWithStream) { console.log(prefix + "pass"); cb(); } else { throw new Error(prefix + "closed prematurely"); } } zipfile.on("error", function(err) { throw err; }); } }); // zip64 pend.go(zip64.runTest); // openReadStream with range pend.go(rangeTest.runTest); // Test error propagation. pend.go(errorsTest.runTest); // Make sure the examples run without crashing. pend.go(function(cb) { var examplesDir = path.join(__dirname, "../examples"); var zipfiles = listZipFiles([path.join(__dirname, "success")]); function canDecodeFileData(filePath) { return !/traditional-encryption|bogus-compression-method/.exec(path.basename(filePath)); } var zipfilesCanDecodeFileData = zipfiles.filter(canDecodeFileData); var tmpDir = path.join(__dirname, ".tmp"); if (typeof fs.rmSync === "function") fs.rmSync(tmpDir, {recursive: true, force: true}); var parametersToTest = { "examples/compareCentralAndLocalHeaders.js": zipfiles, "examples/dump.js": zipfiles, "examples/promises.js": zipfiles, "examples/unzip.js": zipfilesCanDecodeFileData, }; if (JSON.stringify(fs.readdirSync(examplesDir).sort().map(s => `examples/${s}`)) !== JSON.stringify(Object.keys(parametersToTest).sort())) throw new Error("unexpected examples/ directory listing"); // Test this one too, but it's not an example. parametersToTest["test/forAwait.js"] = zipfilesCanDecodeFileData for (var script in parametersToTest) { var args = parametersToTest[script]; if (script === "examples/unzip.js" && typeof fs.rmSync !== "function") { console.log("WARNING: skipping examples/unzip.js tests for node <14"); continue; } args.forEach(function(arg) { var args = [path.resolve(script)]; var options = { stdio: ["ignore", "ignore", "inherit"], timeout: 10_000, }; var testId; if (arg != null) { args.push(path.resolve(arg)); testId = `examples/${script} ${path.basename(arg)}: `; } else { testId = `examples/${script}: `; } // Handle special cases. if (script === "examples/dump.js" && !canDecodeFileData(arg)) { args.push("--no-contents"); } if (script === "examples/promises.js" && !canDecodeFileData(arg)) { args.push("--no-readStream"); } if (script === "examples/unzip.js") { // Quaranetine this in a temp directory. fs.mkdirSync(tmpDir); options.cwd = tmpDir; } process.stdout.write(testId); var {status, error} = child_process.spawnSync("node", args, options); if (status) error = new Error("child process return exit code " + status); if (error) throw error; if (script === "examples/unzip.js") { // Quaranetine this in a temp directory. fs.rmSync(tmpDir, {recursive: true, force: true}); } process.stdout.write("pass\n"); }); } cb(); }); var done = false; pend.wait(function() { console.log("all done"); done = true; }); process.on("exit", function(code) { if (code === 0 && !done) { throw new Error("premature exit. probably means an event never got fired."); } }); function listZipFiles(dirList) { var zipfilePaths = []; dirList.forEach(function(dir) { fs.readdirSync(dir).filter(function(filepath) { return /\.zip$/.exec(filepath); }).forEach(function(name) { zipfilePaths.push(path.relative(".", path.join(dir, name))); }); }); zipfilePaths.sort(); return zipfilePaths; } function addUnicodeSupport(name) { // reading and writing unicode filenames on mac is broken. // we keep all our test data ascii, and then swap in the real names here. // see https://github.com/thejoshwolfe/yauzl/issues/10 name = name.replace(/Turmion Katilot/g, "Turmion Kätilöt"); name = name.replace(/Mista veri pakenee/g, "Mistä veri pakenee"); name = name.replace(/qi ge fangjian/g, "七个房间"); return name; } function manuallyDecodeFileName(fileName) { // file names in this test suite are always utf8 compatible. fileName = fileName.toString("utf8"); fileName = fileName.replace("\\", "/"); if (fileName === "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f") { // we're not doing the unicode path extra field decoding outside of yauzl. // just hardcode this answer. fileName = "七个房间.txt"; } return fileName; } function openWithRandomAccess(zipfilePath, options, implementRead, testId, callback) { util.inherits(InefficientRandomAccessReader, yauzl.RandomAccessReader); function InefficientRandomAccessReader() { yauzl.RandomAccessReader.call(this); } InefficientRandomAccessReader.prototype._readStreamForRange = function(start, end) { return fs.createReadStream(zipfilePath, {start: start, end: end - 1}); }; if (implementRead) { InefficientRandomAccessReader.prototype.read = function(buffer, offset, length, position, callback) { fs.open(zipfilePath, "r", function(err, fd) { if (err) return callback(err); fs.read(fd, buffer, offset, length, position, function(err, bytesRead) { if (bytesRead < length) return callback(new Error("unexpected EOF")); fs.close(fd, function(err) { if (err) return callback(err); callback(); }); }); }); }; } InefficientRandomAccessReader.prototype.close = function(cb) { console.log(testId + "close hook"); yauzl.RandomAccessReader.prototype.close.call(this, cb); }; fs.stat(zipfilePath, function(err, stats) { if (err) return callback(err); var reader = new InefficientRandomAccessReader(); yauzl.fromRandomAccessReader(reader, stats.size, options, function(err, zipfile) { if (err) return callback(err); callback(null, zipfile); }); }); } yauzl-3.4.0/test/wrong-entry-sizes/000077500000000000000000000000001521126516100172675ustar00rootroot00000000000000yauzl-3.4.0/test/wrong-entry-sizes/wrong-entry-sizes.zip000066400000000000000000000005001521126516100234340ustar00rootroot00000000000000PK©…rJa.txt³µ%pPKáòß'PK¯…rJb.txt³µ¥àPK~.ELPKï…rJc/PK?©…rJáòß0´�a.txtPK?¯…rJ~.E´�:b.txtPK?ï…rJýAtc/PK–”yauzl-3.4.0/test/wrong-entry-sizes/wrong-entry-sizes/000077500000000000000000000000001521126516100227155ustar00rootroot00000000000000yauzl-3.4.0/test/wrong-entry-sizes/wrong-entry-sizes/a.txt000066400000000000000000000000471521126516100236770ustar00rootroot00000000000000====================================== yauzl-3.4.0/test/wrong-entry-sizes/wrong-entry-sizes/b.txt000066400000000000000000000001141521126516100236730ustar00rootroot00000000000000=========================================================================== yauzl-3.4.0/test/wrong-entry-sizes/wrong-entry-sizes/c/000077500000000000000000000000001521126516100231375ustar00rootroot00000000000000yauzl-3.4.0/test/wrong-entry-sizes/wrong-entry-sizes/c/.git_please_make_this_directory000066400000000000000000000000001521126516100313520ustar00rootroot00000000000000yauzl-3.4.0/test/zip64.js000066400000000000000000000230551521126516100151600ustar00rootroot00000000000000var fs = require("fs"); var path = require("path"); var yauzl = require("../"); var util = require("util"); var Readable = require("stream").Readable; var Writable = require("stream").Writable; var BufferList = require("bl"); exports.runTest = runTest; function usage() { process.stdout.write("" + "zip64.js usage:\n" + " (no arguments) run the test\n" + " -d dir/ dump the contents of the expected zip file into the specified directory\n" + " -z in.zip out.zip compress in.zip into out.zip\n" + "\n" + "To recreate the file `zip64.zip_fragment`,\n" + "do the following (from the root directory of this project):\n" + "\n" + "```\n" + "mkdir tmp\n" + "node test/zip64.js -d tmp/\n" + "(cd tmp/ && zip -0 zip64.zip a.txt large.bin b.txt)\n" + "node test/zip64.js -z tmp/zip64.zip test/zip64/zip64.zip_fragment\n" + "rm -rf tmp/\n" + "```\n" + ""); process.exit(1); } function cli() { var arg1 = process.argv[2]; var arg2 = process.argv[3]; var arg3 = process.argv[4]; if (arg1 == null) { runTest(); return; } if (/^--?h/.test(arg1)) usage(); if (arg1 === "-d") { if (arg2 == null) usage(); dumpExpectedContents(arg2); return; } if (arg1 === "-z") { if (arg2 == null) usage(); if (arg3 == null) usage(); compressFile(arg2, arg3); return; } usage(); } function dumpExpectedContents(outputDir) { var readStream = newLargeBinContentsProducer(); readStream.pipe(fs.createWriteStream(path.join(outputDir, "large.bin"))); readStream.on("progress", function(numerator, denominator) { process.stderr.write("\r" + numerator + "/" + denominator + " " + ((numerator / denominator * 100) | 0) + "%"); if (numerator === denominator) process.stderr.write("\n"); }); fs.writeFileSync(path.join(outputDir, "a.txt"), "hello a\n"); fs.writeFileSync(path.join(outputDir, "b.txt"), "hello b\n"); } var largeBinLength = 8000000000; function newLargeBinContentsProducer() { // emits the fibonacci sequence: // 0, 1, 1, 2, 3, 5, 8, 13, ... // with each entry encoded in a UInt32BE. // arithmetic overflow will happen eventually, resulting in wrap around. // as a consequence of limited precision, this sequence repeats itself after 6442450944 entires. // however, we only require 2000000000 entires, so it's good enough. var readStream = new Readable(); var prev0 = -1; var prev1 = 1; var byteCount = 0; readStream._read = function(size) { while (true) { if (byteCount >= largeBinLength) { readStream.push(null); return; } var bufferSize = Math.min(0x800000, largeBinLength - byteCount); var buffer = Buffer.allocUnsafe(bufferSize); for (var i = 0; i < bufferSize; i += 4) { var n = ((prev0 + prev1) & 0xffffffff) >>> 0; prev0 = prev1; prev1 = n; byteCount += 4; buffer.writeUInt32BE(n, i, true); } readStream.emit("progress", byteCount, largeBinLength); if (!readStream.push(buffer)) return; } }; readStream.destroy = function() {}; return readStream; } // this is just some bytes so we can identify it. var prefixLength = 0x100; function getPrefixOfStream(stream, cb) { var prefixBuffer = Buffer.allocUnsafe(prefixLength); var writer = new Writable(); writer._write = function(chunk, encoding, callback) { chunk.copy(prefixBuffer, 0, 0, prefixLength); stream.unpipe(writer); cb(prefixBuffer); }; stream.pipe(writer); } function getPrefixOfLargeBinContents(cb) { getPrefixOfStream(newLargeBinContentsProducer(), cb); } function compressFile(inputPath, outputPath) { getPrefixOfLargeBinContents(function(prefixBuffer) { findPrefixInPath(prefixBuffer, function(largeBinContentsOffset) { writeCompressedFile(largeBinContentsOffset); }); }); function findPrefixInPath(prefixBuffer, cb) { var previewLength = 0x1000; fs.createReadStream(inputPath, { start: 0, end: previewLength + prefixLength - 1, }).pipe(BufferList(function(err, data) { if (err) throw err; for (var i = 0; i < previewLength; i++) { if (buffersEqual(data.slice(i, prefixLength), prefixBuffer)) { return cb(i); } } throw new Error("can't find large.bin contents"); })); } function writeCompressedFile(largeBinContentsOffset) { var writeStream = fs.createWriteStream(outputPath); var headerBuffer = Buffer.allocUnsafe(4); headerBuffer.writeUInt32BE(largeBinContentsOffset, 0); writeStream.write(headerBuffer); var firstReader = fs.createReadStream(inputPath, { start: 0, end: largeBinContentsOffset - 1, }); firstReader.pipe(writeStream, {end: false}); firstReader.on("end", function() { var secondReader = fs.createReadStream(inputPath, { start: largeBinContentsOffset + largeBinLength, }); secondReader.pipe(writeStream); }); } } var logPrefix = "test/zip64: "; function runTest(cb) { if (cb == null) cb = function() {}; makeRandomAccessReader(function(reader, size) { yauzl.fromRandomAccessReader(reader, size, function(err, zipfile) { if (err) throw err; var entryIndex = 0; zipfile.on("entry", function(entry) { var expectedContents; if (entryIndex === 0) { if (entry.fileName !== "a.txt") throw new Error(logPrefix + "expected 'a.txt'. got '" + entry.fileName + "'."); expectedContents = "hello a\n"; } else if (entryIndex === 1) { if (entry.fileName !== "large.bin") throw new Error(logPrefix + "expected 'large.bin'. got '" + entry.fileName + "'."); expectedContents = null; // special case } else if (entryIndex === 2) { if (entry.fileName !== "b.txt") throw new Error(logPrefix + "expected 'b.txt'. got '" + entry.fileName + "'."); expectedContents = "hello b\n"; } else { throw new Error(logPrefix + "too many entries"); } entryIndex += 1; zipfile.openReadStream(entry, function(err, readStream) { if (err) throw err; if (expectedContents != null) { readStream.pipe(BufferList(function(err, data) { if (data.toString() !== expectedContents) throw new Error(logPrefix + "expected contents:\n" + expectedContents + "\ngot:\n" + data.toString() + "\n"); console.log(logPrefix + entry.fileName + ": pass"); })); } else { // make sure this is the big thing getPrefixOfLargeBinContents(function(expectedPrefixBuffer) { getPrefixOfStream(readStream, function(actualPrefixBuffer) { readStream.destroy(); if (buffersEqual(expectedPrefixBuffer, actualPrefixBuffer)) { console.log(logPrefix + entry.fileName + ": pass"); } else { throw new Error(logPrefix + "large.bin contents read did not return expected stream"); } }); }); } }); }); zipfile.on("close", function() { console.log(logPrefix + "closed"); if (entryIndex === 3) { console.log(logPrefix + "pass"); cb(); } else { throw new Error(logPrefix + "closed prematurely"); } }); }); }); } function makeRandomAccessReader(cb) { var fileName = "zip64/zip64.zip_fragment"; fs.readFile(path.join(__dirname, fileName), function(err, backendContents) { if (err) return callback(err); if (backendContents.length <= 4) throw new Error("unexpected EOF"); var largeBinContentsOffset = backendContents.readUInt32BE(0) - 4; if (largeBinContentsOffset > backendContents.length) throw new Error(".zip_fragment header is malformed"); var largeBinContentsEnd = largeBinContentsOffset + largeBinLength; var firstRead = true; var pretendSize = backendContents.length + largeBinLength - 4; util.inherits(InflatingRandomAccessReader, yauzl.RandomAccessReader); function InflatingRandomAccessReader() { yauzl.RandomAccessReader.call(this); } InflatingRandomAccessReader.prototype._readStreamForRange = function(start, end) { var thisIsTheFirstRead = firstRead; firstRead = false; var result = new BufferList(); if (end <= largeBinContentsOffset) { result.append(backendContents.slice(start + 4, end + 4)); } else if (start >= largeBinContentsOffset + largeBinLength) { result.append(backendContents.slice(start - largeBinLength + 4, end - largeBinLength + 4)); } else if (start === largeBinContentsOffset && end === largeBinContentsEnd) { return newLargeBinContentsProducer(); } else if (thisIsTheFirstRead && start > largeBinContentsOffset && end === pretendSize) { // yauzl's first move is to cast a large net to try to find the EOCDR. // yauzl's only going to care about the end of this data, so fill in the gaps with dummy data. var dummyTrash = Buffer.allocUnsafe(largeBinContentsEnd - start); result.append(dummyTrash); result.append(backendContents.slice(largeBinContentsOffset + 4)); } else { throw new Error("_readStreamForRange("+start+", "+end+") misaligned to range ["+largeBinContentsOffset+", "+largeBinContentsEnd+"]"); } result.destroy = function() {}; return result; }; var reader = new InflatingRandomAccessReader(); cb(reader, pretendSize); }); } function buffersEqual(buf1, buf2) { for (var i = 0; i < buf1.length; i++) { if (buf1[i] !== buf2[i]) return false; } return true; } if (require.main === module) cli(); yauzl-3.4.0/test/zip64/000077500000000000000000000000001521126516100146155ustar00rootroot00000000000000yauzl-3.4.0/test/zip64/zip64.zip_fragment000066400000000000000000000011201521126516100201720ustar00rootroot00000000000000¢PK Wu�G@m[a.txtUT ÕÚqVÕÚqVux ééhello a PK-‹u�G9's¢ÿÿÿÿÿÿÿÿ 0large.binUT 5ÛqVÕÚqVux ééPÖÜPÖÜPK Wu�GÆ@pb.txtUT ÕÚqVÕÚqVux ééhello b PK Wu�G@m[´�a.txtUTÕÚqVux ééPK-‹u�G9's¢ÿÿÿÿÿÿÿÿ ,´�Glarge.binUT5ÛqVux ééPÖÜPÖÜPK Wu�GÆ@p$´�ÿÿÿÿb.txtUTÕÚqVux ééžPÖÜPK,-åPÖÜPKêQÖÜPKÿÿÿÿ