From 10b8462e7a8330c10770aacb92482b416e96b78e Mon Sep 17 00:00:00 2001 From: Serial <69764315+Serial-ATA@users.noreply.github.com> Date: Sun, 10 Jul 2022 18:30:12 -0400 Subject: [PATCH] WAV: Stop relying on file's provided size (Fix OOM) --- CHANGELOG.md | 1 + src/iff/chunk.rs | 5 ++--- src/iff/wav/read.rs | 15 +++++++++------ src/iff/wav/tag/write.rs | 9 +++++---- tests/fuzz/main.rs | 10 ++++++---- tests/fuzz/wavfile_read_from.rs | 6 ++++++ 6 files changed, 29 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b7971c6..b96f14a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed **AIFF**: Stop relying on the file-provided size when reading (Fixes OOM) +**WAV**: Same as above ## [0.7.1] - 2022-07-08 diff --git a/src/iff/chunk.rs b/src/iff/chunk.rs index 3f18499a..bec7aa2e 100644 --- a/src/iff/chunk.rs +++ b/src/iff/chunk.rs @@ -100,10 +100,9 @@ impl Chunks { use crate::id3::v2::read::parse_id3v2; use crate::id3::v2::read_id3v2_header; - let mut value = try_vec![0; self.size as usize]; - data.read_exact(&mut value)?; + let content = self.content(data)?; - let reader = &mut &*value; + let reader = &mut &*content; let header = read_id3v2_header(reader)?; let id3v2 = parse_id3v2(reader, header)?; diff --git a/src/iff/wav/read.rs b/src/iff/wav/read.rs index 2a04d623..06049553 100644 --- a/src/iff/wav/read.rs +++ b/src/iff/wav/read.rs @@ -12,7 +12,7 @@ use std::io::{Read, Seek, SeekFrom}; use byteorder::{LittleEndian, ReadBytesExt}; -pub(in crate::iff) fn verify_wav(data: &mut T) -> Result +pub(in crate::iff) fn verify_wav(data: &mut T) -> Result<()> where T: Read + Seek, { @@ -31,16 +31,19 @@ where ); } - Ok(u32::from_le_bytes( - id[4..8].try_into().unwrap(), // Infallible - )) + Ok(()) } pub(crate) fn read_from(data: &mut R, read_properties: bool) -> Result where R: Read + Seek, { - let file_size = verify_wav(data)?; + verify_wav(data)?; + + let current_pos = data.stream_position()?; + let file_len = data.seek(SeekFrom::End(0))?; + + data.seek(SeekFrom::Start(current_pos))?; let mut stream_len = 0_u32; let mut total_samples = 0_u32; @@ -51,7 +54,7 @@ where #[cfg(feature = "id3v2")] let mut id3v2_tag: Option = None; - let mut chunks = Chunks::::new(u64::from(file_size)); + let mut chunks = Chunks::::new(file_len); while chunks.next(data).is_ok() { match &chunks.fourcc { diff --git a/src/iff/wav/tag/write.rs b/src/iff/wav/tag/write.rs index e332a9fd..a7199120 100644 --- a/src/iff/wav/tag/write.rs +++ b/src/iff/wav/tag/write.rs @@ -15,12 +15,13 @@ pub(in crate::iff::wav) fn write_riff_info<'a, I>( where I: Iterator, { - let file_size = verify_wav(data)?; + verify_wav(data)?; + let file_len = data.metadata()?.len(); let mut riff_info_bytes = Vec::new(); create_riff_info(&mut tag.items, &mut riff_info_bytes)?; - if let Some(info_list_size) = find_info_list(data, file_size)? { + if let Some(info_list_size) = find_info_list(data, file_len)? { let info_list_start = data.seek(SeekFrom::Current(-12))? as usize; let info_list_end = info_list_start + 8 + info_list_size as usize; @@ -51,13 +52,13 @@ where Ok(()) } -fn find_info_list(data: &mut R, file_size: u32) -> Result> +fn find_info_list(data: &mut R, file_size: u64) -> Result> where R: Read + Seek, { let mut info = None; - let mut chunks = Chunks::::new(u64::from(file_size)); + let mut chunks = Chunks::::new(file_size); while chunks.next(data).is_ok() { if &chunks.fourcc == b"LIST" { diff --git a/tests/fuzz/main.rs b/tests/fuzz/main.rs index 3ae3e5d7..6be3191b 100644 --- a/tests/fuzz/main.rs +++ b/tests/fuzz/main.rs @@ -29,9 +29,11 @@ pub fn oom_test(path: &'static str) { ::read_from(&mut get_reader(path), true).unwrap(); }); - while instant.elapsed().as_secs() < 2 {} - - if !thread.is_finished() { - panic!("Failed to run test"); + while instant.elapsed().as_secs() < 3 { + if thread.is_finished() { + return; + } } + + panic!("Failed to run test"); } diff --git a/tests/fuzz/wavfile_read_from.rs b/tests/fuzz/wavfile_read_from.rs index 8b137891..f641144b 100644 --- a/tests/fuzz/wavfile_read_from.rs +++ b/tests/fuzz/wavfile_read_from.rs @@ -1 +1,7 @@ +use crate::oom_test; +use lofty::iff::WavFile; +#[test] +fn oom1() { + oom_test::("wavfile_read_from/oom-007573d233b412ea1b8038137db28e70d5678291"); +}