Apply review fixes

- crates/media/src/probe.rs
- crates/media/src/mp4guard.rs
- crates/media/src/audio.rs
This commit is contained in:
aiongg
2026-11-04 20:07:37 +00:00
parent 1138860d5d
commit 15645fbec4
3 changed files with 16 additions and 5 deletions
+3 -1
View File
@@ -81,7 +81,9 @@ pub fn decode(bytes: &Bytes) -> Result<Pcm> {
Some(r) => r,
None => contained(|| decode_symphonia(bytes, "mkv")),
},
_ if !crate::mp4guard::probe_fits(bytes) => Err(MediaError::Corrupt("the MP4's sample tables do not fit the file".into())),
Container::Mp4 | Container::Unknown | Container::Mp3 if !crate::mp4guard::probe_fits(bytes) => {
Err(MediaError::Corrupt("the MP4's sample tables do not fit the file".into()))
}
c => contained(|| decode_symphonia(bytes, c.name())),
}
}
+11 -2
View File
@@ -19,9 +19,18 @@ const PROBE_SEARCH_LIMIT: usize = 1024 * 1024;
/// `ftyp` within its search window as the start of an MP4 (the size field 4 bytes before it), so
/// the table check must start where that parser will, not at offset 0.
pub(crate) fn probe_fits(b: &[u8]) -> bool {
let head = &b[..b.len().min(PROBE_SEARCH_LIMIT + 16)];
if crate::Container::sniff(b) == crate::Container::Mp4 && !tables_fit(b) {
return false;
}
// The probe reads leading ID3v2 tags as metadata and searches again after the last one.
let mut rest = b;
while rest.starts_with(b"ID3") {
let size = rest.get(6..10).map(|s| s.iter().fold(0usize, |a, &x| (a << 7) | (x & 0x7f) as usize)).unwrap_or(0);
rest = rest.get(10 + size..).unwrap_or(&[]);
}
let head = &rest[..rest.len().min(PROBE_SEARCH_LIMIT + 16)];
match head.windows(4).position(|w| w == b"ftyp") {
Some(p) => tables_fit(&b[p.saturating_sub(4)..]),
Some(p) => tables_fit(&rest[p.saturating_sub(4)..]),
None => true,
}
}
+2 -2
View File
@@ -71,8 +71,8 @@ pub fn probe_headers(bytes: &Bytes) -> Result<MediaInfo> {
};
if info.audio.is_none() && info.video.is_none() || info.audio.as_ref().is_some_and(|a| a.sample_rate == 0) {
// Plain audio files (and anything our demuxers didn't describe): symphonia's probe.
// Known non-MP4 containers (a WAV's audio bytes can spell an `ftyp`) skip the MP4 table check.
if matches!(c, Container::Mp4 | Container::Unknown) && !crate::mp4guard::probe_fits(bytes) {
// Symphonia opens an MP4 wherever its probe finds an `ftyp` (after leading ID3v2 tags too); other known containers (a WAV's audio bytes can spell an `ftyp`) skip the check.
if matches!(c, Container::Mp4 | Container::Unknown | Container::Mp3) && !crate::mp4guard::probe_fits(bytes) {
return Err(MediaError::Corrupt("the MP4's sample tables do not fit the file".into()));
}
let (codec, rate, channels, frames) = std::panic::catch_unwind(|| crate::audio::probe_symphonia(bytes, c.name()))