Skip to content
This repository was archived by the owner on Sep 3, 2025. It is now read-only.
This repository was archived by the owner on Sep 3, 2025. It is now read-only.

Ignore NULL byte following TXXX frame? #135

@randoragon

Description

@randoragon

Consider a sample mp3 file created in the following way:

ffmpeg -f lavfi -i anullsrc=r=44100:cl=mono -t 5 -q:a 9 -acodec libmp3lame -id3v2_version 0 sample.mp3
mid3v2 --TXXX Key:Value sample.mp3

The first command creates an empty, 5 seconds long mp3 file with no ID3v2 tag.
The second utilizes the mid3v2 utility based on the Python Mutagen module to add an ID3v2.4 TXXX frame with description "Key" and value "Value".

If we now print the tag using id3...

use id3::{Tag, TagLike};

fn main() {
    let tag = Tag::read_from_path("../sample.mp3").unwrap();
    println!("{:#?}", tag);
}

...this is the output:

Tag {
    frames: [
        Frame {
            id: Valid(
                "TXXX",
            ),
            content: ExtendedText(
                ExtendedText {
                    description: "Key",
                    value: "Value\0",
                },
            ),
            tag_alter_preservation: false,
            file_alter_preservation: false,
            encoding: Some(
                UTF8,
            ),
        },
    ],
    version: Id3v24,
}

As you can see, there is a '\0' at the end of the TXXX value. This '\0' is not reported by any other ID3 tool I've tried (mid3v2, eyeD3, id3ted).

I've investigated this issue a lot since yesterday, I've read the ID3 Informal specification a few times, looked at issues in Mutagen (particularly quodlibet/mutagen#379 is interesting). It seems this inconsistency between tooling is sadly a result of the ID3 specification itself being pretty vague on the subject.
For instance, my not-very-educated stance on this is that TXXX is not a text frame and the optional NULL termination rules do not apply to it (justification: dhamaniasad/mutagen#179 (comment)). However, a maintainer over at Mutagen's closed issue had a different opinion (quodlibet/mutagen#379 (comment)), claiming that:

The v2.3 spec explicitly states that text frames (TXXX) can have optional termination, (...)

...which I strongly disagree with, unless I see where this "explicitness" is coming from (I was unable to find it).

Still, as an author of a command-line ID3 tool (rsid3) based on rust-id3, and especially as a user, I do care about compliance between tools. Since Mutagen is probably the most used and popular ID3 library at the moment, I think it's especially beneficial to be compliant with it, so that users can smoothly transition and expect the same results. This is all assuming that Mutagen is compliant with the standard and the differences only arise from varying interpretations of the standard.

I guess my suggestion is to keep some kind of list of differences with Mutagen (and possibly other popular ID3 libraries, if they exist), maybe even include some remarks in the documentation. And I'd love to hear what you think about this, should this project aim for compliance with Mutagen (within the ramifications of the standard), or do we not care about it at all? Is this a bug, a feature, or neither?

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions