Separate writer finalization from resource cleanup in close.c to
enable a future reader-only library target (aaruformatread).
close_write.c contains all write_* helpers and aaruf_finalize_write().
close.c retains aaruf_close() with cleanup only, dispatching writer
finalization via a function pointer set by aaruf_create()/aaruf_open().
Zero behavioral change — same tests pass, same error semantics.
V1 images stored cmpCrc64 over the full LZMA payload including the
5-byte properties prefix, but verify.c unconditionally skipped the
prefix before computing the CRC. This caused aaruf_verify_image() to
report AARUF_ERROR_INVALID_BLOCK_CRC on every valid v1 image.
The fix makes the LZMA properties skip conditional on v2+ images:
- V1: CRC computed over full cmpLength (properties included), then byte-swapped
- V2+: CRC computed over cmpLength minus 5 (properties excluded), no byte-swap
Applies to DataBlock, DeDuplicationTable (v1), and DeDuplicationTable2.
Verified against fixtures created by Aaru 5.3 (v1) and aaruformattool (v2).
Tests added (14 total, VerifyImageFixture suite):
- Happy path: floptical/mf2hd/cdmode1 for both v1 and v2 (6 tests)
- Invalid context: NULL and garbage (2 tests)
- Corruption detection: data block v1/v2, TracksBlock (3 tests)
- Index corruption: invalid offset, bad signature (2 tests)
- Programmatic round-trip: create + write + close + verify (1 test)
Regression tests for the error handling improvements in
fix/flac-error-handling (PR #23). The fix changed decode/encode to
return 0 instead of (size_t)-1 on failure, added NULL allocation
checks, and fixed a decoder memory leak on init failure.
Tests added (flacErrors suite):
- decode_garbage_returns_zero: random non-FLAC data
- decode_truncated_flac_returns_zero: valid magic, truncated stream
- decode_empty_input_returns_zero: NULL source buffer
- decode_zero_length_returns_zero: non-NULL but zero-length source
- encode_zero_length_no_crash: NULL source, verifies no crash/leak
- encode_garbage_roundtrip_fails_cleanly: non-PCM encode + decode
- decode_dst_too_small_returns_zero: undersized output buffer
All tests are self-contained (no fixture files needed) and pass
under AddressSanitizer.
The LZMA encoder was called with numThreads=8 at all 19 call sites,
but LZMA only supports 1 or 2 (and _7ZIP_ST forces it to 1 anyway).
Replace with LZMA_THREADS(ctx) macro that clamps ctx->num_threads
to [1, 2], making the code say what it means and honoring the
consumer's threading preference from the threads=N option.
Switch zstd encoder from simple API (ZSTD_compress) to advanced API
(ZSTD_CCtx + ZSTD_compress2) with configurable worker threads via
ZSTD_c_nbWorkers. Consumer controls threading through threads=N
option string parameter. Default is 1 (single-threaded, bit-identical
output to previous behavior).
- Enable ZSTD_MULTITHREAD compile definition and link pthreads
- Add num_threads field to options struct and context
- Parse threads=N in option string (clamped >= 1)
- Rewrite aaruf_zstd_encode_buffer() with num_threads parameter
- Update all call sites (write.c, close.c)
The spec used `2 << x` where `1 << x` (= 2^x) was intended.
`2 << x` equals 2^(x+1), which is off by factor 2. The code
unanimously uses `1 << x` across 40+ sites. Corrects the
example result from 0x6A0000 to 0x350000 accordingly.