From d971615952aaa7ac2260338823c937277597238d Mon Sep 17 00:00:00 2001 From: Serial <69764315+Serial-ATA@users.noreply.github.com> Date: Mon, 12 Dec 2022 13:17:20 -0500 Subject: [PATCH] ID3v2: Properly handle solidus character (U+002F) in text frames V2 and V3 allow for the separation of multiple values with the solidus (/) character, while in V4 the separator is null (0). This was not accounted for previously, and would break valid V4 strings ("Foo / Bar" would be split into "Foo " and " Bar"). closes #82 --- src/id3/v2/tag.rs | 8 ++++---- tests/files/assets/issue_82_solidus_in_tag.mp3 | Bin 0 -> 699 bytes tests/files/mpeg.rs | 13 +++++++++++++ 3 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 tests/files/assets/issue_82_solidus_in_tag.mp3 diff --git a/src/id3/v2/tag.rs b/src/id3/v2/tag.rs index 0a828d57..bbb03074 100644 --- a/src/id3/v2/tag.rs +++ b/src/id3/v2/tag.rs @@ -531,7 +531,7 @@ impl From for Tag { }), ) => { let item_key = ItemKey::from_key(TagType::ID3v2, description); - for c in content.split(&['\0', '/'][..]) { + for c in content.split('\0') { tag.items.push(TagItem::new( item_key.clone(), ItemValue::Text(c.to_string()), @@ -547,7 +547,7 @@ impl From for Tag { }), ) => { let item_key = ItemKey::from_key(TagType::ID3v2, description); - for c in content.split(&['\0', '/'][..]) { + for c in content.split('\0') { tag.items.push(TagItem::new( item_key.clone(), ItemValue::Locator(c.to_string()), @@ -562,7 +562,7 @@ impl From for Tag { | FrameValue::UnSyncText(LanguageFrame { content, .. }) | FrameValue::Text { value: content, .. } | FrameValue::UserText(EncodedTextFrame { content, .. }) => { - for c in content.split(&['\0', '/'][..]) { + for c in content.split('\0') { tag.items.push(TagItem::new( item_key.clone(), ItemValue::Text(c.to_string()), @@ -603,7 +603,7 @@ impl From for ID3v2Tag { let mut s = String::with_capacity(iter.size_hint().0); s.push_str(&first); iter.for_each(|i| { - s.push('/'); + s.push('\0'); s.push_str(&i); }); diff --git a/tests/files/assets/issue_82_solidus_in_tag.mp3 b/tests/files/assets/issue_82_solidus_in_tag.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..984e85f31e39a4aa8ae2685ad591984b889dac0e GIT binary patch literal 699 zcmeZtF=l1}0w%!_&k!RZg9nJ+^79q+6-qKoa#BHZBNY7qEpSA$`2Yjs5?}x*Fff=j ZFfg!$QXhcq31+5`JvDUl&oVmr2LKi7ip>B3 literal 0 HcmV?d00001 diff --git a/tests/files/mpeg.rs b/tests/files/mpeg.rs index e8a9f854..64e457e3 100644 --- a/tests/files/mpeg.rs +++ b/tests/files/mpeg.rs @@ -52,6 +52,19 @@ fn read_with_junk_bytes_between_frames() { assert_eq!(id3v1_tag.title(), Some("title test")); } +#[test] +fn issue_82_solidus_in_tag() { + let file = Probe::open("tests/files/assets/issue_82_solidus_in_tag.mp3") + .unwrap() + .read() + .unwrap(); + + assert_eq!(file.file_type(), FileType::MPEG); + + let id3v2_tag = &file.tags()[0]; + assert_eq!(id3v2_tag.title(), Some("Foo / title")); +} + #[test] fn write() { let mut file = temp_file!("tests/files/assets/minimal/full_test.mp3");