Make the public per-sector descramble refuse a non-pack sector

descramble_region was fixed to require the MPEG-2 pack start code, but
descramble_sector — the PUBLIC per-sector entry point, and the one the
module-level example tells callers to use — still keyed on the byte 0x14 flag
bits alone. The crate own documented guidance therefore led straight back into
the defect this release exists to fix: a VIDEO_TS.IFO sector holding 0x15 at
0x14 while starting 00 26 00 00 loses 1912 of its 2048 bytes, and because that
sector carries TT_SRPT the disc enumerates 38 titles while an image decrypted
from it enumerates 10, at exit 0.

It has no callers inside the crate, which is exactly why it survived three
rounds: nothing exercised it. Putting the guard inside the function rather than
in each caller is what keeps the safe path the easy one.

The integration test that covers it built its sector from the flag byte alone,
which no real scrambled sector looks like, so it stopped representing the path
it names — the same fixture-realism gap already fixed in four other places this
release.
This commit is contained in:
Matthew Jackson
2026-08-06 09:26:15 -07:00
parent 7deacf1761
commit aa149099ec
2 changed files with 50 additions and 0 deletions
+4
View File
@@ -20,6 +20,10 @@ fn css_descramble_sector_roundtrip_via_public_api() {
};
let mut sector = vec![0xAAu8; 2048];
// Real scrambled DVD sectors are MPEG-2 PS packs, and the public API now
// requires the pack start code as well as the flag bits — byte 0x14 means
// something else entirely in an IFO or UDF sector.
sector[0x00..0x04].copy_from_slice(&[0x00, 0x00, 0x01, 0xBA]);
sector[0x14] = 0x30;
sector[0x54..0x59].copy_from_slice(&[0xDE, 0xAD, 0xBE, 0xEF, 0x42]);
let original = sector.clone();