What's Changed in v2.18.0
Bug fixes
- A Zip64 extra field of a local file header that is too short for the
0xFFFFFFFFsentinels of the header or holds a value aboveNumber.MAX_SAFE_INTEGERno longer failsgetData()withERR_EXTRAFIELD_ZIP64_NOT_FOUNDorERR_UNSUPPORTED_UINT64: the sizes of an entry come from the central directory, so the field is reported asWARNING_MALFORMED_EXTRA_FIELDonentry.warningsand the entry is read. A local file header whose sizes hold the sentinels with no Zip64 extra field behind them, which used to pass silently, is reported the same way. In the three cases an entry without a data descriptor keeps the sentinels as its local sizes, which the local file header check reports asWARNING_MISMATCHED_LOCAL_FILE_HEADER_CRC32_OR_SIZES, i.e.ERR_AMBIGUOUS_ARCHIVEunder the default strictness and a warning withstrictness: "tolerant". Both errors are still raised bygetEntries()for a central directory record whose field is too short or holds such a value, where the sizes and the offset have no other source, and a record whose sizes, offset or disk number hold the sentinel with no Zip64 extra field behind it now failsgetEntries()withERR_EXTRAFIELD_ZIP64_NOT_FOUNDtoo, at every strictness, so none of the entries is listed: it used to be listed with sizes of 4 GB and fail later, with a local file header mismatch orERR_ENTRY_DATA_OUT_OF_BOUNDS, or withERR_LOCAL_FILE_HEADER_NOT_FOUNDfor an offset - An AES extra field on a record that is not encrypted and whose compression method is not 99 is ignored and reported as
WARNING_MALFORMED_EXTRA_FIELD, onZipReader#warningswith thefilenamefor the central directory record and onentry.warningsfor the local file header, and the entry is read with the method its record declares; the field used to override the method andgetData()failed withERR_UNSUPPORTED_COMPRESSION. An AES extra field shorter than 7 bytes, which was ignored silently, is reported the same way. On an encrypted record the field still overrides the method and the conflict is still rejected withERR_UNSUPPORTED_COMPRESSION, since the data may be AES behind a wrong method - The encrypted flag of an entry follows its central directory record. A local file header whose bit 0 is cleared is still
ERR_AMBIGUOUS_ARCHIVEunder the default strictness, and a reader withstrictness: "tolerant"now decrypts the entry and depositsWARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAG, where it used to follow the local file header, read the ciphertext as plaintext and fail - An entry whose strong encryption bit (bit 6 of the general purpose bit flag) differs between the two records is
ERR_AMBIGUOUS_ARCHIVEunder the default strictness, like the encrypted bit, and theERR_UNSUPPORTED_ENCRYPTIONcheck reads the central directory record. A bit set in the local file header only used to reject an encrypted entry, AES or ZipCrypto, as unsupported, and a bit set in the central directory only was ignored; a reader withstrictness: "tolerant"now decrypts the first withWARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAGand reports the second asERR_UNSUPPORTED_ENCRYPTION - The
causeof an error raised in a worker keeps itscodeproperty, e.g."Z_MEM_ERROR"on the cause ofERR_CODEC_OUT_OF_MEMORY. A structured clone never copies that property, so it wasundefinedwith workers on every host, while thecodeof the error itself was already carried by the message posted by the worker
Documentation
ERR_EXTRAFIELD_ZIP64_NOT_FOUND,ERR_UNSUPPORTED_UINT64,WARNING_MALFORMED_EXTRA_FIELDandWARNING_MISMATCHED_LOCAL_FILE_HEADER_BIT_FLAGdocument the cases above, andERR_INVALID_COMPRESSED_DATA,ERR_INVALID_CRC32,ERR_INVALID_UNCOMPRESSED_SIZEandERR_CODEC_OUT_OF_MEMORYstate more precisely the routes on which they are raised: theERR_INVALID_CRC32case of Node.js for bytes trailing the deflate stream withcheckCrc32, the gzip route of an AE-2 entry running only on a host without"deflate-raw"whose bundled codec cannot take over either, e.g. because the WebAssembly module failed to load, and, on a host without"deflate-raw", a bundled codec that cannot allocate its state when the entry starts not being reported asERR_CODEC_OUT_OF_MEMORY, since the native codec takes over through a gzip container unlessuseCompressionStreamisfalse
Tests and continuous integration
- New tests cover the three ways a Zip64 extra field of a local file header is unreadable, and their central directory counterparts, the stray AES extra field on a deflated and on an encrypted entry, the encrypted bit and the strong encryption bit disagreeing between the two records, and a worker whose codec cannot allocate its state, a test that runs on the browsers with module workers, Deno and Bun
Full Changelog: v2.17.0...v2.18.0
Co-Authored-By: Claude Fable 5.1 noreply@anthropic.com