[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