summaryrefslogtreecommitdiff
path: root/libavformat/id3v2.c
diff options
context:
space:
mode:
authorwm4 <nfxjfg@googlemail.com>2018-01-30 13:22:53 +0100
committerwm4 <nfxjfg@googlemail.com>2018-02-04 15:19:41 +0100
commit48bc9fffd11c05e75b9125d8cd90e9263108bd83 (patch)
tree987e904885227f70d96d69245e58460f280b1132 /libavformat/id3v2.c
parentff46124b0df17a1d35249e09ae8eae9a61f16e04 (diff)
id3v2: fix unsynchronization
The ID3v2 "unsynchronization scheme" requires replacing any 0xFF 0x00 sequences with 0xFF. This has to be done on every byte of the source data, while the current code skipped a byte after a replacement. This meant 0xFF 0x00 0xFF 00 was translated to 0xFF 0xFF 0x00 instead of 0xFF 0xFF. It feels a bit messy to do this correctly with the avio use. But fortunately, this translation can be done in-place, so we can just do it in memory. Inspired by what taglib does. Also see 9ae80e6a9cefcab61e867256ba19ef78a4bfe0cb. (The sample file for that commit is gone, so it could not be retested.)
Diffstat (limited to 'libavformat/id3v2.c')
-rw-r--r--libavformat/id3v2.c26
1 files changed, 14 insertions, 12 deletions
diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c
index b80178d67a..f7de26a1d8 100644
--- a/libavformat/id3v2.c
+++ b/libavformat/id3v2.c
@@ -976,19 +976,21 @@ static void id3v2_parse(AVIOContext *pb, AVDictionary **metadata,
}
}
if (unsync || tunsync) {
- int64_t end = avio_tell(pb) + tlen;
- uint8_t *b;
-
- b = buffer;
- while (avio_tell(pb) < end && b - buffer < tlen && !pb->eof_reached) {
- *b++ = avio_r8(pb);
- if (*(b - 1) == 0xff && avio_tell(pb) < end - 1 &&
- b - buffer < tlen &&
- !pb->eof_reached ) {
- uint8_t val = avio_r8(pb);
- *b++ = val ? val : avio_r8(pb);
- }
+ uint8_t *b = buffer;
+ uint8_t *t = buffer;
+ uint8_t *end = t + tlen;
+
+ if (avio_read(pb, buffer, tlen) != tlen) {
+ av_log(s, AV_LOG_ERROR, "Failed to read tag data\n");
+ goto seek;
}
+
+ while (t != end) {
+ *b++ = *t++;
+ if (t != end && t[-1] == 0xff && !t[0])
+ t++;
+ }
+
ffio_init_context(&pb_local, buffer, b - buffer, 0, NULL, NULL, NULL,
NULL);
tlen = b - buffer;