Round 3: fix three defects introduced by the round-2 fixes
Auditing my own fixes found all three. None were in the original code. The VTS crack sort was byte-wise case-SENSITIVE while the filters that select those files (vts_group_of / is_title_vob) are case-insensitive. On a case-sensitive volume a set holding vts_01_1.vob beside VTS_01_2.VOB sorted part 2 first, because V (0x56) precedes v (0x76) — reintroducing exactly the budget-exhaustion the ordering exists to prevent. Now sorted on the same uppercase normalisation the filters apply. Refusing a name that round-trips to empty aborted the WHOLE plan. A sidecar folder named with a single emoji made a backup un-rippable that 1.6.0 handled fine, and reported it as a collision with a file that does not exist. It is now skipped with a warning: the entry is unaddressable either way, but one irrelevant file should not cost the user their rip. The mtime check now applies only to files whose CONTENT the plan read — the IFOs, whose bytes 0xC0/0xC4 place every VOB. Everything else is planned from size alone, which is already checked, so comparing mtime there bought nothing and risked a real false positive: disc backups commonly live on exFAT/FAT32, which stores local time, so a long rip spanning a DST transition would see a whole-hour shift on an untouched multi-gigabyte VOB and abort hours in.
This commit is contained in:
+7
-1
@@ -318,7 +318,13 @@ impl Disc {
|
||||
vts_group_of(&pf.disc_name).as_deref() == Some(vts) && is_title_vob(&pf.disc_name)
|
||||
})
|
||||
.collect();
|
||||
files.sort_by(|a, b| a.disc_name.cmp(&b.disc_name));
|
||||
// Case-INSENSITIVE, matching `vts_group_of`/`is_title_vob`, which
|
||||
// selected these files case-insensitively. A byte-wise sort put
|
||||
// 'V' (0x56) before 'v' (0x76), so a set holding `vts_01_1.vob`
|
||||
// alongside `VTS_01_2.VOB` — reachable on a case-sensitive volume —
|
||||
// started the crack at part 2 and could exhaust the budget in a clear
|
||||
// run, which is the whole failure this ordering exists to prevent.
|
||||
files.sort_by_key(|f| f.disc_name.to_ascii_uppercase());
|
||||
|
||||
let mut extents: Vec<crate::disc::Extent> = Vec::new();
|
||||
for pf in files {
|
||||
|
||||
Reference in New Issue
Block a user