summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2012-11-21 08:48:47 +0100
committerAnton Khirnov <anton@khirnov.net>2012-11-22 13:40:04 +0100
commit9ae80e6a9cefcab61e867256ba19ef78a4bfe0cb (patch)
treec399f75121f89c438569ab497b74bc3f1307af35
parent0d3123666a42ed6c74d0a052342175261304b8ca (diff)
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@libav.org
-rw-r--r--libavformat/id3v2.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c
index 012d7933a8..4516ac74ef 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