Skip to content

archivey 0.2.0

Choose a tag to compare

@davitf davitf released this 23 Oct 01:59
4e33794

First public release. This repository is a rewrite: the earlier v1 / alpha line
(previously published from what is now
davitf/archivey-old) is a separate codebase
with no compatibility promise.

The public API is not frozen until 1.0: minor releases before then may still change it,
and each change will be listed here. No major changes are expected.

Added

  • One interface for every format. open_archive() returns a reader that lists,
    reads, streams and extracts members the same way for ZIP, TAR (plain or compressed),
    7z, RAR, ISO 9660, plain directories and single compressed files. The format is
    detected from the content, so a misnamed file still opens.

  • Native readers. archivey parses ZIP, TAR, 7z and RAR headers itself. The
    compression methods come from three places:

    • the standard library, with no extra package: Deflate, bzip2, LZMA, LZMA2, xz, Delta
      and BCJ, and Zstandard on Python 3.14 and later;
    • archivey's own code: the BCJ2 and ARM64 filters, Unix compress (.Z), ZipCrypto
      and the lzip container;
    • third-party packages in [recommended]: PPMd, Deflate64, Brotli, LZ4, Zstandard
      before Python 3.14, and AES.

    ISO images also need [recommended], and RAR data needs unrar, rar or unar. The
    install page has the details.

  • Encrypted archives in ZIP, 7z and RAR, with one password or a list of candidates.

  • Safe extraction by default. extract_all() blocks path traversal, link escapes
    and special files, and caps size, compression ratio and entry count, under three
    policies (STRICT, STANDARD, TRUSTED). It can also report progress, choose what
    happens to existing files, and do a dry run.

  • Resource limits on listing size, decoder memory, password key-derivation work and
    temporary files.

  • Built for streaming. stream_members() reads every member in one pass, so a solid
    7z or RAR is decoded once. TAR, ZIP and single compressed files also read from a pipe,
    and zstd and gzip files can seek instead of decompressing from the start.

  • Crash isolation. The native decoders known to crash on hostile input run in a
    child process, so a crash costs one member, not your process.

  • Overlapping operations on one reader, from one thread or several, with
    concurrent_operations=True.

  • Verified reads. A failed checksum or a cut member raises an error, and non-fatal
    oddities are reported as diagnostics that DiagnosticPolicy.STRICT turns into errors.

  • The archivey command lists, tests, extracts and prints archives from the shell.
    uvx archivey-cli runs it with the recommended extras.

  • Tested on Python 3.11 to 3.14 on Linux, macOS and Windows, and on free-threaded 3.13t.
    PyPy 3.11 works and every change has to pass the test suite there, but it can't read
    LZ4, PPMd or Deflate64 data; the install page lists the limits.

Changed

  • Breaking: DecoderLimits.max_ppmd_in_process_input (0.2.0rc1) is now
    DecoderLimits.max_ppmd_held_input, with no alias.

Removed

  • Breaking: crc32_digest, public in 0.2.0rc1. Use
    zlib.crc32(data).to_bytes(4, "big") instead.

Fixed

  • About 30 bugs found since 0.2.0rc1, most in reading damaged or crafted archives.

Performance

From one benchmark run on 2026-10-21 at commit de8a6565, archivey takes 0.9 to 2.7
times as long as the standard library or reference reader to read, and 1.5 to 8.5 times
as long to list. benchmarks/RESULTS.md has the full table.

Security

  • SECURITY.md describes how to report a vulnerability privately.
  • Extraction refuses a link whose target can't be looked up. In 0.2.0rc1, a crafted TAR
    (the technique of CPython's CVE-2025-4517) could write outside the destination.
  • [recommended] now requires brotli 1.2.1 or later, which fixes a buffer overflow in
    brotli's decoder (CVE-2026-111497).
  • The test suite replays published vulnerabilities of other archive tools against
    archivey; the security page
    lists them.