From d02f2961990db9ff224e878846eea49f4653dd93 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Mon, 12 Feb 2018 16:26:01 +0100 Subject: id3v2: re-fix handling of v2.4 extended headers The various id3v2 specs handle the extended header sizes differently (because hey, it wouldn't be fun otherwise). http://id3.org/id3v2.3.0 states: "Where the 'Extended header size', currently 6 or 10 bytes, excludes itself." http://id3.org/id3v2.4.0-structure states: Extended header size 4 * %0xxxxxxx Number of flag bytes $01 Extended Flags $xx Where the 'Extended header size' is the size of the whole extended header, stored as a 32 bit synchsafe integer. An extended header can thus never have a size of fewer than six bytes. So in id3v2.4.0 it's the *whole* extended header size (a-la ISOBMFF atom), whereas in id3v2.3.0 it's the extended header size *excluding* those 4 initial bytes. And for other versions, god knows.. Fixes regression introduced in commit da607005. https://bugzilla.gnome.org/show_bug.cgi?id=792983 --- gst-libs/gst/tag/id3v2.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/tag/id3v2.c b/gst-libs/gst/tag/id3v2.c index 5b76f7563..1e90b1bbe 100644 --- a/gst-libs/gst/tag/id3v2.c +++ b/gst-libs/gst/tag/id3v2.c @@ -447,8 +447,30 @@ id3v2_frames_to_tag_list (ID3TagsWorking * work, guint size) /* Extended header if present */ if (work->hdr.flags & ID3V2_HDR_FLAG_EXTHDR) { work->hdr.ext_hdr_size = id3v2_read_synch_uint (work->hdr.frame_data, 4); + + /* In id3v2.4.x the header size is the size of the *whole* + * extended header. + * In id3v2.3.x the header size does *not* include itself. + * In older versions it's undefined but let's assume it follow 2.3.x + */ + switch (ID3V2_VER_MAJOR (work->hdr.version)) { + case 0: + case 1: + case 2: + case 3: + work->hdr.ext_hdr_size += 4; + break; + case 4: + break; + default: + GST_WARNING + ("Don't know how to handled Extended Header for this id3 version"); + break; + } + GST_LOG ("extended header size %d", work->hdr.ext_hdr_size); + if (work->hdr.ext_hdr_size < 6 || - (work->hdr.ext_hdr_size + 4) > work->hdr.frame_data_size) { + work->hdr.ext_hdr_size > work->hdr.frame_data_size) { GST_DEBUG ("Invalid extended header. Broken tag"); return FALSE; } @@ -458,10 +480,9 @@ id3v2_frames_to_tag_list (ID3TagsWorking * work, guint size) ("Tag claims extended header, but doesn't have enough bytes. Broken tag"); return FALSE; } - work->hdr.ext_flag_data = work->hdr.frame_data + 5; - work->hdr.frame_data += work->hdr.ext_hdr_size + 4; - work->hdr.frame_data_size -= work->hdr.ext_hdr_size + 4; + work->hdr.frame_data += work->hdr.ext_hdr_size; + work->hdr.frame_data_size -= work->hdr.ext_hdr_size; } frame_hdr_size = id3v2_frame_hdr_size (work->hdr.version); -- cgit v1.2.1