[PATCH] skip id3v2 tag if a frame id isn't capital =

David Byron none dbyron
Thu Sep 23 09:29:47 CEST 2010


letters/numbers=0A=
=0A=
---=0A=
 Changelog           |    1 +=0A=
 libavformat/id3v2.c |   35 ++++++++++++++++++++++++++++++-----=0A=
 2 files changed, 31 insertions(+), 5 deletions(-)=0A=
=0A=
diff --git a/Changelog b/Changelog=0A=
index 263fb74..ea03ea5 100644=0A=
--- a/Changelog=0A=
+++ b/Changelog=0A=
@@ -4,6 +4,7 @@ releases are sorted from youngest to oldest.=0A=
 =0A=
 version <next>:=0A=
 =0A=
+- skip rest of id3v2 tag if invalid frame id found (not capital =
letters/numbers)=0A=
 - read all id3v2 tags at the beginning of mp3 files=0A=
 - WebM support in Matroska de/muxer=0A=
 - low overhead Ogg muxing=0A=
diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c=0A=
index 877e37d..f324368 100644=0A=
--- a/libavformat/id3v2.c=0A=
+++ b/libavformat/id3v2.c=0A=
@@ -163,6 +163,7 @@ static void read_ttag(AVFormatContext *s, =
ByteIOContext *pb, int taglen, const c=0A=
 =0A=
 void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, =
uint8_t flags)=0A=
 {=0A=
+    int i, j;=0A=
     int isv34, tlen, unsync;=0A=
     char tag[5];=0A=
     int64_t next;=0A=
@@ -171,6 +172,12 @@ void ff_id3v2_parse(AVFormatContext *s, int len, =
uint8_t version, uint8_t flags)=0A=
     ByteIOContext pb;=0A=
     unsigned char *buffer =3D NULL;=0A=
     int buffer_size =3D 0;=0A=
+    int num_frame_id_chars;=0A=
+    int64_t end_of_tag;=0A=
+=0A=
+    /* Figure out where the end of the tag is and make sure=0A=
+       we get there even if we find something bogus */=0A=
+    end_of_tag =3D len + url_ftell(s->pb);=0A=
 =0A=
     switch (version) {=0A=
     case 2:=0A=
@@ -178,12 +185,14 @@ void ff_id3v2_parse(AVFormatContext *s, int len, =
uint8_t version, uint8_t flags)=0A=
             reason =3D "compression";=0A=
             goto error;=0A=
         }=0A=
+        num_frame_id_chars =3D 3;=0A=
         isv34 =3D 0;=0A=
         taghdrlen =3D 6;=0A=
         break;=0A=
 =0A=
     case 3:=0A=
     case 4:=0A=
+        num_frame_id_chars =3D 4;=0A=
         isv34 =3D 1;=0A=
         taghdrlen =3D 10;=0A=
         break;=0A=
@@ -202,9 +211,9 @@ void ff_id3v2_parse(AVFormatContext *s, int len, =
uint8_t version, uint8_t flags)=0A=
         unsigned int tflags;=0A=
         int tunsync =3D 0;=0A=
 =0A=
+        get_buffer(s->pb, tag, num_frame_id_chars);=0A=
+        tag[num_frame_id_chars] =3D 0;=0A=
         if (isv34) {=0A=
-            get_buffer(s->pb, tag, 4);=0A=
-            tag[4] =3D 0;=0A=
             if(version=3D=3D3){=0A=
                 tlen =3D get_be32(s->pb);=0A=
             }else=0A=
@@ -212,10 +221,26 @@ void ff_id3v2_parse(AVFormatContext *s, int len, =
uint8_t version, uint8_t flags)=0A=
             tflags =3D get_be16(s->pb);=0A=
             tunsync =3D tflags & 0x02;=0A=
         } else {=0A=
-            get_buffer(s->pb, tag, 3);=0A=
-            tag[3] =3D 0;=0A=
             tlen =3D get_be24(s->pb);=0A=
         }=0A=
+        /* Validate that the tag is made out of the capital=0A=
+           letters A-Z or 0-9 as indicated by=0A=
+           http://www.id3.org/id3v2.3.0#line-99.  id3v2.2=0A=
+           requires the same thing in section 3.2 of=0A=
+           http://www.id3.org/id3v2-00.  section 4 of=0A=
+           http://www.id3.org/id3v2.4.0-structure for=0A=
+           id3v2.4 */=0A=
+        i =3D 0;=0A=
+        while (i < num_frame_id_chars) {=0A=
+            if (tag[i] && ((tag[i] < 'A') || (tag[i] > 'Z')) &&=0A=
+                ((tag[i] < '0') || (tag[i] > '9'))) {=0A=
+                av_log(s, AV_LOG_WARNING, "invalid frame id (not =
capital letters/numbers)\n");=0A=
+                /* Don't trust tlen if the frame id is bogus */=0A=
+                break;=0A=
+            }=0A=
+            i++;=0A=
+        }=0A=
+=0A=
         len -=3D taghdrlen + tlen;=0A=
 =0A=
         if (len < 0)=0A=
@@ -225,7 +250,6 @@ void ff_id3v2_parse(AVFormatContext *s, int len, =
uint8_t version, uint8_t flags)=0A=
 =0A=
         if (tag[0] =3D=3D 'T') {=0A=
             if (unsync || tunsync) {=0A=
-                int i, j;=0A=
                 av_fast_malloc(&buffer, &buffer_size, tlen);=0A=
                 for (i =3D 0, j =3D 0; i < tlen; i++, j++) {=0A=
                     buffer[j] =3D get_byte(s->pb);=0A=
@@ -257,6 +281,7 @@ void ff_id3v2_parse(AVFormatContext *s, int len, =
uint8_t version, uint8_t flags)=0A=
     if (version =3D=3D 4 && flags & 0x10) /* Footer preset, always 10 =
bytes, skip over it */=0A=
         url_fskip(s->pb, 10);=0A=
 =0A=
+    url_fseek(s->pb, end_of_tag, SEEK_SET);=0A=
     av_free(buffer);=0A=
     return;=0A=
 =0A=
-- =0A=
1.6.0.4=0A=
=0A=

------=_NextPart_000_09EB_01CB5B03.B796E460--




More information about the ffmpeg-devel mailing list