diff --git a/lofty/src/musepack/read.rs b/lofty/src/musepack/read.rs index be403506b..510b71b41 100644 --- a/lofty/src/musepack/read.rs +++ b/lofty/src/musepack/read.rs @@ -6,6 +6,7 @@ use crate::config::ParseOptions; use crate::error::Result; use crate::id3::v2::read::parse_id3v2; use crate::id3::{find_id3v1, find_id3v2, find_lyrics3v2, FindId3v2Config, ID3FindResults}; +use crate::macros::err; use crate::util::io::SeekStreamLen; use std::io::{Read, Seek, SeekFrom}; @@ -47,11 +48,19 @@ where if header.is_some() { file.id3v1_tag = id3v1; - stream_length -= 128; + let Some(new_stream_length) = stream_length.checked_sub(128) else { + err!(SizeMismatch); + }; + + stream_length = new_stream_length; } let ID3FindResults(_, lyrics3v2_size) = find_lyrics3v2(reader)?; - stream_length -= u64::from(lyrics3v2_size); + let Some(new_stream_length) = stream_length.checked_sub(u64::from(lyrics3v2_size)) else { + err!(SizeMismatch); + }; + + stream_length = new_stream_length; reader.seek(SeekFrom::Current(-32))?; @@ -60,9 +69,18 @@ where // Seek back to the start of the tag let pos = reader.stream_position()?; - reader.seek(SeekFrom::Start(pos - u64::from(header.size)))?; - stream_length -= u64::from(header.size); + let tag_size = u64::from(header.size); + let Some(tag_start) = pos.checked_sub(tag_size) else { + err!(SizeMismatch); + }; + + reader.seek(SeekFrom::Start(tag_start))?; + + let Some(new_stream_length) = stream_length.checked_sub(tag_size) else { + err!(SizeMismatch); + }; + stream_length = new_stream_length; } // Restore the position of the magic signature diff --git a/lofty/tests/fuzz/assets/mpcfile_read_from/output.aac b/lofty/tests/fuzz/assets/mpcfile_read_from/output.aac new file mode 100644 index 000000000..9e09b1784 Binary files /dev/null and b/lofty/tests/fuzz/assets/mpcfile_read_from/output.aac differ diff --git a/lofty/tests/fuzz/main.rs b/lofty/tests/fuzz/main.rs index 7ffb41c0d..a8b4e42da 100644 --- a/lofty/tests/fuzz/main.rs +++ b/lofty/tests/fuzz/main.rs @@ -10,6 +10,7 @@ mod aifffile_read_from; mod flacfile_read_from; mod id3v2; mod mp4file_read_from; +mod mpcfile_read_from; mod mpegfile_read_from; mod opusfile_read_from; mod pictureinformation_from_jpeg; diff --git a/lofty/tests/fuzz/mpcfile_read_from.rs b/lofty/tests/fuzz/mpcfile_read_from.rs new file mode 100644 index 000000000..0aa3db470 --- /dev/null +++ b/lofty/tests/fuzz/mpcfile_read_from.rs @@ -0,0 +1,10 @@ +use lofty::config::ParseOptions; +use lofty::file::AudioFile; +use lofty::musepack::MpcFile; + +// Overflow when passing an AAC file to MpcFile::read_from +#[test] +fn panic1() { + let mut reader = crate::get_reader("mpcfile_read_from/output.aac"); + let _ = MpcFile::read_from(&mut reader, ParseOptions::new()); +}