mirror of
https://github.com/Serial-ATA/lofty-rs
synced 2024-12-13 14:12:31 +00:00
WAV: Stop relying on file's provided size (Fix OOM)
This commit is contained in:
parent
8a70a77387
commit
10b8462e7a
6 changed files with 29 additions and 17 deletions
|
@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
**AIFF**: Stop relying on the file-provided size when reading (Fixes OOM)
|
**AIFF**: Stop relying on the file-provided size when reading (Fixes OOM)
|
||||||
|
**WAV**: Same as above
|
||||||
|
|
||||||
## [0.7.1] - 2022-07-08
|
## [0.7.1] - 2022-07-08
|
||||||
|
|
||||||
|
|
|
@ -100,10 +100,9 @@ impl<B: ByteOrder> Chunks<B> {
|
||||||
use crate::id3::v2::read::parse_id3v2;
|
use crate::id3::v2::read::parse_id3v2;
|
||||||
use crate::id3::v2::read_id3v2_header;
|
use crate::id3::v2::read_id3v2_header;
|
||||||
|
|
||||||
let mut value = try_vec![0; self.size as usize];
|
let content = self.content(data)?;
|
||||||
data.read_exact(&mut value)?;
|
|
||||||
|
|
||||||
let reader = &mut &*value;
|
let reader = &mut &*content;
|
||||||
|
|
||||||
let header = read_id3v2_header(reader)?;
|
let header = read_id3v2_header(reader)?;
|
||||||
let id3v2 = parse_id3v2(reader, header)?;
|
let id3v2 = parse_id3v2(reader, header)?;
|
||||||
|
|
|
@ -12,7 +12,7 @@ use std::io::{Read, Seek, SeekFrom};
|
||||||
|
|
||||||
use byteorder::{LittleEndian, ReadBytesExt};
|
use byteorder::{LittleEndian, ReadBytesExt};
|
||||||
|
|
||||||
pub(in crate::iff) fn verify_wav<T>(data: &mut T) -> Result<u32>
|
pub(in crate::iff) fn verify_wav<T>(data: &mut T) -> Result<()>
|
||||||
where
|
where
|
||||||
T: Read + Seek,
|
T: Read + Seek,
|
||||||
{
|
{
|
||||||
|
@ -31,16 +31,19 @@ where
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(u32::from_le_bytes(
|
Ok(())
|
||||||
id[4..8].try_into().unwrap(), // Infallible
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn read_from<R>(data: &mut R, read_properties: bool) -> Result<WavFile>
|
pub(crate) fn read_from<R>(data: &mut R, read_properties: bool) -> Result<WavFile>
|
||||||
where
|
where
|
||||||
R: Read + Seek,
|
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 stream_len = 0_u32;
|
||||||
let mut total_samples = 0_u32;
|
let mut total_samples = 0_u32;
|
||||||
|
@ -51,7 +54,7 @@ where
|
||||||
#[cfg(feature = "id3v2")]
|
#[cfg(feature = "id3v2")]
|
||||||
let mut id3v2_tag: Option<ID3v2Tag> = None;
|
let mut id3v2_tag: Option<ID3v2Tag> = None;
|
||||||
|
|
||||||
let mut chunks = Chunks::<LittleEndian>::new(u64::from(file_size));
|
let mut chunks = Chunks::<LittleEndian>::new(file_len);
|
||||||
|
|
||||||
while chunks.next(data).is_ok() {
|
while chunks.next(data).is_ok() {
|
||||||
match &chunks.fourcc {
|
match &chunks.fourcc {
|
||||||
|
|
|
@ -15,12 +15,13 @@ pub(in crate::iff::wav) fn write_riff_info<'a, I>(
|
||||||
where
|
where
|
||||||
I: Iterator<Item = (&'a str, &'a str)>,
|
I: Iterator<Item = (&'a str, &'a str)>,
|
||||||
{
|
{
|
||||||
let file_size = verify_wav(data)?;
|
verify_wav(data)?;
|
||||||
|
let file_len = data.metadata()?.len();
|
||||||
|
|
||||||
let mut riff_info_bytes = Vec::new();
|
let mut riff_info_bytes = Vec::new();
|
||||||
create_riff_info(&mut tag.items, &mut riff_info_bytes)?;
|
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_start = data.seek(SeekFrom::Current(-12))? as usize;
|
||||||
let info_list_end = info_list_start + 8 + info_list_size as usize;
|
let info_list_end = info_list_start + 8 + info_list_size as usize;
|
||||||
|
|
||||||
|
@ -51,13 +52,13 @@ where
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_info_list<R>(data: &mut R, file_size: u32) -> Result<Option<u32>>
|
fn find_info_list<R>(data: &mut R, file_size: u64) -> Result<Option<u32>>
|
||||||
where
|
where
|
||||||
R: Read + Seek,
|
R: Read + Seek,
|
||||||
{
|
{
|
||||||
let mut info = None;
|
let mut info = None;
|
||||||
|
|
||||||
let mut chunks = Chunks::<LittleEndian>::new(u64::from(file_size));
|
let mut chunks = Chunks::<LittleEndian>::new(file_size);
|
||||||
|
|
||||||
while chunks.next(data).is_ok() {
|
while chunks.next(data).is_ok() {
|
||||||
if &chunks.fourcc == b"LIST" {
|
if &chunks.fourcc == b"LIST" {
|
||||||
|
|
|
@ -29,9 +29,11 @@ pub fn oom_test<A: AudioFile>(path: &'static str) {
|
||||||
<A as AudioFile>::read_from(&mut get_reader(path), true).unwrap();
|
<A as AudioFile>::read_from(&mut get_reader(path), true).unwrap();
|
||||||
});
|
});
|
||||||
|
|
||||||
while instant.elapsed().as_secs() < 2 {}
|
while instant.elapsed().as_secs() < 3 {
|
||||||
|
if thread.is_finished() {
|
||||||
if !thread.is_finished() {
|
return;
|
||||||
panic!("Failed to run test");
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
panic!("Failed to run test");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1,7 @@
|
||||||
|
use crate::oom_test;
|
||||||
|
use lofty::iff::WavFile;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn oom1() {
|
||||||
|
oom_test::<WavFile>("wavfile_read_from/oom-007573d233b412ea1b8038137db28e70d5678291");
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue