udf: honor ICB allocation-descriptor type (Short/Long/Extended AD)

read_icb_extents hardcoded an 8-byte Short-AD stride for every file. Large
BD-ROM .m2ts streams use 16-byte Long ADs; striding them as Short ADs reads
descriptor #0 correctly (length+lba align) but lands #1 in the middle of the
first Long AD (its zero impl_use bytes). The AD-list terminator (data_len==0
=> break) then fired on that zero and stopped after the first extent, so every
multi-extent title truncated at ~1 GiB. The same reader backs read_file, so
disc AACS-input files (/AACS/*.inf) and the m2ts mux extents were both
affected.

Read the ICB Tag flags (AD type) and stride 8/16/20 bytes for Short/Long/
Extended ADs accordingly; Extended ADs carry the lba at off+12.

aacs: extract trim_mkb and restore its guard so an MKB whose content length
the parser cannot determine (mkb_content_len == 0) is returned intact instead
of truncated to empty.

Regression tests: Long-AD read_icb_extents returns all extents; Long-AD
read_file returns full content; trim_mkb never zeroes an unrecognised MKB.
This commit is contained in:
Matthew Jackson
2026-06-07 19:53:40 -07:00
parent 061f68594a
commit 06c30aa466
4 changed files with 198 additions and 11 deletions
+6 -4
View File
@@ -1307,13 +1307,15 @@ impl Disc {
.read_file(reader, "/AACS/Unit_Key_RO.inf")
.or_else(|_| udf_fs.read_file(reader, "/AACS/DUPLICATE/Unit_Key_RO.inf"))
.map_err(|_| Error::AacsNoKeys)?;
let mut mkb = udf_fs
let mkb = udf_fs
.read_file(reader, "/AACS/MKB_RO.inf")
.or_else(|_| udf_fs.read_file(reader, "/AACS/MKB_RW.inf"))
.map_err(|_| Error::AacsNoKeys)?;
let n = crate::aacs::mkb_content_len(&mkb);
mkb.truncate(n);
Ok((inf, mkb))
// Trim trailing padding to the real MKB content length, never zeroing
// an unrecognised MKB (see `crate::aacs::trim_mkb` — restores the
// pre-0.31.0 guard so the online key service never receives an empty
// MKB).
Ok((inf, crate::aacs::trim_mkb(mkb)))
}
/// Read a disc's AACS key-input files from an ISO image: returns