diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2014-01-16 21:47:09 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2014-01-16 21:50:17 +0100 |
commit | bd953f94044eec49142d3d61993682f8b2186613 (patch) | |
tree | 0897070724eff4c17732c2cac1ab80a4cc9312b1 | |
parent | 9e96051d5d03c13692090bff5c804fa5aaa11375 (diff) | |
parent | 486c45767587151b517bb6fde602d43d178da203 (diff) | |
download | ffmpeg-bd953f94044eec49142d3d61993682f8b2186613.tar.gz |
Merge commit '486c45767587151b517bb6fde602d43d178da203' into release/0.10
* commit '486c45767587151b517bb6fde602d43d178da203':
mpc8: Check the seek table size parsed from the bitstream
zmbvdec: Check the buffer size for uncompressed data
ape: Don't allow the seektable to be omitted
shorten: Break out of loop looking for fmt chunk if none is found
shorten: Use a checked bytestream reader for the wave header
smacker: Make sure we don't fill in huffman codes out of range
Conflicts:
libavcodec/shorten.c
libavcodec/smacker.c
libavcodec/zmbv.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavcodec/shorten.c | 34 | ||||
-rw-r--r-- | libavcodec/smacker.c | 9 | ||||
-rw-r--r-- | libavcodec/zmbv.c | 11 | ||||
-rw-r--r-- | libavformat/ape.c | 2 | ||||
-rw-r--r-- | libavformat/mpc8.c | 4 |
5 files changed, 36 insertions, 24 deletions
diff --git a/libavcodec/shorten.c b/libavcodec/shorten.c index e9aa93a2d3..fa815e9f15 100644 --- a/libavcodec/shorten.c +++ b/libavcodec/shorten.c @@ -205,34 +205,38 @@ static int decode_wave_header(AVCodecContext *avctx, const uint8_t *header, { int len; short wave_format; - const uint8_t *end= header + header_size; + GetByteContext gb; - if (bytestream_get_le32(&header) != MKTAG('R', 'I', 'F', 'F')) { + bytestream2_init(&gb, header, header_size); + + if (bytestream2_get_le32(&gb) != MKTAG('R', 'I', 'F', 'F')) { av_log(avctx, AV_LOG_ERROR, "missing RIFF tag\n"); return AVERROR_INVALIDDATA; } - header += 4; /* chunk size */ + bytestream2_skip(&gb, 4); /* chunk size */ - if (bytestream_get_le32(&header) != MKTAG('W', 'A', 'V', 'E')) { + if (bytestream2_get_le32(&gb) != MKTAG('W', 'A', 'V', 'E')) { av_log(avctx, AV_LOG_ERROR, "missing WAVE tag\n"); return AVERROR_INVALIDDATA; } - while (bytestream_get_le32(&header) != MKTAG('f', 'm', 't', ' ')) { - len = bytestream_get_le32(&header); - if (len < 0 || end - header - 8 < len) + while (bytestream2_get_le32(&gb) != MKTAG('f', 'm', 't', ' ')) { + len = bytestream2_get_le32(&gb); + bytestream2_skip(&gb, len); + if (bytestream2_get_bytes_left(&gb) < 16) { + av_log(avctx, AV_LOG_ERROR, "no fmt chunk found\n"); return AVERROR_INVALIDDATA; - header += len; + } } - len = bytestream_get_le32(&header); + len = bytestream2_get_le32(&gb); if (len < 16) { av_log(avctx, AV_LOG_ERROR, "fmt chunk was too short\n"); return AVERROR_INVALIDDATA; } - wave_format = bytestream_get_le16(&header); + wave_format = bytestream2_get_le16(&gb); switch (wave_format) { case WAVE_FORMAT_PCM: @@ -242,11 +246,11 @@ static int decode_wave_header(AVCodecContext *avctx, const uint8_t *header, return AVERROR(ENOSYS); } - header += 2; // skip channels (already got from shorten header) - avctx->sample_rate = bytestream_get_le32(&header); - header += 4; // skip bit rate (represents original uncompressed bit rate) - header += 2; // skip block align (not needed) - avctx->bits_per_coded_sample = bytestream_get_le16(&header); + bytestream2_skip(&gb, 2); // skip channels (already got from shorten header) + avctx->sample_rate = bytestream2_get_le32(&gb); + bytestream2_skip(&gb, 4); // skip bit rate (represents original uncompressed bit rate) + bytestream2_skip(&gb, 2); // skip block align (not needed) + avctx->bits_per_coded_sample = bytestream2_get_le16(&gb); if (avctx->bits_per_coded_sample != 16) { av_log(avctx, AV_LOG_ERROR, "unsupported number of bits per sample\n"); diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c index 418538378e..3b048e429b 100644 --- a/libavcodec/smacker.c +++ b/libavcodec/smacker.c @@ -263,10 +263,11 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int if(ctx.last[0] == -1) ctx.last[0] = huff.current++; if(ctx.last[1] == -1) ctx.last[1] = huff.current++; if(ctx.last[2] == -1) ctx.last[2] = huff.current++; - if(huff.current > huff.length){ - ctx.last[0] = ctx.last[1] = ctx.last[2] = 1; - av_log(smk->avctx, AV_LOG_ERROR, "bigtree damaged\n"); - return -1; + if (ctx.last[0] >= huff.length || + ctx.last[1] >= huff.length || + ctx.last[2] >= huff.length) { + av_log(smk->avctx, AV_LOG_ERROR, "Huffman codes out of range\n"); + err = AVERROR_INVALIDDATA; } *recodes = huff.values; diff --git a/libavcodec/zmbv.c b/libavcodec/zmbv.c index a68e42d789..38ab7253f1 100644 --- a/libavcodec/zmbv.c +++ b/libavcodec/zmbv.c @@ -500,10 +500,13 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac return -1; } - if (c->comp == 0) { //Uncompressed data - memcpy(c->decomp_buf, buf, len); - c->decomp_size = 1; - } else { // ZLIB-compressed data + if (c->comp == 0) { //Uncompressed data + if (c->decomp_size < len) { + av_log(avctx, AV_LOG_ERROR, "Buffer too small\n"); + return AVERROR_INVALIDDATA; + } + memcpy(c->decomp_buf, buf, len); + } else { // ZLIB-compressed data c->zstream.total_in = c->zstream.total_out = 0; c->zstream.next_in = buf; c->zstream.avail_in = len; diff --git a/libavformat/ape.c b/libavformat/ape.c index d712331fb1..d345382202 100644 --- a/libavformat/ape.c +++ b/libavformat/ape.c @@ -255,7 +255,7 @@ static int ape_read_header(AVFormatContext * s, AVFormatParameters * ap) ape->totalframes); return -1; } - if (ape->seektablelength && (ape->seektablelength / sizeof(*ape->seektable)) < ape->totalframes) { + if (ape->seektablelength / sizeof(*ape->seektable) < ape->totalframes) { av_log(s, AV_LOG_ERROR, "Number of seek entries is less than number of frames: %zu vs. %"PRIu32"\n", ape->seektablelength / sizeof(*ape->seektable), ape->totalframes); diff --git a/libavformat/mpc8.c b/libavformat/mpc8.c index 01c1cc725b..4117d03e5a 100644 --- a/libavformat/mpc8.c +++ b/libavformat/mpc8.c @@ -143,6 +143,10 @@ static void mpc8_parse_seektable(AVFormatContext *s, int64_t off) av_log(s, AV_LOG_ERROR, "No seek table at given position\n"); return; } + if (size < 0 || size >= INT_MAX / 2) { + av_log(s, AV_LOG_ERROR, "Bad seek table size\n"); + return; + } if(!(buf = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE))) return; avio_read(s->pb, buf, size); |