diff --git a/um_audio/src/lib.rs b/um_audio/src/lib.rs index f4af545..05f0454 100644 --- a/um_audio/src/lib.rs +++ b/um_audio/src/lib.rs @@ -103,4 +103,12 @@ mod tests { let result = detect_audio_type(mp3_data).expect("failed to parse mp3"); assert_eq!(result, AudioType::MP3); } + + #[test] + fn test_mp3_invalid_data() { + let mut mp3_data = [0; 4096]; + mp3_data[0..4].copy_from_slice(&[0xff; 4]); + let result = detect_audio_type(&mp3_data).expect("failed to parse mp3"); + assert_eq!(result, AudioType::Unknown); + } } diff --git a/um_audio/src/sync_frame.rs b/um_audio/src/sync_frame.rs index 45ee29a..b717554 100644 --- a/um_audio/src/sync_frame.rs +++ b/um_audio/src/sync_frame.rs @@ -1,11 +1,21 @@ pub const SYNC_FRAME_TEST_SIZE: usize = 0xff; pub fn is_mp3(magic: u32) -> bool { - // Frame sync should have the first 11 bits set to 1. - const MP3_AND_MASK: u32 = 0b1111_1111_1110_0000u32 << 16; - const MP3_EXPECTED: u32 = 0b1111_1111_1110_0000u32 << 16; + // Check for 11-bit sync word, followed by 2 bits of version, and 2 bits of layer. + // MPEG Version: MPEG Version 2 (ISO/IEC 13818-3) or MPEG Version 1 (ISO/IEC 11172-3) + const MP3_AND_MASK: u32 = 0b1111_1111_1111_0110u32 << 16; + const MP3_EXPECTED: u32 = 0b1111_1111_1111_0010u32 << 16; - (magic & MP3_AND_MASK) == MP3_EXPECTED + if (magic & MP3_AND_MASK) != MP3_EXPECTED { + return false; + } + + // Check for bitrate index and sampling rate frequency index. + let bitrate = ((magic >> 12) & 0b1111) as u8; + let sampling_rate = ((magic >> 10) & 0b11) as u8; + + // They should not be all 1s. + bitrate != 0b1111 && sampling_rate != 0b11 } pub fn is_aac(magic: u32) -> bool {