| Name | Modified | Size | Downloads / Week |
|---|---|---|---|
| Parent folder | |||
| README.md | 2026-09-13 | 4.4 kB | |
| v2.15.0 source code.tar.gz | 2026-09-13 | 4.0 MB | |
| v2.15.0 source code.zip | 2026-09-13 | 4.5 MB | |
| Totals: 3 Items | 8.6 MB | 5 | |
What's Changed in v2.15.0
New features
- A filename or comment stored without the UTF-8 flag is decoded as UTF-8 when its bytes are valid UTF-8 and no
filenameEncodingorcommentEncodingoption is set, instead of IBM Code Page 437. macOS Archive Utility,ditto, the macOS build of Info-ZIPzipand Java 6 write such names, which read back as mojibake until now while 7-Zip, libarchive andjarshow them right. Pure ASCII names are unchanged, an explicit encoding option disables the detection, and a valid Info-ZIP Unicode Path extra field still wins - The WebAssembly deflate runs in gzip mode and reads the CRC-32 of the entry from the trailer, as the native
CompressionStreamroute already did, so the separate CRC-32 pass over the input on the JavaScript thread is gone for that codec: about 1 % of the time of a 20 MB text entry on Node.js. On the native-only build, the route wrappinggzipwheredeflate-rawis missing reuses the CRC-32 it computes for the trailer instead of running a second pass
Bug fixes
filenameValidationrejects, under"balanced", a".."path component delimited by backslashes ("..\\file.txt", which a Windows host resolves as a parent directory) and a name starting with a single backslash (a root-relative or UNC path on Windows), and under"strict"a name holding a NUL character. A backslash is otherwise still a valid filename character- A custom
ReaderwhosereadUint8Arrayreturns a Node.jsBufferreads archives again. The end of central directory record was kept asBuffer#slice(...).buffer, a view on the whole scan window or on theBufferpool, so its fields were read from the wrong bytes and every archive failed withERR_SPLIT_ZIP_FILEor "File format is not recognized", since 2.8.30 - Retaining an
Entryno longer retains the whole central directory (#682).rawFilename,rawExtraFieldandrawCommentwere views on the buffer holding the directory, as was the digital signature, so one entry kept alive pinned the metadata of every other one, 3.9 MB in the reporter's archive, and the.bufferof those fields exposed the reader's buffer, e.g. a Node.jsBufferpool. Each entry now owns one copy of its three fields terminateWorkers()runs in-process the requests queued while every worker slot was busy and resolves once they have finished. A request queued behind the call used to get a fresh worker after the call had resolved, so aZipReaderreading two entries at once withmaxWorkers: 1kept a worker alive past the call, and the WebAssembly builds reset the module under it. Writers were not affected: everyadd()waits for a slot before asking the pool
Documentation
checkAmbiguitydocuments that duplicate filenames are compared exactly, afternormalizeFilename: two names differing by letter case or by Unicode normalization form are distinct entries, even though they collide on a case-insensitive or normalizing filesystemBENCHMARKS.mdstates what the rows of a fresh process include, the JIT warm-up of each library and, for the WebAssembly rows, the module instantiation of about 20 ms, and that no decompression row verifies the CRC-32: zip.js and jszip leave the check off by default and fflate has none on read. Turning it on in zip.js adds one pass over the output, about 15 ms per 20 MB
Build
- The worker and WebAssembly modules embedded in the bundles are minified without property mangling before the main bundles mangle them, so the mangled-name guard no longer reports a spurious single-letter name on every regeneration. The bundles are unchanged within a few bytes
Tests and continuous integration
- New tests pin the unflagged UTF-8 names (zip.js's own
useUnicodeFileNames: falseoutput, a CP437 name, an explicitfilenameEncodingwinning and a realdittoarchive), the ownership of the raw metadata against a pooled reader, the gzip trailer on the WebAssembly codec with the routes asserted through spies, the termination with a queued request, the clamped date warning under every timestamp option combination, the exact exported size when no deflate implementation is reachable, and the three worker options read as truthy values
Full Changelog: https://github.com/gildas-lormeau/zip.js/compare/v2.14.1...v2.15.0
Co-Authored-By: Claude Fable 5.1 noreply@anthropic.com