mirror of
https://github.com/Serial-ATA/lofty-rs
synced 2025-03-04 14:57:17 +00:00
ID3v2: Properly capitalize ID3v2Version
This commit is contained in:
parent
a4e62d674c
commit
bb74a9fdf4
9 changed files with 48 additions and 47 deletions
|
@ -29,6 +29,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- `Id3v2ErrorKind` -> `ID3v2ErrorKind`
|
||||
- `ErrorKind::Id3v2` -> `ErrorKind::ID3v2`
|
||||
- `Id3v2TagFlags` -> `ID3v2TagFlags`
|
||||
- `Id3v2Version` -> `ID3v2Version`
|
||||
- Properly capitalized the variants of `TagType`
|
||||
- `Ape` -> `APE`
|
||||
- `Id3v1` -> `ID3v1`
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#![no_main]
|
||||
use libfuzzer_sys::fuzz_target;
|
||||
use lofty::id3::v2::Id3v2Version;
|
||||
use lofty::id3::v2::ID3v2Version;
|
||||
|
||||
fuzz_target!(|data: &[u8]| {
|
||||
let _ = lofty::Picture::from_apic_bytes(data, Id3v2Version::V4);
|
||||
});
|
||||
let _ = lofty::Picture::from_apic_bytes(data, ID3v2Version::V4);
|
||||
});
|
||||
|
|
|
@ -6,7 +6,7 @@ use crate::id3::v2::items::popularimeter::Popularimeter;
|
|||
use crate::id3::v2::util::text_utils::{
|
||||
decode_text, read_to_terminator, utf16_decode, TextEncoding,
|
||||
};
|
||||
use crate::id3::v2::Id3v2Version;
|
||||
use crate::id3::v2::ID3v2Version;
|
||||
use crate::picture::Picture;
|
||||
|
||||
use std::io::{Cursor, Read};
|
||||
|
@ -16,7 +16,7 @@ use byteorder::ReadBytesExt;
|
|||
pub(super) fn parse_content(
|
||||
content: &mut &[u8],
|
||||
id: &str,
|
||||
version: Id3v2Version,
|
||||
version: ID3v2Version,
|
||||
) -> Result<Option<FrameValue>> {
|
||||
Ok(match id {
|
||||
// The ID was previously upgraded, but the content remains unchanged, so version is necessary
|
||||
|
@ -43,7 +43,7 @@ pub(super) fn parse_content(
|
|||
fn parse_user_defined(
|
||||
mut content: &mut &[u8],
|
||||
link: bool,
|
||||
version: Id3v2Version,
|
||||
version: ID3v2Version,
|
||||
) -> Result<Option<FrameValue>> {
|
||||
if content.len() < 2 {
|
||||
return Ok(None);
|
||||
|
@ -107,7 +107,7 @@ fn parse_user_defined(
|
|||
fn parse_text_language(
|
||||
content: &mut &[u8],
|
||||
id: &str,
|
||||
version: Id3v2Version,
|
||||
version: ID3v2Version,
|
||||
) -> Result<Option<FrameValue>> {
|
||||
if content.len() < 5 {
|
||||
return Ok(None);
|
||||
|
@ -140,7 +140,7 @@ fn parse_text_language(
|
|||
Ok(Some(value))
|
||||
}
|
||||
|
||||
fn parse_text(content: &mut &[u8], version: Id3v2Version) -> Result<Option<FrameValue>> {
|
||||
fn parse_text(content: &mut &[u8], version: ID3v2Version) -> Result<Option<FrameValue>> {
|
||||
if content.len() < 2 {
|
||||
return Ok(None);
|
||||
}
|
||||
|
@ -191,8 +191,8 @@ fn parse_popularimeter(content: &mut &[u8]) -> Result<FrameValue> {
|
|||
}))
|
||||
}
|
||||
|
||||
fn verify_encoding(encoding: u8, version: Id3v2Version) -> Result<TextEncoding> {
|
||||
if let Id3v2Version::V2 = version {
|
||||
fn verify_encoding(encoding: u8, version: ID3v2Version) -> Result<TextEncoding> {
|
||||
if let ID3v2Version::V2 = version {
|
||||
if encoding != 0 && encoding != 1 {
|
||||
return Err(ID3v2Error::new(ID3v2ErrorKind::Other(
|
||||
"ID3v2.2 only supports Latin-1 and UTF-16 encodings",
|
||||
|
|
|
@ -9,7 +9,7 @@ use crate::id3::v2::items::encoded_text_frame::EncodedTextFrame;
|
|||
use crate::id3::v2::items::language_frame::LanguageFrame;
|
||||
use crate::id3::v2::util::text_utils::encode_text;
|
||||
use crate::id3::v2::util::upgrade::{upgrade_v2, upgrade_v3};
|
||||
use crate::id3::v2::Id3v2Version;
|
||||
use crate::id3::v2::ID3v2Version;
|
||||
use crate::picture::Picture;
|
||||
use crate::tag::item::{ItemKey, ItemValue, TagItem};
|
||||
use crate::tag::TagType;
|
||||
|
@ -207,7 +207,7 @@ impl FrameValue {
|
|||
FrameValue::UserText(content) | FrameValue::UserURL(content) => content.as_bytes(),
|
||||
FrameValue::URL(link) => link.as_bytes().to_vec(),
|
||||
FrameValue::Picture { encoding, picture } => {
|
||||
picture.as_apic_bytes(Id3v2Version::V4, *encoding)?
|
||||
picture.as_apic_bytes(ID3v2Version::V4, *encoding)?
|
||||
},
|
||||
FrameValue::Popularimeter(popularimeter) => popularimeter.as_bytes(),
|
||||
FrameValue::Binary(binary) => binary.clone(),
|
||||
|
|
|
@ -2,7 +2,7 @@ use super::header::{parse_header, parse_v2_header};
|
|||
use super::Frame;
|
||||
use crate::error::{ID3v2Error, ID3v2ErrorKind, Result};
|
||||
use crate::id3::v2::frame::content::parse_content;
|
||||
use crate::id3::v2::{FrameValue, Id3v2Version};
|
||||
use crate::id3::v2::{FrameValue, ID3v2Version};
|
||||
use crate::macros::try_vec;
|
||||
|
||||
use std::io::Read;
|
||||
|
@ -10,15 +10,15 @@ use std::io::Read;
|
|||
use byteorder::{BigEndian, ReadBytesExt};
|
||||
|
||||
impl Frame {
|
||||
pub(crate) fn read<R>(reader: &mut R, version: Id3v2Version) -> Result<(Option<Self>, bool)>
|
||||
pub(crate) fn read<R>(reader: &mut R, version: ID3v2Version) -> Result<(Option<Self>, bool)>
|
||||
where
|
||||
R: Read,
|
||||
{
|
||||
// The header will be upgraded to ID3v2.4 past this point, so they can all be treated the same
|
||||
let (id, size, mut flags) = match match version {
|
||||
Id3v2Version::V2 => parse_v2_header(reader)?,
|
||||
Id3v2Version::V3 => parse_header(reader, false)?,
|
||||
Id3v2Version::V4 => parse_header(reader, true)?,
|
||||
ID3v2Version::V2 => parse_v2_header(reader)?,
|
||||
ID3v2Version::V3 => parse_header(reader, false)?,
|
||||
ID3v2Version::V4 => parse_header(reader, true)?,
|
||||
} {
|
||||
None => return Ok((None, true)),
|
||||
Some(frame_header) => frame_header,
|
||||
|
|
|
@ -56,7 +56,7 @@ use flags::ID3v2TagFlags;
|
|||
|
||||
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
|
||||
/// The ID3v2 version
|
||||
pub enum Id3v2Version {
|
||||
pub enum ID3v2Version {
|
||||
/// ID3v2.2
|
||||
V2,
|
||||
/// ID3v2.3
|
||||
|
@ -86,7 +86,7 @@ pub(crate) fn synch_u32(n: u32) -> Result<u32> {
|
|||
#[derive(Copy, Clone)]
|
||||
pub(crate) struct Id3v2Header {
|
||||
#[cfg(feature = "id3v2")]
|
||||
pub version: Id3v2Version,
|
||||
pub version: ID3v2Version,
|
||||
pub flags: ID3v2TagFlags,
|
||||
pub size: u32,
|
||||
pub extended_size: u32,
|
||||
|
@ -105,9 +105,9 @@ where
|
|||
|
||||
// Version is stored as [major, minor], but here we don't care about minor revisions unless there's an error.
|
||||
let version = match header[3] {
|
||||
2 => Id3v2Version::V2,
|
||||
3 => Id3v2Version::V3,
|
||||
4 => Id3v2Version::V4,
|
||||
2 => ID3v2Version::V2,
|
||||
3 => ID3v2Version::V3,
|
||||
4 => ID3v2Version::V4,
|
||||
major => {
|
||||
return Err(ID3v2Error::new(ID3v2ErrorKind::BadId3v2Version(major, header[4])).into())
|
||||
},
|
||||
|
@ -118,7 +118,7 @@ where
|
|||
// Compression was a flag only used in ID3v2.2 (bit 2).
|
||||
// At the time the ID3v2.2 specification was written, a compression scheme wasn't decided.
|
||||
// The spec recommends just ignoring the tag in this case.
|
||||
if version == Id3v2Version::V2 && flags & 0x40 == 0x40 {
|
||||
if version == ID3v2Version::V2 && flags & 0x40 == 0x40 {
|
||||
return Err(ID3v2Error::new(ID3v2ErrorKind::Other(
|
||||
"Encountered a compressed ID3v2.2 tag",
|
||||
))
|
||||
|
@ -127,9 +127,9 @@ where
|
|||
|
||||
let mut flags_parsed = ID3v2TagFlags {
|
||||
unsynchronisation: flags & 0x80 == 0x80,
|
||||
experimental: (version == Id3v2Version::V4 || version == Id3v2Version::V3)
|
||||
experimental: (version == ID3v2Version::V4 || version == ID3v2Version::V3)
|
||||
&& flags & 0x20 == 0x20,
|
||||
footer: (version == Id3v2Version::V4 || version == Id3v2Version::V3)
|
||||
footer: (version == ID3v2Version::V4 || version == ID3v2Version::V3)
|
||||
&& flags & 0x10 == 0x10,
|
||||
crc: false, // Retrieved later if applicable
|
||||
#[cfg(feature = "id3v2_restrictions")]
|
||||
|
@ -140,7 +140,7 @@ where
|
|||
let mut extended_size = 0;
|
||||
|
||||
let extended_header =
|
||||
(version == Id3v2Version::V4 || version == Id3v2Version::V3) && flags & 0x40 == 0x40;
|
||||
(version == ID3v2Version::V4 || version == ID3v2Version::V3) && flags & 0x40 == 0x40;
|
||||
|
||||
if extended_header {
|
||||
extended_size = unsynch_u32(bytes.read_u32::<BigEndian>()?);
|
||||
|
|
|
@ -2,7 +2,7 @@ use super::flags::ID3v2TagFlags;
|
|||
use super::frame::id::FrameID;
|
||||
use super::frame::{Frame, FrameFlags, FrameValue};
|
||||
use super::util::text_utils::TextEncoding;
|
||||
use super::Id3v2Version;
|
||||
use super::ID3v2Version;
|
||||
use crate::error::{LoftyError, Result};
|
||||
use crate::id3::v2::frame::FrameRef;
|
||||
use crate::id3::v2::items::encoded_text_frame::EncodedTextFrame;
|
||||
|
@ -93,7 +93,7 @@ macro_rules! impl_accessor {
|
|||
/// [`SynchronizedText::as_bytes`](crate::id3::v2::SynchronizedText::as_bytes) for writing.
|
||||
pub struct Id3v2Tag {
|
||||
flags: ID3v2TagFlags,
|
||||
pub(super) original_version: Id3v2Version,
|
||||
pub(super) original_version: ID3v2Version,
|
||||
frames: Vec<Frame>,
|
||||
}
|
||||
|
||||
|
@ -110,7 +110,7 @@ impl Default for Id3v2Tag {
|
|||
fn default() -> Self {
|
||||
Self {
|
||||
flags: ID3v2TagFlags::default(),
|
||||
original_version: Id3v2Version::V4,
|
||||
original_version: ID3v2Version::V4,
|
||||
frames: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ impl Id3v2Tag {
|
|||
///
|
||||
/// This is here, since the tag is upgraded to `ID3v2.4`, but a `v2.2` or `v2.3`
|
||||
/// tag may have been read.
|
||||
pub fn original_version(&self) -> Id3v2Version {
|
||||
pub fn original_version(&self) -> ID3v2Version {
|
||||
self.original_version
|
||||
}
|
||||
}
|
||||
|
@ -644,7 +644,7 @@ impl<'a, I: Iterator<Item = FrameRef<'a>> + 'a> Id3v2TagRef<'a, I> {
|
|||
mod tests {
|
||||
use crate::id3::v2::items::popularimeter::Popularimeter;
|
||||
use crate::id3::v2::{
|
||||
read_id3v2_header, Frame, FrameFlags, FrameID, FrameValue, Id3v2Tag, Id3v2Version,
|
||||
read_id3v2_header, Frame, FrameFlags, FrameID, FrameValue, ID3v2Version, Id3v2Tag,
|
||||
LanguageFrame, TextEncoding,
|
||||
};
|
||||
use crate::tag::utils::test_utils::read_path;
|
||||
|
@ -845,7 +845,7 @@ mod tests {
|
|||
}
|
||||
|
||||
#[allow(clippy::field_reassign_with_default)]
|
||||
fn create_full_test_tag(version: Id3v2Version) -> Id3v2Tag {
|
||||
fn create_full_test_tag(version: ID3v2Version) -> Id3v2Tag {
|
||||
let mut tag = Id3v2Tag::default();
|
||||
tag.original_version = version;
|
||||
|
||||
|
@ -934,7 +934,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn id3v24_full() {
|
||||
let tag = create_full_test_tag(Id3v2Version::V4);
|
||||
let tag = create_full_test_tag(ID3v2Version::V4);
|
||||
let parsed_tag = read_tag("tests/tags/assets/id3v2/test_full.id3v24");
|
||||
|
||||
assert_eq!(tag, parsed_tag);
|
||||
|
@ -942,7 +942,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn id3v23_full() {
|
||||
let tag = create_full_test_tag(Id3v2Version::V3);
|
||||
let tag = create_full_test_tag(ID3v2Version::V3);
|
||||
let parsed_tag = read_tag("tests/tags/assets/id3v2/test_full.id3v23");
|
||||
|
||||
assert_eq!(tag, parsed_tag);
|
||||
|
@ -950,7 +950,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn id3v22_full() {
|
||||
let tag = create_full_test_tag(Id3v2Version::V2);
|
||||
let tag = create_full_test_tag(ID3v2Version::V2);
|
||||
let parsed_tag = read_tag("tests/tags/assets/id3v2/test_full.id3v22");
|
||||
|
||||
assert_eq!(tag, parsed_tag);
|
||||
|
@ -958,7 +958,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn id3v24_footer() {
|
||||
let mut tag = create_full_test_tag(Id3v2Version::V4);
|
||||
let mut tag = create_full_test_tag(ID3v2Version::V4);
|
||||
tag.flags.footer = true;
|
||||
|
||||
let mut writer = Vec::new();
|
||||
|
|
|
@ -2,7 +2,7 @@ use crate::error::{ErrorKind, LoftyError, Result};
|
|||
#[cfg(feature = "id3v2")]
|
||||
use crate::{
|
||||
error::{ID3v2Error, ID3v2ErrorKind},
|
||||
id3::v2::{util::text_utils::TextEncoding, Id3v2Version},
|
||||
id3::v2::{util::text_utils::TextEncoding, ID3v2Version},
|
||||
};
|
||||
|
||||
use std::borrow::Cow;
|
||||
|
@ -564,7 +564,7 @@ impl Picture {
|
|||
/// * The mimetype is not [`MimeType::Png`] or [`MimeType::Jpeg`]
|
||||
pub fn as_apic_bytes(
|
||||
&self,
|
||||
version: Id3v2Version,
|
||||
version: ID3v2Version,
|
||||
text_encoding: TextEncoding,
|
||||
) -> Result<Vec<u8>> {
|
||||
use crate::id3::v2::util::text_utils;
|
||||
|
@ -573,11 +573,11 @@ impl Picture {
|
|||
|
||||
let max_size = match version {
|
||||
// ID3v2.2 uses a 24-bit number for sizes
|
||||
Id3v2Version::V2 => 0xFFFF_FF16_u64,
|
||||
ID3v2Version::V2 => 0xFFFF_FF16_u64,
|
||||
_ => u64::from(u32::MAX),
|
||||
};
|
||||
|
||||
if version == Id3v2Version::V2 {
|
||||
if version == ID3v2Version::V2 {
|
||||
// ID3v2.2 PIC is pretty limited with formats
|
||||
let format = match self.mime_type {
|
||||
MimeType::Png => "PNG",
|
||||
|
@ -627,7 +627,7 @@ impl Picture {
|
|||
/// ID3v2.2:
|
||||
///
|
||||
/// * The format is not "PNG" or "JPG"
|
||||
pub fn from_apic_bytes(bytes: &[u8], version: Id3v2Version) -> Result<(Self, TextEncoding)> {
|
||||
pub fn from_apic_bytes(bytes: &[u8], version: ID3v2Version) -> Result<(Self, TextEncoding)> {
|
||||
use crate::id3::v2::util::text_utils;
|
||||
|
||||
let mut cursor = Cursor::new(bytes);
|
||||
|
@ -637,7 +637,7 @@ impl Picture {
|
|||
None => return Err(LoftyError::new(ErrorKind::NotAPicture)),
|
||||
};
|
||||
|
||||
let mime_type = if version == Id3v2Version::V2 {
|
||||
let mime_type = if version == ID3v2Version::V2 {
|
||||
let mut format = [0; 3];
|
||||
cursor.read_exact(&mut format)?;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use lofty::id3::v2::{Id3v2Version, TextEncoding};
|
||||
use lofty::id3::v2::{ID3v2Version, TextEncoding};
|
||||
use lofty::{Picture, PictureInformation, PictureType};
|
||||
|
||||
use std::fs::File;
|
||||
|
@ -28,7 +28,7 @@ fn create_original_picture() -> Picture {
|
|||
fn id3v24_apic() {
|
||||
let buf = get_buf("tests/picture/assets/png_640x628.apic");
|
||||
|
||||
let (pic, _) = Picture::from_apic_bytes(&*buf, Id3v2Version::V4).unwrap();
|
||||
let (pic, _) = Picture::from_apic_bytes(&*buf, ID3v2Version::V4).unwrap();
|
||||
|
||||
assert_eq!(create_original_picture(), pic);
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ fn as_apic_bytes() {
|
|||
let original_picture = create_original_picture();
|
||||
|
||||
let original_as_apic = original_picture
|
||||
.as_apic_bytes(Id3v2Version::V4, TextEncoding::Latin1)
|
||||
.as_apic_bytes(ID3v2Version::V4, TextEncoding::Latin1)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(buf, original_as_apic);
|
||||
|
@ -50,7 +50,7 @@ fn as_apic_bytes() {
|
|||
fn id3v22_pic() {
|
||||
let buf = get_buf("tests/picture/assets/png_640x628.pic");
|
||||
|
||||
let (pic, _) = Picture::from_apic_bytes(&*buf, Id3v2Version::V2).unwrap();
|
||||
let (pic, _) = Picture::from_apic_bytes(&*buf, ID3v2Version::V2).unwrap();
|
||||
|
||||
assert_eq!(create_original_picture(), pic);
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ fn as_apic_bytes_v2() {
|
|||
let original_picture = create_original_picture();
|
||||
|
||||
let original_as_pic = original_picture
|
||||
.as_apic_bytes(Id3v2Version::V2, TextEncoding::Latin1)
|
||||
.as_apic_bytes(ID3v2Version::V2, TextEncoding::Latin1)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(buf, original_as_pic);
|
||||
|
|
Loading…
Add table
Reference in a new issue