What's Changed in v2.11.3
Bug fixes
- Entries written with an unknown size, which is what
ZipWriterStreamand anyReadableStreamsource produce, no longer make the archive unreadable by the macOS extractors. The size of such an entry is only known once it has been written, so the writer has to pick the layout of the data descriptor before writing the first byte and commits to the ZIP64 one. The central directory is written last, when the real sizes are known, but it kept that layout: the 32-bit size fields stayed at0xFFFFFFFFand the real sizes went to the ZIP64 extra field of the entry. Archive Utility anddittoonly read that extra field when the archive carries a ZIP64 end of central directory record, which was not written for an archive small enough not to need one, so they read0xFFFFFFFFas the size of the entry. A stored entry then failed withCouldn't read pkzip signature, a deflated one survived because the inflater ends on its own and never uses the size.unzip, 7-Zip and Windows Explorer read all of them. The central directory now drops the ZIP64 layout of an entry whose sizes turned out to fit in 32 bits, and an archive that does keep an entry in the ZIP64 layout now ends with a ZIP64 end of central directory record. An archive of one stored 1 MB entry written throughZipWriterStreamis also 20 bytes smaller (#678) ZipDirectoryEntry#getExportedSize()no longer refuses to predict the size of a filesystem holding implicit directories. Those are the intermediate directories created by a name such asa/b/c.txt, they are not written to the archive, so they cannot change the order the entries are written in. The check that rejects abufferedWriteexport whose write order is not determined counted them as real directories, so it gave up on almost every filesystem built byaddBlob()and friends. An explicit directory entry with children still throwsERR_UNDETERMINED_SIZE, as it must- The
lastModDateof the entry returned byZipWriter#add()is now the date the archive actually stores. It reported the date rounded and clamped to the MS-DOS range even when the entry carries an extended timestamp or an NTFS timestamp, which hold the date at a higher resolution and without an upper bound. Reading the entry back gave a date theadd()call had not reported
Error handling
ZipWriter#add()throwsERR_INVALID_READERwhen its second argument is neither aReaderinstance, aReadableStreaminstance, nor an object exposing areadableproperty. Passing aBlob, a string or aUint8Arraydirectly, which has to be wrapped inBlobReader,TextReaderorUint8ArrayReader, wrote an empty entry with no error at all- Writing a split zip file into a USDZ file throws
ERR_UNSUPPORTED_SPLIT_USDZ. It used to write the split archive and silently break the 64-byte alignment USDZ requires, the offset of the breakage depending on where the disks happen to roll over. A USDZ file is a single package anyway, and a.zip/.z01/.z02set is not one
Documentation
- The
leveloption documents that an entry is stored instead of being compressed, rather than failing, when the environment provides no usableCompressionStreamand the embedded implementation cannot be loaded. ThecompressionMethodof the entry returned byZipWriter#add()is0in that case, which is how the fallback is detected - The
zip64option documents why an entry of unknown size is written with ZIP64 in its local header, and that its central directory record drops ZIP64 when the actual sizes fit in 32 bits. Thezip64option ofZipWriter#close()documents that ZIP64 is also used when an entry is stored with ZIP64 - Two
@seelinks in the types rendered with their label pasted inside the URL in the generated documentation
Tests and continuous integration
- New test asserting the layout of the size fields of an entry written with an unknown size, in the local header, the data descriptor and the central directory, for a stored entry, a deflated entry, an AES entry, a ZipCrypto entry and an entry with
zip64set totrue - New tests covering the rejection of a split writer in a USDZ file, the size prediction of a filesystem holding implicit directories, the date reported by
ZipWriter#add()past the MS-DOS ceiling, and the readersZipWriter#add()rejects