mirror of
https://github.com/Serial-ATA/lofty-rs
synced 2024-11-10 06:34:18 +00:00
Vorbis/Ape: Verify FlagCompilation
item contents on merge
This commit is contained in:
parent
790c1ab1e5
commit
1474efa9a3
6 changed files with 46 additions and 16 deletions
|
@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- **VorbisComments**/**ApeTag**: Verify contents of `ItemKey::FlagCompilation` during `Tag` merge ([PR](https://github.com/Serial-ATA/lofty-rs/pull/387))
|
||||||
|
|
||||||
## [0.19.2] - 2024-04-26
|
## [0.19.2] - 2024-04-26
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -10,12 +10,13 @@ use crate::tag::item::ItemValueRef;
|
||||||
use crate::tag::{
|
use crate::tag::{
|
||||||
try_parse_year, Accessor, ItemKey, ItemValue, MergeTag, SplitTag, Tag, TagExt, TagItem, TagType,
|
try_parse_year, Accessor, ItemKey, ItemValue, MergeTag, SplitTag, Tag, TagExt, TagItem, TagType,
|
||||||
};
|
};
|
||||||
|
use crate::util::flag_item;
|
||||||
|
use crate::util::io::{FileLike, Truncate};
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
use crate::util::io::{FileLike, Truncate};
|
|
||||||
use lofty_attr::tag;
|
use lofty_attr::tag;
|
||||||
|
|
||||||
macro_rules! impl_accessor {
|
macro_rules! impl_accessor {
|
||||||
|
@ -163,6 +164,20 @@ impl ApeTag {
|
||||||
ItemKey::TrackTotal => set_number(&item, |number| self.set_track_total(number)),
|
ItemKey::TrackTotal => set_number(&item, |number| self.set_track_total(number)),
|
||||||
ItemKey::DiscNumber => set_number(&item, |number| self.set_disk(number)),
|
ItemKey::DiscNumber => set_number(&item, |number| self.set_disk(number)),
|
||||||
ItemKey::DiscTotal => set_number(&item, |number| self.set_disk_total(number)),
|
ItemKey::DiscTotal => set_number(&item, |number| self.set_disk_total(number)),
|
||||||
|
|
||||||
|
// Normalize flag items
|
||||||
|
ItemKey::FlagCompilation => {
|
||||||
|
let Some(text) = item.item_value.text() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let Some(flag) = flag_item(text) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let value = u8::from(flag).to_string();
|
||||||
|
self.insert(ApeItem::text("Compilation", value));
|
||||||
|
},
|
||||||
_ => {
|
_ => {
|
||||||
if let Ok(item) = item.try_into() {
|
if let Ok(item) = item.try_into() {
|
||||||
self.insert(item);
|
self.insert(item);
|
||||||
|
|
|
@ -21,6 +21,7 @@ use crate::picture::{Picture, PictureType, TOMBSTONE_PICTURE};
|
||||||
use crate::tag::{
|
use crate::tag::{
|
||||||
try_parse_year, Accessor, ItemKey, ItemValue, MergeTag, SplitTag, Tag, TagExt, TagItem, TagType,
|
try_parse_year, Accessor, ItemKey, ItemValue, MergeTag, SplitTag, Tag, TagExt, TagItem, TagType,
|
||||||
};
|
};
|
||||||
|
use crate::util::flag_item;
|
||||||
use crate::util::io::{FileLike, Length, Truncate};
|
use crate::util::io::{FileLike, Length, Truncate};
|
||||||
use crate::util::text::{decode_text, TextDecodeOptions, TextEncoding};
|
use crate::util::text::{decode_text, TextDecodeOptions, TextEncoding};
|
||||||
|
|
||||||
|
@ -1387,13 +1388,13 @@ impl MergeTag for SplitTagRemainder {
|
||||||
|
|
||||||
// Flag items
|
// Flag items
|
||||||
for item_key in [&ItemKey::FlagCompilation, &ItemKey::FlagPodcast] {
|
for item_key in [&ItemKey::FlagCompilation, &ItemKey::FlagPodcast] {
|
||||||
let Some(flag_value) = tag.take_strings(item_key).next() else {
|
let Some(text) = tag.take_strings(item_key).next() else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
if flag_value != "1" && flag_value != "0" {
|
let Some(flag_value) = flag_item(&text) else {
|
||||||
continue;
|
continue;
|
||||||
}
|
};
|
||||||
|
|
||||||
let frame_id = item_key
|
let frame_id = item_key
|
||||||
.map_key(TagType::Id3v2, false)
|
.map_key(TagType::Id3v2, false)
|
||||||
|
@ -1401,7 +1402,7 @@ impl MergeTag for SplitTagRemainder {
|
||||||
|
|
||||||
merged.frames.push(new_text_frame(
|
merged.frames.push(new_text_frame(
|
||||||
FrameId::Valid(Cow::Borrowed(frame_id)),
|
FrameId::Valid(Cow::Borrowed(frame_id)),
|
||||||
flag_value,
|
u8::from(flag_value).to_string(),
|
||||||
FrameFlags::default(),
|
FrameFlags::default(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ use crate::picture::{Picture, PictureType, TOMBSTONE_PICTURE};
|
||||||
use crate::tag::{
|
use crate::tag::{
|
||||||
try_parse_year, Accessor, ItemKey, ItemValue, MergeTag, SplitTag, Tag, TagExt, TagItem, TagType,
|
try_parse_year, Accessor, ItemKey, ItemValue, MergeTag, SplitTag, Tag, TagExt, TagItem, TagType,
|
||||||
};
|
};
|
||||||
|
use crate::util::flag_item;
|
||||||
use crate::util::io::{FileLike, Length, Truncate};
|
use crate::util::io::{FileLike, Length, Truncate};
|
||||||
use atom::{AdvisoryRating, Atom, AtomData};
|
use atom::{AdvisoryRating, Atom, AtomData};
|
||||||
|
|
||||||
|
@ -705,18 +706,10 @@ impl MergeTag for SplitTagRemainder {
|
||||||
ItemKey::DiscNumber => convert_to_uint(&mut discs.0, text.as_str()),
|
ItemKey::DiscNumber => convert_to_uint(&mut discs.0, text.as_str()),
|
||||||
ItemKey::DiscTotal => convert_to_uint(&mut discs.1, text.as_str()),
|
ItemKey::DiscTotal => convert_to_uint(&mut discs.1, text.as_str()),
|
||||||
ItemKey::FlagCompilation | ItemKey::FlagPodcast => {
|
ItemKey::FlagCompilation | ItemKey::FlagPodcast => {
|
||||||
let Ok(num) = text.as_str().parse::<u8>() else {
|
let Some(data) = flag_item(text.as_str()) else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
let data = match num {
|
|
||||||
0 => false,
|
|
||||||
1 => true,
|
|
||||||
_ => {
|
|
||||||
// Ignore all other, unexpected values
|
|
||||||
continue;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
merged.atoms.push(Atom {
|
merged.atoms.push(Atom {
|
||||||
ident: ident.into_owned(),
|
ident: ident.into_owned(),
|
||||||
data: AtomDataStorage::Single(AtomData::Bool(data)),
|
data: AtomDataStorage::Single(AtomData::Bool(data)),
|
||||||
|
|
|
@ -9,12 +9,13 @@ use crate::probe::Probe;
|
||||||
use crate::tag::{
|
use crate::tag::{
|
||||||
try_parse_year, Accessor, ItemKey, ItemValue, MergeTag, SplitTag, Tag, TagExt, TagItem, TagType,
|
try_parse_year, Accessor, ItemKey, ItemValue, MergeTag, SplitTag, Tag, TagExt, TagItem, TagType,
|
||||||
};
|
};
|
||||||
|
use crate::util::flag_item;
|
||||||
|
use crate::util::io::{FileLike, Length, Truncate};
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
use crate::util::io::{FileLike, Length, Truncate};
|
|
||||||
use lofty_attr::tag;
|
use lofty_attr::tag;
|
||||||
|
|
||||||
macro_rules! impl_accessor {
|
macro_rules! impl_accessor {
|
||||||
|
@ -575,10 +576,19 @@ impl MergeTag for SplitTagRemainder {
|
||||||
let item_value = item.item_value;
|
let item_value = item.item_value;
|
||||||
|
|
||||||
// Discard binary items, as they are not allowed in Vorbis comments
|
// Discard binary items, as they are not allowed in Vorbis comments
|
||||||
let (ItemValue::Text(val) | ItemValue::Locator(val)) = item_value else {
|
let (ItemValue::Text(mut val) | ItemValue::Locator(mut val)) = item_value else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Normalize flag items
|
||||||
|
if item_key == ItemKey::FlagCompilation {
|
||||||
|
let Some(flag) = flag_item(&val) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
val = u8::from(flag).to_string();
|
||||||
|
}
|
||||||
|
|
||||||
let key;
|
let key;
|
||||||
match item_key {
|
match item_key {
|
||||||
ItemKey::Unknown(unknown) => {
|
ItemKey::Unknown(unknown) => {
|
||||||
|
|
|
@ -2,3 +2,11 @@ pub(crate) mod alloc;
|
||||||
pub mod io;
|
pub mod io;
|
||||||
pub(crate) mod math;
|
pub(crate) mod math;
|
||||||
pub(crate) mod text;
|
pub(crate) mod text;
|
||||||
|
|
||||||
|
pub(crate) fn flag_item(item: &str) -> Option<bool> {
|
||||||
|
match item {
|
||||||
|
"1" | "true" => Some(true),
|
||||||
|
"0" | "false" => Some(false),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue