Recovers CD sector prefix/suffix arenas in a v2 image whose resumed dump
sessions left the final deduplication table referencing slots past the
shrunken data block. Scans the file for every prefix/suffix generation,
rebuilds a fresh compact arena and DDT2 for the final table by sourcing
each custom slot from the generation that held it, and rewrites the index.
Supports --dry-run to report recoverable/lost slots without writing.
Covers custom prefix/suffix bytes surviving a resumed dump session, a
resume that adds no new customs keeping the arena intact, and non-BCD
headers being stored verbatim rather than regenerated.
The Mode 1 user-data DDT entry was always written as Mode1Correct even
when the prefix or ECC/EDC was wrong; report Errored in that case like the
Mode 2 paths. The all-zero paths assigned SectorStatusNotDumped without
the <<60 status shift (harmless only because it is zero) and the Mode 2
all-zero path never marked its DDTs dirty, so an all-blank Mode 2 track
wrote no DDT at all; shift the status and set the dirty flags. Also widen
a truncating (uint32_t) cast on the Mode 2 prefix slot index to uint64_t.
The arenas were malloc'd and grown by doubling with realloc into the same
pointer: doubling could not grow a zero-length buffer, a failed realloc
leaked and lost the only pointer, and the Mode 2 Form 1/Form 2 paths left
part of each 288-byte slot uninitialized, writing heap garbage into the
image. Add a grow_arena() helper that grows before appending, keeps the
pointer on failure, and zeroes new capacity; allocate the arenas with
calloc and zero partial slots before copying.
The write path decoded the MSF header with a naive nibble multiply and
compared against the positive sector address, so a header that was not
valid BCD but aliased the expected address (e.g. 0x1A vs 0x20) was
classified correct and silently rewritten as canonical BCD on read, and
lead-in (negative) sectors never matched. Validate BCD nibbles and range
via cd_header_matches_lba() using the signed LBA, and reconstruct the
prefix from the signed LBA on read.
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.