zxc

Bertrand Lebonnois·hellobertrand.zxc

Asymmetric lossless compression built for ultra-fast decode

winget install --id hellobertrand.zxc --exact --source winget

Latest 0.14.1

Release Notes

Release Notes

v0.14.1 is a hardening release:every decode path got stricter, block decompression is 10-13 % faster, reusable contexts reach all five wrappers, and seekable archives can verify per-block checksums.

Drop-in for v0.14.0. Same format v8, byte-identical output at every level (verified on Silesia), soname still libzxc.so.4. One symbol added, zxc_seekable_set_checksum; none removed or changed.

Decoder hardening

• A forged block size passed off a truncated decode as success (#428). A payload size spanning the EOF marker made the frame walk run off the archive and return what it had, with checksums off (the default). A data block's payload can no longer exceed the header's block size, the walk must end on the EOF block, and a seek-table entry spans at most one block. The check sits in the block decoder shared by every reader. Both rules are now normative in FORMAT.md. • Stack address stored in heap memory (#429). Multi-threaded seekable jobs held the caller's output pointer. This was harmless, since workers are joined before return, but a scanner can't prove that. Jobs now carry offsets from one base pointer on the caller's stack. • zxc_stream_decompress ignored the dictionary size limit (#430). A dictionary above ZXC_DICT_SIZE_MAX was accepted, or rejected with a misleading ZXC_ERROR_DICT_MISMATCH. The check moved into the shared stream engine. • Contexts (#417, #422). Static contexts reject oversized blocks up front. An empty input through a context now yields the canonical 36-byte archive, like the one-shot API.

API

• Reusable contexts in every wrapper (#424, #414, #415). Cctx and Dctx now ship in Rust, Go, Python, Node.js and WASM. A dictionary given to the factory applies to every call that doesn't override it. The block API also takes a dictionary's shared literal Huffman table (#415), so small blocks no longer spend bytes describing their own. • Seekable checksum verification (#425). zxc_seekable_decompress_range can verify per-block checksums through zxc_seekable_set_checksum. It is off by default and exposed in all five wrappers. Also fixed:an overflowing offset plus length slipped past the bounds check, and an incomplete range returned a silent partial read instead of ZXC_ERROR_CORRUPT_DATA.

CLI

• -l and -t read checksum status from the HAS_CHECKSUM header flag (#435). -j adds checksum_method; exit codes are unchanged. Thanks to @Vladexy88x for the fix.

Performance

• zxc_decompress_block writes straight to the destination (#418). Given the zxc_decompress_block_bound() capacity, it skips the bounce-buffer copy and runs 10-13 % faster, from 64 KB to 2 MB blocks (Apple M3, level 3, Silesia). An exact-size destination falls back to the bounce buffer instead of failing with ZXC_ERROR_OVERFLOW.

Build & Packaging

• Trusted publishing for the release workflows (#421), replacing long-lived tokens. • Rapidhash is resolved at configure time (#420). The vendored copy is used unless -DZXC_USE_SYSTEM_RAPIDHASH=ON, and a missing copy fails at configure rather than mid-build. Thanks to @jeanga for the issue. • Wrapper packaging and release integrity tightened (#409). Publish jobs no longer install an unpinned global npm (#426, #427). • One seeded checksum entry point (#423), tidier nudge tuning macros (#412), and SARIF uploads skipped on fork PRs.

Documentation

FORMAT.md gains the two decoder rules and the dictionary ID derivation (#413):a 32-bit value that binds a dictionary to an archive without authenticating it. The Rust crate's zxc-compress / zxc naming is clarified (#410), with README refinements (#408).

Changelog

• api:Enforces strict block size and EOF validation (#428) • api:Implements reusable compression contexts (#424) • api:Enhances seekable API with checksum control and robust range validation (#425) • api:Fix empty frame compression in contexts (#422) • api:Enforce strict block size bounds for static decompression contexts (#417) • api:Adds shared literal table support to block API (#415) • api:Extends dictionary support for reusable contexts (#414) • api:Refines README documentation (#408) • perf:Optimizes block decompression for direct and flexible output (#418) • cli:Report checksum presence from the archive header in -l and -t (#435) • build:Migrate release workflows to trusted publishing (#421) • build:Enforce rapidhash resolution at configure/setup time (#420) • build:Resolve dependency resolution in wrapper test (#410) (#411) • build:Enhances wrapper packaging and release integrity (#409) • doc:Clarify crate branding and improve documentation metadata (#410) • misc:Compile library objects separately for fuzzers (#440) • misc:Add fuzzer for streaming API (#443) • misc:Skip SARIF uploads for fork pull requests • misc:Enforce dictionary size limits on decompression path (#430) • misc:Prevent stack memory escape in multi-threaded decompression (#429) • misc:Drop unpinned global npm install from publish job (#426) • misc:Drop unpinned global npm install from publish job (#427) • misc:Consolidates checksums (#423) • misc:Formalizes dictionary ID calculation and enhances fuzzer (#ossf-557281704) (#413) • misc:Tidy the nudge tuning macros (#412)

Full Changelog:v0.14.0...v0.14.1

Installer type: zip

x64—EC89AFD109861EA195782B4AEC04AB9D69C06B19F043B6D82EFCD02C2E0506A7

Details

License
BSD-3-Clause

Older versions (3)

0.14.0
x64—958F3A54E329CA44F904424DE1C8D2DFC931A4CCCA0871C3B0981AEC51E9435D
0.13.3
x64—4589E99CF081F844518EA1A6C40D851120C1A8A0EC75A92BE352AF402DF53AF0
0.12.0
x64—8488DED1F24A084A89E5B098BE962E758BC1F9B7F3E5B5F522187DC998C258B3