diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ee81c0b..78aad5fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,12 +39,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - When skipping invalid frames in `ParsingMode::{BestAttempt, Relaxed}`, the parser will no longer be able to go out of the bounds of the frame content ([issue](https://github.com/Serial-ATA/lofty-rs/issues/458)) ([PR](https://github.com/Serial-ATA/lofty-rs/pull/459)) - **MP4**: Support for flag items (ex. `cpil`) of any size (not just 1 byte) ([issue](https://github.com/Serial-ATA/lofty-rs/issues/457)) ([PR](https://github.com/Serial-ATA/lofty-rs/pull/460)) -- **Fuzzing** (Thanks [@qarmin](https://github.com/qarmin)!) ([PR](https://github.com/Serial-ATA/lofty-rs/pull/476)): +- **Fuzzing** (Thanks [@qarmin](https://github.com/qarmin)!) ([PR](https://github.com/Serial-ATA/lofty-rs/pull/476)) ([PR](https://github.com/Serial-ATA/lofty-rs/pull/479)): - **MusePack**: Fix panic when ID3v2 tag sizes exceed the stream length ([issue](https://github.com/Serial-ATA/lofty-rs/issues/470)) - **WAV**: Fix panic when calculating bit depth with abnormally large `bytes_per_sample` ([issue](https://github.com/Serial-ATA/lofty-rs/issues/471)) - **WavPack***: Fix panic when encountering wrongly sized blocks ([issue](https://github.com/Serial-ATA/lofty-rs/issues/472)) - **WavPack***: Fix panic when encountering zero-sized blocks ([issue](https://github.com/Serial-ATA/lofty-rs/issues/473)) - **MPEG**: Fix panic when APE tags are incorrectly sized ([issue](https://github.com/Serial-ATA/lofty-rs/issues/474)) + - **ID3v2**: Fix panic when parsing non-ASCII `TDAT` and `TIME` frames in `TDRC` conversion ([issue](https://github.com/Serial-ATA/lofty-rs/issues/477)) ## [0.21.1] - 2024-08-28 diff --git a/lofty/src/id3/v2/read.rs b/lofty/src/id3/v2/read.rs index b7fe1fba..43b6bc83 100644 --- a/lofty/src/id3/v2/read.rs +++ b/lofty/src/id3/v2/read.rs @@ -70,49 +70,49 @@ fn construct_tdrc_from_v3(tag: &mut Id3v2Tag) { return; } - let date = tag.get_text(&TDAT); - let mut date_used = false; - - let time = tag.get_text(&TIME); - let mut time_used = false; - let mut tdrc = Timestamp { year: year_frame.timestamp.year, ..Timestamp::default() }; + + let mut date_used = false; + let mut time_used = false; 'build: { - if let Some(date) = date { - if date.len() != 4 { - log::warn!("Invalid TDAT frame, retaining."); - break 'build; - } + let Some(date) = tag.get_text(&TDAT) else { + break 'build; + }; - let (Ok(day), Ok(month)) = (date[..2].parse::(), date[2..].parse::()) else { - log::warn!("Invalid TDAT frame, retaining."); - break 'build; - }; - - tdrc.month = Some(month); - tdrc.day = Some(day); - date_used = true; - - if let Some(time) = time { - if time.len() != 4 { - log::warn!("Invalid TIME frame, retaining."); - break 'build; - } - - let (Ok(hour), Ok(minute)) = (time[..2].parse::(), time[2..].parse::()) - else { - log::warn!("Invalid TIME frame, retaining."); - break 'build; - }; - - tdrc.hour = Some(hour); - tdrc.minute = Some(minute); - time_used = true; - } + if date.len() != 4 || !date.is_ascii() { + log::warn!("Invalid TDAT frame, retaining."); + break 'build; } + + let (Ok(day), Ok(month)) = (date[..2].parse::(), date[2..].parse::()) else { + log::warn!("Invalid TDAT frame, retaining."); + break 'build; + }; + + tdrc.month = Some(month); + tdrc.day = Some(day); + date_used = true; + + let Some(time) = tag.get_text(&TIME) else { + break 'build; + }; + + if time.len() != 4 || !time.is_ascii() { + log::warn!("Invalid TIME frame, retaining."); + break 'build; + } + + let (Ok(hour), Ok(minute)) = (time[..2].parse::(), time[2..].parse::()) else { + log::warn!("Invalid TIME frame, retaining."); + break 'build; + }; + + tdrc.hour = Some(hour); + tdrc.minute = Some(minute); + time_used = true; } tag.insert(Frame::Timestamp(TimestampFrame::new( diff --git a/lofty/tests/fuzz/assets/mpegfile_read_from/crash-b8f2fc10e2ab6c4e60c371aea3949871fc61a39b_minimized b/lofty/tests/fuzz/assets/mpegfile_read_from/crash-b8f2fc10e2ab6c4e60c371aea3949871fc61a39b_minimized new file mode 100644 index 00000000..ef025f07 Binary files /dev/null and b/lofty/tests/fuzz/assets/mpegfile_read_from/crash-b8f2fc10e2ab6c4e60c371aea3949871fc61a39b_minimized differ diff --git a/lofty/tests/fuzz/mpegfile_read_from.rs b/lofty/tests/fuzz/mpegfile_read_from.rs index ef47c036..cee3a3d8 100644 --- a/lofty/tests/fuzz/mpegfile_read_from.rs +++ b/lofty/tests/fuzz/mpegfile_read_from.rs @@ -26,6 +26,13 @@ fn crash3() { let _ = MpegFile::read_from(&mut reader, ParseOptions::new()); } +#[test_log::test] +fn crash4() { + let mut reader = + get_reader("mpegfile_read_from/crash-b8f2fc10e2ab6c4e60c371aea3949871fc61a39b_minimized"); + let _ = MpegFile::read_from(&mut reader, ParseOptions::new()); +} + #[test_log::test] fn oom1() { oom_test::("mpegfile_read_from/oom-f8730cbfa5682ab12343ccb70de9b71a061ef4d0");