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.
8.5.0 - 2026-04-01
- remove
zip64 commentand addzip64 extensible data sector(#747)
- cleanup README (#758)
8.4.0 - 2026-03-23
- add a check for building benches (#748)
- skip BufReader for Stored files in make_reader (#739)
- move pull request template to correct folder (#749)
8.3.1 - 2026-03-21
- cleanup repository files (#743)
8.3.0 - 2026-03-19
- add must_use (#727)
- improve and fix extended timestamp extra field parsing (#713)
- add crc32 ignore option (#710)
- path related code in single file (#712)
- refactor some imports (#734)
- move code to distinct file (datetime, FixedSizeBlock) (#733)
- move stream code to
src/read/stream.rs(#731) - remove zip64 extra field update (#732)
- improve part of the code with clippy help (#725)
- simplify code for unicode extra field and improve error message (#724)
- reorganize code (#714)
- avoid pulling in
zeroize_derive(#720)
8.2.0 - 2026-03-02
- allow custom salt (#680)
- Support compressing bzip2 when feature
bzip2-rsis enabled, sincebzip2/bzip2-sysnow supports it (#685) - enforce clippy in CI (#674)
- zip64 central header (issue 617) (#629)
- allow aes password as bytes (#686)
- handle extra field padding (#682)
- Simplify 2 type conversions in src/write.rs (#687)
- AI tweaks for string type conversions in src/types.rs (#670)
8.1.0 - 2026-02-16
- (writer) Allow getting underlying writer of ZipWriter (#464)
- add system to FileOption, so byte-for-byte identical archives can be created across platforms (#660)
- Bugs in extra-data length calculation in src/write.rs (#662)
8.0.0 - 2026-02-14
- document zip flags as enum (#639)
- Migrate to Rust 2024 (#650)
- [breaking] Remove deprecated methods of
DateTime(#597)
7.4.0 - 2026-02-05
- Increase MSRV to 1.88 and update dependencies (#626)
7.3.0 - 2026-02-04
- Document feature
unreservedand make the mapping of extra fields public (#616) - Return an error if abort_file() fails when exceeding non-large-file limit (#598)
- Bump version to 7.3.0 (semver checks fail if it's still 7.3.0-pre1)
7.3.0-pre1 - 2026-01-27
- Reject empty ZipCrypto password when encrypting files (can still be used when decrypting)
- make zip crate safer and more readable (#536)
- Optimizations for CP437 conversion (#559)
- Trigger release 7.3.0-pre1 to reset cargo-semver-checks baseline
7.2.0 - 2026-01-20
- Need to include zip64 extra field in central directory (fix #353) (#360)
- Fails to extract file which might or might not be malformed (#376) (#426)
- (aes) Allow AES encryption while streaming (#463)
- Default "platform" field in zip files should be set to the local platform, rather than always "Unix" (#470) (#471)
- Define cfg_if! and cfg_if_expr! internal macros (#438)
- Change an assert to debug_assert when encrypting/decrypting AES, and eliminate a fallible operation (#521)
- eliminate a String clone per new file added to archive, and other related refactors (#522)
7.1.0 - 2026-01-14
- display the underlying error in Display impl for
ZipError(#483) - Enable creation of
ZipArchivewithout reparsing (#485)
- Return InvalidPassword rather than panic when AES key is the wrong length (#457)
- bench with auto zip64 comment (#505)
- add condition for
getrandomdependency (#504) - (zipcrypto) Support streaming ZipCrypto encryption, don't store entire file in memory (#462)
- Lock
lzma-rust2to at least 0.15.5 (#491)
7.0.0 - 2025-12-05
- Removed the following features:
getrandom,hmac,pbkdf2,sha1,zeroize. - Removed
lzma-staticandxz-staticfeature flags, which were deprecated synonyms oflzmaandxz. (#405, #425)
- (
SimpleFileOptions) const DEFAULT implementation (#474) - ZipWriter
set_auto_large_file()method to enable large-file data descriptor when necessary (#468)
- print previous error when failing to search another cde (#460)
- cargo doc warnings (#472)
- Write ZIP64 data descriptors when large_file option is true (#467)
- Pin generic-array to an old version to work around RustCrypto/traits#2036 until next RustCrypto & aes-crypto releases (#458)
- Revert version bump so that release-plz will trigger
- expose more flate2 feature flags (#476)
- Next release will be 7.0.0
- release v6.0.0 (#442)
- Bump lzma-rust2 to v0.15 (#465)
6.0.0 - 2025-10-09
- Add by_index_with_options(), which can be used to ignore encryption in a file's metadata (#439) and may be used for other file-specific overrides in the future.
- [breaking]
FileOptions::add_extra_datais now generic and accepts anyAsRef<[u8]>. (#435)
5.1.1 - 2025-09-11
- panic when reading empty extended-timestamp field (#404) (#422)
- Restore original file timestamp when unzipping with
chrono(#46)
- Configure Amazon Q rules (#421)
5.1.0 - 2025-09-10
- Add legacy shrink/reduce/implode compression (#303)
5.0.1 - 2025-09-09
- AES metadata was not copied correctly in raw copy methods, which could corrupt the copied file. (#417)
5.0.0 - 2025-09-05
- Implement by_path*() methods on ZipArchive (#382)
4.6.1 - 2025-09-03
- Fixes an issue introduced by the swap from
lzma-rstoliblzma(#407)
4.6.0 - 2025-08-30
- Allow to read zip files with unsupported extended timestamps (#400)
- enable clamp_opt for ppmd and xz (#401)
4.5.0 - 2025-08-21
4.4.0 - 2025-08-21
- Add
lzma-staticandxz-staticfeatures that enableliblzma/static(#393)
- Move deprecated annotations to fix a Clippy warning (#391)
4.3.0 - 2025-07-09
- Add support for PPMd (#370)
4.2.0 - 2025-06-21
- Write ZIP file to stream (#246)
4.1.0 - 2025-06-14
- Add has_overlapping_files method
4.0.0 - 2025-05-21
- Allow extraction of Zip64 where "Version needed to extract" is higher than "Version made by" (#356)
- Revert nt-time upgrade (would increase MSRV)
- Revert constant_time_eq update (would increase MSRV)
- Update fully-qualified names of liblzma imports
3.0.0 - 2025-05-14
- return correct offset in SeekableTake::seek (#342)
- When only zopfli is available, decompression of deflate should not be possible (#348)
- Specify
flate2dependency of thedeflate-flate2feature. (#345)
- drop unused crossbeam-utils dependency (#339)
- remove
deflate-flate2dependency on specific backend - [breaking] Drop deprecated
deflate-minizfeature flag (#351)
2.6.1 - 2025-04-03
- avoid scanning through all local file headers while opening an archive (#281)
2.6.0 - 2025-03-30
- No documented changes.
2.5.0 - 2025-03-23
- improve error message for duplicated file (#277)
2.4.2 - 2025-03-18
deep_copy_fileproduced a mangled file header on big-endian platforms (#309)
2.4.1 - 2025-03-17
- type issue in test
- double as_ref().canonicalize()?
- CI failures
- Create directory for extraction if necessary (#314)
2.4.0 - 2025-03-17
ZipArchive::root_dirandZipArchive::extract_unwrapped_root_dir(#304)
- wasm build failure due to a missing use statement (#313)
2.3.0 - 2025-03-16
- Add support for NTFS extra field (#279)
- (test) Conditionalize a zip64 doctest (#308)
- fix failing tests, remove symlink loop check
- Canonicalize output path to avoid false negatives
- Symlink handling in stream extraction
- Canonicalize output paths and symlink targets, and ensure they descend from the destination (CVE-2025-29787)
- Fix clippy and cargo fmt warnings (#310)
2.2.3 - 2025-02-26
- Change the inner structure of
DateTime(#267)
- cargo fix --edition
2.2.2 - 2024-12-16
- rewrite the EOCD/EOCD64 detection to fix extreme performance regression (#247)
2.2.1 - 2024-11-20
- remove executable bit (#238)
- (lzma) fixed panic in case of invalid lzma stream (#259)
- resolve new clippy warnings on nightly (#262)
- resolve clippy warning in nightly (#252)
- Faster cde rejection (#255)
2.2.0 - 2024-08-11
- Expose
ZipArchive::central_directory_start(#232)
2.1.6 - 2024-07-29
- (#33) Rare combination of settings could lead to writing a corrupt archive with overlength extra data, and data_start locations when reading the archive back were also wrong (#221)
- Eliminate some magic numbers and unnecessary path prefixes (#225)
2.1.5 - 2024-07-20
- change invalid_state() return type to io::Result
2.1.4 - 2024-07-18
- fix(#215): Upgrade to deflate64 0.1.9
- Panic when reading a file truncated in the middle of an XZ block header
- Some archives with over u16::MAX files were handled incorrectly or slowly (#189)
- Check number of files when deciding whether a CDE is the real one
- Could still select a fake CDE over a real one in some cases
- May have to consider multiple CDEs before filtering for validity
- We now keep searching for a real CDE header after read an invalid one from the file comment
- Always search for data start when opening an archive for append, and reject the header if data appears to start after central directory
deep_copy_fileno longer allows overwriting an existing file, to match the behavior ofshallow_copy_file- File start position was wrong when extra data was present
- Abort file if central extra data is too large
- Overflow panic when central directory extra data is too large
- ZIP64 header was being written twice when copying a file
- ZIP64 header was being written to central header twice
- Start position was incorrect when file had no extra data
- Allow all reserved headers we can create
- Fix a bug where alignment padding interacts with other extra-data fields
- Fix bugs involving alignment padding and Unicode extra fields
- Incorrect header when adding AES-encrypted files
- Parse the extra field and reject it if invalid
- Incorrect behavior following a rare combination of
merge_archive,abort_fileanddeep_copy_file. As well, we now return an error when a file is being copied to itself. - path_to_string now properly handles the case of an empty path
- Implement
DebugforZipWritereven when it's not implemented for the inner writer's type - Fix an issue where the central directory could be incorrectly detected
finish_into_readable()would corrupt the archive if the central directory had moved
- Verify with debug assertions that no FixedSizeBlock expects a multi-byte alignment (#198)
- Use new do_or_abort_file method
- Speed up CRC when encrypting small files
- Limit the number of extra fields
- Refactor extra-data validation
- Store extra data in plain vectors until after validation
- Only build one IndexMap after choosing among the possible valid headers
- Simplify validation of empty extra-data fields
- Validate automatic extra-data fields only once, even if several are present
- Remove redundant
validate_extra_data()call - Skip searching for the ZIP32 header if a valid ZIP64 header is present (#189)
- Fix a bug introduced by c934c824
- Fix a failing unit test
- Fix build errors on older Rust versions
- Fix build
- Fix another fuzz failure
- Switch to
ok_or_abort_file, and inline when that fails borrow checker - Switch to
ok_or_abort_file, and inline when that fails borrow checker - Fix a build error
- Fix boxed_local warning (can borrow instead)
- Partial debug
- Fix more errors when parsing multiple extra fields
- Fix an error when decoding AES header
- Fix an error caused by not allowing 0xa11e field
- Bug fix: crypto_header was being counted toward extra_data_end
- Bug fix: revert a change where crypto_header was incorrectly treated as an extra field
- Fix a bug where a modulo of 0 was used
- Fix a bug when ZipCrypto, alignment and a custom header are used
- Fix a bug when both ZipCrypto and alignment are used
- Fix another bug: header_end vs extra_data_end
- Fix use of a stale value in a
debug_assert_eq! - Fix: may still get an incorrect size if opening an invalid file for append
- Fix: may need the absolute start as tiebreaker to ensure deterministic behavior
2.1.3 - 2024-06-04
- Some date/time filters were previously unreliable (i.e. later-pass filters had no earliest-pass or latest-fail, and vice-versa)
- Decode Zip-Info UTF8 name and comment fields (#159)
- Return extended timestamp fields copied rather than borrowed (#183)
- Fix a new Clippy warning
- Fix a bug and inline
deserializefor safety - Add check for wrong-length blocks, and incorporate fixed-size requirement into the trait name
- Fix a fuzz failure by using checked_sub
- Add feature gate for new unit test
2.1.1 - 2024-05-28
- Derive
DebugforZipWriter - lower default version to 4.5 and use the version-needed-to-extract where feasible.
- use a MIN_VERSION constant
- Bug fixes for debug implementation
- Bug fixes for debug implementation
- Update unit tests
- Remove unused import
2.1.0 - 2024-05-25
- Support mutual conversion between
DateTimeand MS-DOS pair
- version-needed-to-extract was incorrect in central header, and version-made-by could be lower than that (#100)
- version-needed-to-extract was incorrect in central header, and version-made-by could be lower than that (#100)
- Another tweak to ensure
version_neededis applied - Tweaks to make
version_neededandversion_made_bywork with recently-merged changes
2.0.0 - 2024-05-24
- Add
fmt::DisplayforDateTime - Implement more traits for
DateTime
- Change type of
last_modified_timetoOption<DateTime> - [breaking] Rename
from_msdostofrom_msdos_unchecked, make it unsafe, and addtry_from_msdos(#145)
- Continue to accept archives with invalid DateTime, and use
now_utc()as default only when writing, not reading
1.3.1 - 2024-05-21
- Make
deflateenable both default implementations - Merge the hidden deflate-flate2 flag into the public one
- Rename _deflate-non-zopfli to _deflate-flate2
- Reject encrypted and using_data_descriptor files slightly faster in read_zipfile_from_stream
- Convert
impl TryInto<NaiveDateTime> for DateTimetoimpl TryFrom<DateTime> for NaiveDateTime(#136)
- Change default compression implementation to
flate2/zlib-ng
1.3.0 - 2024-05-17
- Add
is_symlinkmethod
- Extract symlinks into symlinks on Unix and Windows, and fix a bug that affected making directories writable on MacOS
- Eliminate deprecation warning when
--all-featuresimplicitly enables the deprecated feature - Check if archive contains a symlink's target, without borrowing both at the same time
- Eliminate a clone that's no longer necessary
- is_dir only needs to look at the filename
- Remove unnecessary #[cfg] attributes
- Fix borrow-of-moved-value
- Box doesn't directly convert to PathBuf, so convert back to String first
- partial revert - only &str has chars(), but Box should auto-deref
- contains_key needs a
Box<str>, so generifyis_dirto accept one - Add missing
ZipFileData::is_dir()method - Fix another Windows-specific error
- More bug fixes for Windows-specific symlink code
- More bug fixes for Windows-specific symlink code
- Bug fix: variable name change
- Bug fix: need both internal and output path to determine whether to symlink_dir
- Another bug fix
- Fix another error-type conversion error
- Fix error-type conversion on Windows
- Fix conditionally-unused import
- Fix continued issues, and factor out the Vec-to-OsString conversion (cc: #125)
- Fix CI failure involving conversion to OsString for symlinks (see my comments on #125)
- Move path join into platform-independent code
1.2.3 - 2024-05-10
- Remove a window when an extracted directory might be unexpectedly listable and/or
cdable by non-owners - Extract directory contents on Unix even if the directory doesn't have write permission (https://github.com/zip-rs/zip-old/issues/423)
- More conditionally-unused imports
1.2.2 - 2024-05-09
- Failed to clear "writing_raw" before finishing a symlink, leading to dropped extra fields
- Use boxed slice for archive comment, since it can't be concatenated
- Optimize for the fact that false signatures can't overlap with real ones
1.2.1 - 2024-05-06
- Prevent panic when trying to read a file with an unsupported compression method
- Prevent panic after reading an invalid LZMA file
- Make
Storedthe default compression method ifDeflatedisn't available, so that zip files are readable by as much software as possible - version_needed was wrong when e.g. cfg(bzip2) but current file wasn't bzip2 (#100)
- file paths shouldn't start with slashes (#102)
- Overhaul
impl Arbitrary for FileOptions - Remove unused
atomicmodule
1.2.0 - 2024-05-06
- Add method
decompressed_size()so non-recursive ZIP bombs can be detected
- Make
ZipWriter::finish()consume theZipWriter
- Use panic! rather than abort to ensure the fuzz harness can process the failure
- Update fuzz_write to use replace_with
- Remove a drop that can no longer be explicit
- Add
#![allow(unexpected_cfgs)]in nightly
1.1.4 - 2024-05-04
- Build was failing with bzip2 enabled
- use is_dir in more places where Windows paths might be handled incorrectly
- Quick filter for paths that contain "/../" or "/./" or start with "./" or "../"
- Fast handling for separator-free paths
- Speed up logic if main separator isn't '/'
- Drop
normalized_componentsslightly sooner when not using it - Speed up
path_to_stringin cases where the path is already in the proper format
- Refactor: can short-circuit handling of paths that start with MAIN_SEPARATOR, no matter what MAIN_SEPARATOR is
- Bug fix: non-canonical path detection when MAIN_SEPARATOR is not slash or occurs twice in a row
- Bug fix: must recreate if . or .. is a path element
- Bug fix
- #58 (partial):
bzip2-rscan't replacebzip2because it's decompress-only
1.1.3 - 2024-04-30
- Rare bug where find_and_parse would give up prematurely on detecting a false end-of-CDR header
1.1.2 - 2024-04-28
- Alignment was previously handled incorrectly (#33)
- deprecate
deflate-minizfeature since it's now equivalent todeflate(#35)
index_for_name,index_for_path,name_for_index: get the index of a file given its path or vice-versa, without initializing metadata from the local-file header or needing to mutably borrow theZipArchive.add_symlink_from_path,shallow_copy_file_from_path,deep_copy_file_from_path,raw_copy_file_to_path: copy a file or create a symlink usingAsRef<Path>arguments
add_directory_from_pathandstart_file_from_pathare no longer deprecated, and they now normalize..as well as..
- Support for decoding LZMA.
- Eliminated a custom
AtomicU64type by replacing it withOnceLockin the only place it's used. FileOptionsnow has the subtypeSimpleFileOptionswhich implementsCopybut has no extra data.
- The published package on crates.io no longer includes the tests or examples.
- Now uses boxed slices rather than
StringorVecfor metadata fields that aren't likely to grow.
- Support for
DEFLATE64(decompression only). - Support for Zopfli compression levels up to
i64::MAX.
InvalidPasswordis now a kind ofZipErrorto eliminate the need for nestedResultstructs.- Updated dependencies.
- Updated dependencies.
- MSRV increased to
1.67.
- Fixed some rare bugs that could cause panics when trying to read an invalid ZIP file or using an incorrect password.
- Where possible, methods are now
const. This improves performance, especially when reading.
- Date and time conversion methods now return
DateTimeRangeErrorrather than()on error.
- Replaces the
flush_on_finish_fileparameter ofZipWriter::newandZipWriter::Appendwith aset_flush_on_finish_filemethod.
- Fixes build errors that occur when all default features are disabled.
- Fixes more cases of a bug when ZIP64 magic bytes occur in filenames.
zlib-ngfor fast Deflate compression. This is now the default for compression levels 0-9.chronoto convert zip::DateTime to and from chrono::NaiveDateTime
- Zopfli for aggressive Deflate compression.
flush_on_finish_fileparameter forZipWriter.
- Uses the
aes::cipher::KeyInittrait fromaes0.8.2 where appropriate.
- Calling
abort_file()no longer corrupts the archive if called on a shallow copy of a remaining file, or on an archive whose CDR entries are out of sequence. However, it may leave an unused entry in the archive. - Calling
abort_file()while writing a ZipCrypto-encrypted file no longer causes a crash. - Calling
abort_file()on the last file beforefinish()no longer produces an invalid ZIP file or garbage in the comment.
ZipWritermethodsget_comment()andget_raw_comment().
- Fixed an issue where code might spuriously fail during write fuzzing.
- New method
with_alignmentonFileOptions.
ZipWriternow once again implementsSendif the underlying writer does.
- Methods
start_file_aligned,start_file_with_extra_data,end_local_start_central_extra_dataandend_extra_data(see below).
- Alignment and extra-data fields are now attributes of [
zip::unstable::write::FileOptions], allowing them to be specified foradd_directoryandadd_symlink. - Extra-data fields are now formatted by the
FileOptionsmethodadd_extra_data. - Improved performance, especially for
shallow_copy_fileanddeep_copy_fileon files with extra data.
- Fixes a rare bug where the size of the extra-data field could overflow when
large_filewas set. - Fixes more cases of a bug when ZIP64 magic bytes occur in filenames.
- Fixed a bug that occurs when ZIP64 magic bytes occur twice in a filename or across two filenames.
- Added experimental [
zip::unstable::write::FileOptions::with_deprecated_encryption] API to enable encrypting files with PKWARE encryption.
- Fixed a bug that occurs when a filename in a ZIP32 file includes the ZIP64 magic bytes.
- Method
abort_file- removes the current or most recently-finished file from the archive.
- Fixed a bug where a file could remain open for writing after validations failed.
- Bumped the version number in order to upload an updated README to crates.io.
- Calling
start_filewith invalid parameters no longer closes theZipWriter. - Attempting to write a 4GiB file without calling
FileOptions::large_file(true)now removes the file from the archive but does not close theZipWriter. - Attempting to write a file with an unrepresentable or invalid last-modified date will instead add it with a date of 1980-01-01 00:00:00.
- Method
is_writing_file- indicates whether a file is open for writing.
- Fixed a possible bug in deep_copy_file.
- Fixed a Clippy warning that was missed during the last release.
- Fixed a bug that could cause later writes to fail after a
deep_copy_filecall.
- Updated dependency versions.
- Fixed an issue that prevented
ZipWriterfrom implementingSend.
- Detects duplicate filenames.
deep_copy_filecould set incorrect Unix permissions.deep_copy_filecould handle files incorrectly if their compressed size was u32::MAX bytes or less but their uncompressed size was not.- Documented that
deep_copy_filedoes not copy a directory's contents.
- Improved performance of
deep_copy_fileby using a HashMap and eliminating a redundant search.
deep_copy_filemethod: more standards-compliant way to copy a file from within the ZipWriter
- Unused flag
#![feature(read_buf)]was breaking compatibility with stable compiler.
- Updated
aesdependency to0.8.2(zip-rs/zip-old#354) - Updated other dependency versions.
- Added experimental [
zip::unstable::write::FileOptions::with_deprecated_encryption] API to enable encrypting files with PKWARE encryption.
shallow_copy_filemethod: copy a file from within the ZipWriter
- #333: disabled the default features of the
timedependency, and alsoformattingandmacros, as they were enabled by mistake. - Deprecated
DateTime::from_timein favor ofDateTime::try_from