A DDT2 entry whose slot index points past the stored prefix/suffix block
(e.g. a resume-damaged or corrupt image) caused an out-of-bounds heap
read that was silently returned as sector data. Validate the pointer and
index against the arena length before copying, returning
AARUF_ERROR_CANNOT_READ_BLOCK with an Errored status instead. Also clamp
the two legacy Mode 2 fallback copies to the actual bare-sector length.
On aaruf_open(resume_mode=true) the loaded prefix/suffix arena blocks had
their lengths recorded but the append offsets were left at zero, so a
resumed dump session re-appended custom sync/ECC bytes from offset 0,
overwriting existing slots and leaving the DDT2 pointing past the
rewritten (shrunken) block. Record the block length on load and set the
append offset to it on resume so new customs append after existing slots.
## Types of changes
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
- [x] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] New filesystem, test images in [url]
- [ ] New media image, test images in [url]
- [ ] New partition scheme, test images in [url]
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
- [x] I have read the **CONTRIBUTING** document.
- [ ] My code follows the code style of this project.
- [ ] My change requires a change to the documentation.
- [ ] I have updated the documentation accordingly.
- [ ] I have added tests to cover my changes.
- [ ] All new and existing tests passed.
Add missing media types PS5BD and UHDBD to aaruf_get_xml_mediatype for optical discs.
Maybe the "xml" function should replaced by some generic meaning (e.g. aaruf_get_metadata_mediatype), since export is in .json file.
Separate read-only metadata accessors from write-path mutators to
prepare for the dual-license split (MIT reader / LGPL writer).
metadata.c retains 20 aaruf_get_* functions: geometry, media sequence,
creator, comments, media title, media/drive manufacturer/model/serial/
barcode/part number, firmware revision, CICM metadata, Aaru JSON
metadata, user/negative/overflow sectors, and image info.
metadata_write.c receives 28 functions: 15 aaruf_set_* (geometry,
media sequence, creator, comments, media title, media/drive
manufacturer/model/serial/barcode/part number, firmware revision,
Aaru JSON metadata) and 13 aaruf_clear_* counterparts.
No shared static helpers between the two files. No behavioral change.
All functions are independent public API — no function pointer or
callback mechanism needed (unlike close.c which required a finalization
hook).
Verified:
- Builds cleanly, zero warnings
- 163/165 tests pass (2 pre-existing failures)
- metadata.o exports no set_/clear_ symbols
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)
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)