Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The slash (/) characters in tags are not correctly parsed #103

Open
tranxuanthang opened this issue Oct 25, 2022 · 3 comments · May be fixed by #146
Open

The slash (/) characters in tags are not correctly parsed #103

tranxuanthang opened this issue Oct 25, 2022 · 3 comments · May be fixed by #146

Comments

@tranxuanthang
Copy link

tranxuanthang commented Oct 25, 2022

Looks like slash characters in tags are not parsed correctly by rust-id3 and are converted to null terminator character.

Some examples are:

  • (artist name) Alan Walker, Au/Ra, Tomine Harket => "Alan Walker, Au\0Ra, Tomine Harket"
  • (artist name) Derek Duke/Russell Brower => "Derek Duke\0Russell Brower"
  • (album & track name) Misty Mountains (In Dwarvish/Khuzdul) => "Misty Mountains (In Dwarvish\0Khuzdul)"

EDIT: Update example file. I'm not quite sure yet but it seems that the issue only happens in ID3 v2.3 version.

let mut tag = id3::Tag::new();
tag.add_frame(id3::Frame::text("TPE1", "Derek Duke/Russell Brower"));
tag.write_to_path("test.id3", id3::Version::Id3v23).unwrap();
let tag = id3::Tag::read_from_path("test.id3").unwrap();
println!("{:?}", tag.artist()); // Some("Derek Duke\0Russell Brower")

test.zip

@tranxuanthang
Copy link
Author

tranxuanthang commented Oct 27, 2022

After seeing these:

I understand the issue better now. But still I think assuming the slash / character as separator for multiple entries for ID3 v2.2 or v2.3 might end up messing with a few artist names. One of these cases is my first example, calling tag.artists() will get you Some(["Alan Walker, Au", "Ra, Tomine Harket"]).

At least, I think the null/slash substitute definitely should not apply for all text fields, for example album name and track name. And tag.artist() should return the expected result, without null terminator character.

@polyfloyd
Copy link
Owner

ID3 has support for split values in text frames. In v2.2 and v2.3 the separator is a slash while in v2.4 it is a null byte.

I intended the library to have a uniform ID3v2.4 interface, so everything that it reads is normalized to use null bytes. But I must admit that this leaves much to desire...

Splitting happens at a very low level, just after decoding at src/stream/frame/content.rs:449

It might be worth considering making the split functions of TagLike version aware so at least the underlying content remains untouched unless desired

@Holzhaus
Copy link
Contributor

Holzhaus commented Nov 22, 2024

ID3 has support for split values in text frames. In v2.2 and v2.3 the separator is a slash while in v2.4 it is a null byte.ple is

I intended the library to have a uniform ID3v2.4 interface, so everything that it reads is normalized to use null bytes.

This is not entirely correct. The ID3v2.2.0 and ID3v2.3.0 specs only mention that certain text frames may contain multiple values, not all of them. This library currently assumes that the slash always indicates multiple values for these versions.

TIn some cases, replacing the slash with a null bytes leads to the opposite of what was originally intended: Instead of achieving a uniform interface, users of this library have to implement custom workarounds for different tag versions. One example is the TRCK frame:

TRCK
The 'Track number/Position in set' frame is a numeric string containing the order number of the audio-file on its original recording. This may be extended with a "/" character and a numeric string containing the total numer of tracks/elements on the original recording. E.g. "4/9".

Source: https://id3.org/id3v2.3.0#line-473

For an ID3v2.4 tag, this works...

$ cargo run --example id3info -- testdata/picard-2.12.3-id3v23-utf16.id3
# ID3 ID3v2.3 - 32 frames
...
TRCK="1/8"
...

... but for an ID3v2.3 tag, the value is wrongly parsed as multi-values:

$ cargo run --example id3info -- testdata/picard-2.12.3-id3v24-utf8.id3
# ID3 ID3v2.4 - 33 frames
...
TRCK="1\08"
...

I opened #146 to fix this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants