Audit v3 fixes: all 3 tiers (19 findings)

Tier 1 (compilation + correctness):
- Fix nightly-only is_multiple_of → % 2 != 0 (stable Rust compat)
- Fix parse_sample_rate: check 192 before 96 (was returning wrong rate)
- macOS drive discovery: split unix.rs → linux.rs + macos.rs
- Linux: EACCES returns DevicePermission not DeviceNotFound
- CLI pipe.rs: Ctrl+C signal handler added

Tier 2 (correctness + security):
- MkvStream: reset demuxer after scanning→streaming transition
- Windows SPTI: zero data buffer before ioctl
- AACS cert verification: documented why silently skipped
- KEYDB: HOME + USERPROFILE fallback for Windows
- Library modules: pub(crate) for internal modules
- AACS: explicit re-exports, AES primitives pub(crate)

Tier 3 (performance + polish):
- IsoStream: batch 64-sector reads (was 1 sector at a time)
- DiscStream: buffer swap instead of copy in decrypt_and_buffer
- Vec capacity hints in TS/PS demuxer hot paths
- NetworkStream: TLS warning documented
- Batch rip: per-title progress display
- cargo fmt: 0 violations

319 tests, 0 fmt violations.
This commit is contained in:
MattJackson
2026-04-11 19:24:25 +00:00
parent e25035fe8c
commit 75f15cae62
22 changed files with 174 additions and 73 deletions
+63
View File
@@ -0,0 +1,63 @@
//! Linux drive discovery and device resolution.
use crate::error::{Error, Result};
use crate::identity::DriveId;
pub fn find_drives() -> Vec<(String, DriveId)> {
let mut drives = Vec::new();
for i in 0..16 {
let path = format!("/dev/sg{}", i);
if !std::path::Path::new(&path).exists() {
continue;
}
if let Ok(mut transport) = crate::scsi::open(std::path::Path::new(&path)) {
if let Ok(id) = DriveId::from_drive(transport.as_mut()) {
if !id.raw_inquiry.is_empty() && (id.raw_inquiry[0] & 0x1F) == 0x05 {
drives.push((path, id));
}
}
}
}
drives
}
pub fn resolve_device(path: &str) -> Result<(String, Option<String>)> {
if path.contains("/sg") {
if !std::path::Path::new(path).exists() {
return Err(Error::DeviceNotFound {
path: path.to_string(),
});
}
return Ok((path.to_string(), None));
}
if path.contains("/sr") {
let mut sr_transport = crate::scsi::open(std::path::Path::new(path))?;
let sr_id = DriveId::from_drive(sr_transport.as_mut())?;
drop(sr_transport);
for (sg_path, sg_id) in find_drives() {
if sg_id.vendor_id == sr_id.vendor_id
&& sg_id.product_id == sr_id.product_id
&& sg_id.serial_number == sr_id.serial_number
{
let warning = format!(
"{} is a block device (sr) — using {} (sg) for raw access",
path, sg_path
);
return Ok((sg_path, Some(warning)));
}
}
return Ok((
path.to_string(),
Some(format!(
"{} is a block device (sr) — no matching sg device found",
path
)),
));
}
if !std::path::Path::new(path).exists() {
return Err(Error::DeviceNotFound {
path: path.to_string(),
});
}
Ok((path.to_string(), None))
}