[FFmpeg-cvslog] id3v2: fix reading unsynchronized frames.

Anton Khirnov git at videolan.org
Thu Nov 22 15:46:51 CET 2012


ffmpeg | branch: master | Anton Khirnov <anton at khirnov.net> | Wed Nov 21 08:48:47 2012 +0100| [9ae80e6a9cefcab61e867256ba19ef78a4bfe0cb] | committer: Anton Khirnov

id3v2: fix reading unsynchronized frames.

Current code would incorrectly process e.g. 'ff 00 ff 00 ff' to
'ff ff ff', while it should be 'ff ff 00 ff'.

Fixes Bug 395.

CC: libav-stable at libav.org

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

 libavformat/id3v2.c |   18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c
index 012d793..4516ac7 100644
--- a/libavformat/id3v2.c
+++ b/libavformat/id3v2.c
@@ -617,21 +617,23 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t
         /* check for text tag or supported special meta tag */
         } else if (tag[0] == 'T' || (extra_meta && (extra_func = get_extra_meta_func(tag, isv34)))) {
             if (unsync || tunsync) {
-                int i, j;
+                int64_t end = avio_tell(s->pb) + tlen;
+                uint8_t *b;
                 av_fast_malloc(&buffer, &buffer_size, tlen);
                 if (!buffer) {
                     av_log(s, AV_LOG_ERROR, "Failed to alloc %d bytes\n", tlen);
                     goto seek;
                 }
-                for (i = 0, j = 0; i < tlen; i++, j++) {
-                    buffer[j] = avio_r8(s->pb);
-                    if (j > 0 && !buffer[j] && buffer[j - 1] == 0xff) {
-                        /* Unsynchronised byte, skip it */
-                        j--;
+                b = buffer;
+                while (avio_tell(s->pb) < end) {
+                    *b++ = avio_r8(s->pb);
+                    if (*(b - 1) == 0xff && avio_tell(s->pb) < end - 1) {
+                        uint8_t val = avio_r8(s->pb);
+                        *b++ = val ? val : avio_r8(s->pb);
                     }
                 }
-                ffio_init_context(&pb, buffer, j, 0, NULL, NULL, NULL, NULL);
-                tlen = j;
+                ffio_init_context(&pb, buffer, b - buffer, 0, NULL, NULL, NULL, NULL);
+                tlen = b - buffer;
                 pbx = &pb; // read from sync buffer
             } else {
                 pbx = s->pb; // read straight from input



More information about the ffmpeg-cvslog mailing list