Skip to content
pmarreckPublic

About

Cleanroom 7z archive implementation in Zig

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

 

History

120 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

z7z

Mechatron Prime CI License: MIT

A cleanroom 7z archive implementation in Zig. Creates, extracts, and verifies archives using the methods listed below. Complete current 7z verification coverage for validate and validate_gui is the goal; remaining codecs and archive features are tracked in PLAN.md. ZIP and RAR containers belong to separate libraries.

Features

  • LZMA2 compression — BT4+HC2/HC3 match finder, forward optimal parser, parallel compression
  • AES-256-CBC encryption — password-protected archives with -p/--password
  • BCJ x86 filter — executable pre-processing for better compression
  • MIME-grouped solid blocks — content-based file type detection via libmagic (--solid/--no-solid overrides)
  • Full metadata — mtime, birthtime (fixes 7zz's long-standing bug of storing ctime instead), atime, POSIX permissions
  • Extended attributes — xattrs preserved on macOS and Linux, including com.apple.ResourceFork (resource forks); stored as custom property 0x7A, invisible to 7zz (7zz t validates clean). Ephemeral xattrs (com.apple.quarantine, etc.) are excluded. Use --no-xattr to skip
  • Symlink support — with path-traversal security
  • Deep verification API — Zig-native metadata stats, expansion guardrails, streaming CRC verification, and seekable range input without retaining extracted payloads
  • Deflate decoding via Zig 0.16's standard library, including BCJ, BCJ2, and encrypted pipelines.
  • Deflate64 decoding with a 64 KiB history and extended lengths, including BCJ2 inputs.
  • BZip2 decoding through pinned pure-Zig bzip2z, with checked allocation budgets and preserved sink errors. BCJ2 pull integration remains pending.
  • Additional decode filters: Delta, Swap2/Swap4, ARM, Thumb, ARM64, PowerPC, SPARC, IA64, and RISC-V.
  • Progress reporting — rate/ETA on interactive terminals
  • stdin/stdout — pipe support via -/@stdin/@stdout
  • i18n groundwork — --lang flag, Z7Z_LANG env var (30-language translation ready)
  • Cross-platform — macOS aarch64, Linux x86_64/aarch64, Windows x86_64/aarch64

Architecture

CLI (C) ──► C FFI boundary ──► Zig core (pure logic, no I/O)

All business logic lives in the Zig core with no direct I/O. The C FFI is exercised by the C CLI, so Zig consumers can import the Zig module directly when they need allocator-aware APIs such as archive.inspect(), archive.verify(), and archive.verifyRange().

Raw Streaming Verification

codec.verifySingleCoder(coder, reader, writer, packed_size, unpack_size, options, diagnostic, allocator) accepts a metadata.Coder, *std.Io.Reader, and *std.Io.Writer. It currently supports raw Deflate64 (04 01 09) and LZMA (03 01 01), with one input and one output stream. Other methods or coder graphs return UnsupportedMethod; there is no whole-buffer fallback.

The caller supplies the compressed payload length and exact decoded length. Memory depends on the dictionary and fixed buffers, not entry size. Set ReaderCoderOptions.max_dictionary_size to bound the LZMA dictionary allocation, and use a budgeted allocator for a total memory limit. Decoded bytes go to the caller's writer, which can compute CRC-32 without retaining output. The caller must check that checksum and flush its writer; the codec does neither. Partial output on any error is unverified.

For ZIP LZMA, parse the nine-byte ZIP method header first, pass its five-byte properties separately in coder, and subtract nine from the packed size. Set require_lzma_end_marker when ZIP general-purpose flag bit 1 is set. Otherwise both marker-bearing and correctly terminated size-delimited streams are accepted. Trailing compressed bytes and decoded-size mismatches are rejected.

CoderDiagnostic is populated on return, including failure. Its byte/bit cursor is relative to the raw compressed payload and excludes decoder read-ahead; Deflate64 reports consumed bits (excluding final padding), LZMA reports consumed bytes. This is a parser stopping position, not a claim about which byte was originally damaged. Add the container payload offset when reporting a file location. Allocation, property, and unsupported-method errors before decoding leave a zero cursor. Reader/writer failures remain ReadFailed/WriteFailed, separate from DecompressFailed and resource errors. A failed operation must not be resumed from the underlying reader's current position.

The feature matrix records tested paths and remaining gaps. PPMd and general coder-graph support are still incomplete; development oracles are retained until the verification inventory is complete.

Performance

Compared against 7zz at -mx=5 on macOS/ARM64 (Apple M4):

Workload z7z 7zz -mmt=1 z7z vs 7zz-st
1.16MB text 10.5ms 20.6ms 1.97x faster
4MB text 18.8ms 67.7ms 3.61x faster
1MB random 8.1ms 50.1ms 6.17x faster

Compression ratios within 1-2% of 7zz at -mx=5. Full bidirectional interop verified.

Run ./bm for the current benchmark suite. It records compression timings plus a z7z verify (25x) microbenchmark over deterministic text, uniform random, gaussian/semi-compressible, and fake-tree datasets in tests/benchmark/benchmark.log.

Building

Requires Zig 0.16. Use the top-level scripts so native builds go through Nix's patched, deterministic package path:

./build                            # ReleaseFast build
./build debug                      # debug build
./build_all                        # ReleaseFast builds for all 5 supported targets
./test                             # full test suite
./bm                               # benchmark suite

Or with Nix:

nix develop                        # enter dev shell
nix build                          # build package
nix flake check                    # run checks

Usage

z7z create archive.7z file1.txt file2.txt dir/   # create archive
z7z create -p secret enc.7z file1.txt             # encrypted archive
z7z extract archive.7z                            # extract to current dir
z7z extract archive.7z -o outdir/                 # extract to specific dir
z7z list archive.7z                               # list contents
z7z --help                                        # full usage

Status

Run nix develop -c ./corruption-coverage --output /tmp/z7z-coverage archive.7z to assess seeded mutation detection across four profiles with simultaneous confidence bounds. See the coverage protocol for sampling assumptions, classification, limits, and replay.

This is an active work in progress. See PLAN.md for the roadmap.

License

MIT

About

Cleanroom 7z archive implementation in Zig

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages