Fix read-fault misclassification, DTS AMODE channel table, and untestable guards
- resolve_fmts_key_map: distinguish a genuinely-not-FMTS disc from a
transient live-drive read fault. read_filesystem now returns the new
Error::UdfNotFilesystem for a deterministic tag/format mismatch (no AVDP,
no partition descriptor, no FSD); resolve maps only UdfNotFilesystem (fs)
and UdfNotFound (.tbl absent) to Ok(None), and PROPAGATES DiscRead / other
I/O faults so a marginal AACS 2.1 disc fails loud instead of silently
dropping forensic content under a base-Unit-Key-only map.
- DTS_AMODE_CH (mp4/audio.rs): extend 10→16 entries
{1,2,2,2,2,3,3,4,4,5,6,6,6,7,8,8} (the spec per-AMODE channel table / ETSI TS 102 114) so
the spec-legal high AMODEs that now pass the decodability gate declare
their true channelcount (AMODE 13→7, 14/15→8) instead of a truncated 6.
- session.rs resolve_keys "called before scan" guard is now testable:
from_parts_for_test takes Option<Disc>; added a test that a disc-less
session returns a clean DeviceNotReady Err rather than panicking.
- mp4/read.rs: a track with samples but a missing/malformed stts (mandatory
per ISO/IEC 14496-12) is dropped rather than emitting all-zero timestamps,
matching the existing stco/stsc guards; all-tracks-dropped → Mp4Invalid.
- Remove the inert MuxInput::Iso.key_map field (the Iso path re-derives its
map inside build_iso_pipeline); the live path keeps Live.key_map.
All four fixes are mutation-verified.
This commit is contained in:
+23
-2
@@ -381,9 +381,12 @@ impl DiscSession {
|
||||
/// The drive slot stays `None` (a `MuxInput::Session` mux never touches it —
|
||||
/// it reads through the staged `reader`); `device` carries a sentinel path so
|
||||
/// the driver's missing-reader error still has a name.
|
||||
///
|
||||
/// `disc` is an `Option` so a test can construct a session that has NOT been
|
||||
/// scanned (`None`) to exercise the `resolve_keys` "called before scan" guard.
|
||||
#[cfg(test)]
|
||||
pub(crate) fn from_parts_for_test(
|
||||
disc: Disc,
|
||||
disc: Option<Disc>,
|
||||
reader: Option<Box<dyn SectorSource>>,
|
||||
key_fetch: Option<KeyFetch>,
|
||||
) -> DiscSession {
|
||||
@@ -391,7 +394,7 @@ impl DiscSession {
|
||||
drive: None,
|
||||
device: "test://session".to_string(),
|
||||
spec: KeySpec::default(),
|
||||
disc: Some(disc),
|
||||
disc,
|
||||
reader,
|
||||
key_fetch,
|
||||
}
|
||||
@@ -733,4 +736,22 @@ mod tests {
|
||||
"the disc is left untouched"
|
||||
);
|
||||
}
|
||||
|
||||
/// `resolve_keys` called before `scan` (disc slot still `None`) must return the
|
||||
/// clean typed `DeviceNotReady` guard, never reach the `.expect("disc present
|
||||
/// (checked above)")` below it and panic.
|
||||
///
|
||||
/// Mutation: change the `if self.disc.is_none()` guard to `.expect()`/panic
|
||||
/// (e.g. drop the early return) → this test panics instead of getting an Err.
|
||||
#[test]
|
||||
fn resolve_keys_before_scan_is_clean_device_not_ready() {
|
||||
let mut session = DiscSession::from_parts_for_test(None, None, None);
|
||||
let err = session
|
||||
.resolve_keys(factory_of(|| HasUnitKey([1; 16])))
|
||||
.expect_err("resolve_keys before scan must error, not panic");
|
||||
assert!(
|
||||
matches!(err, Error::DeviceNotReady { .. }),
|
||||
"expected DeviceNotReady, got {err:?}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user