Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

Close

#4 ID3v2 frame size is incorrectly stored sync safe

open
nobody
None
5
2007-05-19
2007-05-19
go4shoe
No

according to

====================================
3.3. ID3v2 frame overview

As the tag consists of a tag header and a tag body with one or more
frames, all the frames consists of a frame header followed by one or
more fields containing the actual information. The layout of the
frame header:

Frame ID $xx xx xx xx (four characters)
Size $xx xx xx xx
Flags $xx xx

====================================

the size is stored as 4 byte int (and not sync safe)
please check:

AP_ID3v2_tags.cpp Revision 104
line 1357
I think you have to remove the call to convert_to_syncsafe32 (and when reading)

Discussion

  • Mellow Flow
    Mellow Flow
    2007-07-02

    Logged In: YES
    user_id=1469152
    Originator: NO

    You are quoting a portion of the id3v2.2/2.3 standards. AtomicParsley only writes id3v2.4 - and in 2.4, the integers are syncsafe:

    4. ID3v2 frame overview

    Frame ID $xx xx xx xx (four characters)
    Size 4 * %0xxxxxxx
    Flags $xx xx

    The size is excluding the frame header ('total
    frame size' - 10 bytes) and stored as a 32 bit synchsafe integer.

    ------------
    You can see in APar_ID32_ScanID3Tag the version tests:

    if (id32_atom->ID32_TagInfo->ID3v2Tag_MajorVersion == 4) {
    id32_atom->ID32_TagInfo->ID3v2Tag_Length = syncsafe32_to_UInt32(fulltag_ptr);
    fulltag_ptr+=4;
    } else if (id32_atom->ID32_TagInfo->ID3v2Tag_MajorVersion == 3) {
    id32_atom->ID32_TagInfo->ID3v2Tag_Length = UInt32FromBigEndian(fulltag_ptr); //TODO: when testing ends, this switches to syncsafe
    fulltag_ptr+=4;
    } else if (id32_atom->ID32_TagInfo->ID3v2Tag_MajorVersion == 2) {
    id32_atom->ID32_TagInfo->ID3v2Tag_Length = UInt24FromBigEndian(fulltag_ptr);
    fulltag_ptr+=3;
    }

    please also note the comment after the TODO. In version 2.3, while it isn't expressly called "syncsafe", the integers for the ->headers<- are depicted in *exactly* the same way as in 2.4:

    2.3 : 4 * %0xxxxxxx
    2.4 : 4 * %0xxxxxxx

    This patch should be applied:
    } else if (id32_atom->ID32_TagInfo->ID3v2Tag_MajorVersion == 3) {
    -id32_atom->ID32_TagInfo->ID3v2Tag_Length = UInt32FromBigEndian(fulltag_ptr); //TODO: when testing ends, this switches to syncsafe
    +id32_atom->ID32_TagInfo->ID3v2Tag_Length = syncsafe32_to_UInt32(fulltag_ptr);
    -------------------
    The frames themselves do differ (they are normal integers in 2.3 as you point out). So the comment in how 2.3 frames are handled is wrong (and only the comment - the frames in 2.3 are normal integers, not syncsafe):

    } else if (id32_atom->ID32_TagInfo->ID3v2Tag_MajorVersion == 3) {
    -target_list_frameinfo->ID3v2_Frame_Length = UInt32FromBigEndian(fulltag_ptr); //TODO: when testing ends, this switches to syncsafe
    +target_list_frameinfo->ID3v2_Frame_Length = UInt32FromBigEndian(fulltag_ptr);

    Another issue is that convert_to_syncsafe32() is used for all tag versions in APar_Render_ID32_Tag when there explicit accommodations for 2.2 & 2.3. However (and this is why it isn't any issue at all), AtomicParsley only writes id3v2.4 frames and can't convert from 2.x to 2.4. From AtomicParsley -ID3h:

    AtomicParsley writes ID3 version 2.4.0 tags *only*. There is no up-converting from older versions.