All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
1.18.2 - 2026-07-03
- Windows only (no effect on other platforms): hardened the directory-traversal and output-directory checks used when unpacking against Windows path normalization. Windows strips a path component's trailing dots and spaces and treats
:as a drive/stream separator, so an entry name like" ."could resolve to the output directory itself (re-applying the entry's permissions to it, GHSA-v2g6-7r9j-v6px) and a name like".. \evil.txt"could escape the output directory. The allocation-free fast path that clears genuine descendant entry names (avoiding agetCanonicalFile()call) no longer clears such names; they are canonicalized and rejected as malicious when their canonical path cannot be resolved or does not stay inside the output directory. The output-directory check compares canonicaljava.nio.file.Paths so a self-referencing name is recognised even whengetCanonicalFile()renders it with a trailing separator. Reported by Marcono1234.
1.18.1 - 2026-07-01
ZipUtil.unpackno longer applies a ZIP entry's stored file permissions to the output directory itself when an entry's name resolves to it (for example an entry named/), which could change the output directory's permissions (GHSA-v2g6-7r9j-v6px).
1.18.0 - 2026-07-01
packoverloads that write to an existingjava.util.zip.ZipOutputStream.
- Raised the minimum runtime to Java 8 (bytecode target moved from 1.6 to 1.8).
- Upgraded the
slf4j-apidependency from 1.6.6 to 2.0.18. zt-zip uses only the SLF4J API; applications that pick this newer API up transitively and still use an SLF4J 1.x binding must move to an SLF4J 2.x-compatible binding. slf4j-apiis now a runtime-scoped dependency (previouslycompilescope), so it is no longer on the consumer compile classpath. Declare a directslf4j-apidependency if your own code references SLF4J.
Zipsunpack with a transformer no longer hangs when the transformer produces no entry, and a transformer that throws now surfaces its real exception to the caller instead of a misleading "Write end dead" pipe error.Zips.addEntry/addEntriesno longer fail with "Stream closed" when adding a directoryFileSource; a directory is now stored as a proper directory entry (#138).ZipUtil.packno longer fails withFileNotFoundExceptionwhen a directory contains a broken (dangling) symbolic link; such entries are skipped (#122).ZipUtil.packEntries/packEntry(File, File, NameMapper)now skip an entry whoseNameMapperreturnsnull(the same convention as the directorypack) instead of throwingNullPointerExceptionand leaving a partial zip.- The
ZipUtilmethods that take a separate destination —addEntry/addEntries,removeEntry/removeEntries,replaceEntry/replaceEntries,addOrReplaceEntries,transformEntry/transformEntries,repack— now reject a destination equal to the source with anIllegalArgumentExceptioninstead of truncating and destroying the source before reading it; use the in-place variant (without a destination) instead. ByteSource(and thebyte[]ZipUtil.addEntry/replaceEntryoverloads) now acceptnullbytes as the documented directory entry instead of throwingNullPointerException.ByteSourcewithnullbytes and theSTOREDmethod now produces a valid empty entry (size 0, CRC 0) instead of failing with "STORED entry missing size, compressed size, or crc-32".
- Hardened the relative path-traversal checks when unpacking, using
java.nio.file.Pathfor consistent sub-directory containment checks. - The
Zipsfluent API unpack path (Zips.get(...).unpack().destination(...).process()) now applies the same path-traversal guard asZipUtil.unpack, rejecting entries that resolve outside the destination directory; this covers both the plain and transformer branches (#180). - In-place unpack now creates its temporary directory securely with
Files.createTempDirectory(atomic, owner-only permissions) instead of a predictable, world-readable directory. AsiExtraFieldnow validates the declared symbolic-link length against the bytes actually present before allocating, so a forged length in a crafted archive can no longer trigger a large (up to ~2 GB) memory allocation per entry while unpacking (#181).AsiExtraFieldnow rejects a truncated ASI extra field with aZipExceptioninstead of letting anArrayIndexOutOfBoundsException/NegativeArraySizeExceptionabort unpacking, completing the bounds check added in #181.BackslashUnpackernow validates the resolved path before creating any directories, so a backslash-separated..\entry can no longer create directories outside the output directory (the file write itself was already blocked).ZipUtil.explode,repackandunexplodenow create their working file or directory atomically (File.createTempFile/Files.createTempDirectory) instead of a predictable name next to the target, closing a symlink/TOCTOU race when the target sits in a shared directory; the predictableFileUtils.getTempFileForhelper is deprecated.ZipUtil.unwrapnow throws aZipExceptionfor an entry name whose path prefix resolves outside the name (such as a~- or:-prefixed name) instead of letting an uncheckedStringIndexOutOfBoundsExceptionabort the operation.
1.17 - 2024-01-28
- ProGuard rule to preserve
org.zeroturnaround.zip.extra.ZipExtraField.<init>.
- Exclude
rebel.xmlfile from the release artefact.
1.15 - 2022-03-04
- Ignore bad extra field entry error for permission extraction.
1.14 - 2020-02-10
removeEntriesthat copies to anOutputStream.createEmpty.
1.13 - 2018-05-02
- Same-zip bug for the
transformEntrymethod.
- Fixed a possible security vulnerability reported by the Snyk Security Research Team.
1.12 - 2017-08-01
- Resource leakage with
ZipInputStream. NoSuchMethodErroron Android platforms.
1.11 - 2017-01-31
iterateandunpackmethods that accept aCharset.
1.10 - 2016-10-28
- User-configurable compression level for
packEntries(). - More overloaded
pack()methods for convenience.
- Bumped embedded Apache Commons from 1.4 to 2.2.
1.9 - 2015-11-20
- Support for Java 7 POSIX file permissions.
- Ability to create and update byte-array backed ZIP streams.
- Ability to specify/replace the compression level of a
ZipEntry. BackslashUnpackerfor broken (Windows) ZIP archives.
- Bumped minimal supported Java version to Java 5.
- Not closing the
InputStreamafter processing eachZipEntrySource. - Buffering when creating and updating ZIP streams.
1.8 - 2014-07-07
ZipUtil.packis more memory efficient for large directories.- Improved
Charsetsupport.
- Dependency on commons-io.
- Preserving the compressed state of copied entries.
- Packing files from a directory based on an accept filter.
1.6-SNAPSHOT - 2012-09-17
- Started to write a changelog.
- Public CI, https://travis-ci.org/.