Skip to content

Commit

Permalink
MP4: Fix panic on improperly sized freeform idents
Browse files Browse the repository at this point in the history
  • Loading branch information
Serial-ATA committed Jul 23, 2024
1 parent 8c58bef commit 87f1768
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fix panic when reading properties of a file with no timescale specified ([issue](https://github.com/Serial-ATA/lofty-rs/issues/418))
- Fix panics when reading improperly sized freeform atom identifiers ([issue](https://github.com/Serial-ATA/lofty-rs/issues/425)) ([issue](https://github.com/Serial-ATA/lofty-rs/issues/426))
- Fix panic when `data` atom length is less than 16 bytes ([issue](https://github.com/Serial-ATA/lofty-rs/issues/429))
- Fix panic with improperly sized freeform identifiers ([issue](https://github.com/Serial-ATA/lofty-rs/issues/430))
- Fix panic when `hdlr` atom is an unexpected length ([issue](https://github.com/Serial-ATA/lofty-rs/issues/435))
- **WAV**:
- Fix panic when reading properties with large written bytes per second ([issue](https://github.com/Serial-ATA/lofty-rs/issues/420))
Expand Down
17 changes: 10 additions & 7 deletions lofty/src/mp4/atom_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ impl AtomInfo {
err!(BadAtom("Found an incomplete freeform identifier"));
}

atom_ident = parse_freeform(data, len, reader_size, parse_mode)?;
atom_ident = parse_freeform(data, len - ATOM_HEADER_LEN, parse_mode)?;
} else {
atom_ident = AtomIdent::Fourcc(identifier);
}
Expand All @@ -224,7 +224,6 @@ impl AtomInfo {
fn parse_freeform<R>(
data: &mut R,
atom_len: u64,
reader_size: u64,
parse_mode: ParsingMode,
) -> Result<AtomIdent<'static>>
where
Expand All @@ -237,8 +236,10 @@ where
err!(BadAtom("Found an incomplete freeform identifier"));
}

let mean = freeform_chunk(data, b"mean", reader_size, parse_mode)?;
let name = freeform_chunk(data, b"name", reader_size - 4, parse_mode)?;
let (mean, bytes_read) = freeform_chunk(data, b"mean", atom_len, parse_mode)?;
let atom_len = atom_len - bytes_read;

let (name, _bytes_read) = freeform_chunk(data, b"name", atom_len, parse_mode)?;

Ok(AtomIdent::Freeform {
mean: mean.into(),
Expand All @@ -251,7 +252,7 @@ fn freeform_chunk<R>(
name: &[u8],
reader_size: u64,
parse_mode: ParsingMode,
) -> Result<String>
) -> Result<(String, u64)>
where
R: Read + Seek,
{
Expand All @@ -275,11 +276,13 @@ where
let mut content = try_vec![0; (len - 12) as usize];
data.read_exact(&mut content)?;

utf8_decode(content).map_err(|_| {
let content = utf8_decode(content).map_err(|_| {
LoftyError::new(ErrorKind::BadAtom(
"Found a non UTF-8 string while reading freeform identifier",
))
})
})?;

Ok((content, len))
},
_ => err!(BadAtom(
"Found freeform identifier \"----\" with no trailing \"mean\" or \"name\" atoms"
Expand Down
Binary file not shown.
8 changes: 8 additions & 0 deletions lofty/tests/fuzz/mp4file_read_from.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,11 @@ fn panic4() {
);
let _ = Mp4File::read_from(&mut reader, ParseOptions::new());
}

#[test]
fn panic5() {
let mut reader = crate::get_reader(
"mp4file_read_from/steam_at_mention_IDX_97_RAND_34488648178055098192895.m4a",
);
let _ = Mp4File::read_from(&mut reader, ParseOptions::new());
}

0 comments on commit 87f1768

Please sign in to comment.