COOLJAPAN
← All posts

OxiArc 0.3.4 Released — Byte-for-Byte Interop with liblzma, libbz2, and bsdtar

OxiArc 0.3.4 is an interoperability hardening release: spec-conformance defects surfaced by downstream FVRS integration testing were root-caused and fixed across LZMA/LZMA2, bzip2, 7z, ZIP, TAR, XZ, and LZH. Every codec is now validated bidirectionally against liblzma, libbz2, bsdtar/libarchive, and CPython, with hermetic golden-vector regression suites. 1,799 tests passing, Pure Rust.

release oxiarc interop liblzma bzip2 7z zip lzh pure-rust compression

A codec that only talks to itself isn’t really compatible with anything. 0.3.4 makes OxiArc fluent with the reference implementations.

Today we released OxiArc 0.3.4 — an interoperability hardening release. A batch of spec-conformance defects, surfaced by downstream integration testing in FVRS, was root-caused and fixed across the LZMA, bzip2, LZH, 7z, ZIP, TAR, and XZ stacks.

No C, no Fortran, no zlib, no libarchive, no external shared libraries. Just clean, memory-safe, blazing-fast archiving and compression that compiles to a single static binary, targets WASM, and runs everywhere.

OxiArc is the Pure Rust replacement for the zip, tar, gzip, zstd, and 7-zip tools — and for the Rust crates zip, flate2, zstd, bzip2, lz4, tar, snap, brotli, and miniz_oxide.

Why 0.3.4 is a meaningful step

Self-consistent round-trip tests catch a lot — but they cannot catch two implementations quietly agreeing on the wrong thing. 0.3.4 closes that gap by validating every fixed codec bidirectionally against its reference implementation:

Every one of these fixes was validated at development time against the real reference tool — liblzma, libbz2, bsdtar/libarchive, CPython’s stdlib — and the resulting golden vectors are committed as fully hermetic test data, so the test suite needs no external tools at run time.

Technical Deep Dive

  1. Distance-slot probability table (oxiarc-lzma). The table used a custom overlapping layout instead of the spec’s PosDecoders + dist - posSlot indexing (per LzmaSpec.cpp), and was resized 114 → 115 (SPEC_POS_PROBS = 1 + FULL_DISTANCES - END_POS_MODEL_INDEX) to match.
  2. State::update_literal (oxiarc-lzma). States ≥ 10 mapped 10 → 6 instead of the spec’s state - 6 (10 → 4), corrupting decode of real liblzma streams past ~64 KB — a bug invisible to self-round-trip tests because oxiarc’s own encoder and decoder agreed with each other, just not with the spec.
  3. MSB-first bit I/O (oxiarc-bzip2). A new private bit-I/O module replaces the LSB-first (DEFLATE-style) reader/writer with the MSB-first stream the bzip2 format actually uses, alongside the non-reflected CRC-32 (0x04C11DB7, init 0xFFFFFFFF) bzip2 expects instead of the reflected ZIP/GZIP variant.
  4. zip/name_codec and lzh/name_codec (oxiarc-archive). New modules implement the correct decode chain — strict UTF-8 when the EFS bit is set, Shift_JIS when it is not, and an injective CP437 fallback that never collapses distinct raw names into the same U+FFFD string — wired into both the central-directory and local-file-header paths.
  5. Hermetic interop regression suites. 12 tests decode real liblzma LZMA1/.lzma/LZMA2 streams; 13 tests cover real libbz2 output including a 1.2 MB two-block stream crossing the 900 KB boundary; a 7z/ZIP/TAR suite exercises bsdtar and python3-tarfile golden fixtures — all embedded as binary test data, none requiring the reference tool to be installed.

Getting Started

CLI:

cargo install oxiarc-cli

Library:

cargo add oxiarc-archive oxiarc-lzma oxiarc-bzip2

Nothing changes in how you call these codecs — the fixes are internal spec-conformance corrections, not API changes:

use oxiarc_archive::SevenZReader;
use oxiarc_lzma::{LzmaEncoder, LzmaDecoder};
use std::fs::File;

// Extract a real liblzma-produced .7z — CRCs now verified per entry
let file = File::open("archive.7z")?;
let mut sz = SevenZReader::new(file)?;
for entry in sz.entries() {
    let data = sz.extract(&entry)?;
    println!("{}: {} bytes", entry.name, data.len());
}

If you’ve been round-tripping through oxiarc-lzma or oxiarc-bzip2 only against itself, upgrading now means your .xz, .lzma, and .bz2 output will open cleanly in xz, bzip2, and every other tool that speaks the real format.

What’s New in 0.3.4

Tips

This is the foundation

Real-world interoperability is what lets OxiArc sit underneath the rest of the ecosystem without surprises: FVRS integration testing is what surfaced these defects in the first place, and the same LZMA/bzip2/7z/ZIP/TAR/XZ paths are exercised by OxiMedia, SciRS2/NumRS2, RusMES, OxiGDAL, and ToRSh wherever they read or write archives that also need to open correctly outside the COOLJAPAN ecosystem.

Repository: https://github.com/cool-japan/oxiarc

Star the repo if you want an archiver that doesn’t just agree with itself, but actually speaks the formats other tools speak too.

The era of “close enough to the spec” is over. Pure Rust archiving that’s byte-for-byte compatible is here.

KitaSan at COOLJAPAN OÜ July 6, 2026

↑ Back to all posts