From dd9e92ed52214ead1f0defcb53a9f9f7f5284a67 Mon Sep 17 00:00:00 2001 From: Matthew Jackson <1085847+MattJackson@users.noreply.github.com> Date: Thu, 6 Aug 2026 10:15:53 -0700 Subject: [PATCH] Retry a short read instead of skipping past it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous commit bounded the crack scan inspection by the bytes actually read, which stopped it examining stale buffer bytes from an earlier batch. But the cursor still advanced by the REQUESTED count, so those sectors were skipped outright — trading "scans the wrong data" for "silently scans less than it thinks", on exactly the damaged media where a title key is hardest to find. The cursor now advances by what was read, so the next iteration resumes where the read stopped. Floored at one sector so a source returning Ok(0) cannot spin. Found by reading the fix again rather than by the next audit round. --- src/css/mod.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/css/mod.rs b/src/css/mod.rs index 64d55db..38b6dbc 100644 --- a/src/css/mod.rs +++ b/src/css/mod.rs @@ -277,6 +277,13 @@ fn crack_key_scan( } let n = (ext.sector_count - i).min(batch); let want = n as usize * 2048; + // How far the cursor advances. Set from the bytes actually READ on + // the Ok path so a short read is RETRIED from where it stopped + // rather than skipped: bounding only the inspection (which is what + // stops stale buffer bytes being scanned) would otherwise leave + // those sectors unexamined, quietly shrinking the crack's coverage + // on exactly the damaged media where a key is hardest to find. + let mut advance = n; match reader.read_sectors(ext.start_lba + i, n as u16, &mut buf[..want], true) { Ok(got) => { // A readable batch: the gate is open — reset the locked run. @@ -292,6 +299,8 @@ fn crack_key_scan( // installed and its wrong descrambles are only partly caught // by the per-sector crib. let usable = (got / 2048).min(n as usize); + // At least one, so a source returning Ok(0) cannot spin here. + advance = (usable as u32).max(1); for s in 0..usable { tried += 1; let sect = &buf[s * 2048..(s + 1) * 2048]; @@ -330,7 +339,7 @@ fn crack_key_scan( } } } - i += n; + i += advance; } }