summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Almer <jamrial@gmail.com>2013-05-31 17:27:53 -0300
committerPaul B Mahol <onemda@gmail.com>2013-05-31 21:10:57 +0000
commit6510686c16633339b7f23236abd2c32a62424ba2 (patch)
tree04f6c3810318263b66016bacf1fc0c7d1f0d0d30
parentf70d0212ce13347395eb5643bab9fba4dd8e2ee3 (diff)
lavf/tta: check header and seek table checksum
Since we don't check for seek table integrity in the decoder anymore, check it in the demuxer instead (Only tta files are guaranteed to have one, and it should be valid there). Check also for header integrity, since the check done in the decoder is ignored because matroska doesn't store the header at all. Signed-off-by: James Almer <jamrial@gmail.com>
-rw-r--r--libavformat/tta.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/libavformat/tta.c b/libavformat/tta.c
index cb04ff44e0..f6b8a88f82 100644
--- a/libavformat/tta.c
+++ b/libavformat/tta.c
@@ -21,8 +21,10 @@
#include "libavcodec/get_bits.h"
#include "avformat.h"
+#include "avio_internal.h"
#include "internal.h"
#include "id3v1.h"
+#include "libavutil/crc.h"
#include "libavutil/dict.h"
typedef struct {
@@ -31,6 +33,12 @@ typedef struct {
int last_frame_size;
} TTAContext;
+static unsigned long tta_check_crc(unsigned long checksum, const uint8_t *buf,
+ unsigned int len)
+{
+ return av_crc(av_crc_get_table(AV_CRC_32_IEEE_LE), checksum, buf, len);
+}
+
static int tta_probe(AVProbeData *p)
{
if (AV_RL32(&p->buf[0]) == MKTAG('T', 'T', 'A', '1') &&
@@ -48,12 +56,13 @@ static int tta_read_header(AVFormatContext *s)
AVStream *st;
int i, channels, bps, samplerate;
uint64_t framepos, start_offset;
- uint32_t datalen;
+ uint32_t datalen, crc;
if (!av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX))
ff_id3v1_read(s);
start_offset = avio_tell(s->pb);
+ ffio_init_checksum(s->pb, tta_check_crc, UINT32_MAX);
if (avio_rl32(s->pb) != AV_RL32("TTA1"))
return -1; // not tta file
@@ -72,7 +81,11 @@ static int tta_read_header(AVFormatContext *s)
return AVERROR_INVALIDDATA;
}
- avio_skip(s->pb, 4); // header crc
+ crc = ffio_get_checksum(s->pb) ^ UINT32_MAX;
+ if (crc != avio_rl32(s->pb)) {
+ av_log(s, AV_LOG_ERROR, "Header CRC error\n");
+ return AVERROR_INVALIDDATA;
+ }
c->frame_size = samplerate * 256 / 245;
c->last_frame_size = datalen % c->frame_size;
@@ -106,13 +119,18 @@ static int tta_read_header(AVFormatContext *s)
avio_seek(s->pb, start_offset, SEEK_SET);
avio_read(s->pb, st->codec->extradata, st->codec->extradata_size);
+ ffio_init_checksum(s->pb, tta_check_crc, UINT32_MAX);
for (i = 0; i < c->totalframes; i++) {
uint32_t size = avio_rl32(s->pb);
av_add_index_entry(st, framepos, i * c->frame_size, size, 0,
AVINDEX_KEYFRAME);
framepos += size;
}
- avio_skip(s->pb, 4); // seektable crc
+ crc = ffio_get_checksum(s->pb) ^ UINT32_MAX;
+ if (crc != avio_rl32(s->pb)) {
+ av_log(s, AV_LOG_ERROR, "Seek table CRC error\n");
+ return AVERROR_INVALIDDATA;
+ }
st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
st->codec->codec_id = AV_CODEC_ID_TTA;