Skip to content

Commit 003848c

Browse files
uklotzdeSerial-ATA
authored andcommitted
id3v2: Report bad or unsupported frame IDs
1 parent bbfaa27 commit 003848c

File tree

5 files changed

+47
-14
lines changed

5 files changed

+47
-14
lines changed

src/error.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
//! which can be extended at any time.
55
66
use crate::file::FileType;
7+
use crate::ItemKey;
78

89
use std::collections::TryReserveError;
910
use std::fmt::{Debug, Display, Formatter};
@@ -83,7 +84,11 @@ pub enum Id3v2ErrorKind {
8384

8485
// Frame
8586
/// Arises when a frame ID contains invalid characters (must be within `'A'..'Z'` or `'0'..'9'`)
86-
BadFrameId,
87+
/// or if the ID is too short/long.
88+
BadFrameId(Vec<u8>),
89+
/// Arises when no frame ID is available in the ID3v2 specification for an item key
90+
/// and the associated value type.
91+
UnsupportedFrameId(ItemKey),
8792
/// Arises when a frame doesn't have enough data
8893
BadFrameLength,
8994
/// Arises when reading/writing a compressed or encrypted frame with no data length indicator
@@ -133,7 +138,10 @@ impl Display for Id3v2ErrorKind {
133138
},
134139

135140
// Frame
136-
Self::BadFrameId => write!(f, "Failed to parse a frame ID"),
141+
Self::BadFrameId(frame_id) => write!(f, "Failed to parse a frame ID: 0x{frame_id:x?}"),
142+
Self::UnsupportedFrameId(item_key) => {
143+
write!(f, "Unsupported frame ID for item key {item_key:?}")
144+
},
137145
Self::BadFrameLength => write!(
138146
f,
139147
"Frame isn't long enough to extract the necessary information"

src/id3/v2/frame/header.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@ where
2424
return Ok(None);
2525
}
2626

27-
let id_str = std::str::from_utf8(&frame_header[..3])
28-
.map_err(|_| Id3v2Error::new(Id3v2ErrorKind::BadFrameId))?;
27+
let frame_id = &frame_header[..3];
28+
let id_str = std::str::from_utf8(frame_id)
29+
.map_err(|_| Id3v2Error::new(Id3v2ErrorKind::BadFrameId(frame_id.to_vec())))?;
2930
let id = upgrade_v2(id_str).map_or_else(|| Cow::Owned(id_str.to_owned()), Cow::Borrowed);
3031

3132
let frame_id = FrameId::new_cow(id)?;
@@ -63,8 +64,9 @@ where
6364
frame_id_end = 3;
6465
}
6566

67+
let frame_id = &frame_header[..frame_id_end];
6668
let id_str = std::str::from_utf8(&frame_header[..frame_id_end])
67-
.map_err(|_| Id3v2Error::new(Id3v2ErrorKind::BadFrameId))?;
69+
.map_err(|_| Id3v2Error::new(Id3v2ErrorKind::BadFrameId(frame_id.to_vec())))?;
6870

6971
let mut size = u32::from_be_bytes([
7072
frame_header[4],

src/id3/v2/frame/id.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ impl<'a> FrameId<'a> {
3838
match id.len() {
3939
3 => Ok(FrameId::Outdated(id)),
4040
4 => Ok(FrameId::Valid(id)),
41-
_ => Err(Id3v2Error::new(Id3v2ErrorKind::BadFrameId).into()),
41+
_ => Err(
42+
Id3v2Error::new(Id3v2ErrorKind::BadFrameId(id.into_owned().into_bytes())).into(),
43+
),
4244
}
4345
}
4446

@@ -52,7 +54,10 @@ impl<'a> FrameId<'a> {
5254
pub(super) fn verify_id(id_str: &str) -> Result<()> {
5355
for c in id_str.chars() {
5456
if !c.is_ascii_uppercase() && !c.is_ascii_digit() {
55-
return Err(Id3v2Error::new(Id3v2ErrorKind::BadFrameId).into());
57+
return Err(Id3v2Error::new(Id3v2ErrorKind::BadFrameId(
58+
id_str.as_bytes().to_vec(),
59+
))
60+
.into());
5661
}
5762
}
5863

@@ -93,7 +98,7 @@ impl<'a> TryFrom<&'a ItemKey> for FrameId<'a> {
9398
}
9499
}
95100

96-
Err(Id3v2Error::new(Id3v2ErrorKind::BadFrameId).into())
101+
Err(Id3v2Error::new(Id3v2ErrorKind::UnsupportedFrameId(k.clone())).into())
97102
},
98103
}
99104
}

src/id3/v2/frame/mod.rs

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,12 @@ impl<'a> Frame<'a> {
112112
None => id,
113113
Some(upgraded) => Cow::Borrowed(upgraded),
114114
},
115-
_ => return Err(Id3v2Error::new(Id3v2ErrorKind::BadFrameId).into()),
115+
_ => {
116+
return Err(Id3v2Error::new(Id3v2ErrorKind::BadFrameId(
117+
id.into_owned().into_bytes(),
118+
))
119+
.into())
120+
},
116121
};
117122

118123
let id = FrameId::new_cow(id_upgraded)?;
@@ -504,8 +509,12 @@ impl<'a> TryFrom<&'a TagItem> for FrameRef<'a> {
504509
frame_id = id;
505510
},
506511
Err(_) => {
507-
let Some(desc) = tag_item.key().map_key(TagType::Id3v2, true) else {
508-
return Err(Id3v2Error::new(Id3v2ErrorKind::BadFrameId).into());
512+
let item_key = tag_item.key();
513+
let Some(desc) = item_key.map_key(TagType::Id3v2, true) else {
514+
return Err(Id3v2Error::new(Id3v2ErrorKind::UnsupportedFrameId(
515+
item_key.clone(),
516+
))
517+
.into());
509518
};
510519

511520
match tag_item.value() {
@@ -525,7 +534,12 @@ impl<'a> TryFrom<&'a TagItem> for FrameRef<'a> {
525534
content: locator.clone(),
526535
})
527536
},
528-
_ => return Err(Id3v2Error::new(Id3v2ErrorKind::BadFrameId).into()),
537+
_ => {
538+
return Err(Id3v2Error::new(Id3v2ErrorKind::UnsupportedFrameId(
539+
item_key.clone(),
540+
))
541+
.into())
542+
},
529543
}
530544
},
531545
}

src/id3/v2/tag.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,9 @@ impl Accessor for Id3v2Tag {
533533
fn set_comment(&mut self, value: String) {
534534
let mut value = Some(value);
535535
self.frames.retain_mut(|frame| {
536-
let Some(CommentFrame { content, .. }) = filter_comment_frame_by_description_mut(frame, &EMPTY_CONTENT_DESCRIPTOR) else {
536+
let Some(CommentFrame { content, .. }) =
537+
filter_comment_frame_by_description_mut(frame, &EMPTY_CONTENT_DESCRIPTOR)
538+
else {
537539
return true;
538540
};
539541
if let Some(value) = value.take() {
@@ -759,7 +761,9 @@ impl SplitTag for Id3v2Tag {
759761
) => {
760762
if owner == MUSICBRAINZ_UFID_OWNER {
761763
let mut identifier = Cursor::new(identifier);
762-
let Ok(recording_id) = decode_text(&mut identifier, TextEncoding::Latin1, false) else {
764+
let Ok(recording_id) =
765+
decode_text(&mut identifier, TextEncoding::Latin1, false)
766+
else {
763767
return true; // Keep frame
764768
};
765769
tag.items.push(TagItem::new(

0 commit comments

Comments
 (0)