[FFmpeg-cvslog] wv,mpc8: don't return apetag data in packets.

Anton Khirnov git at videolan.org
Tue Jul 31 23:05:10 CEST 2012


ffmpeg | branch: master | Anton Khirnov <anton at khirnov.net> | Mon Jul 30 07:28:35 2012 +0200| [782e64fbe1daa84c38594db037d0edfac7193c37] | committer: Anton Khirnov

wv,mpc8: don't return apetag data in packets.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=782e64fbe1daa84c38594db037d0edfac7193c37
---

 libavformat/apetag.c |   21 +++++++++++++++------
 libavformat/apetag.h |    4 +++-
 libavformat/mpc8.c   |    9 ++++++++-
 libavformat/wv.c     |    9 ++++++++-
 4 files changed, 34 insertions(+), 9 deletions(-)

diff --git a/libavformat/apetag.c b/libavformat/apetag.c
index 062f746..dd74631 100644
--- a/libavformat/apetag.c
+++ b/libavformat/apetag.c
@@ -113,40 +113,47 @@ static int ape_tag_read_field(AVFormatContext *s)
     return 0;
 }
 
-void ff_ape_parse_tag(AVFormatContext *s)
+int64_t ff_ape_parse_tag(AVFormatContext *s)
 {
     AVIOContext *pb = s->pb;
     int file_size = avio_size(pb);
     uint32_t val, fields, tag_bytes;
     uint8_t buf[8];
+    int64_t tag_start;
     int i;
 
     if (file_size < APE_TAG_FOOTER_BYTES)
-        return;
+        return 0;
 
     avio_seek(pb, file_size - APE_TAG_FOOTER_BYTES, SEEK_SET);
 
     avio_read(pb, buf, 8);     /* APETAGEX */
     if (strncmp(buf, "APETAGEX", 8)) {
-        return;
+        return 0;
     }
 
     val = avio_rl32(pb);       /* APE tag version */
     if (val > APE_TAG_VERSION) {
         av_log(s, AV_LOG_ERROR, "Unsupported tag version. (>=%d)\n", APE_TAG_VERSION);
-        return;
+        return 0;
     }
 
     tag_bytes = avio_rl32(pb); /* tag size */
     if (tag_bytes - APE_TAG_FOOTER_BYTES > (1024 * 1024 * 16)) {
         av_log(s, AV_LOG_ERROR, "Tag size is way too big\n");
-        return;
+        return 0;
+    }
+
+    tag_start = file_size - tag_bytes - APE_TAG_FOOTER_BYTES;
+    if (tag_start < 0) {
+        av_log(s, AV_LOG_ERROR, "Invalid tag size %u.\n", tag_bytes);
+        return 0;
     }
 
     fields = avio_rl32(pb);    /* number of fields */
     if (fields > 65536) {
         av_log(s, AV_LOG_ERROR, "Too many tag fields (%d)\n", fields);
-        return;
+        return 0;
     }
 
     val = avio_rl32(pb);       /* flags */
@@ -159,4 +166,6 @@ void ff_ape_parse_tag(AVFormatContext *s)
 
     for (i=0; i<fields; i++)
         if (ape_tag_read_field(s) < 0) break;
+
+    return tag_start;
 }
diff --git a/libavformat/apetag.h b/libavformat/apetag.h
index a0e6ead..279972f 100644
--- a/libavformat/apetag.h
+++ b/libavformat/apetag.h
@@ -27,7 +27,9 @@
 
 /**
  * Read and parse an APE tag
+ *
+ * @return offset of the tag start in the file
  */
-void ff_ape_parse_tag(AVFormatContext *s);
+int64_t ff_ape_parse_tag(AVFormatContext *s);
 
 #endif /* AVFORMAT_APETAG_H */
diff --git a/libavformat/mpc8.c b/libavformat/mpc8.c
index 93848f4..6b9f77e 100644
--- a/libavformat/mpc8.c
+++ b/libavformat/mpc8.c
@@ -52,6 +52,8 @@ typedef struct {
     int frame;
     int64_t header_pos;
     int64_t samples;
+
+    int64_t apetag_start;
 } MPCContext;
 
 static inline int64_t bs_get_v(uint8_t **bs)
@@ -243,7 +245,7 @@ static int mpc8_read_header(AVFormatContext *s)
 
     if (pb->seekable) {
         int64_t pos = avio_tell(s->pb);
-        ff_ape_parse_tag(s);
+        c->apetag_start = ff_ape_parse_tag(s);
         avio_seek(s->pb, pos, SEEK_SET);
     }
 
@@ -258,6 +260,11 @@ static int mpc8_read_packet(AVFormatContext *s, AVPacket *pkt)
 
     while(!s->pb->eof_reached){
         pos = avio_tell(s->pb);
+
+        /* don't return bogus packets with the ape tag data */
+        if (c->apetag_start && pos >= c->apetag_start)
+            return AVERROR_EOF;
+
         mpc8_get_chunk_header(s->pb, &tag, &size);
         if (size < 0)
             return -1;
diff --git a/libavformat/wv.c b/libavformat/wv.c
index 3fd1abc..39bb614 100644
--- a/libavformat/wv.c
+++ b/libavformat/wv.c
@@ -64,6 +64,8 @@ typedef struct {
     int block_parsed;
     uint8_t extra[WV_EXTRA_SIZE];
     int64_t pos;
+
+    int64_t apetag_start;
 } WVContext;
 
 static int wv_probe(AVProbeData *p)
@@ -88,6 +90,11 @@ static int wv_read_block_header(AVFormatContext *ctx, AVIOContext *pb,
     uint32_t chmask;
 
     wc->pos = avio_tell(pb);
+
+    /* don't return bogus packets with the ape tag data */
+    if (wc->apetag_start && wc->pos >= wc->apetag_start)
+        return AVERROR_EOF;
+
     if (!append) {
         tag = avio_rl32(pb);
         if (tag != MKTAG('w', 'v', 'p', 'k'))
@@ -252,7 +259,7 @@ static int wv_read_header(AVFormatContext *s)
 
     if (s->pb->seekable) {
         int64_t cur = avio_tell(s->pb);
-        ff_ape_parse_tag(s);
+        wc->apetag_start = ff_ape_parse_tag(s);
         if (!av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX))
             ff_id3v1_read(s);
         avio_seek(s->pb, cur, SEEK_SET);



More information about the ffmpeg-cvslog mailing list