diff options
Diffstat (limited to 'libavformat/takdec.c')
-rw-r--r-- | libavformat/takdec.c | 50 |
1 files changed, 38 insertions, 12 deletions
diff --git a/libavformat/takdec.c b/libavformat/takdec.c index 584cbcc..3eb1a8e 100644 --- a/libavformat/takdec.c +++ b/libavformat/takdec.c @@ -2,25 +2,27 @@ * Raw TAK demuxer * Copyright (c) 2012 Paul B Mahol * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/crc.h" #include "libavcodec/tak.h" #include "avformat.h" +#include "avio_internal.h" #include "internal.h" #include "rawdec.h" #include "apetag.h" @@ -37,6 +39,12 @@ static int tak_probe(AVProbeData *p) return 0; } +static unsigned long tak_check_crc(unsigned long checksum, const uint8_t *buf, + unsigned int len) +{ + return av_crc(av_crc_get_table(AV_CRC_24_IEEE), checksum, buf, len); +} + static int tak_read_header(AVFormatContext *s) { TAKDemuxContext *tc = s->priv_data; @@ -52,7 +60,7 @@ static int tak_read_header(AVFormatContext *s) st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = AV_CODEC_ID_TAK; - st->need_parsing = AVSTREAM_PARSE_FULL; + st->need_parsing = AVSTREAM_PARSE_FULL_RAW; tc->mlast_frame = 0; if (avio_rl32(pb) != MKTAG('t', 'B', 'a', 'K')) { @@ -60,7 +68,7 @@ static int tak_read_header(AVFormatContext *s) return 0; } - while (!pb->eof_reached) { + while (!avio_feof(pb)) { enum TAKMetaDataType type; int size; @@ -71,16 +79,28 @@ static int tak_read_header(AVFormatContext *s) case TAK_METADATA_STREAMINFO: case TAK_METADATA_LAST_FRAME: case TAK_METADATA_ENCODER: - buffer = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); + if (size <= 3) + return AVERROR_INVALIDDATA; + + buffer = av_malloc(size - 3 + FF_INPUT_BUFFER_PADDING_SIZE); if (!buffer) return AVERROR(ENOMEM); + memset(buffer + size - 3, 0, FF_INPUT_BUFFER_PADDING_SIZE); - if (avio_read(pb, buffer, size) != size) { + ffio_init_checksum(pb, tak_check_crc, 0xCE04B7U); + if (avio_read(pb, buffer, size - 3) != size - 3) { av_freep(&buffer); return AVERROR(EIO); } + if (ffio_get_checksum(s->pb) != avio_rb24(pb)) { + av_log(s, AV_LOG_ERROR, "%d metadata block CRC error.\n", type); + if (s->error_recognition & AV_EF_EXPLODE) { + av_freep(&buffer); + return AVERROR_INVALIDDATA; + } + } - init_get_bits(&gb, buffer, size * 8); + init_get_bits8(&gb, buffer, size - 3); break; case TAK_METADATA_MD5: { uint8_t md5[16]; @@ -88,8 +108,14 @@ static int tak_read_header(AVFormatContext *s) if (size != 19) return AVERROR_INVALIDDATA; + ffio_init_checksum(pb, tak_check_crc, 0xCE04B7U); avio_read(pb, md5, 16); - avio_skip(pb, 3); + if (ffio_get_checksum(s->pb) != avio_rb24(pb)) { + av_log(s, AV_LOG_ERROR, "MD5 metadata block CRC error.\n"); + if (s->error_recognition & AV_EF_EXPLODE) + return AVERROR_INVALIDDATA; + } + av_log(s, AV_LOG_VERBOSE, "MD5="); for (i = 0; i < 16; i++) av_log(s, AV_LOG_VERBOSE, "%02x", md5[i]); @@ -127,7 +153,7 @@ static int tak_read_header(AVFormatContext *s) st->start_time = 0; avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); st->codec->extradata = buffer; - st->codec->extradata_size = size; + st->codec->extradata_size = size - 3; buffer = NULL; } else if (type == TAK_METADATA_LAST_FRAME) { if (size != 11) @@ -155,7 +181,7 @@ static int raw_read_packet(AVFormatContext *s, AVPacket *pkt) AVIOContext *pb = s->pb; int64_t size, left; - left = tc->data_end - avio_tell(s->pb); + left = tc->data_end - avio_tell(pb); size = FFMIN(left, 1024); if (size <= 0) return AVERROR_EOF; |