ID3v2 frame size is incorrectly stored sync safe
Status: Beta
Brought to you by:
puck_lock
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)
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.