[FFmpeg-devel] skip multiple id3v2 headers

David Byron dbyron
Mon Sep 13 23:23:47 CEST 2010


> There really are not that many explanations
> A. one value is truly wrong and not useable
> B. (much more likely) there is a bug in the code reading
>     the tags and it somehow gets confused
> 
> your patch is only correct for case A but you provide no
> argument why this unlikely case would be the reason for
> the problem 

See below for what's with any luck a convincing argument.

> or why the one value trusted after the patch is better
> than the other before the patch.

I didn't mean for this patch to have anything to do with multiple id3v2
tags.  I've attached two files.  Each has one id3v2 tag.  The only
differences are the four bytes at offset 0x1887.

good_id3v2_with_one_frame.mp3: 00 00 00 00
bad_id3v2_with_one_frame.mp3:  ff fb b2 40

The end of the previous id3v2 tag is offset 0x1885, so starting at 0x1886 we
have these id3v2 tag headers:

good_id3v2_with_one_frame.mp3: 00 00 00 00 00 00 00 00 00 00 (tag header 00
00 00 00, length 00 00 00 00, flags 00 00)
bad_id3v2_with_one_frame.mp3:  00 ff fb b2 40 00 00 00 00 00 (tag header 00
ff fb b2, length 40 00 00 00, flags 00 00)

When processing good_id3v2_with_one_frame.mp3, ff_id3v2_parse (correctly)
inteprets the 00 bytes as padding and tries to skip to the end (line 246 of
id3v2.c):

            url_fskip(s->pb, tlen);

tlen is 0 a this point, so this doesn't do anything.  Here's the output of
gdb with unpatched id3v2.c:

246                 url_fskip(s->pb, tlen);
(gdb) p tlen
$1 = 0
(gdb) n
253         if (len > 0) {
(gdb) n
255             url_fskip(s->pb, len);
(gdb) p len
$2 = 502
(gdb) n
257         if (version == 4 && flags & 0x10) /* Footer preset, always 10
bytes, skip over it */
(gdb) n
260         av_free(buffer);
(gdb) n
267     }
(gdb) p url_ftell(s->pb)
$3 = 6790

When processing bad_id3v2_with_one_frame.mp3, these 4 bytes appears in the
id3v2 frame header and correspond to a frame length of 0x40000000.  So, on
line 222, ff_id3v2_parse (correctly) stops parsing (again with unpatched
id3v2.c):

219             len -= taghdrlen + tlen;
(gdb) p len
$30 = 512
(gdb) n
221             if (len < 0)
(gdb)
253         if (len > 0) {
(gdb) p len
$31 = -1073741322
(gdb) n
257         if (version == 4 && flags & 0x10) /* Footer preset, always 10
bytes, skip over it */
(gdb) n
260         av_free(buffer);
(gdb)
267     }
(gdb) p url_ftell(s->pb)
$32 = 6288

Trouble is, the buffer is still pointing in the middle of the id3v2 tag.

-DB
-------------- next part --------------
A non-text attachment was scrubbed...
Name: good_id3v2_with_one_frame.mp3
Type: audio/mpeg
Size: 7417 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20100913/8ec8e2d3/attachment.mp3>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: bad_id3v2_with_one_frame.mp3
Type: audio/mpeg
Size: 7417 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20100913/8ec8e2d3/attachment-0001.mp3>



More information about the ffmpeg-devel mailing list