Do not use internals of ByteIOContext during APE tags parsing.
authorMatti Hamalainen <(mhamalai@students.oamk.fi>
Tue, 11 Aug 2009 16:55:49 +0000 (16:55 +0000)
committerKostya Shishkov <kostya.shishkov@gmail.com>
Tue, 11 Aug 2009 16:55:49 +0000 (16:55 +0000)
Patch by Matti Hamalainen, mail = reverse("if.kmao.stneduts@ialamahm")
Thread: [PATCH] 2/6 Fix broken APE tag key handling

Originally committed as revision 19628 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavformat/ape.c

index e1a8954..02fd4fa 100644 (file)
@@ -91,22 +91,27 @@ typedef struct {
     uint32_t *seektable;
 } APEContext;
 
     uint32_t *seektable;
 } APEContext;
 
-static void ape_tag_read_field(AVFormatContext *s)
+static int ape_tag_read_field(AVFormatContext *s)
 {
     ByteIOContext *pb = s->pb;
     uint8_t key[1024], value[1024];
 {
     ByteIOContext *pb = s->pb;
     uint8_t key[1024], value[1024];
-    uint32_t size;
-    int i, l;
+    uint32_t size, flags;
+    int i, l, c;
 
     size = get_le32(pb);  /* field size */
 
     size = get_le32(pb);  /* field size */
-    url_fskip(pb, 4);     /* skip field flags */
-
-    for (i=0; pb->buf_ptr[i]!='0' && pb->buf_ptr[i]>=0x20 && pb->buf_ptr[i]<=0x7E; i++);
-
-    l = FFMIN(i,    sizeof(key) -1);
-    get_buffer(pb, key,  l);
-    key[l]  = 0;
-    url_fskip(pb, 1 + i-l);
+    flags = get_le32(pb); /* field flags */
+    for (i = 0; i < sizeof(key) - 1; i++) {
+        c = get_byte(pb);
+        if (c < 0x20 || c > 0x7E)
+            break;
+        else
+            key[i] = c;
+    }
+    key[i] = 0;
+    if (c != 0) {
+        av_log(s, AV_LOG_WARNING, "Invalid APE tag key '%s'.\n", key);
+        return -1;
+    }
     l = FFMIN(size, sizeof(value)-1);
     get_buffer(pb, value, l);
     value[l] = 0;
     l = FFMIN(size, sizeof(value)-1);
     get_buffer(pb, value, l);
     value[l] = 0;
@@ -114,6 +119,7 @@ static void ape_tag_read_field(AVFormatContext *s)
     if (l < size)
         av_log(s, AV_LOG_WARNING, "Too long '%s' tag was truncated.\n", key);
     av_metadata_set(&s->metadata, key, value);
     if (l < size)
         av_log(s, AV_LOG_WARNING, "Too long '%s' tag was truncated.\n", key);
     av_metadata_set(&s->metadata, key, value);
+    return 0;
 }
 
 static void ape_parse_tag(AVFormatContext *s)
 }
 
 static void ape_parse_tag(AVFormatContext *s)
@@ -161,7 +167,7 @@ static void ape_parse_tag(AVFormatContext *s)
     url_fseek(pb, file_size - tag_bytes, SEEK_SET);
 
     for (i=0; i<fields; i++)
     url_fseek(pb, file_size - tag_bytes, SEEK_SET);
 
     for (i=0; i<fields; i++)
-        ape_tag_read_field(s);
+        if (ape_tag_read_field(s) < 0) break;
 
 #if ENABLE_DEBUG
     av_log(s, AV_LOG_DEBUG, "\nAPE Tags:\n\n");
 
 #if ENABLE_DEBUG
     av_log(s, AV_LOG_DEBUG, "\nAPE Tags:\n\n");