diff --git a/src/logic/id3/mod.rs b/src/logic/id3/mod.rs index b377d85e..47d8aa24 100644 --- a/src/logic/id3/mod.rs +++ b/src/logic/id3/mod.rs @@ -12,10 +12,22 @@ use std::io::{Read, Seek, SeekFrom}; use std::ops::Neg; // https://github.com/polyfloyd/rust-id3/blob/e142ec656bf70a8153f6e5b34a37f26df144c3c1/src/stream/unsynch.rs#L18-L20 -pub(crate) fn decode_u32(n: u32) -> u32 { +pub(crate) fn unsynch_u32(n: u32) -> u32 { n & 0xFF | (n & 0xFF00) >> 1 | (n & 0xFF_0000) >> 2 | (n & 0xFF00_0000) >> 3 } +// https://github.com/polyfloyd/rust-id3/blob/e142ec656bf70a8153f6e5b34a37f26df144c3c1/src/stream/unsynch.rs#L9-L15 +pub(crate) fn synch_u32(n: u32) -> Result { + if n > 0x1000_0000 { + return Err(LoftyError::TooMuchData); + } + + let mut x: u32 = n & 0x7F | (n & 0xFFFF_FF80) << 1; + x = x & 0x7FFF | (x & 0xFFFF_8000) << 1; + x = x & 0x7F_FFFF | (x & 0xFF80_0000) << 1; + Ok(x) +} + pub(crate) fn find_lyrics3v2(data: &mut R) -> Result<(bool, u32)> where R: Read + Seek, diff --git a/src/logic/id3/v2/frame/header.rs b/src/logic/id3/v2/frame/header.rs index 1789d91e..b207ff2e 100644 --- a/src/logic/id3/v2/frame/header.rs +++ b/src/logic/id3/v2/frame/header.rs @@ -50,7 +50,7 @@ where let id_str = std::str::from_utf8(&frame_header[..4]).map_err(|_| LoftyError::BadFrameID)?; let (id, size) = if synchsafe { - let size = crate::logic::id3::decode_u32(u32::from_be_bytes([ + let size = crate::logic::id3::unsynch_u32(u32::from_be_bytes([ frame_header[4], frame_header[5], frame_header[6], diff --git a/src/logic/id3/v2/mod.rs b/src/logic/id3/v2/mod.rs index 68042f21..d8f1ac5a 100644 --- a/src/logic/id3/v2/mod.rs +++ b/src/logic/id3/v2/mod.rs @@ -1,4 +1,4 @@ -use crate::logic::id3::decode_u32; +use crate::logic::id3::unsynch_u32; use crate::Result; use std::io::{Read, Seek, SeekFrom}; @@ -103,7 +103,7 @@ pub enum Id3v2Frame { EncapsulatedObject, /// When an ID3v2.2 key couldn't be upgraded /// - /// This **will not** be written. It is up to the user to upgrade and store the key as [`ItemKey::Unknown`](crate::ItemKey::Unknown). + /// This **will not** be written. It is up to the user to upgrade and store the key as another variant. Outdated(String), } @@ -117,7 +117,7 @@ where data.read_exact(&mut id3_header)?; if &id3_header[..3] == b"ID3" { - let size = decode_u32(BigEndian::read_u32(&id3_header[6..])); + let size = unsynch_u32(BigEndian::read_u32(&id3_header[6..])); if read { data.seek(SeekFrom::Current(-10))?; diff --git a/src/logic/mpeg/read.rs b/src/logic/mpeg/read.rs index 1bc9aa5e..544d371e 100644 --- a/src/logic/mpeg/read.rs +++ b/src/logic/mpeg/read.rs @@ -1,6 +1,6 @@ use super::header::{Header, XingHeader}; use crate::files::MpegFile; -use crate::logic::id3::decode_u32; +use crate::logic::id3::unsynch_u32; use crate::logic::id3::v2::read::parse_id3v2; use crate::{FileProperties, LoftyError, Result}; @@ -92,7 +92,7 @@ where let mut remaining_header = [0; 6]; data.read_exact(&mut remaining_header)?; - let size = (decode_u32(BigEndian::read_u32(&remaining_header[2..])) + 10) as usize; + let size = (unsynch_u32(BigEndian::read_u32(&remaining_header[2..])) + 10) as usize; data.seek(SeekFrom::Current(-10))?; let mut id3v2_read = vec![0; size]; diff --git a/src/types/file.rs b/src/types/file.rs index e30bfb18..7cb59ac3 100644 --- a/src/types/file.rs +++ b/src/types/file.rs @@ -315,7 +315,7 @@ impl FileType { where R: Read + Seek, { - use crate::logic::{id3::decode_u32, mpeg::header::verify_frame_sync}; + use crate::logic::{id3::unsynch_u32, mpeg::header::verify_frame_sync}; if data.seek(SeekFrom::End(0))? == 0 { return Err(LoftyError::EmptyFile); @@ -329,7 +329,7 @@ impl FileType { let ret = match sig.first().unwrap() { 77 if sig.starts_with(b"MAC") => Ok(Self::APE), 73 if sig.starts_with(b"ID3") => { - let size = decode_u32(u32::from_be_bytes( + let size = unsynch_u32(u32::from_be_bytes( sig[6..10] .try_into() .map_err(|_| LoftyError::UnknownFormat)?,