Skip to content

v0.11.0

Choose a tag to compare

@dkulyk dkulyk released this 09 Sep 13:05
· 8 commits to main since this release
9e65701

Added

  • Checksums come from zlib instead of PHP. A deflated entry is handed to zlib as
    a gzip stream, so its checksum and length are verified while it is decoded
    rather than in a second pass. Decoding 16 MiB of incompressible data goes from
    33 ms to 3.9 ms, and reading a package of 2000 small parts is about a tenth
    faster. A part stream hands decoded chunks over without
    copying them, so reading 16 MiB through openStream() costs 2.9 ms against
    3.4 ms through ZipArchive::getStream().
  • A part copied from one open package to another moves its compressed bytes as
    they are, when nothing has read from its stream and the destination wants the
    compression the source used. Moving a 16 MiB part goes from 99 ms to 0.4 ms.
    No API changes; the source file must not change before the destination is
    saved, and one that does raises ConcurrentModificationException.

Fixed

  • An entry whose directory understates how much it holds is refused after about
    a megabyte rather than after the whole expansion.
  • An archive of exactly 65535 entries is written with a ZIP64 record; without one
    this library refused to read back what it had just written.

Removed

  • Breaking: ext-zip is no longer required. The runtime now needs PHP 8.1,
    ext-dom and ext-zlib; the public API is unchanged, and CI runs an
    end-to-end check on a build with the extension disabled.

Changed

  • Validation, repair, inbound-reference lookup, part moves/removal, and signature removal
    no longer create and retain empty relationship collections for parts without
    a relationship part. Explicitly requested collections remain live and writable.
  • The ZIP central directory is read by the library instead of by ext-zip.
    Opening a package and detecting an Office file walk it lazily; on a 4000-entry
    package a container open goes from 8.6 ms to 4.9 ms and detection from 1.12 ms
    to 0.05 ms.
  • Saving writes the archive directly instead of copying the source file and
    letting ext-zip rewrite it; unchanged entries that sit side by side move in one
    pass. Replacing one part of a 200-part, 12.6 MB package goes from 16.0 ms to
    8.8 ms, and peak memory during a save from 30 MB to 4 MB. [Content_Types].xml
    is always the first entry; an entry of 4 GiB or more is refused.
  • Entry contents are decompressed by the library. A part is decoded in chunks,
    so reading one as a stream no longer materialises it, and it is accepted only
    when its size, its CRC-32 and the number of compressed bytes consumed all agree
    with its directory record. Opening a package and opening a part stream both got
    faster.