diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2013-07-29 03:55:03 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2013-07-29 03:56:26 +0200 |
commit | a3539d26eceebe69d890ad39e2ab0dcc19433246 (patch) | |
tree | 7ec11a6b7101dbb1876a6d9c43229a919fec70a9 | |
parent | 7118358a950e20a4439d796f16892b27dad6c754 (diff) | |
parent | 4ff5167ee7fdee6d35c1bb2558172329ae6ec770 (diff) | |
download | ffmpeg-a3539d26eceebe69d890ad39e2ab0dcc19433246.tar.gz |
Merge commit '4ff5167ee7fdee6d35c1bb2558172329ae6ec770' into release/0.10
* commit '4ff5167ee7fdee6d35c1bb2558172329ae6ec770':
wmapro: make sure there is room to store the current packet
lavc: move put_bits_left in put_bits.h
4xm: do not overread the source buffer in decode_p_block
4xm: check bitstream_size boundary before using it
4xm: reject frames not compatible with the declared version
4xm: use the correct logging context
4xm: check the return value of read_huffman_tables().
4xm: don't rely on get_buffer() initializing the frame.
vmdav: convert to bytestream2
smacker: check frame size validity
smacker: pad the extradata allocation
smacker: check the return value of smacker_decode_tree
smacker: fix an off by one in huff.length computation
Prepare for 0.8.8 Release
tiff: do not overread the source buffer
apetag: use int64_t for filesize
wavpack: return meaningful errors
Conflicts:
RELEASE
libavcodec/4xm.c
libavcodec/vmdav.c
libavformat/smacker.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavcodec/4xm.c | 36 | ||||
-rw-r--r-- | libavcodec/dv.c | 5 | ||||
-rw-r--r-- | libavcodec/put_bits.h | 8 | ||||
-rw-r--r-- | libavcodec/smacker.c | 13 | ||||
-rw-r--r-- | libavcodec/tiff.c | 5 | ||||
-rw-r--r-- | libavcodec/vmdav.c | 157 | ||||
-rw-r--r-- | libavcodec/wavpack.c | 39 | ||||
-rw-r--r-- | libavcodec/wmaprodec.c | 8 | ||||
-rw-r--r-- | libavformat/apetag.c | 2 | ||||
-rw-r--r-- | libavformat/smacker.c | 9 |
10 files changed, 152 insertions, 130 deletions
diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c index 96b8c05605..7dc7b13da0 100644 --- a/libavcodec/4xm.c +++ b/libavcodec/4xm.c @@ -25,6 +25,7 @@ */ #include "libavutil/intreadwrite.h" +#include "libavutil/avassert.h" #include "avcodec.h" #include "dsputil.h" #include "get_bits.h" @@ -347,6 +348,10 @@ static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, int lo decode_p_block(f, dst , src , log2w, log2h, stride); decode_p_block(f, dst + (1<<log2w), src + (1<<log2w), log2w, log2h, stride); }else if(code == 3 && f->version<2){ + if (start > src || src > end) { + av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n"); + return; + } mcdc(dst, src, log2w, h, stride, 1, 0); }else if(code == 4){ if (f->g.buffer_end - f->g.buffer < 1){ @@ -368,6 +373,10 @@ static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, int lo av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n"); return; } + if (start > src || src > end) { + av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n"); + return; + } mcdc(dst, src, log2w, h, stride, 0, bytestream2_get_le16(&f->g2)); }else if(code == 6){ if (f->g2.buffer_end - f->g2.buffer < 2){ @@ -665,8 +674,8 @@ static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length){ color[0]= bytestream2_get_le16u(&g3); color[1]= bytestream2_get_le16u(&g3); - if(color[0]&0x8000) av_log(NULL, AV_LOG_ERROR, "unk bit 1\n"); - if(color[1]&0x8000) av_log(NULL, AV_LOG_ERROR, "unk bit 2\n"); + if(color[0]&0x8000) av_log(f->avctx, AV_LOG_ERROR, "unk bit 1\n"); + if(color[1]&0x8000) av_log(f->avctx, AV_LOG_ERROR, "unk bit 2\n"); color[2]= mix(color[0], color[1]); color[3]= mix(color[1], color[0]); @@ -694,7 +703,10 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length){ unsigned int prestream_size; const uint8_t *prestream; - if (bitstream_size > (1<<26) || length < bitstream_size + 12) { + if (bitstream_size > (1 << 26)) + return AVERROR_INVALIDDATA; + + if (length < bitstream_size + 12) { av_log(f->avctx, AV_LOG_ERROR, "packet size too small\n"); return AVERROR_INVALIDDATA; } @@ -702,15 +714,19 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length){ prestream_size = 4 * AV_RL32(buf + bitstream_size + 4); prestream = buf + bitstream_size + 12; - if (prestream_size > (1<<26) || - prestream_size != length - (bitstream_size + 12)){ + if(prestream_size + bitstream_size + 12 != length + || prestream_size > (1<<26)){ av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d %d\n", prestream_size, bitstream_size, length); return -1; } - prestream= read_huffman_tables(f, prestream, buf + length - prestream); - if (!prestream) - return -1; + prestream = read_huffman_tables(f, prestream, prestream_size); + if (!prestream) { + av_log(f->avctx, AV_LOG_ERROR, "Error reading Huffman tables.\n"); + return AVERROR_INVALIDDATA; + } + + av_assert0(prestream <= buf + length); init_get_bits(&f->gb, buf + 4, 8*bitstream_size); @@ -805,6 +821,9 @@ static int decode_frame(AVCodecContext *avctx, av_log(f->avctx, AV_LOG_ERROR, "cframe id mismatch %d %d\n", id, avctx->frame_number); } + if (f->version <= 1) + return AVERROR_INVALIDDATA; + cfrm->size= cfrm->id= 0; frame_4cc= AV_RL32("pfrm"); }else @@ -848,6 +867,7 @@ static int decode_frame(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } + memset(f->last_picture.data[0], 0, avctx->height * FFABS(f->last_picture.linesize[0])); } p->pict_type= AV_PICTURE_TYPE_P; diff --git a/libavcodec/dv.c b/libavcodec/dv.c index bf74001c09..16dad98353 100644 --- a/libavcodec/dv.c +++ b/libavcodec/dv.c @@ -372,11 +372,6 @@ typedef struct BlockInfo { static const int vs_total_ac_bits = (100 * 4 + 68*2) * 5; static const int mb_area_start[5] = { 1, 6, 21, 43, 64 }; -static inline int put_bits_left(PutBitContext* s) -{ - return (s->buf_end - s->buf) * 8 - put_bits_count(s); -} - /* decode AC coefficients */ static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, DCTELEM *block) { diff --git a/libavcodec/put_bits.h b/libavcodec/put_bits.h index 9256e7fa4d..a5bc7314a7 100644 --- a/libavcodec/put_bits.h +++ b/libavcodec/put_bits.h @@ -73,6 +73,14 @@ static inline int put_bits_count(PutBitContext *s) } /** + * @return the number of bits available in the bitstream. + */ +static inline int put_bits_left(PutBitContext* s) +{ + return (s->buf_end - s->buf_ptr) * 8 - 32 + s->bit_left; +} + +/** * Pad the end of the output stream with zeros. */ static inline void flush_put_bits(PutBitContext *s) diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c index 8e8da392fd..418538378e 100644 --- a/libavcodec/smacker.c +++ b/libavcodec/smacker.c @@ -252,7 +252,7 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int ctx.recode2 = tmp2.values; ctx.last = last; - huff.length = ((size + 3) >> 2) + 3; + huff.length = ((size + 3) >> 2) + 4; huff.maxlength = 0; huff.current = 0; huff.values = av_mallocz(huff.length * sizeof(int)); @@ -654,7 +654,16 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, h[i].lengths = av_mallocz(256 * sizeof(int)); h[i].values = av_mallocz(256 * sizeof(int)); skip_bits1(&gb); - smacker_decode_tree(&gb, &h[i], 0, 0); + if (smacker_decode_tree(&gb, &h[i], 0, 0) < 0) { + for (; i >= 0; i--) { + if (vlc[i].table) + ff_free_vlc(&vlc[i]); + av_free(h[i].bits); + av_free(h[i].lengths); + av_free(h[i].values); + } + return AVERROR_INVALIDDATA; + } skip_bits1(&gb); if(h[i].current > 1) { res = init_vlc(&vlc[i], SMKTREE_BITS, h[i].length, diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index c4da35d8e2..19408322ef 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -235,10 +235,13 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, const uin break; case TIFF_PACKBITS: for(pixels = 0; pixels < width;){ + if (ssrc + size - src < 2) + return AVERROR_INVALIDDATA; code = (int8_t)*src++; if(code >= 0){ code++; - if(pixels + code > width){ + if (pixels + code > width || + ssrc + size - src < code) { av_log(s->avctx, AV_LOG_ERROR, "Copy went out of bounds\n"); return -1; } diff --git a/libavcodec/vmdav.c b/libavcodec/vmdav.c index 7006f61f2b..ad46b5c1f1 100644 --- a/libavcodec/vmdav.c +++ b/libavcodec/vmdav.c @@ -48,6 +48,7 @@ #define VMD_HEADER_SIZE 0x330 #define PALETTE_COUNT 256 +#include "bytestream.h" /* * Video Decoder @@ -75,8 +76,6 @@ typedef struct VmdVideoContext { static void lz_unpack(const unsigned char *src, int src_len, unsigned char *dest, int dest_len) { - const unsigned char *s; - const unsigned char *s_end; unsigned char *d; unsigned char *d_end; unsigned char queue[QUEUE_SIZE]; @@ -87,19 +86,17 @@ static void lz_unpack(const unsigned char *src, int src_len, unsigned int speclen; unsigned char tag; unsigned int i, j; + GetByteContext gb; - s = src; - s_end = src + src_len; + bytestream2_init(&gb, src, src_len); d = dest; d_end = d + dest_len; - - if (s_end - s < 8) - return; - dataleft = AV_RL32(s); - s += 4; + dataleft = bytestream2_get_le32(&gb); memset(queue, 0x20, QUEUE_SIZE); - if (AV_RL32(s) == 0x56781234) { - s += 4; + if (bytestream2_get_bytes_left(&gb) < 4) + return; + if (bytestream2_peek_le32(&gb) == 0x56781234) { + bytestream2_get_le32(&gb); qpos = 0x111; speclen = 0xF + 3; } else { @@ -107,13 +104,13 @@ static void lz_unpack(const unsigned char *src, int src_len, speclen = 100; /* no speclen */ } - while (s_end - s > 0 && dataleft > 0) { - tag = *s++; + while (dataleft > 0 && bytestream2_get_bytes_left(&gb) > 0) { + tag = bytestream2_get_byteu(&gb); if ((tag == 0xFF) && (dataleft > 8)) { - if (d_end - d < 8 || s_end - s < 8) + if (d_end - d < 8 || bytestream2_get_bytes_left(&gb) < 8) return; for (i = 0; i < 8; i++) { - queue[qpos++] = *d++ = *s++; + queue[qpos++] = *d++ = bytestream2_get_byteu(&gb); qpos &= QUEUE_MASK; } dataleft -= 8; @@ -122,21 +119,17 @@ static void lz_unpack(const unsigned char *src, int src_len, if (dataleft == 0) break; if (tag & 0x01) { - if (d_end - d < 1 || s_end - s < 1) + if (d_end - d < 1 || bytestream2_get_bytes_left(&gb) < 1) return; - queue[qpos++] = *d++ = *s++; + queue[qpos++] = *d++ = bytestream2_get_byte(&gb); qpos &= QUEUE_MASK; dataleft--; } else { - if (s_end - s < 2) - return; - chainofs = *s++; - chainofs |= ((*s & 0xF0) << 4); - chainlen = (*s++ & 0x0F) + 3; + chainofs = bytestream2_get_byte(&gb); + chainofs |= ((bytestream2_peek_byte(&gb) & 0xF0) << 4); + chainlen = (bytestream2_get_byte(&gb) & 0x0F) + 3; if (chainlen == speclen) { - if (s_end - s < 1) - return; - chainlen = *s++ + 0xF + 3; + chainlen = bytestream2_get_byte(&gb) + 0xF + 3; } if (d_end - d < chainlen) return; @@ -152,51 +145,47 @@ static void lz_unpack(const unsigned char *src, int src_len, } } } - -static int rle_unpack(const unsigned char *src, int src_len, int src_count, - unsigned char *dest, int dest_len) +static int rle_unpack(const unsigned char *src, unsigned char *dest, + int src_count, int src_size, int dest_len) { - const unsigned char *ps; - const unsigned char *ps_end; unsigned char *pd; int i, l; unsigned char *dest_end = dest + dest_len; + GetByteContext gb; - ps = src; - ps_end = src + src_len; + bytestream2_init(&gb, src, src_size); pd = dest; if (src_count & 1) { - if (ps_end - ps < 1) + if (bytestream2_get_bytes_left(&gb) < 1) return 0; - *pd++ = *ps++; + *pd++ = bytestream2_get_byteu(&gb); } src_count >>= 1; i = 0; do { - if (ps_end - ps < 1) + if (bytestream2_get_bytes_left(&gb) < 1) break; - l = *ps++; + l = bytestream2_get_byteu(&gb); if (l & 0x80) { l = (l & 0x7F) * 2; - if (dest_end - pd < l || ps_end - ps < l) - return ps - src; - memcpy(pd, ps, l); - ps += l; + if (dest_end - pd < l || bytestream2_get_bytes_left(&gb) < l) + return bytestream2_tell(&gb); + bytestream2_get_buffer(&gb, pd, l); pd += l; } else { - if (dest_end - pd < i || ps_end - ps < 2) - return ps - src; + if (dest_end - pd < i || bytestream2_get_bytes_left(&gb) < 2) + return bytestream2_tell(&gb); for (i = 0; i < l; i++) { - *pd++ = ps[0]; - *pd++ = ps[1]; + *pd++ = bytestream2_get_byteu(&gb); + *pd++ = bytestream2_get_byteu(&gb); } - ps += 2; + bytestream2_skip(&gb, 2); } i += l; } while (i < src_count); - return ps - src; + return bytestream2_tell(&gb); } static void vmd_decode(VmdVideoContext *s) @@ -205,12 +194,8 @@ static void vmd_decode(VmdVideoContext *s) unsigned int *palette32; unsigned char r, g, b; - /* point to the start of the encoded data */ - const unsigned char *p = s->buf + 16; - const unsigned char *p_end = s->buf + s->size; + GetByteContext gb; - const unsigned char *pb; - const unsigned char *pb_end; unsigned char meth; unsigned char *dp; /* pointer to current frame */ unsigned char *pp; /* pointer to previous frame */ @@ -255,29 +240,31 @@ static void vmd_decode(VmdVideoContext *s) } /* check if there is a new palette */ + bytestream2_init(&gb, s->buf + 16, s->size - 16); if (s->buf[15] & 0x02) { - if (p_end - p < 2 + 3 * PALETTE_COUNT) - return; - p += 2; + bytestream2_skip(&gb, 2); palette32 = (unsigned int *)s->palette; - for (i = 0; i < PALETTE_COUNT; i++) { - r = *p++ * 4; - g = *p++ * 4; - b = *p++ * 4; - palette32[i] = 0xFF << 24 | r << 16 | g << 8 | b; - palette32[i] |= palette32[i] >> 6 & 0x30303; + if (bytestream2_get_bytes_left(&gb) >= PALETTE_COUNT * 3) { + for (i = 0; i < PALETTE_COUNT; i++) { + r = bytestream2_get_byteu(&gb) * 4; + g = bytestream2_get_byteu(&gb) * 4; + b = bytestream2_get_byteu(&gb) * 4; + palette32[i] = 0xFFU << 24 | (r << 16) | (g << 8) | (b); + palette32[i] |= palette32[i] >> 6 & 0x30303; + } } } - if (p < p_end) { + if (s->size > 0) { /* originally UnpackFrame in VAG's code */ - pb = p; - pb_end = p_end; - meth = *pb++; + bytestream2_init(&gb, gb.buffer, s->buf + s->size - gb.buffer); + if (bytestream2_get_bytes_left(&gb) < 1) + return; + meth = bytestream2_get_byteu(&gb); if (meth & 0x80) { - lz_unpack(pb, p_end - pb, s->unpack_buffer, s->unpack_buffer_size); + lz_unpack(gb.buffer, bytestream2_get_bytes_left(&gb), + s->unpack_buffer, s->unpack_buffer_size); meth &= 0x7F; - pb = s->unpack_buffer; - pb_end = s->unpack_buffer + s->unpack_buffer_size; + bytestream2_init(&gb, s->unpack_buffer, s->unpack_buffer_size); } dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x]; @@ -287,15 +274,12 @@ static void vmd_decode(VmdVideoContext *s) for (i = 0; i < frame_height; i++) { ofs = 0; do { - if (pb_end - pb < 1) - return; - len = *pb++; + len = bytestream2_get_byte(&gb); if (len & 0x80) { len = (len & 0x7F) + 1; - if (ofs + len > frame_width || pb_end - pb < len) + if (ofs + len > frame_width || bytestream2_get_bytes_left(&gb) < len) return; - memcpy(&dp[ofs], pb, len); - pb += len; + bytestream2_get_buffer(&gb, &dp[ofs], len); ofs += len; } else { /* interframe pixel copy */ @@ -317,10 +301,7 @@ static void vmd_decode(VmdVideoContext *s) case 2: for (i = 0; i < frame_height; i++) { - if (pb_end -pb < frame_width) - return; - memcpy(dp, pb, frame_width); - pb += frame_width; + bytestream2_get_buffer(&gb, dp, frame_width); dp += s->frame.linesize[0]; pp += s->prev_frame.linesize[0]; } @@ -330,22 +311,16 @@ static void vmd_decode(VmdVideoContext *s) for (i = 0; i < frame_height; i++) { ofs = 0; do { - if (pb_end - pb < 1) - return; - len = *pb++; + len = bytestream2_get_byte(&gb); if (len & 0x80) { len = (len & 0x7F) + 1; - if (pb_end - pb < 1) - return; - if (*pb++ == 0xFF) - len = rle_unpack(pb, pb_end - pb, len, &dp[ofs], frame_width - ofs); - else { - if (pb_end - pb < len) - return; - memcpy(&dp[ofs], pb, len); - } - pb += len; - ofs += len; + if (bytestream2_get_byte(&gb) == 0xFF) + len = rle_unpack(gb.buffer, &dp[ofs], + len, bytestream2_get_bytes_left(&gb), + frame_width - ofs); + else + bytestream2_get_buffer(&gb, &dp[ofs], len); + bytestream2_skip(&gb, len); } else { /* interframe pixel copy */ if (ofs + len + 1 > frame_width || !s->prev_frame.data[0]) diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index 6e33dcbb6e..867a3410ca 100644 --- a/libavcodec/wavpack.c +++ b/libavcodec/wavpack.c @@ -773,13 +773,13 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, if (block_no >= wc->fdec_num && wv_alloc_frame_context(wc) < 0) { av_log(avctx, AV_LOG_ERROR, "Error creating frame decode context\n"); - return -1; + return AVERROR_INVALIDDATA; } s = wc->fdec[block_no]; if (!s) { av_log(avctx, AV_LOG_ERROR, "Context for block %d is not present\n", block_no); - return -1; + return AVERROR_INVALIDDATA; } memset(s->decorr, 0, MAX_TERMS * sizeof(Decorr)); @@ -1022,7 +1022,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, case WP_ID_CHANINFO: if (size <= 1) { av_log(avctx, AV_LOG_ERROR, "Insufficient channel information\n"); - return -1; + return AVERROR_INVALIDDATA; } chan = *buf++; switch (size - 2) { @@ -1041,10 +1041,11 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, chmask = avctx->channel_layout; } if (chan != avctx->channels) { - av_log(avctx, AV_LOG_ERROR, "Block reports total %d channels, " - "decoder believes it's %d channels\n", chan, - avctx->channels); - return -1; + av_log(avctx, AV_LOG_ERROR, + "Block reports total %d channels, " + "decoder believes it's %d channels\n", + chan, avctx->channels); + return AVERROR_INVALIDDATA; } if (!avctx->channel_layout) avctx->channel_layout = chmask; @@ -1059,31 +1060,31 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, if (!got_terms) { av_log(avctx, AV_LOG_ERROR, "No block with decorrelation terms\n"); - return -1; + return AVERROR_INVALIDDATA; } if (!got_weights) { av_log(avctx, AV_LOG_ERROR, "No block with decorrelation weights\n"); - return -1; + return AVERROR_INVALIDDATA; } if (!got_samples) { av_log(avctx, AV_LOG_ERROR, "No block with decorrelation samples\n"); - return -1; + return AVERROR_INVALIDDATA; } if (!got_entropy) { av_log(avctx, AV_LOG_ERROR, "No block with entropy info\n"); - return -1; + return AVERROR_INVALIDDATA; } if (s->hybrid && !got_hybrid) { av_log(avctx, AV_LOG_ERROR, "Hybrid config not found\n"); - return -1; + return AVERROR_INVALIDDATA; } if (!got_bs) { av_log(avctx, AV_LOG_ERROR, "Packed samples not found\n"); - return -1; + return AVERROR_INVALIDDATA; } if (!got_float && avctx->sample_fmt == AV_SAMPLE_FMT_FLT) { av_log(avctx, AV_LOG_ERROR, "Float information not found\n"); - return -1; + return AVERROR_INVALIDDATA; } if (s->got_extra_bits && avctx->sample_fmt != AV_SAMPLE_FMT_FLT) { const int size = get_bits_left(&s->gb_extra_bits); @@ -1103,7 +1104,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, samplecount = wv_unpack_stereo(s, &s->gb, samples, AV_SAMPLE_FMT_FLT); if (samplecount < 0) - return -1; + return samplecount; samplecount >>= 1; } else { @@ -1117,7 +1118,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, samplecount = wv_unpack_mono(s, &s->gb, samples, AV_SAMPLE_FMT_FLT); if (samplecount < 0) - return -1; + return samplecount; if (s->stereo && avctx->sample_fmt == AV_SAMPLE_FMT_S16) { int16_t *dst = (int16_t*)samples + 1; @@ -1194,7 +1195,7 @@ static int wavpack_decode_frame(AVCodecContext *avctx, void *data, if (s->samples <= 0) { av_log(avctx, AV_LOG_ERROR, "Invalid number of samples: %d\n", s->samples); - return AVERROR(EINVAL); + return AVERROR_INVALIDDATA; } if (frame_flags & 0x80) { @@ -1228,13 +1229,13 @@ static int wavpack_decode_frame(AVCodecContext *avctx, void *data, av_log(avctx, AV_LOG_ERROR, "Block %d has invalid size (size %d " "vs. %d bytes left)\n", s->block, frame_size, buf_size); wavpack_decode_flush(avctx); - return -1; + return AVERROR_INVALIDDATA; } if ((samplecount = wavpack_decode_block(avctx, s->block, s->frame.data[0], got_frame_ptr, buf, frame_size)) < 0) { wavpack_decode_flush(avctx); - return -1; + return samplecount; } s->block++; buf += frame_size; buf_size -= frame_size; diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c index 85c18f03c2..53bce957df 100644 --- a/libavcodec/wmaprodec.c +++ b/libavcodec/wmaprodec.c @@ -1466,6 +1466,14 @@ static void save_bits(WMAProDecodeCtx *s, GetBitContext* gb, int len, return; } + if (len > put_bits_left(&s->pb)) { + av_log(s->avctx, AV_LOG_ERROR, + "Cannot append %d bits, only %d bits available.\n", + len, put_bits_left(&s->pb)); + s->packet_loss = 1; + return; + } + s->num_saved_bits += len; if (!append) { avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), diff --git a/libavformat/apetag.c b/libavformat/apetag.c index 8d53e4cdf7..7346ba7f7f 100644 --- a/libavformat/apetag.c +++ b/libavformat/apetag.c @@ -65,7 +65,7 @@ static int ape_tag_read_field(AVFormatContext *s) void ff_ape_parse_tag(AVFormatContext *s) { AVIOContext *pb = s->pb; - int file_size = avio_size(pb); + int64_t file_size = avio_size(pb); uint32_t val, fields, tag_bytes; uint8_t buf[8]; int i; diff --git a/libavformat/smacker.c b/libavformat/smacker.c index 2385088200..9f8fbf5308 100644 --- a/libavformat/smacker.c +++ b/libavformat/smacker.c @@ -203,7 +203,8 @@ static int smacker_read_header(AVFormatContext *s, AVFormatParameters *ap) /* load trees to extradata, they will be unpacked by decoder */ - st->codec->extradata = av_malloc(smk->treesize + 16); + st->codec->extradata = av_mallocz(smk->treesize + 16 + + FF_INPUT_BUFFER_PADDING_SIZE); st->codec->extradata_size = smk->treesize + 16; if(!st->codec->extradata){ av_log(s, AV_LOG_ERROR, "Cannot allocate %i bytes of extradata\n", smk->treesize + 16); @@ -298,12 +299,14 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt) /* if audio chunks are present, put them to stack and retrieve later */ for(i = 0; i < 7; i++) { if(flags & 1) { - unsigned int size; + uint32_t size; uint8_t *tmpbuf; size = avio_rl32(s->pb) - 4; - if(size + 4L > frame_size) + if (!size || size + 4L > frame_size) { + av_log(s, AV_LOG_ERROR, "Invalid audio part size\n"); return AVERROR_INVALIDDATA; + } frame_size -= size; frame_size -= 4; smk->curstream++; |