[FFmpeg-devel] [PATCH] MP3: ID3V2 corrupted => bad offset
Michael Niedermayer
michaelni
Fri Dec 5 14:19:13 CET 2008
On Fri, Dec 05, 2008 at 01:41:32PM +0100, Yvan Labadie wrote:
> Hi,
>
> According to the ID3v2 standard, frame sizes are stored using 32bit
> SynchSafe Integer format
> (http://www.id3.org/id3v2.4.0-structure?highlight=%28SynchSafe%29).
> That's why libavformat/mp3.c uses id3v2_get_size() function.
> But I discovered that a lot of mp3 (about a fourth of my mp3s!) use classic
> 32bit unsigned integer!!!
> So with these mp3s ID3v2 parse fails and then AVFormatContext->data_offset
> is invalid!
>
> and having a bad data_offset can be very critical for some applications
> (like mine 0:-) ).
>
> For my patch, I use the ID3v2 size extracted from its header to deduce the
> offset.
> Then after parsing ID3 I seek to this offset and I made another check by
> verifying that it corresponds to a mp3 frame sync, and if it doesn't I look
> for the first frame sync and made it the offset.
>
> if id3 tag is corrupted, result is :
> data_offset is good (so mp3_parse_vbr_tags success)
> tag parse still fail but if file doesn't respect standards, we cannot do a
> lot...
>
>
> diff -urN ./libavformat/mp3.c ../ffmpeg-export-2008-12-05_patched/libavformat/mp3.c
> --- ./libavformat/mp3.c 2008-10-03 12:16:29.000000000 +0200
> +++ ../ffmpeg-export-2008-12-05_patched/libavformat/mp3.c 2008-12-05 13:03:05.000000000 +0100
> @@ -453,6 +453,7 @@
> uint8_t buf[ID3v1_TAG_SIZE];
> int len, ret, filesize;
> int64_t off;
> + uint16_t sync=0;
>
> st = av_new_stream(s, 0);
> if (!st)
> @@ -488,14 +489,19 @@
> ((buf[8] & 0x7f) << 7) |
> (buf[9] & 0x7f);
> id3v2_parse(s, len, buf[3], buf[5]);
> + url_fseek(s->pb, len + ID3v2_HEADER_SIZE, SEEK_SET); //go at the end of the ID3v2 tag (avoid error on some corrupted tag)
this change is incorrect, its id3v2_parse() job to end at that point
> } else {
> url_fseek(s->pb, 0, SEEK_SET);
> }
> -
> - off = url_ftell(s->pb);
> - mp3_parse_vbr_tags(s, st, off);
> - url_fseek(s->pb, off, SEEK_SET);
> -
> +
trailing whitespace is forbidden in ffmpeg svn
> + do{ //we have to be sure we're at the begining of a frame otherwise offset will be incorrect and parse_vbr_tags will fail
> + sync = sync << 8;
> + sync |= (0x00ff & get_byte(s->pb));
> + }while((sync&0xffe0) != 0xFFe0);//look for frame sync
> + off = url_ftell(s->pb)-2; //so this is the correct offset
this is fragile
what you should do is, if mp3_parse_vbr_tags() fails try the non sync safe
interpretation of the len _if and only if_ this is reliable in practice
otherwise there are existing functions that check the validity of mp3 frame
headers.
Either way, we need a sample mp3 that fails and this patch is postponed
until previously approved patches to mp3.c have been applied by someone
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
Republics decline into democracies and democracies degenerate into
despotisms. -- Aristotle
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20081205/cfbd34c0/attachment.pgp>
More information about the ffmpeg-devel
mailing list