Fix rc5 audit findings: keydb doc, pipeline ordering, hot-loop Arc, tests
- keydb.rs: separate default_path()/no_home_dir() doc blocks; correct the false XDG lock-step claim (Linux write path uses $HOME, ignores XDG_CONFIG_HOME; read-side search also checks XDG_CONFIG_HOME). - io/pipeline.rs: use Release/Acquire on the abandoned flag so a leaked consumer reliably skips close() on weak memory models (ARM64/POWER), not just x86 TSO. - mux/disc.rs: cache the decrypt-loss Arc at construction; lost_bytes() no longer clones an Arc per frame on the mux hot path. - disc/dvd.rs: assert display_aspect mapping for both 16:9 (PAL test) and 4:3 (NTSC test). - mux/resolve.rs: extract css_error_aborts() helper and unit-test the scrambled-but-uncracked CSS guard (Fix 6) incl. the --raw exemption. - aacs/keys.rs: add unit tests for mkb_type_raw/mkb_type/mkb_is_uhd and MkbType (Category C 2.0 UHD, prerecorded 1.0, no-0x10-record None). - release.yml: publish job needs [verify, test] so a failing test suite blocks crates.io publication.
This commit is contained in:
+17
-10
@@ -108,6 +108,11 @@ pub struct DiscStream {
|
||||
/// inline `decrypt::decrypt_sectors` step. `DecryptKeys::None`
|
||||
/// (raw / unencrypted disc) makes the decorator a pass-through.
|
||||
reader: DecryptingSectorSource<Box<dyn SectorSource>>,
|
||||
/// Shared decrypt-loss counter, cloned once at construction from
|
||||
/// `reader.decrypt_loss()`. `lost_bytes()` loads it directly so the
|
||||
/// per-frame hot path performs no per-call `Arc::clone` (matching the
|
||||
/// `PipelinedPesStream` pattern).
|
||||
decrypt_loss: std::sync::Arc<std::sync::atomic::AtomicU64>,
|
||||
title: DiscTitle,
|
||||
/// Mirror of the keys handed in at construction. The decorator
|
||||
/// owns the cryptographic state; this field is kept for
|
||||
@@ -253,12 +258,17 @@ impl DiscStream {
|
||||
_ => 1,
|
||||
};
|
||||
|
||||
// Wrap the input reader in DecryptingSectorSource so the internal
|
||||
// fill_extents path sees plaintext bytes. For DecryptKeys::None
|
||||
// (unencrypted / raw / test fixtures) the decorator is a pass-through.
|
||||
let reader = DecryptingSectorSource::new(reader, decrypt_keys.clone());
|
||||
// Clone the shared loss counter once here so `lost_bytes()` never
|
||||
// clones an Arc per frame on the mux hot path.
|
||||
let decrypt_loss = reader.decrypt_loss();
|
||||
|
||||
Self {
|
||||
// Wrap the input reader in DecryptingSectorSource so the
|
||||
// internal fill_extents path sees plaintext bytes. For
|
||||
// DecryptKeys::None (unencrypted / raw / test fixtures)
|
||||
// the decorator is a pass-through.
|
||||
reader: DecryptingSectorSource::new(reader, decrypt_keys.clone()),
|
||||
reader,
|
||||
decrypt_loss,
|
||||
title,
|
||||
decrypt_keys,
|
||||
unit_align,
|
||||
@@ -802,11 +812,8 @@ impl crate::pes::Stream for DiscStream {
|
||||
// them). Both are real missing content the abort gate must see; without
|
||||
// the decrypt term a partial key failure reports lost_bytes=0 and a rip
|
||||
// missing segments passes even under abort_on_lost_secs=0.
|
||||
self.lost_bytes.saturating_add(
|
||||
self.reader
|
||||
.decrypt_loss()
|
||||
.load(std::sync::atomic::Ordering::Relaxed),
|
||||
)
|
||||
self.lost_bytes
|
||||
.saturating_add(self.decrypt_loss.load(std::sync::atomic::Ordering::Relaxed))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user