diff options
author | Michael Niedermayer <[email protected]> | 2011-10-02 21:37:59 +0200 |
---|---|---|
committer | Michael Niedermayer <[email protected]> | 2011-10-02 21:37:59 +0200 |
commit | 7fc85451fd47a4607f3cc47d1daa84ae122f5a46 (patch) | |
tree | f94ae472ddeea47eee50ef33ee6ecdd3e7e1e501 /libavcodec | |
parent | 42c8fdb943b210b2f79e2510a91ca0f542c9bad0 (diff) | |
parent | b89a0c9d7f4c4a23d709761033ad5e2f9c2881fa (diff) |
Merge branch 'release/0.8' into release/0.7
* release/0.8: (185 commits)
h264: fix intra 16x16 mode check when using mbaff and constrained_intra_pred.
h264: check for invalid bit depth value.
h264: add entries for 11 and 12 bits in ff_h264_chroma_qp[][]
h264: fix the check for invalid SPS:num_ref_frames.
h264: do not let invalid values in h->ref_count on ff_h264_decode_ref_pic_list_reordering() errors.
Reject video with non multiple of 16 width/height in the 4xm decoder.
4xm decoder: fix data size for i2 frames.
4xm decoder: print some error messages in case of errors.
Check for out of bound accesses in the 4xm decoder.
Prevent block size from inreasing in the shorten decoder.
Check for out of bound reads in PTX decoder.
Clear FF_INPUT_BUFFER_PADDING_SIZE bytes at the end of the temporary buffers used in 4xm decoder.
Fix the check for missing references in ff_er_frame_end() for H264.
Prevent NULL dereference when the huffman table is invalid in the 4xm decoder.
Fix use of uninitialized memory in 4X Technologies demuxer.
h264: increase ref_poc size to 32 as it can be per field.
h264: set unused ref_counts to 0 as a precautionary meassure.
Remove Chnagelog it has nothing to do with reality
fate: fix motion pixels checksum change caused by backported bugfix
avienc: Add a limit on the number of skiped frames muxed in a row.
...
Conflicts:
Doxyfile
RELEASE
VERSION
libavformat/utils.c
Merged-by: Michael Niedermayer <[email protected]>
Diffstat (limited to 'libavcodec')
54 files changed, 800 insertions, 232 deletions
diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c index d89b494b09..7344f4cd1f 100644 --- a/libavcodec/4xm.c +++ b/libavcodec/4xm.c @@ -133,7 +133,9 @@ typedef struct FourXContext{ GetBitContext pre_gb; ///< ac/dc prefix GetBitContext gb; const uint8_t *bytestream; + const uint8_t *bytestream_end; const uint16_t *wordstream; + const uint16_t *wordstream_end; int mv[256]; VLC pre_vlc; int last_dc; @@ -328,6 +330,10 @@ static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, int lo assert(code>=0 && code<=6); if(code == 0){ + if (f->bytestream_end - f->bytestream < 1){ + av_log(f->avctx, AV_LOG_ERROR, "bytestream overread\n"); + return; + } src += f->mv[ *f->bytestream++ ]; if(start > src || src > end){ av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n"); @@ -345,15 +351,31 @@ static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, int lo }else if(code == 3 && f->version<2){ mcdc(dst, src, log2w, h, stride, 1, 0); }else if(code == 4){ + if (f->bytestream_end - f->bytestream < 1){ + av_log(f->avctx, AV_LOG_ERROR, "bytestream overread\n"); + return; + } src += f->mv[ *f->bytestream++ ]; if(start > src || src > end){ av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n"); return; } + if (f->wordstream_end - f->wordstream < 1){ + av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n"); + return; + } mcdc(dst, src, log2w, h, stride, 1, av_le2ne16(*f->wordstream++)); }else if(code == 5){ + if (f->wordstream_end - f->wordstream < 1){ + av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n"); + return; + } mcdc(dst, src, log2w, h, stride, 0, av_le2ne16(*f->wordstream++)); }else if(code == 6){ + if (f->wordstream_end - f->wordstream < 2){ + av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n"); + return; + } if(log2w){ dst[0] = av_le2ne16(*f->wordstream++); dst[1] = av_le2ne16(*f->wordstream++); @@ -375,6 +397,8 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length){ if(f->version>1){ extra=20; + if (length < extra) + return -1; bitstream_size= AV_RL32(buf+8); wordstream_size= AV_RL32(buf+12); bytestream_size= AV_RL32(buf+16); @@ -385,11 +409,10 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length){ bytestream_size= FFMAX(length - bitstream_size - wordstream_size, 0); } - if(bitstream_size+ bytestream_size+ wordstream_size + extra != length - || bitstream_size > (1<<26) - || bytestream_size > (1<<26) - || wordstream_size > (1<<26) - ){ + if (bitstream_size > length || + bytestream_size > length - bitstream_size || + wordstream_size > length - bytestream_size - bitstream_size || + extra > length - bytestream_size - bitstream_size - wordstream_size){ av_log(f->avctx, AV_LOG_ERROR, "lengths %d %d %d %d\n", bitstream_size, bytestream_size, wordstream_size, bitstream_size+ bytestream_size+ wordstream_size - length); return -1; @@ -399,10 +422,13 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length){ if (!f->bitstream_buffer) return AVERROR(ENOMEM); f->dsp.bswap_buf(f->bitstream_buffer, (const uint32_t*)(buf + extra), bitstream_size/4); + memset((uint8_t*)f->bitstream_buffer + bitstream_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); init_get_bits(&f->gb, f->bitstream_buffer, 8*bitstream_size); f->wordstream= (const uint16_t*)(buf + extra + bitstream_size); + f->wordstream_end= f->wordstream + wordstream_size/2; f->bytestream= buf + extra + bitstream_size + wordstream_size; + f->bytestream_end = f->bytestream + bytestream_size; init_mv(f); @@ -531,7 +557,7 @@ static int decode_i_mb(FourXContext *f){ return 0; } -static const uint8_t *read_huffman_tables(FourXContext *f, const uint8_t * const buf){ +static const uint8_t *read_huffman_tables(FourXContext *f, const uint8_t * const buf, int buf_size){ int frequency[512]; uint8_t flag[512]; int up[512]; @@ -539,6 +565,7 @@ static const uint8_t *read_huffman_tables(FourXContext *f, const uint8_t * const int bits_tab[257]; int start, end; const uint8_t *ptr= buf; + const uint8_t *ptr_end = buf + buf_size; int j; memset(frequency, 0, sizeof(frequency)); @@ -549,6 +576,8 @@ static const uint8_t *read_huffman_tables(FourXContext *f, const uint8_t * const for(;;){ int i; + if (start <= end && ptr_end - ptr < end - start + 1 + 1) + return NULL; for(i=start; i<=end; i++){ frequency[i]= *ptr++; } @@ -601,9 +630,10 @@ static const uint8_t *read_huffman_tables(FourXContext *f, const uint8_t * const len_tab[j]= len; } - init_vlc(&f->pre_vlc, ACDC_VLC_BITS, 257, - len_tab , 1, 1, - bits_tab, 4, 4, 0); + if (init_vlc(&f->pre_vlc, ACDC_VLC_BITS, 257, + len_tab , 1, 1, + bits_tab, 4, 4, 0)) + return NULL; return ptr; } @@ -621,10 +651,13 @@ static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length){ const int height= f->avctx->height; uint16_t *dst= (uint16_t*)f->current_picture.data[0]; const int stride= f->current_picture.linesize[0]>>1; + const uint8_t *buf_end = buf + length; for(y=0; y<height; y+=16){ for(x=0; x<width; x+=16){ unsigned int color[4], bits; + if (buf_end - buf < 8) + return -1; memset(color, 0, sizeof(color)); //warning following is purely guessed ... color[0]= bytestream_get_le16(&buf); @@ -658,18 +691,23 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length){ uint16_t *dst= (uint16_t*)f->current_picture.data[0]; const int stride= f->current_picture.linesize[0]>>1; const unsigned int bitstream_size= AV_RL32(buf); - const int token_count av_unused = AV_RL32(buf + bitstream_size + 8); - unsigned int prestream_size= 4*AV_RL32(buf + bitstream_size + 4); - const uint8_t *prestream= buf + bitstream_size + 12; + unsigned int prestream_size; + const uint8_t *prestream; + + if (bitstream_size > (1<<26) || length < bitstream_size + 12) + return -1; + prestream_size = 4*AV_RL32(buf + bitstream_size + 4); + prestream = buf + bitstream_size + 12; - if(prestream_size + bitstream_size + 12 != length - || bitstream_size > (1<<26) - || prestream_size > (1<<26)){ + if (prestream_size > (1<<26) || + prestream_size != length - (bitstream_size + 12)){ 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); + prestream= read_huffman_tables(f, prestream, buf + length - prestream); + if (!prestream) + return -1; init_get_bits(&f->gb, buf + 4, 8*bitstream_size); @@ -679,6 +717,7 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length){ if (!f->bitstream_buffer) return AVERROR(ENOMEM); f->dsp.bswap_buf(f->bitstream_buffer, (const uint32_t*)prestream, prestream_size/4); + memset((uint8_t*)f->bitstream_buffer + prestream_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); init_get_bits(&f->pre_gb, f->bitstream_buffer, 8*prestream_size); f->last_dc= 0*128*8*8; @@ -710,6 +749,8 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *p, temp; int i, frame_4cc, frame_size; + if (buf_size < 12) + return AVERROR_INVALIDDATA; frame_4cc= AV_RL32(buf); if(buf_size != AV_RL32(buf+4)+8 || buf_size < 20){ av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d\n", buf_size, AV_RL32(buf+4)); @@ -722,6 +763,11 @@ static int decode_frame(AVCodecContext *avctx, const int whole_size= AV_RL32(buf+16); CFrameBuffer *cfrm; + if (data_size < 0 || whole_size < 0){ + av_log(f->avctx, AV_LOG_ERROR, "sizes invalid\n"); + return AVERROR_INVALIDDATA; + } + for(i=0; i<CFRAME_BUFFER_COUNT; i++){ if(f->cfrm[i].id && f->cfrm[i].id < avctx->frame_number) av_log(f->avctx, AV_LOG_ERROR, "lost c frame %d\n", f->cfrm[i].id); @@ -738,6 +784,8 @@ static int decode_frame(AVCodecContext *avctx, } cfrm= &f->cfrm[i]; + if (data_size > UINT_MAX - cfrm->size - FF_INPUT_BUFFER_PADDING_SIZE) + return AVERROR_INVALIDDATA; cfrm->data= av_fast_realloc(cfrm->data, &cfrm->allocated_size, cfrm->size + data_size + FF_INPUT_BUFFER_PADDING_SIZE); if(!cfrm->data){ //explicit check needed as memcpy below might not catch a NULL av_log(f->avctx, AV_LOG_ERROR, "realloc falure"); @@ -781,12 +829,16 @@ static int decode_frame(AVCodecContext *avctx, if(frame_4cc == AV_RL32("ifr2")){ p->pict_type= AV_PICTURE_TYPE_I; - if(decode_i2_frame(f, buf-4, frame_size) < 0) + if(decode_i2_frame(f, buf-4, frame_size+4) < 0){ + av_log(f->avctx, AV_LOG_ERROR, "decode i2 frame failed\n"); return -1; + } }else if(frame_4cc == AV_RL32("ifrm")){ p->pict_type= AV_PICTURE_TYPE_I; - if(decode_i_frame(f, buf, frame_size) < 0) + if(decode_i_frame(f, buf, frame_size) < 0){ + av_log(f->avctx, AV_LOG_ERROR, "decode i frame failed\n"); return -1; + } }else if(frame_4cc == AV_RL32("pfrm") || frame_4cc == AV_RL32("pfr2")){ if(!f->last_picture.data[0]){ f->last_picture.reference= 1; @@ -797,8 +849,10 @@ static int decode_frame(AVCodecContext *avctx, } p->pict_type= AV_PICTURE_TYPE_P; - if(decode_p_frame(f, buf, frame_size) < 0) + if(decode_p_frame(f, buf, frame_size) < 0){ + av_log(f->avctx, AV_LOG_ERROR, "decode p frame failed\n"); return -1; + } }else if(frame_4cc == AV_RL32("snd_")){ av_log(avctx, AV_LOG_ERROR, "ignoring snd_ chunk length:%d\n", buf_size); }else{ @@ -831,6 +885,10 @@ static av_cold int decode_init(AVCodecContext *avctx){ av_log(avctx, AV_LOG_ERROR, "extradata wrong or missing\n"); return 1; } + if((avctx->width % 16) || (avctx->height % 16)) { + av_log(avctx, AV_LOG_ERROR, "unsupported width/height\n"); + return AVERROR_INVALIDDATA; + } avcodec_get_frame_defaults(&f->current_picture); avcodec_get_frame_defaults(&f->last_picture); diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 175e6a0d2a..e30be95e77 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -568,6 +568,7 @@ OBJS-$(CONFIG_WEBM_MUXER) += xiph.o mpeg4audio.o \ OBJS-$(CONFIG_WTV_DEMUXER) += mpeg4audio.o mpegaudiodata.o # external codec libraries +OBJS-$(CONFIG_LIBAACPLUS_ENCODER) += libaacplus.o OBJS-$(CONFIG_LIBCELT_DECODER) += libcelt_dec.o OBJS-$(CONFIG_LIBDIRAC_DECODER) += libdiracdec.o OBJS-$(CONFIG_LIBDIRAC_ENCODER) += libdiracenc.o libdirac_libschro.o diff --git a/libavcodec/aacsbr.c b/libavcodec/aacsbr.c index 82092b385d..10b8daf280 100644 --- a/libavcodec/aacsbr.c +++ b/libavcodec/aacsbr.c @@ -33,6 +33,7 @@ #include "fft.h" #include "aacps.h" #include "libavutil/libm.h" +#include "libavutil/avassert.h" #include <stdint.h> #include <float.h> @@ -1457,6 +1458,7 @@ static void sbr_mapping(AACContext *ac, SpectralBandReplication *sbr, uint16_t *table = ch_data->bs_freq_res[e + 1] ? sbr->f_tablehigh : sbr->f_tablelow; int k; + av_assert0(sbr->kx[1] <= table[0]); for (i = 0; i < ilim; i++) for (m = table[i]; m < table[i + 1]; m++) sbr->e_origmapped[e][m - sbr->kx[1]] = ch_data->env_facs[e+1][i]; diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index ba312558b0..de7bc7a45b 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -1333,10 +1333,11 @@ static int adpcm_decode_frame(AVCodecContext *avctx, buf_size -= 128; } break; - case CODEC_ID_ADPCM_IMA_EA_EACS: + case CODEC_ID_ADPCM_IMA_EA_EACS: { + unsigned header_size = 4 + (8<<st); samples_in_chunk = bytestream_get_le32(&src) >> (1-st); - if (samples_in_chunk > buf_size-4-(8<<st)) { + if (buf_size < header_size || samples_in_chunk > buf_size - header_size) { src += buf_size - 4; break; } @@ -1351,6 +1352,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, *samples++ = adpcm_ima_expand_nibble(&c->status[st], *src&0x0F, 3); } break; + } case CODEC_ID_ADPCM_IMA_EA_SEAD: for (; src < buf+buf_size; src++) { *samples++ = adpcm_ima_expand_nibble(&c->status[0], src[0] >> 4, 6); diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index f1c664f5d1..c038524f75 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -370,6 +370,7 @@ void avcodec_register_all(void) REGISTER_ENCDEC (XSUB, xsub); /* external libraries */ + REGISTER_ENCODER (LIBAACPLUS, libaacplus); REGISTER_DECODER (LIBCELT, libcelt); REGISTER_ENCDEC (LIBDIRAC, libdirac); REGISTER_ENCODER (LIBFAAC, libfaac); diff --git a/libavcodec/anm.c b/libavcodec/anm.c index 02244f70e1..8e40059576 100644 --- a/libavcodec/anm.c +++ b/libavcodec/anm.c @@ -79,6 +79,8 @@ static inline int op(uint8_t **dst, const uint8_t *dst_end, int striplen = FFMIN(count, remaining); if (buf) { striplen = FFMIN(striplen, buf_end - *buf); + if (*buf >= buf_end) + goto exhausted; memcpy(*dst, *buf, striplen); *buf += striplen; } else if (pixel >= 0) diff --git a/libavcodec/avs.c b/libavcodec/avs.c index 354b53c241..c7dcf0e2dc 100644 --- a/libavcodec/avs.c +++ b/libavcodec/avs.c @@ -47,6 +47,7 @@ avs_decode_frame(AVCodecContext * avctx, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; + const uint8_t *buf_end = avpkt->data + avpkt->size; int buf_size = avpkt->size; AvsContext *const avs = avctx->priv_data; AVFrame *picture = data; @@ -69,6 +70,8 @@ avs_decode_frame(AVCodecContext * avctx, out = avs->picture.data[0]; stride = avs->picture.linesize[0]; + if (buf_end - buf < 4) + return AVERROR_INVALIDDATA; sub_type = buf[0]; type = buf[1]; buf += 4; @@ -79,6 +82,8 @@ avs_decode_frame(AVCodecContext * avctx, first = AV_RL16(buf); last = first + AV_RL16(buf + 2); + if (first >= 256 || last > 256 || buf_end - buf < 4 + 4 + 3 * (last - first)) + return AVERROR_INVALIDDATA; buf += 4; for (i=first; i<last; i++, buf+=3) pal[i] = (buf[0] << 18) | (buf[1] << 10) | (buf[2] << 2); @@ -114,9 +119,13 @@ avs_decode_frame(AVCodecContext * avctx, return -1; } + if (buf_end - buf < 256 * vect_w * vect_h) + return AVERROR_INVALIDDATA; table = buf + (256 * vect_w * vect_h); if (sub_type != AVS_I_FRAME) { int map_size = ((318 / vect_w + 7) / 8) * (198 / vect_h); + if (buf_end - table < map_size) + return AVERROR_INVALIDDATA; init_get_bits(&change_map, table, map_size * 8); table += map_size; } @@ -124,6 +133,8 @@ avs_decode_frame(AVCodecContext * avctx, for (y=0; y<198; y+=vect_h) { for (x=0; x<318; x+=vect_w) { if (sub_type == AVS_I_FRAME || get_bits1(&change_map)) { + if (buf_end - table < 1) + return AVERROR_INVALIDDATA; vect = &buf[*table++ * (vect_w * vect_h)]; for (j=0; j<vect_w; j++) { out[(y + 0) * stride + x + j] = vect[(0 * vect_w) + j]; diff --git a/libavcodec/bink.c b/libavcodec/bink.c index 4328a43525..63f17eb577 100644 --- a/libavcodec/bink.c +++ b/libavcodec/bink.c @@ -246,7 +246,7 @@ static void read_tree(GetBitContext *gb, Tree *tree) tree->syms[i] = get_bits(gb, 4); tmp1[tree->syms[i]] = 1; } - for (i = 0; i < 16; i++) + for (i = 0; i < 16 && len < 16 - 1; i++) if (!tmp1[i]) tree->syms[++len] = i; } else { @@ -343,14 +343,14 @@ static int read_motion_values(AVCodecContext *avctx, GetBitContext *gb, Bundle * memset(b->cur_dec, v, t); b->cur_dec += t; } else { - do { + while (b->cur_dec < dec_end) { v = GET_HUFF(gb, b->tree); if (v) { sign = -get_bits1(gb); v = (v ^ sign) - sign; } *b->cur_dec++ = v; - } while (b->cur_dec < dec_end); + } } return 0; } @@ -374,7 +374,7 @@ static int read_block_types(AVCodecContext *avctx, GetBitContext *gb, Bundle *b) memset(b->cur_dec, v, t); b->cur_dec += t; } else { - do { + while (b->cur_dec < dec_end) { v = GET_HUFF(gb, b->tree); if (v < 12) { last = v; @@ -382,10 +382,12 @@ static int read_block_types(AVCodecContext *avctx, GetBitContext *gb, Bundle *b) } else { int run = bink_rlelens[v - 12]; + if (dec_end - b->cur_dec < run) + return -1; memset(b->cur_dec, last, run); b->cur_dec += run; } - } while (b->cur_dec < dec_end); + } } return 0; } @@ -456,6 +458,7 @@ static int read_dcs(AVCodecContext *avctx, GetBitContext *gb, Bundle *b, { int i, j, len, len2, bsize, sign, v, v2; int16_t *dst = (int16_t*)b->cur_dec; + int16_t *dst_end =( int16_t*)b->data_end; CHECK_READ_VAL(gb, b, len); v = get_bits(gb, start_bits - has_sign); @@ -463,10 +466,14 @@ static int read_dcs(AVCodecContext *avctx, GetBitContext *gb, Bundle *b, sign = -get_bits1(gb); v = (v ^ sign) - sign; } + if (dst_end - dst < 1) + return -1; *dst++ = v; len--; for (i = 0; i < len; i += 8) { len2 = FFMIN(len - i, 8); + if (dst_end - dst < len2) + return -1; bsize = get_bits(gb, 4); if (bsize) { for (j = 0; j < len2; j++) { @@ -534,6 +541,8 @@ static int binkb_read_bundle(BinkContext *c, GetBitContext *gb, int bundle_num) int i, len; CHECK_READ_VAL(gb, b, len); + if (b->data_end - b->cur_dec < len * (1 + (bits > 8))) + return -1; if (bits <= 8) { if (!issigned) { for (i = 0; i < len; i++) @@ -964,8 +973,9 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, for (i = 0; i < BINK_NB_SRC; i++) read_bundle(gb, c, i); - ref_start = c->last.data[plane_idx]; - ref_end = c->last.data[plane_idx] + ref_start = c->last.data[plane_idx] ? c->last.data[plane_idx] + : c->pic.data[plane_idx]; + ref_end = ref_start + (bw - 1 + c->last.linesize[plane_idx] * (bh - 1)) * 8; for (i = 0; i < 64; i++) @@ -994,7 +1004,8 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, if (by == bh) break; dst = c->pic.data[plane_idx] + 8*by*stride; - prev = c->last.data[plane_idx] + 8*by*stride; + prev = (c->last.data[plane_idx] ? c->last.data[plane_idx] + : c->pic.data[plane_idx]) + 8*by*stride; for (bx = 0; bx < bw; bx++, dst += 8, prev += 8) { blk = get_value(c, BINK_SRC_BLOCK_TYPES); // 16x16 block type on odd line means part of the already decoded block, so skip it diff --git a/libavcodec/bitstream.c b/libavcodec/bitstream.c index f0fa9652c6..e2a3d56d05 100644 --- a/libavcodec/bitstream.c +++ b/libavcodec/bitstream.c @@ -109,8 +109,8 @@ static int alloc_table(VLC *vlc, int size, int use_static) if(use_static) abort(); //cant do anything, init_vlc() is used with too little memory vlc->table_allocated += (1 << vlc->bits); - vlc->table = av_realloc(vlc->table, - sizeof(VLC_TYPE) * 2 * vlc->table_allocated); + vlc->table = av_realloc_f(vlc->table, + vlc->table_allocated, sizeof(VLC_TYPE) * 2); if (!vlc->table) return -1; } diff --git a/libavcodec/dca.c b/libavcodec/dca.c index 5166fc5337..69df8f4597 100644 --- a/libavcodec/dca.c +++ b/libavcodec/dca.c @@ -898,6 +898,9 @@ static void qmf_32_subbands(DCAContext * s, int chans, else /* Perfect reconstruction */ prCoeff = fir_32bands_perfect; + for (i = sb_act; i < 32; i++) + s->raXin[i] = 0.0; + /* Reconstructed channel sample index */ for (subindex = 0; subindex < 8; subindex++) { /* Load in one sample from each subband and clear inactive subbands */ @@ -905,8 +908,6 @@ static void qmf_32_subbands(DCAContext * s, int chans, uint32_t v = AV_RN32A(&samples_in[i][subindex]) ^ ((i-1)&2)<<30; AV_WN32A(&s->raXin[i], v); } - for (; i < 32; i++) - s->raXin[i] = 0.0; s->synth.synth_filter_float(&s->imdct, s->subband_fir_hist[chans], &s->hist_index[chans], diff --git a/libavcodec/dsicinav.c b/libavcodec/dsicinav.c index f12560714a..faca821c7d 100644 --- a/libavcodec/dsicinav.c +++ b/libavcodec/dsicinav.c @@ -217,7 +217,11 @@ static int cinvideo_decode_frame(AVCodecContext *avctx, bitmap_frame_size = buf_size - 4; /* handle palette */ + if (bitmap_frame_size < palette_colors_count * (3 + (palette_type != 0))) + return AVERROR_INVALIDDATA; if (palette_type == 0) { + if (palette_colors_count > 256) + return AVERROR_INVALIDDATA; for (i = 0; i < palette_colors_count; ++i) { cin->palette[i] = bytestream_get_le24(&buf); bitmap_frame_size -= 3; diff --git a/libavcodec/eacmv.c b/libavcodec/eacmv.c index 408d948812..4cd6a6fd1f 100644 --- a/libavcodec/eacmv.c +++ b/libavcodec/eacmv.c @@ -56,7 +56,7 @@ static void cmv_decode_intra(CmvContext * s, const uint8_t *buf, const uint8_t * unsigned char *dst = s->frame.data[0]; int i; - for (i=0; i < s->avctx->height && buf+s->avctx->width<=buf_end; i++) { + for (i=0; i < s->avctx->height && buf_end - buf >= s->avctx->width; i++) { memcpy(dst, buf, s->avctx->width); dst += s->frame.linesize[0]; buf += s->avctx->width; @@ -88,7 +88,7 @@ static void cmv_decode_inter(CmvContext * s, const uint8_t *buf, const uint8_t * i = 0; for(y=0; y<s->avctx->height/4; y++) - for(x=0; x<s->avctx->width/4 && buf+i<buf_end; x++) { + for(x=0; x<s->avctx->width/4 && buf_end - buf > i; x++) { if (buf[i]==0xFF) { unsigned char *dst = s->frame.data[0] + (y*4)*s->frame.linesize[0] + x*4; if (raw+16<buf_end && *raw==0xFF) { /* intra */ @@ -110,9 +110,10 @@ static void cmv_decode_inter(CmvContext * s, const uint8_t *buf, const uint8_t * }else{ /* inter using last frame as reference */ int xoffset = (buf[i] & 0xF) - 7; int yoffset = ((buf[i] >> 4)) - 7; - cmv_motcomp(s->frame.data[0], s->frame.linesize[0], - s->last_frame.data[0], s->last_frame.linesize[0], - x*4, y*4, xoffset, yoffset, s->avctx->width, s->avctx->height); + if (s->last_frame.data[0]) + cmv_motcomp(s->frame.data[0], s->frame.linesize[0], + s->last_frame.data[0], s->last_frame.linesize[0], + x*4, y*4, xoffset, yoffset, s->avctx->width, s->avctx->height); } i++; } @@ -122,7 +123,7 @@ static void cmv_process_header(CmvContext *s, const uint8_t *buf, const uint8_t { int pal_start, pal_count, i; - if(buf+16>=buf_end) { + if(buf_end - buf < 16) { av_log(s->avctx, AV_LOG_WARNING, "truncated header\n"); return; } @@ -139,7 +140,7 @@ static void cmv_process_header(CmvContext *s, const uint8_t *buf, const uint8_t pal_count = AV_RL16(&buf[14]); buf += 16; - for (i=pal_start; i<pal_start+pal_count && i<AVPALETTE_COUNT && buf+2<buf_end; i++) { + for (i=pal_start; i<pal_start+pal_count && i<AVPALETTE_COUNT && buf_end - buf >= 3; i++) { s->palette[i] = AV_RB24(buf); buf += 3; } @@ -157,6 +158,9 @@ static int cmv_decode_frame(AVCodecContext *avctx, CmvContext *s = avctx->priv_data; const uint8_t *buf_end = buf + buf_size; + if (buf_end - buf < EA_PREAMBLE_SIZE) + return AVERROR_INVALIDDATA; + if (AV_RL32(buf)==MVIh_TAG||AV_RB32(buf)==MVIh_TAG) { cmv_process_header(s, buf+EA_PREAMBLE_SIZE, buf_end); return buf_size; diff --git a/libavcodec/error_resilience.c b/libavcodec/error_resilience.c index d6ac81f009..0e410f96e8 100644 --- a/libavcodec/error_resilience.c +++ b/libavcodec/error_resilience.c @@ -660,7 +660,7 @@ static int is_intra_more_likely(MpegEncContext *s){ if(s->codec_id == CODEC_ID_H264){ H264Context *h= (void*)s; - if(h->ref_count[0] <= 0 || !h->ref_list[0][0].data[0]) + if (h->list_count <= 0 || h->ref_count[0] <= 0 || !h->ref_list[0][0].data[0]) return 1; } diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c index ece095cf09..011c75faae 100644 --- a/libavcodec/flacdec.c +++ b/libavcodec/flacdec.c @@ -228,9 +228,11 @@ static int get_metadata_size(const uint8_t *buf, int buf_size) buf += 4; do { + if (buf_end - buf < 4) + return 0; ff_flac_parse_block_header(buf, &metadata_last, NULL, &metadata_size); buf += 4; - if (buf + metadata_size > buf_end) { + if (buf_end - buf < metadata_size) { /* need more data in order to read the complete header */ return 0; } diff --git a/libavcodec/flicvideo.c b/libavcodec/flicvideo.c index 8cc72e241e..2055596503 100644 --- a/libavcodec/flicvideo.c +++ b/libavcodec/flicvideo.c @@ -132,7 +132,6 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, FlicDecodeContext *s = avctx->priv_data; int stream_ptr = 0; - int stream_ptr_after_color_chunk; int pixel_ptr; int palette_ptr; unsigned char palette_idx1; @@ -172,7 +171,11 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, pixels = s->frame.data[0]; pixel_limit = s->avctx->height * s->frame.linesize[0]; + if (buf_size < 16 || buf_size > INT_MAX - (3 * 256 + FF_INPUT_BUFFER_PADDING_SIZE)) + return AVERROR_INVALIDDATA; frame_size = AV_RL32(&buf[stream_ptr]); + if (frame_size > buf_size) + frame_size = buf_size; stream_ptr += 6; /* skip the magic number */ num_chunks = AV_RL16(&buf[stream_ptr]); stream_ptr += 10; /* skip padding */ @@ -180,13 +183,16 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, frame_size -= 16; /* iterate through the chunks */ - while ((frame_size > 0) && (num_chunks > 0)) { + while ((frame_size >= 6) && (num_chunks > 0)) { + int stream_ptr_after_chunk; chunk_size = AV_RL32(&buf[stream_ptr]); if (chunk_size > frame_size) { av_log(avctx, AV_LOG_WARNING, "Invalid chunk_size = %u > frame_size = %u\n", chunk_size, frame_size); chunk_size = frame_size; } + stream_ptr_after_chunk = stream_ptr + chunk_size; + stream_ptr += 4; chunk_type = AV_RL16(&buf[stream_ptr]); stream_ptr += 2; @@ -194,8 +200,6 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, switch (chunk_type) { case FLI_256_COLOR: case FLI_COLOR: - stream_ptr_after_color_chunk = stream_ptr + chunk_size - 6; - /* check special case: If this file is from the Magic Carpet * game and uses 6-bit colors even though it reports 256-color * chunks in a 0xAF12-type file (fli_type is set to 0xAF13 during @@ -219,6 +223,9 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, if (color_changes == 0) color_changes = 256; + if (stream_ptr + color_changes * 3 > stream_ptr_after_chunk) + break; + for (j = 0; j < color_changes; j++) { unsigned int entry; @@ -235,13 +242,6 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, s->palette[palette_ptr++] = entry; } } - - /* color chunks sometimes have weird 16-bit alignment issues; - * therefore, take the hardline approach and set the stream_ptr - * to the value calculated w.r.t. the size specified by the color - * chunk header */ - stream_ptr = stream_ptr_after_color_chunk; - break; case FLI_DELTA: @@ -249,6 +249,8 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, compressed_lines = AV_RL16(&buf[stream_ptr]); stream_ptr += 2; while (compressed_lines > 0) { + if (stream_ptr + 2 > stream_ptr_after_chunk) + break; line_packets = AV_RL16(&buf[stream_ptr]); stream_ptr += 2; if ((line_packets & 0xC000) == 0xC000) { @@ -268,6 +270,8 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, CHECK_PIXEL_PTR(0); pixel_countdown = s->avctx->width; for (i = 0; i < line_packets; i++) { + if (stream_ptr + 2 > stream_ptr_after_chunk) + break; /* account for the skip bytes */ pixel_skip = buf[stream_ptr++]; pixel_ptr += pixel_skip; @@ -284,6 +288,8 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, } } else { CHECK_PIXEL_PTR(byte_run * 2); + if (stream_ptr + byte_run * 2 > stream_ptr_after_chunk) + break; for (j = 0; j < byte_run * 2; j++, pixel_countdown--) { palette_idx1 = buf[stream_ptr++]; pixels[pixel_ptr++] = palette_idx1; @@ -310,6 +316,8 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, CHECK_PIXEL_PTR(0); pixel_countdown = s->avctx->width; line_packets = buf[stream_ptr++]; + if (stream_ptr + 2 * line_packets > stream_ptr_after_chunk) + break; if (line_packets > 0) { for (i = 0; i < line_packets; i++) { /* account for the skip bytes */ @@ -319,6 +327,8 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, byte_run = (signed char)(buf[stream_ptr++]); if (byte_run > 0) { CHECK_PIXEL_PTR(byte_run); + if (stream_ptr + byte_run > stream_ptr_after_chunk) + break; for (j = 0; j < byte_run; j++, pixel_countdown--) { palette_idx1 = buf[stream_ptr++]; pixels[pixel_ptr++] = palette_idx1; @@ -356,6 +366,8 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, stream_ptr++; pixel_countdown = s->avctx->width; while (pixel_countdown > 0) { + if (stream_ptr + 1 > stream_ptr_after_chunk) + break; byte_run = (signed char)(buf[stream_ptr++]); if (byte_run > 0) { palette_idx1 = buf[stream_ptr++]; @@ -370,6 +382,8 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, } else { /* copy bytes if byte_run < 0 */ byte_run = -byte_run; CHECK_PIXEL_PTR(byte_run); + if (stream_ptr + byte_run > stream_ptr_after_chunk) + break; for (j = 0; j < byte_run; j++) { palette_idx1 = buf[stream_ptr++]; pixels[pixel_ptr++] = palette_idx1; @@ -387,10 +401,9 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, case FLI_COPY: /* copy the chunk (uncompressed frame) */ - if (chunk_size - 6 > s->avctx->width * s->avctx->height) { + if (chunk_size - 6 != s->avctx->width * s->avctx->height) { av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \ - "bigger than image, skipping chunk\n", chunk_size - 6); - stream_ptr += chunk_size - 6; + "has incorrect size, skipping chunk\n", chunk_size - 6); } else { for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height; y_ptr += s->frame.linesize[0]) { @@ -403,7 +416,6 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, case FLI_MINI: /* some sort of a thumbnail? disregard this chunk... */ - stream_ptr += chunk_size - 6; break; default: @@ -411,6 +423,8 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, break; } + stream_ptr = stream_ptr_after_chunk; + frame_size -= chunk_size; num_chunks--; } diff --git a/libavcodec/h264.c b/libavcodec/h264.c index 0ac20a60c0..47ac9f02c6 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -106,12 +106,9 @@ int ff_h264_check_intra4x4_pred_mode(H264Context *h){ } return 0; -} //FIXME cleanup like ff_h264_check_intra_pred_mode +} //FIXME cleanup like check_intra_pred_mode -/** - * checks if the top & left blocks are available if needed & changes the dc mode so it only uses the available blocks. - */ -int ff_h264_check_intra_pred_mode(H264Context *h, int mode){ +static int check_intra_pred_mode(H264Context *h, int mode, int is_chroma){ MpegEncContext * const s = &h->s; static const int8_t top [7]= {LEFT_DC_PRED8x8, 1,-1,-1}; static const int8_t left[7]= { TOP_DC_PRED8x8,-1, 2,-1,DC_128_PRED8x8}; @@ -131,7 +128,7 @@ int ff_h264_check_intra_pred_mode(H264Context *h, int mode){ if((h->left_samples_available&0x8080) != 0x8080){ mode= left[ mode ]; - if(h->left_samples_available&0x8080){ //mad cow disease mode, aka MBAFF + constrained_intra_pred + if(is_chroma && (h->left_samples_available&0x8080)){ //mad cow disease mode, aka MBAFF + constrained_intra_pred mode= ALZHEIMER_DC_L0T_PRED8x8 + (!(h->left_samples_available&0x8000)) + 2*(mode == DC_128_PRED8x8); } if(mode<0){ @@ -143,6 +140,23 @@ int ff_h264_check_intra_pred_mode(H264Context *h, int mode){ return mode; } +/** + * checks if the top & left blocks are available if needed & changes the dc mode so it only uses the available blocks. + */ +int ff_h264_check_intra16x16_pred_mode(H264Context *h, int mode) +{ + return check_intra_pred_mode(h, mode, 0); +} + +/** + * checks if the top & left blocks are available if needed & changes the dc mode so it only uses the available blocks. + */ +int ff_h264_check_intra_chroma_pred_mode(H264Context *h, int mode) +{ + return check_intra_pred_mode(h, mode, 1); +} + + const uint8_t *ff_h264_decode_nal(H264Context *h, const uint8_t *src, int *dst_length, int *consumed, int length){ int i, si, di; uint8_t *dst; @@ -1018,17 +1032,20 @@ static av_cold void common_init(H264Context *h){ memset(h->pps.scaling_matrix8, 16, 2*64*sizeof(uint8_t)); } -int ff_h264_decode_extradata(H264Context *h) +int ff_h264_decode_extradata(H264Context *h, const uint8_t *buf, int size) { AVCodecContext *avctx = h->s.avctx; - if(avctx->extradata[0] == 1){ + if(!buf || size <= 0) + return -1; + + if(buf[0] == 1){ int i, cnt, nalsize; - unsigned char *p = avctx->extradata; + const unsigned char *p = buf; h->is_avc = 1; - if(avctx->extradata_size < 7) { + if(size < 7) { av_log(avctx, AV_LOG_ERROR, "avcC too short\n"); return -1; } @@ -1040,6 +1057,8 @@ int ff_h264_decode_extradata(H264Context *h) p += 6; for (i = 0; i < cnt; i++) { nalsize = AV_RB16(p) + 2; + if(nalsize > size - (p-buf)) + return -1; if(decode_nal_units(h, p, nalsize) < 0) { av_log(avctx, AV_LOG_ERROR, "Decoding sps %d from avcC failed\n", i); return -1; @@ -1050,6 +1069,8 @@ int ff_h264_decode_extradata(H264Context *h) cnt = *(p++); // Number of pps for (i = 0; i < cnt; i++) { nalsize = AV_RB16(p) + 2; + if(nalsize > size - (p-buf)) + return -1; if (decode_nal_units(h, p, nalsize) < 0) { av_log(avctx, AV_LOG_ERROR, "Decoding pps %d from avcC failed\n", i); return -1; @@ -1057,10 +1078,10 @@ int ff_h264_decode_extradata(H264Context *h) p += nalsize; } // Now store right nal length size, that will be use to parse all other nals - h->nal_length_size = (avctx->extradata[4] & 0x03) + 1; + h->nal_length_size = (buf[4] & 0x03) + 1; } else { h->is_avc = 0; - if(decode_nal_units(h, avctx->extradata, avctx->extradata_size) < 0) + if(decode_nal_units(h, buf, size) < 0) return -1; } return 0; @@ -1104,7 +1125,7 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx){ } if(avctx->extradata_size > 0 && avctx->extradata && - ff_h264_decode_extradata(h)) + ff_h264_decode_extradata(h, avctx->extradata, avctx->extradata_size)) return -1; if(h->sps.bitstream_restriction_flag && s->avctx->has_b_frames < h->sps.num_reorder_frames){ @@ -2872,6 +2893,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ h->ref_count[1]= h->pps.ref_count[1]; if(h->slice_type_nos != AV_PICTURE_TYPE_I){ + unsigned max= (16<<(s->picture_structure != PICT_FRAME))-1; if(h->slice_type_nos == AV_PICTURE_TYPE_B){ h->direct_spatial_mv_pred= get_bits1(&s->gb); } @@ -2882,25 +2904,27 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ if(h->slice_type_nos==AV_PICTURE_TYPE_B) h->ref_count[1]= get_ue_golomb(&s->gb) + 1; - if(h->ref_count[0]-1 > 32-1 || h->ref_count[1]-1 > 32-1){ - av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow\n"); - h->ref_count[0]= h->ref_count[1]= 1; - return -1; - } + } + if(h->ref_count[0]-1 > max || h->ref_count[1]-1 > max){ + av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow\n"); + h->ref_count[0]= h->ref_count[1]= 1; + return -1; } if(h->slice_type_nos == AV_PICTURE_TYPE_B) h->list_count= 2; else h->list_count= 1; }else - h->list_count= 0; + h->ref_count[1]= h->ref_count[0]= h->list_count= 0; if(!default_ref_list_done){ ff_h264_fill_default_ref_list(h); } - if(h->slice_type_nos!=AV_PICTURE_TYPE_I && ff_h264_decode_ref_pic_list_reordering(h) < 0) + if(h->slice_type_nos!=AV_PICTURE_TYPE_I && ff_h264_decode_ref_pic_list_reordering(h) < 0) { + h->ref_count[1]= h->ref_count[0]= 0; return -1; + } if(h->slice_type_nos!=AV_PICTURE_TYPE_I){ s->last_picture_ptr= &h->ref_list[0][0]; diff --git a/libavcodec/h264.h b/libavcodec/h264.h index 76e9832975..0a380e03c1 100644 --- a/libavcodec/h264.h +++ b/libavcodec/h264.h @@ -101,7 +101,7 @@ */ #define DELAYED_PIC_REF 4 -#define QP_MAX_NUM (51 + 2*6) // The maximum supported qp +#define QP_MAX_NUM (51 + 4*6) // The maximum supported qp /* NAL unit types */ enum { @@ -584,7 +584,7 @@ typedef struct H264Context{ }H264Context; -extern const uint8_t ff_h264_chroma_qp[3][QP_MAX_NUM+1]; ///< One chroma qp table for each supported bit depth (8, 9, 10). +extern const uint8_t ff_h264_chroma_qp[5][QP_MAX_NUM+1]; ///< One chroma qp table for each possible bit depth (8-12). /** * Decode SEI @@ -658,12 +658,17 @@ int ff_h264_check_intra4x4_pred_mode(H264Context *h); /** * Check if the top & left blocks are available if needed & change the dc mode so it only uses the available blocks. */ -int ff_h264_check_intra_pred_mode(H264Context *h, int mode); +int ff_h264_check_intra16x16_pred_mode(H264Context *h, int mode); + +/** + * Check if the top & left blocks are available if needed & change the dc mode so it only uses the available blocks. + */ +int ff_h264_check_intra_chroma_pred_mode(H264Context *h, int mode); void ff_h264_write_back_intra_pred_mode(H264Context *h); void ff_h264_hl_decode_mb(H264Context *h); int ff_h264_frame_start(H264Context *h); -int ff_h264_decode_extradata(H264Context *h); +int ff_h264_decode_extradata(H264Context *h, const uint8_t *buf, int size); av_cold int ff_h264_decode_init(AVCodecContext *avctx); av_cold int ff_h264_decode_end(AVCodecContext *avctx); av_cold void ff_h264_decode_init_vlc(void); diff --git a/libavcodec/h264_cabac.c b/libavcodec/h264_cabac.c index 3975a61699..7aaecf3c2e 100644 --- a/libavcodec/h264_cabac.c +++ b/libavcodec/h264_cabac.c @@ -2003,14 +2003,14 @@ decode_intra_mb: ff_h264_write_back_intra_pred_mode(h); if( ff_h264_check_intra4x4_pred_mode(h) < 0 ) return -1; } else { - h->intra16x16_pred_mode= ff_h264_check_intra_pred_mode( h, h->intra16x16_pred_mode ); + h->intra16x16_pred_mode= ff_h264_check_intra16x16_pred_mode( h, h->intra16x16_pred_mode ); if( h->intra16x16_pred_mode < 0 ) return -1; } if(decode_chroma){ h->chroma_pred_mode_table[mb_xy] = pred_mode = decode_cabac_mb_chroma_pre_mode( h ); - pred_mode= ff_h264_check_intra_pred_mode( h, pred_mode ); + pred_mode= ff_h264_check_intra_chroma_pred_mode( h, pred_mode ); if( pred_mode < 0 ) return -1; h->chroma_pred_mode= pred_mode; } else { diff --git a/libavcodec/h264_cavlc.c b/libavcodec/h264_cavlc.c index 0ddc430661..92cae7fa93 100644 --- a/libavcodec/h264_cavlc.c +++ b/libavcodec/h264_cavlc.c @@ -735,12 +735,12 @@ decode_intra_mb: if( ff_h264_check_intra4x4_pred_mode(h) < 0) return -1; }else{ - h->intra16x16_pred_mode= ff_h264_check_intra_pred_mode(h, h->intra16x16_pred_mode); + h->intra16x16_pred_mode= ff_h264_check_intra16x16_pred_mode(h, h->intra16x16_pred_mode); if(h->intra16x16_pred_mode < 0) return -1; } if(decode_chroma){ - pred_mode= ff_h264_check_intra_pred_mode(h, get_ue_golomb_31(&s->gb)); + pred_mode= ff_h264_check_intra_chroma_pred_mode(h, get_ue_golomb_31(&s->gb)); if(pred_mode < 0) return -1; h->chroma_pred_mode= pred_mode; diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c index 080b6a93b5..d560d3f86a 100644 --- a/libavcodec/h264_parser.c +++ b/libavcodec/h264_parser.c @@ -251,7 +251,7 @@ static int h264_parse(AVCodecParserContext *s, h->got_first = 1; if (avctx->extradata_size) { h->s.avctx = avctx; - ff_h264_decode_extradata(h); + ff_h264_decode_extradata(h, avctx->extradata, avctx->extradata_size); } } diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c index 61fb12ce0c..423f54b324 100644 --- a/libavcodec/h264_ps.c +++ b/libavcodec/h264_ps.c @@ -70,7 +70,7 @@ static const AVRational pixel_aspect[17]={ QP(37,d), QP(37,d), QP(37,d), QP(38,d), QP(38,d), QP(38,d),\ QP(39,d), QP(39,d), QP(39,d), QP(39,d) -const uint8_t ff_h264_chroma_qp[3][QP_MAX_NUM+1] = { +const uint8_t ff_h264_chroma_qp[5][QP_MAX_NUM+1] = { { CHROMA_QP_TABLE_END(8) }, @@ -83,6 +83,19 @@ const uint8_t ff_h264_chroma_qp[3][QP_MAX_NUM+1] = { 6, 7, 8, 9, 10, 11, CHROMA_QP_TABLE_END(10) }, + { + 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, + 12,13,14,15, 16, 17, + CHROMA_QP_TABLE_END(11) + }, + { + 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, + 12,13,14,15, 16, 17, + 18,19,20,21, 22, 23, + CHROMA_QP_TABLE_END(12) + }, }; static const uint8_t default_scaling4[2][16]={ @@ -333,6 +346,11 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){ sps->residual_color_transform_flag = get_bits1(&s->gb); sps->bit_depth_luma = get_ue_golomb(&s->gb) + 8; sps->bit_depth_chroma = get_ue_golomb(&s->gb) + 8; + if (sps->bit_depth_luma > 12U || sps->bit_depth_chroma > 12U) { + av_log(h->s.avctx, AV_LOG_ERROR, "illegal bit depth value (%d, %d)\n", + sps->bit_depth_luma, sps->bit_depth_chroma); + goto fail; + } sps->transform_bypass = get_bits1(&s->gb); decode_scaling_matrices(h, sps, NULL, 1, sps->scaling_matrix4, sps->scaling_matrix8); }else{ @@ -365,7 +383,7 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){ } sps->ref_frame_count= get_ue_golomb_31(&s->gb); - if(sps->ref_frame_count > MAX_PICTURE_COUNT-2 || sps->ref_frame_count >= 32U){ + if(sps->ref_frame_count > MAX_PICTURE_COUNT-2 || sps->ref_frame_count > 16U){ av_log(h->s.avctx, AV_LOG_ERROR, "too many reference frames\n"); goto fail; } diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c index 83a5564e4c..063ac97955 100644 --- a/libavcodec/h264_refs.c +++ b/libavcodec/h264_refs.c @@ -301,7 +301,7 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h){ void ff_h264_fill_mbaff_ref_list(H264Context *h){ int list, i, j; - for(list=0; list<2; list++){ //FIXME try list_count + for(list=0; list<h->list_count; list++){ for(i=0; i<h->ref_count[list]; i++){ Picture *frame = &h->ref_list[list][i]; Picture *field = &h->ref_list[list][16+2*i]; diff --git a/libavcodec/j2k_dwt.c b/libavcodec/j2k_dwt.c index 9ba770ad83..ab7a1ab757 100644 --- a/libavcodec/j2k_dwt.c +++ b/libavcodec/j2k_dwt.c @@ -321,6 +321,8 @@ int ff_j2k_dwt_init(DWTContext *s, uint16_t border[2][2], int decomp_levels, int int i, j, lev = decomp_levels, maxlen, b[2][2]; + if (decomp_levels >= FF_DWT_MAX_DECLVLS) + return AVERROR_INVALIDDATA; s->ndeclevels = decomp_levels; s->type = type; diff --git a/libavcodec/j2kdec.c b/libavcodec/j2kdec.c index 73af6a73df..96b4f64098 100644 --- a/libavcodec/j2kdec.c +++ b/libavcodec/j2kdec.c @@ -961,18 +961,20 @@ static int decode_codestream(J2kDecoderContext *s) static int jp2_find_codestream(J2kDecoderContext *s) { - int32_t atom_size; + uint32_t atom_size; int found_codestream = 0, search_range = 10; // skip jpeg2k signature atom s->buf += 12; - while(!found_codestream && search_range) { + while(!found_codestream && search_range && s->buf_end - s->buf >= 8) { atom_size = AV_RB32(s->buf); if(AV_RB32(s->buf + 4) == JP2_CODESTREAM) { found_codestream = 1; s->buf += 8; } else { + if (s->buf_end - s->buf < atom_size) + return 0; s->buf += atom_size; search_range--; } @@ -1005,7 +1007,8 @@ static int decode_frame(AVCodecContext *avctx, return AVERROR(EINVAL); // check if the image is in jp2 format - if((AV_RB32(s->buf) == 12) && (AV_RB32(s->buf + 4) == JP2_SIG_TYPE) && + if(s->buf_end - s->buf >= 12 && + (AV_RB32(s->buf) == 12) && (AV_RB32(s->buf + 4) == JP2_SIG_TYPE) && (AV_RB32(s->buf + 8) == JP2_SIG_VALUE)) { if(!jp2_find_codestream(s)) { av_log(avctx, AV_LOG_ERROR, "couldn't find jpeg2k codestream atom\n"); diff --git a/libavcodec/libaacplus.c b/libavcodec/libaacplus.c new file mode 100644 index 0000000000..c8c87be549 --- /dev/null +++ b/libavcodec/libaacplus.c @@ -0,0 +1,136 @@ +/* + * Interface to libaacplus for aac+ (sbr+ps) encoding + * Copyright (c) 2010 tipok <[email protected]> + * + * This file is part of FFmpeg. + * + * 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. + * + * 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 FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * Interface to libaacplus for aac+ (sbr+ps) encoding. + */ + +#include "avcodec.h" +#include <aacplus.h> + +typedef struct aacPlusAudioContext { + aacplusEncHandle aacplus_handle; +} aacPlusAudioContext; + +static av_cold int aacPlus_encode_init(AVCodecContext *avctx) +{ + aacPlusAudioContext *s = avctx->priv_data; + aacplusEncConfiguration *aacplus_cfg; + unsigned long samples_input, max_bytes_output; + + /* number of channels */ + if (avctx->channels < 1 || avctx->channels > 2) { + av_log(avctx, AV_LOG_ERROR, "encoding %d channel(s) is not allowed\n", avctx->channels); + return -1; + } + + s->aacplus_handle = aacplusEncOpen(avctx->sample_rate, + avctx->channels, + &samples_input, &max_bytes_output); + if(!s->aacplus_handle) { + av_log(avctx, AV_LOG_ERROR, "can't open encoder\n"); + return -1; + } + + /* check aacplus version */ + aacplus_cfg = aacplusEncGetCurrentConfiguration(s->aacplus_handle); + + /* put the options in the configuration struct */ + if(avctx->profile != FF_PROFILE_AAC_LOW && avctx->profile != FF_PROFILE_UNKNOWN) { + av_log(avctx, AV_LOG_ERROR, "invalid AAC profile: %d, only LC supported\n", avctx->profile); + aacplusEncClose(s->aacplus_handle); + return -1; + } + + aacplus_cfg->bitRate = avctx->bit_rate; + aacplus_cfg->bandWidth = avctx->cutoff; + if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) { + aacplus_cfg->outputFormat = 0; //raw aac + } + aacplus_cfg->inputFormat = AACPLUS_INPUT_16BIT; + if (!aacplusEncSetConfiguration(s->aacplus_handle, aacplus_cfg)) { + av_log(avctx, AV_LOG_ERROR, "libaacplus doesn't support this output format!\n"); + return -1; + } + + avctx->frame_size = samples_input / avctx->channels; + + avctx->coded_frame= avcodec_alloc_frame(); + avctx->coded_frame->key_frame= 1; + + /* Set decoder specific info */ + avctx->extradata_size = 0; + if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) { + + unsigned char *buffer = NULL; + unsigned long decoder_specific_info_size; + + if (aacplusEncGetDecoderSpecificInfo(s->aacplus_handle, &buffer, + &decoder_specific_info_size) == 1) { + avctx->extradata = av_malloc(decoder_specific_info_size + FF_INPUT_BUFFER_PADDING_SIZE); + avctx->extradata_size = decoder_specific_info_size; + memcpy(avctx->extradata, buffer, avctx->extradata_size); + } +#undef free + free(buffer); +#define free please_use_av_free + } + return 0; +} + +static int aacPlus_encode_frame(AVCodecContext *avctx, + unsigned char *frame, int buf_size, void *data) +{ + aacPlusAudioContext *s = avctx->priv_data; + int bytes_written; + + bytes_written = aacplusEncEncode(s->aacplus_handle, + data, + avctx->frame_size * avctx->channels, + frame, + buf_size); + + return bytes_written; +} + +static av_cold int aacPlus_encode_close(AVCodecContext *avctx) +{ + aacPlusAudioContext *s = avctx->priv_data; + + av_freep(&avctx->coded_frame); + av_freep(&avctx->extradata); + + aacplusEncClose(s->aacplus_handle); + return 0; +} + +AVCodec ff_libaacplus_encoder = { + "libaacplus", + AVMEDIA_TYPE_AUDIO, + CODEC_ID_AAC, + sizeof(aacPlusAudioContext), + aacPlus_encode_init, + aacPlus_encode_frame, + aacPlus_encode_close, + .sample_fmts = (const enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE}, + .long_name = NULL_IF_CONFIG_SMALL("libaacplus AAC+ (Advanced Audio Codec with SBR+PS)"), +}; diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c index ac1b79fcc7..990badb87b 100644 --- a/libavcodec/libvpxenc.c +++ b/libavcodec/libvpxenc.c @@ -481,8 +481,8 @@ static int queue_frames(AVCodecContext *avctx, uint8_t *buf, int buf_size, break; case VPX_CODEC_STATS_PKT: { struct vpx_fixed_buf *stats = &ctx->twopass_stats; - stats->buf = av_realloc(stats->buf, - stats->sz + pkt->data.twopass_stats.sz); + stats->buf = av_realloc_f(stats->buf, 1, + stats->sz + pkt->data.twopass_stats.sz); if (!stats->buf) { av_log(avctx, AV_LOG_ERROR, "Stat buffer realloc failed\n"); return AVERROR(ENOMEM); diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c index cc5b9837f8..bf542accdf 100644 --- a/libavcodec/libx264.c +++ b/libavcodec/libx264.c @@ -70,9 +70,14 @@ static int encode_nals(AVCodecContext *ctx, uint8_t *buf, int size, /* Write the SEI as part of the first frame. */ if (x4->sei_size > 0 && nnal > 0) { + if (x4->sei_size > size) { + av_log(ctx, AV_LOG_ERROR, "Error: nal buffer is too small\n"); + return -1; + } memcpy(p, x4->sei, x4->sei_size); p += x4->sei_size; x4->sei_size = 0; + // why is x4->sei not freed? } for (i = 0; i < nnal; i++){ @@ -83,6 +88,11 @@ static int encode_nals(AVCodecContext *ctx, uint8_t *buf, int size, memcpy(x4->sei, nals[i].p_payload, nals[i].i_payload); continue; } + if (nals[i].i_payload > (size - (p - buf))) { + // return only complete nals which fit in buf + av_log(ctx, AV_LOG_ERROR, "Error: nal buffer is too small\n"); + break; + } memcpy(p, nals[i].p_payload, nals[i].i_payload); p += nals[i].i_payload; } diff --git a/libavcodec/motionpixels.c b/libavcodec/motionpixels.c index b18efa6b9c..635a7d14a1 100644 --- a/libavcodec/motionpixels.c +++ b/libavcodec/motionpixels.c @@ -52,14 +52,16 @@ typedef struct MotionPixelsContext { static av_cold int mp_decode_init(AVCodecContext *avctx) { MotionPixelsContext *mp = avctx->priv_data; + int w4 = (avctx->width + 3) & ~3; + int h4 = (avctx->height + 3) & ~3; motionpixels_tableinit(); mp->avctx = avctx; dsputil_init(&mp->dsp, avctx); - mp->changes_map = av_mallocz(avctx->width * avctx->height); + mp->changes_map = av_mallocz(avctx->width * h4); mp->offset_bits_len = av_log2(avctx->width * avctx->height) + 1; mp->vpt = av_mallocz(avctx->height * sizeof(YuvPixel)); - mp->hpt = av_mallocz(avctx->height * avctx->width / 16 * sizeof(YuvPixel)); + mp->hpt = av_mallocz(h4 * w4 / 16 * sizeof(YuvPixel)); avctx->pix_fmt = PIX_FMT_RGB555; avcodec_get_frame_defaults(&mp->frame); return 0; @@ -253,6 +255,7 @@ static int mp_decode_frame(AVCodecContext *avctx, mp->dsp.bswap_buf((uint32_t *)mp->bswapbuf, (const uint32_t *)buf, buf_size / 4); if (buf_size & 3) memcpy(mp->bswapbuf + (buf_size & ~3), buf + (buf_size & ~3), buf_size & 3); + memset(mp->bswapbuf + buf_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); init_get_bits(&gb, mp->bswapbuf, buf_size * 8); memset(mp->changes_map, 0, avctx->width * avctx->height); @@ -279,6 +282,8 @@ static int mp_decode_frame(AVCodecContext *avctx, if (sz == 0) goto end; + if (mp->max_codes_bits <= 0) + goto end; if (init_vlc(&mp->vlc, mp->max_codes_bits, mp->codes_count, &mp->codes[0].size, sizeof(HuffCode), 1, &mp->codes[0].code, sizeof(HuffCode), 4, 0)) goto end; mp_decode_frame_helper(mp, &gb); diff --git a/libavcodec/mpc8.c b/libavcodec/mpc8.c index 2864b1a010..bca57451ca 100644 --- a/libavcodec/mpc8.c +++ b/libavcodec/mpc8.c @@ -127,6 +127,8 @@ static av_cold int mpc8_decode_init(AVCodecContext * avctx) skip_bits(&gb, 3);//sample rate c->maxbands = get_bits(&gb, 5) + 1; + if (c->maxbands >= BANDS) + return AVERROR_INVALIDDATA; channels = get_bits(&gb, 4) + 1; if (channels > 2) { av_log_missing_feature(avctx, "Multichannel MPC SV8", 1); @@ -260,6 +262,8 @@ static int mpc8_decode_frame(AVCodecContext * avctx, maxband = c->last_max_band + get_vlc2(gb, band_vlc.table, MPC8_BANDS_BITS, 2); if(maxband > 32) maxband -= 33; } + if(maxband > c->maxbands) + return AVERROR_INVALIDDATA; c->last_max_band = maxband; /* read subband indexes */ diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index 458ac19980..f4743c5000 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -366,8 +366,8 @@ static int init_duplicate_context(MpegEncContext *s, MpegEncContext *base){ int i; // edge emu needs blocksize + filter length - 1 (=17x17 for halfpel / 21x21 for h264) - FF_ALLOCZ_OR_GOTO(s->avctx, s->allocated_edge_emu_buffer, (s->width+64)*2*21*2, fail); //(width + edge + align)*interlaced*MBsize*tolerance - s->edge_emu_buffer= s->allocated_edge_emu_buffer + (s->width+64)*2*21; + FF_ALLOCZ_OR_GOTO(s->avctx, s->allocated_edge_emu_buffer, (s->width+64)*2*21*2*2, fail); //(width + edge + align)*interlaced*MBsize*tolerance + s->edge_emu_buffer= s->allocated_edge_emu_buffer + (s->width+64)*2*21*2; //FIXME should be linesize instead of s->width*2 but that is not known before get_buffer() FF_ALLOCZ_OR_GOTO(s->avctx, s->me.scratchpad, (s->width+64)*4*16*2*sizeof(uint8_t), fail) diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h index 57cc59c6e1..3d0d8b0e0b 100644 --- a/libavcodec/mpegvideo.h +++ b/libavcodec/mpegvideo.h @@ -123,7 +123,7 @@ typedef struct Picture{ int pic_id; /**< h264 pic_num (short -> no wrap version of pic_num, pic_num & max_pic_num; long -> long_pic_num) */ int long_ref; ///< 1->long term reference 0->short term reference - int ref_poc[2][2][16]; ///< h264 POCs of the frames used as reference (FIXME need per slice) + int ref_poc[2][2][32]; ///< h264 POCs of the frames/fields used as reference (FIXME need per slice) int ref_count[2][2]; ///< number of entries in ref_poc (FIXME need per slice) int mbaff; ///< h264 1 -> MBAFF frame 0-> not MBAFF int field_picture; ///< whether or not the picture was encoded in seperate fields diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index a6e9c7c7be..3c92aa93f4 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -411,9 +411,10 @@ av_cold int MPV_encode_init(AVCodecContext *avctx) if ((s->codec_id == CODEC_ID_MPEG4 || s->codec_id == CODEC_ID_H263 || s->codec_id == CODEC_ID_H263P) && (avctx->sample_aspect_ratio.num > 255 || avctx->sample_aspect_ratio.den > 255)) { - av_log(avctx, AV_LOG_ERROR, "Invalid pixel aspect ratio %i/%i, limit is 255/255\n", + av_log(avctx, AV_LOG_WARNING, "Invalid pixel aspect ratio %i/%i, limit is 255/255 reducing\n", avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den); - return -1; + av_reduce(&avctx->sample_aspect_ratio.num, &avctx->sample_aspect_ratio.den, + avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den, 255); } if((s->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME|CODEC_FLAG_ALT_SCAN)) diff --git a/libavcodec/ppc/asm.S b/libavcodec/ppc/asm.S index 2706d6b1d8..bbbf8a4a66 100644 --- a/libavcodec/ppc/asm.S +++ b/libavcodec/ppc/asm.S @@ -44,10 +44,13 @@ X(\name): L(\name): .endm -.macro movrel rd, sym +.macro movrel rd, sym, gp ld \rd, \sym@got(r2) .endm +.macro get_got rd +.endm + #else /* ARCH_PPC64 */ #define PTR .int @@ -65,19 +68,25 @@ X(\name): \name: .endm -.macro movrel rd, sym +.macro movrel rd, sym, gp #if CONFIG_PIC - bcl 20, 31, lab_pic_\@ -lab_pic_\@: - mflr \rd - addis \rd, \rd, (\sym - lab_pic_\@)@ha - addi \rd, \rd, (\sym - lab_pic_\@)@l + lwz \rd, \sym@got(\gp) #else lis \rd, \sym@ha la \rd, \sym@l(\rd) #endif .endm +.macro get_got rd +#if CONFIG_PIC + bcl 20, 31, .Lgot\@ +.Lgot\@: + mflr \rd + addis \rd, \rd, _GLOBAL_OFFSET_TABLE_ - .Lgot\@@ha + addi \rd, \rd, _GLOBAL_OFFSET_TABLE_ - .Lgot\@@l +#endif +.endm + #endif /* ARCH_PPC64 */ #if HAVE_IBM_ASM diff --git a/libavcodec/ppc/fft_altivec_s.S b/libavcodec/ppc/fft_altivec_s.S index 5d3c5406c3..16ce838c97 100644 --- a/libavcodec/ppc/fft_altivec_s.S +++ b/libavcodec/ppc/fft_altivec_s.S @@ -353,6 +353,7 @@ extfunc ff_fft_calc\interleave\()_altivec mflr r0 stp r0, 2*PS(r1) stpu r1, -(160+16*PS)(r1) + get_got r11 addi r6, r1, 16*PS stvm r6, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29 mfvrsave r0 @@ -360,14 +361,14 @@ extfunc ff_fft_calc\interleave\()_altivec li r6, 0xfffffffc mtvrsave r6 - movrel r6, fft_data + movrel r6, fft_data, r11 lvm r6, v14, v15, v16, v17, v18, v19, v20, v21 lvm r6, v22, v23, v24, v25, v26, v27, v28, v29 li r9, 16 - movrel r12, X(ff_cos_tabs) + movrel r12, X(ff_cos_tabs), r11 - movrel r6, fft_dispatch_tab\interleave\()_altivec + movrel r6, fft_dispatch_tab\interleave\()_altivec, r11 lwz r3, 0(r3) subi r3, r3, 2 slwi r3, r3, 2+ARCH_PPC64 diff --git a/libavcodec/ptx.c b/libavcodec/ptx.c index 3273fd2f8e..756dbcd58b 100644 --- a/libavcodec/ptx.c +++ b/libavcodec/ptx.c @@ -39,12 +39,15 @@ static av_cold int ptx_init(AVCodecContext *avctx) { static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; + const uint8_t *buf_end = avpkt->data + avpkt->size; PTXContext * const s = avctx->priv_data; AVFrame *picture = data; AVFrame * const p = &s->picture; unsigned int offset, w, h, y, stride, bytes_per_pixel; uint8_t *ptr; + if (buf_end - buf < 14) + return AVERROR_INVALIDDATA; offset = AV_RL16(buf); w = AV_RL16(buf+8); h = AV_RL16(buf+10); @@ -57,6 +60,9 @@ static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, avctx->pix_fmt = PIX_FMT_RGB555; + + if (buf_end - buf < offset) + return AVERROR_INVALIDDATA; if (offset != 0x2c) av_log_ask_for_sample(avctx, "offset != 0x2c\n"); @@ -80,6 +86,8 @@ static int ptx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, stride = p->linesize[0]; for (y=0; y<h; y++) { + if (buf_end - buf < w * bytes_per_pixel) + break; #if HAVE_BIGENDIAN unsigned int x; for (x=0; x<w*bytes_per_pixel; x+=bytes_per_pixel) diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c index 6eb836456c..1665c8daed 100644 --- a/libavcodec/qdm2.c +++ b/libavcodec/qdm2.c @@ -1353,6 +1353,8 @@ static void qdm2_fft_decode_tones (QDM2Context *q, int duration, GetBitContext * return; local_int_14 = (offset >> local_int_8); + if (local_int_14 >= FF_ARRAY_ELEMS(fft_level_index_table)) + return; if (q->nb_channels > 1) { channel = get_bits1(gb); @@ -1797,6 +1799,8 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx) avctx->channels = s->nb_channels = s->channels = AV_RB32(extradata); extradata += 4; + if (s->channels > MPA_MAX_CHANNELS) + return AVERROR_INVALIDDATA; avctx->sample_rate = AV_RB32(extradata); extradata += 4; @@ -1818,6 +1822,8 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx) // something like max decodable tones s->group_order = av_log2(s->group_size) + 1; s->frame_size = s->group_size / 16; // 16 iterations per super block + if (s->frame_size > FF_ARRAY_ELEMS(s->output_buffer) / 2) + return AVERROR_INVALIDDATA; s->sub_sampling = s->fft_order - 7; s->frequency_range = 255 / (1 << (2 - s->sub_sampling)); diff --git a/libavcodec/qdrw.c b/libavcodec/qdrw.c index cd3146388e..6432728cb8 100644 --- a/libavcodec/qdrw.c +++ b/libavcodec/qdrw.c @@ -37,6 +37,7 @@ static int decode_frame(AVCodecContext *avctx, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; + const uint8_t *buf_end = avpkt->data + avpkt->size; int buf_size = avpkt->size; QdrawContext * const a = avctx->priv_data; AVFrame * const p= (AVFrame*)&a->pic; @@ -59,6 +60,8 @@ static int decode_frame(AVCodecContext *avctx, outdata = a->pic.data[0]; + if (buf_end - buf < 0x68 + 4) + return AVERROR_INVALIDDATA; buf += 0x68; /* jump to palette */ colors = AV_RB32(buf); buf += 4; @@ -67,6 +70,8 @@ static int decode_frame(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "Error color count - %i(0x%X)\n", colors, colors); return -1; } + if (buf_end - buf < (colors + 1) * 8) + return AVERROR_INVALIDDATA; pal = (uint32_t*)p->data[1]; for (i = 0; i <= colors; i++) { @@ -89,6 +94,8 @@ static int decode_frame(AVCodecContext *avctx, } p->palette_has_changed = 1; + if (buf_end - buf < 18) + return AVERROR_INVALIDDATA; buf += 18; /* skip unneeded data */ for (i = 0; i < avctx->height; i++) { int size, left, code, pix; @@ -100,6 +107,9 @@ static int decode_frame(AVCodecContext *avctx, out = outdata; size = AV_RB16(buf); /* size of packed line */ buf += 2; + if (buf_end - buf < size) + return AVERROR_INVALIDDATA; + left = size; next = buf + size; while (left > 0) { @@ -115,6 +125,8 @@ static int decode_frame(AVCodecContext *avctx, } else { /* copy */ if ((out + code) > (outdata + a->pic.linesize[0])) break; + if (buf_end - buf < code + 1) + return AVERROR_INVALIDDATA; memcpy(out, buf, code + 1); out += code + 1; buf += code + 1; diff --git a/libavcodec/shorten.c b/libavcodec/shorten.c index f593d0a164..4c1abe8e4c 100644 --- a/libavcodec/shorten.c +++ b/libavcodec/shorten.c @@ -155,7 +155,7 @@ static void fix_bitshift(ShortenContext *s, int32_t *buffer) if (s->bitshift != 0) for (i = 0; i < s->blocksize; i++) - buffer[s->nwrap + i] <<= s->bitshift; + buffer[i] <<= s->bitshift; } @@ -483,9 +483,15 @@ static int shorten_decode_frame(AVCodecContext *avctx, case FN_BITSHIFT: s->bitshift = get_ur_golomb_shorten(&s->gb, BITSHIFTSIZE); break; - case FN_BLOCKSIZE: - s->blocksize = get_uint(s, av_log2(s->blocksize)); + case FN_BLOCKSIZE: { + int blocksize = get_uint(s, av_log2(s->blocksize)); + if (blocksize > s->blocksize) { + av_log(avctx, AV_LOG_ERROR, "Increasing block size is not supported\n"); + return AVERROR_PATCHWELCOME; + } + s->blocksize = blocksize; break; + } case FN_QUIT: *data_size = 0; return buf_size; diff --git a/libavcodec/sunrast.c b/libavcodec/sunrast.c index 558b0edd8f..209d2c0ad3 100644 --- a/libavcodec/sunrast.c +++ b/libavcodec/sunrast.c @@ -46,6 +46,7 @@ static av_cold int sunrast_init(AVCodecContext *avctx) { static int sunrast_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; + const uint8_t *buf_end = avpkt->data + avpkt->size; SUNRASTContext * const s = avctx->priv_data; AVFrame *picture = data; AVFrame * const p = &s->picture; @@ -53,6 +54,9 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data, uint8_t *ptr; const uint8_t *bufstart = buf; + if (avpkt->size < 32) + return AVERROR_INVALIDDATA; + if (AV_RB32(buf) != 0x59a66a95) { av_log(avctx, AV_LOG_ERROR, "this is not sunras encoded data\n"); return -1; @@ -64,13 +68,14 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data, type = AV_RB32(buf+20); maptype = AV_RB32(buf+24); maplength = AV_RB32(buf+28); + buf += 32; - if (type == RT_FORMAT_TIFF || type == RT_FORMAT_IFF) { - av_log(avctx, AV_LOG_ERROR, "unsupported (compression) type\n"); + if (type < RT_OLD || type > RT_FORMAT_IFF) { + av_log(avctx, AV_LOG_ERROR, "invalid (compression) type\n"); return -1; } - if (type > RT_FORMAT_IFF) { - av_log(avctx, AV_LOG_ERROR, "invalid (compression) type\n"); + if (av_image_check_size(w, h, 0, avctx)) { + av_log(avctx, AV_LOG_ERROR, "invalid image size\n"); return -1; } if (maptype & ~1) { @@ -78,7 +83,10 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data, return -1; } - buf += 32; + if (type == RT_FORMAT_TIFF || type == RT_FORMAT_IFF) { + av_log(avctx, AV_LOG_ERROR, "unsupported (compression) type\n"); + return -1; + } switch (depth) { case 1: @@ -98,8 +106,6 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data, if (p->data[0]) avctx->release_buffer(avctx, p); - if (av_image_check_size(w, h, 0, avctx)) - return -1; if (w != avctx->width || h != avctx->height) avcodec_set_dimensions(avctx, w, h); if (avctx->get_buffer(avctx, p) < 0) { @@ -109,6 +115,9 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data, p->pict_type = AV_PICTURE_TYPE_I; + if (buf_end - buf < maplength) + return AVERROR_INVALIDDATA; + if (depth != 8 && maplength) { av_log(avctx, AV_LOG_WARNING, "useless colormap found or file is corrupted, trying to recover\n"); @@ -143,8 +152,11 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data, uint8_t *end = ptr + h*stride; x = 0; - while (ptr != end) { + while (ptr != end && buf < buf_end) { run = 1; + if (buf_end - buf < 1) + return AVERROR_INVALIDDATA; + if ((value = *buf++) == 0x80) { run = *buf++ + 1; if (run != 1) @@ -163,6 +175,8 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data, } } else { for (y=0; y<h; y++) { + if (buf_end - buf < len) + break; memcpy(ptr, buf, len); ptr += stride; buf += alen; diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c index e7839be8b5..92d84b0f82 100644 --- a/libavcodec/svq3.c +++ b/libavcodec/svq3.c @@ -612,7 +612,7 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type) dir = i_mb_type_info[mb_type - 8].pred_mode; dir = (dir >> 1) ^ 3*(dir & 1) ^ 1; - if ((h->intra16x16_pred_mode = ff_h264_check_intra_pred_mode(h, dir)) == -1){ + if ((h->intra16x16_pred_mode = ff_h264_check_intra16x16_pred_mode(h, dir)) == -1){ av_log(h->s.avctx, AV_LOG_ERROR, "check_intra_pred_mode = -1\n"); return -1; } @@ -711,7 +711,7 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type) s->current_picture.mb_type[mb_xy] = mb_type; if (IS_INTRA(mb_type)) { - h->chroma_pred_mode = ff_h264_check_intra_pred_mode(h, DC_PRED8x8); + h->chroma_pred_mode = ff_h264_check_intra_chroma_pred_mode(h, DC_PRED8x8); } return 0; diff --git a/libavcodec/tiertexseqv.c b/libavcodec/tiertexseqv.c index f3a044882e..160da8c630 100644 --- a/libavcodec/tiertexseqv.c +++ b/libavcodec/tiertexseqv.c @@ -35,15 +35,19 @@ typedef struct SeqVideoContext { } SeqVideoContext; -static const unsigned char *seq_unpack_rle_block(const unsigned char *src, unsigned char *dst, int dst_size) +static const unsigned char *seq_unpack_rle_block(const unsigned char *src, + const unsigned char *src_end, + unsigned char *dst, int dst_size) { int i, len, sz; GetBitContext gb; int code_table[64]; - /* get the rle codes (at most 64 bytes) */ - init_get_bits(&gb, src, 64 * 8); + /* get the rle codes */ + init_get_bits(&gb, src, (src_end - src) * 8); for (i = 0, sz = 0; i < 64 && sz < dst_size; i++) { + if (get_bits_left(&gb) < 4) + return NULL; code_table[i] = get_sbits(&gb, 4); sz += FFABS(code_table[i]); } @@ -54,8 +58,12 @@ static const unsigned char *seq_unpack_rle_block(const unsigned char *src, unsig len = code_table[i]; if (len < 0) { len = -len; + if (src_end - src < 1) + return NULL; memset(dst, *src++, FFMIN(len, dst_size)); } else { + if (src_end - src < len) + return NULL; memcpy(dst, src, FFMIN(len, dst_size)); src += len; } @@ -65,25 +73,30 @@ static const unsigned char *seq_unpack_rle_block(const unsigned char *src, unsig return src; } -static const unsigned char *seq_decode_op1(SeqVideoContext *seq, const unsigned char *src, unsigned char *dst) +static const unsigned char *seq_decode_op1(SeqVideoContext *seq, + const unsigned char *src, + const unsigned char *src_end, + unsigned char *dst) { const unsigned char *color_table; int b, i, len, bits; GetBitContext gb; unsigned char block[8 * 8]; + if (src_end - src < 1) + return NULL; len = *src++; if (len & 0x80) { switch (len & 3) { case 1: - src = seq_unpack_rle_block(src, block, sizeof(block)); + src = seq_unpack_rle_block(src, src_end, block, sizeof(block)); for (b = 0; b < 8; b++) { memcpy(dst, &block[b * 8], 8); dst += seq->frame.linesize[0]; } break; case 2: - src = seq_unpack_rle_block(src, block, sizeof(block)); + src = seq_unpack_rle_block(src, src_end, block, sizeof(block)); for (i = 0; i < 8; i++) { for (b = 0; b < 8; b++) dst[b * seq->frame.linesize[0]] = block[i * 8 + b]; @@ -92,9 +105,13 @@ static const unsigned char *seq_decode_op1(SeqVideoContext *seq, const unsigned break; } } else { + if (len <= 0) + return NULL; + bits = ff_log2_tab[len - 1] + 1; + if (src_end - src < len + 8 * bits) + return NULL; color_table = src; src += len; - bits = ff_log2_tab[len - 1] + 1; init_get_bits(&gb, src, bits * 8 * 8); src += bits * 8; for (b = 0; b < 8; b++) { for (i = 0; i < 8; i++) @@ -106,10 +123,16 @@ static const unsigned char *seq_decode_op1(SeqVideoContext *seq, const unsigned return src; } -static const unsigned char *seq_decode_op2(SeqVideoContext *seq, const unsigned char *src, unsigned char *dst) +static const unsigned char *seq_decode_op2(SeqVideoContext *seq, + const unsigned char *src, + const unsigned char *src_end, + unsigned char *dst) { int i; + if (src_end - src < 8 * 8) + return NULL; + for (i = 0; i < 8; i++) { memcpy(dst, src, 8); src += 8; @@ -119,11 +142,16 @@ static const unsigned char *seq_decode_op2(SeqVideoContext *seq, const unsigned return src; } -static const unsigned char *seq_decode_op3(SeqVideoContext *seq, const unsigned char *src, unsigned char *dst) +static const unsigned char *seq_decode_op3(SeqVideoContext *seq, + const unsigned char *src, + const unsigned char *src_end, + unsigned char *dst) { int pos, offset; do { + if (src_end - src < 2) + return NULL; pos = *src++; offset = ((pos >> 3) & 7) * seq->frame.linesize[0] + (pos & 7); dst[offset] = *src++; @@ -132,8 +160,9 @@ static const unsigned char *seq_decode_op3(SeqVideoContext *seq, const unsigned return src; } -static void seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int data_size) +static int seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int data_size) { + const unsigned char *data_end = data + data_size; GetBitContext gb; int flags, i, j, x, y, op; unsigned char c[3]; @@ -144,6 +173,8 @@ static void seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int if (flags & 1) { palette = (uint32_t *)seq->frame.data[1]; + if (data_end - data < 256 * 3) + return AVERROR_INVALIDDATA; for (i = 0; i < 256; i++) { for (j = 0; j < 3; j++, data++) c[j] = (*data << 2) | (*data >> 4); @@ -153,6 +184,8 @@ static void seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int } if (flags & 2) { + if (data_end - data < 128) + return AVERROR_INVALIDDATA; init_get_bits(&gb, data, 128 * 8); data += 128; for (y = 0; y < 128; y += 8) for (x = 0; x < 256; x += 8) { @@ -160,17 +193,20 @@ static void seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int op = get_bits(&gb, 2); switch (op) { case 1: - data = seq_decode_op1(seq, data, dst); + data = seq_decode_op1(seq, data, data_end, dst); break; case 2: - data = seq_decode_op2(seq, data, dst); + data = seq_decode_op2(seq, data, data_end, dst); break; case 3: - data = seq_decode_op3(seq, data, dst); + data = seq_decode_op3(seq, data, data_end, dst); break; } + if (!data) + return AVERROR_INVALIDDATA; } } + return 0; } static av_cold int seqvideo_decode_init(AVCodecContext *avctx) @@ -202,7 +238,8 @@ static int seqvideo_decode_frame(AVCodecContext *avctx, return -1; } - seqvideo_decode(seq, buf, buf_size); + if (seqvideo_decode(seq, buf, buf_size)) + return AVERROR_INVALIDDATA; *data_size = sizeof(AVFrame); *(AVFrame *)data = seq->frame; diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index c54eaee346..ed01b70147 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -170,6 +170,8 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, const uin } switch(s->compr){ case TIFF_RAW: + if (ssrc + size - src < width) + return AVERROR_INVALIDDATA; if (!s->fill_order) { memcpy(dst, src, width); } else { @@ -277,6 +279,8 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t * uint32_t *pal; const uint8_t *rp, *gp, *bp; + if (end_buf - buf < 12) + return -1; tag = tget_short(&buf, s->le); type = tget_short(&buf, s->le); count = tget_long(&buf, s->le); @@ -336,7 +340,7 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t * case TIFF_SHORT: case TIFF_LONG: s->bpp = 0; - for(i = 0; i < count; i++) s->bpp += tget(&buf, type, s->le); + for(i = 0; i < count && buf < end_buf; i++) s->bpp += tget(&buf, type, s->le); break; default: s->bpp = -1; @@ -450,6 +454,8 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t * case TIFF_PAL: pal = (uint32_t *) s->palette; off = type_sizes[type]; + if (count / 3 > 256 || end_buf - buf < count / 3 * off * 3) + return -1; rp = buf; gp = buf + count / 3 * off; bp = buf + count / 3 * off * 2; @@ -493,12 +499,16 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture = data; AVFrame * const p= (AVFrame*)&s->picture; const uint8_t *orig_buf = buf, *end_buf = buf + buf_size; - int id, le, off, ret; + unsigned off; + int id, le, ret; int i, j, entries; - int stride, soff, ssize; + int stride; + unsigned soff, ssize; uint8_t *dst; //parse image header + if (end_buf - buf < 8) + return AVERROR_INVALIDDATA; id = AV_RL16(buf); buf += 2; if(id == 0x4949) le = 1; else if(id == 0x4D4D) le = 0; @@ -518,9 +528,9 @@ static int decode_frame(AVCodecContext *avctx, } /* parse image file directory */ off = tget_long(&buf, le); - if(orig_buf + off + 14 >= end_buf){ + if (off >= UINT_MAX - 14 || end_buf - orig_buf < off + 14) { av_log(avctx, AV_LOG_ERROR, "IFD offset is greater than image size\n"); - return -1; + return AVERROR_INVALIDDATA; } buf = orig_buf + off; entries = tget_short(&buf, le); @@ -544,23 +554,23 @@ static int decode_frame(AVCodecContext *avctx, stride = p->linesize[0]; dst = p->data[0]; for(i = 0; i < s->height; i += s->rps){ - if(s->stripsizes) + if(s->stripsizes) { + if (s->stripsizes >= end_buf) + return AVERROR_INVALIDDATA; ssize = tget(&s->stripsizes, s->sstype, s->le); - else + } else ssize = s->stripsize; - if (ssize > buf_size) { - av_log(avctx, AV_LOG_ERROR, "Buffer size is smaller than strip size\n"); - return -1; - } - if(s->stripdata){ + if (s->stripdata >= end_buf) + return AVERROR_INVALIDDATA; soff = tget(&s->stripdata, s->sot, s->le); }else soff = s->stripoff; - if (soff < 0) { - av_log(avctx, AV_LOG_ERROR, "Invalid stripoff: %d\n", soff); - return AVERROR(EINVAL); + + if (soff > buf_size || ssize > buf_size - soff) { + av_log(avctx, AV_LOG_ERROR, "Invalid strip size/offset\n"); + return -1; } if(tiff_unpack_strip(s, dst, stride, orig_buf + soff, ssize, FFMIN(s->rps, s->height - i)) < 0) break; diff --git a/libavcodec/tiffenc.c b/libavcodec/tiffenc.c index f7228f128f..97e1dd38c4 100644 --- a/libavcodec/tiffenc.c +++ b/libavcodec/tiffenc.c @@ -42,6 +42,7 @@ static const uint8_t type_sizes2[6] = { }; typedef struct TiffEncoderContext { + AVClass *avclass; AVCodecContext *avctx; AVFrame picture; @@ -216,6 +217,7 @@ static int encode_frame(AVCodecContext * avctx, unsigned char *buf, uint8_t *yuv_line = NULL; int shift_h, shift_v; + s->avctx = avctx; s->buf_start = buf; s->buf = &ptr; s->buf_size = buf_size; diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 5520ede336..7247932248 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -829,6 +829,11 @@ int attribute_align_arg avcodec_decode_audio3(AVCodecContext *avctx, int16_t *sa avctx->pkt = avpkt; + if (!avpkt->data && avpkt->size) { + av_log(avctx, AV_LOG_ERROR, "invalid packet: NULL data, size != 0\n"); + return AVERROR(EINVAL); + } + if((avctx->codec->capabilities & CODEC_CAP_DELAY) || avpkt->size){ //FIXME remove the check below _after_ ensuring that all audio check that the available space is enough if(*frame_size_ptr < AVCODEC_MAX_AUDIO_FRAME_SIZE){ diff --git a/libavcodec/vmdav.c b/libavcodec/vmdav.c index b9acfe921c..1f9694ea29 100644 --- a/libavcodec/vmdav.c +++ b/libavcodec/vmdav.c @@ -72,9 +72,11 @@ typedef struct VmdVideoContext { #define QUEUE_SIZE 0x1000 #define QUEUE_MASK 0x0FFF -static void lz_unpack(const unsigned char *src, unsigned char *dest, int dest_len) +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,8 +89,12 @@ static void lz_unpack(const unsigned char *src, unsigned char *dest, int dest_le unsigned int i, j; s = src; + s_end = src + src_len; d = dest; d_end = d + dest_len; + + if (s_end - s < 8) + return; dataleft = AV_RL32(s); s += 4; memset(queue, 0x20, QUEUE_SIZE); @@ -101,10 +107,10 @@ static void lz_unpack(const unsigned char *src, unsigned char *dest, int dest_le speclen = 100; /* no speclen */ } - while (dataleft > 0) { + while (s_end - s > 0 && dataleft > 0) { tag = *s++; if ((tag == 0xFF) && (dataleft > 8)) { - if (d + 8 > d_end) + if (d_end - d < 8 || s_end - s < 8) return; for (i = 0; i < 8; i++) { queue[qpos++] = *d++ = *s++; @@ -116,18 +122,23 @@ static void lz_unpack(const unsigned char *src, unsigned char *dest, int dest_le if (dataleft == 0) break; if (tag & 0x01) { - if (d + 1 > d_end) + if (d_end - d < 1 || s_end - s < 1) return; queue[qpos++] = *d++ = *s++; qpos &= QUEUE_MASK; dataleft--; } else { + if (s_end - s < 2) + return; chainofs = *s++; chainofs |= ((*s & 0xF0) << 4); chainlen = (*s++ & 0x0F) + 3; - if (chainlen == speclen) + if (chainlen == speclen) { + if (s_end - s < 1) + return; chainlen = *s++ + 0xF + 3; - if (d + chainlen > d_end) + } + if (d_end - d < chainlen) return; for (j = 0; j < chainlen; j++) { *d = queue[chainofs++ & QUEUE_MASK]; @@ -142,32 +153,39 @@ static void lz_unpack(const unsigned char *src, unsigned char *dest, int dest_le } } -static int rle_unpack(const unsigned char *src, unsigned char *dest, - int src_len, int dest_len) +static int rle_unpack(const unsigned char *src, int src_len, int src_count, + unsigned char *dest, 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; ps = src; + ps_end = src + src_len; pd = dest; - if (src_len & 1) + if (src_count & 1) { + if (ps_end - ps < 1) + return 0; *pd++ = *ps++; + } - src_len >>= 1; + src_count >>= 1; i = 0; do { + if (ps_end - ps < 1) + break; l = *ps++; if (l & 0x80) { l = (l & 0x7F) * 2; - if (pd + l > dest_end) + if (dest_end - pd < l || ps_end - ps < l) return ps - src; memcpy(pd, ps, l); ps += l; pd += l; } else { - if (pd + i > dest_end) + if (dest_end - pd < i || ps_end - ps < 2) return ps - src; for (i = 0; i < l; i++) { *pd++ = ps[0]; @@ -176,7 +194,7 @@ static int rle_unpack(const unsigned char *src, unsigned char *dest, ps += 2; } i += l; - } while (i < src_len); + } while (i < src_count); return ps - src; } @@ -189,8 +207,10 @@ static void vmd_decode(VmdVideoContext *s) /* point to the start of the encoded data */ const unsigned char *p = s->buf + 16; + const unsigned char *p_end = s->buf + s->size; 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 */ @@ -204,6 +224,16 @@ static void vmd_decode(VmdVideoContext *s) frame_y = AV_RL16(&s->buf[8]); frame_width = AV_RL16(&s->buf[10]) - frame_x + 1; frame_height = AV_RL16(&s->buf[12]) - frame_y + 1; + if (frame_x < 0 || frame_width < 0 || + frame_x >= s->avctx->width || + frame_width > s->avctx->width || + frame_x + frame_width > s->avctx->width) + return; + if (frame_y < 0 || frame_height < 0 || + frame_y >= s->avctx->height || + frame_height > s->avctx->height || + frame_y + frame_height > s->avctx->height) + return; if ((frame_width == s->avctx->width && frame_height == s->avctx->height) && (frame_x || frame_y)) { @@ -216,8 +246,9 @@ static void vmd_decode(VmdVideoContext *s) /* if only a certain region will be updated, copy the entire previous * frame before the decode */ - if (frame_x || frame_y || (frame_width != s->avctx->width) || - (frame_height != s->avctx->height)) { + if (s->prev_frame.data[0] && + (frame_x || frame_y || (frame_width != s->avctx->width) || + (frame_height != s->avctx->height))) { memcpy(s->frame.data[0], s->prev_frame.data[0], s->avctx->height * s->frame.linesize[0]); @@ -225,6 +256,8 @@ static void vmd_decode(VmdVideoContext *s) /* check if there is a new palette */ if (s->buf[15] & 0x02) { + if (p_end - p < 2 + 3 * PALETTE_COUNT) + return; p += 2; palette32 = (unsigned int *)s->palette; for (i = 0; i < PALETTE_COUNT; i++) { @@ -233,16 +266,17 @@ static void vmd_decode(VmdVideoContext *s) b = *p++ * 4; palette32[i] = (r << 16) | (g << 8) | (b); } - s->size -= (256 * 3 + 2); } - if (s->size >= 0) { + if (p < p_end) { /* originally UnpackFrame in VAG's code */ pb = p; + pb_end = p_end; meth = *pb++; if (meth & 0x80) { - lz_unpack(pb, s->unpack_buffer, s->unpack_buffer_size); + lz_unpack(pb, p_end - pb, s->unpack_buffer, s->unpack_buffer_size); meth &= 0x7F; pb = s->unpack_buffer; + pb_end = s->unpack_buffer + s->unpack_buffer_size; } dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x]; @@ -252,17 +286,19 @@ static void vmd_decode(VmdVideoContext *s) for (i = 0; i < frame_height; i++) { ofs = 0; do { + if (pb_end - pb < 1) + return; len = *pb++; if (len & 0x80) { len = (len & 0x7F) + 1; - if (ofs + len > frame_width) + if (ofs + len > frame_width || pb_end - pb < len) return; memcpy(&dp[ofs], pb, len); pb += len; ofs += len; } else { /* interframe pixel copy */ - if (ofs + len + 1 > frame_width) + if (ofs + len + 1 > frame_width || !s->prev_frame.data[0]) return; memcpy(&dp[ofs], &pp[ofs], len + 1); ofs += len + 1; @@ -280,6 +316,8 @@ 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; dp += s->frame.linesize[0]; @@ -291,18 +329,25 @@ static void vmd_decode(VmdVideoContext *s) for (i = 0; i < frame_height; i++) { ofs = 0; do { + if (pb_end - pb < 1) + return; len = *pb++; if (len & 0x80) { len = (len & 0x7F) + 1; + if (pb_end - pb < 1) + return; if (*pb++ == 0xFF) - len = rle_unpack(pb, &dp[ofs], len, frame_width - ofs); - else + 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; } else { /* interframe pixel copy */ - if (ofs + len + 1 > frame_width) + if (ofs + len + 1 > frame_width || !s->prev_frame.data[0]) return; memcpy(&dp[ofs], &pp[ofs], len + 1); ofs += len + 1; @@ -523,7 +568,10 @@ static int vmdaudio_decode_frame(AVCodecContext *avctx, silent_chunks = 0; if (block_type == BLOCK_TYPE_INITIAL) { - uint32_t flags = AV_RB32(buf); + uint32_t flags; + if (buf_size < 4) + return -1; + flags = AV_RB32(buf); silent_chunks = av_popcount(flags); buf += 4; buf_size -= 4; diff --git a/libavcodec/vp56.c b/libavcodec/vp56.c index 30f3efbc46..5b787b6135 100644 --- a/libavcodec/vp56.c +++ b/libavcodec/vp56.c @@ -465,6 +465,7 @@ static int vp56_size_changed(AVCodecContext *avctx) s->mb_height = (avctx->coded_height+15) / 16; if (s->mb_width > 1000 || s->mb_height > 1000) { + avcodec_set_dimensions(avctx, 0, 0); av_log(avctx, AV_LOG_ERROR, "picture too big\n"); return -1; } @@ -519,8 +520,10 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size, if (s->frames[i].data[0]) avctx->release_buffer(avctx, &s->frames[i]); } - if (is_alpha) + if (is_alpha) { + avcodec_set_dimensions(avctx, 0, 0); return -1; + } } if (!is_alpha) { diff --git a/libavcodec/vp6.c b/libavcodec/vp6.c index d05a3618f7..3721d52192 100644 --- a/libavcodec/vp6.c +++ b/libavcodec/vp6.c @@ -137,8 +137,11 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size, if (coeff_offset) { buf += coeff_offset; buf_size -= coeff_offset; - if (buf_size < 0) + if (buf_size < 0) { + if (s->framep[VP56_FRAME_CURRENT]->key_frame) + avcodec_set_dimensions(s->avctx, 0, 0); return 0; + } if (s->use_huffman) { s->parse_coeff = vp6_parse_coeff_huffman; init_get_bits(&s->gb, buf, buf_size<<3); diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index a785b90046..28e866356d 100644 --- a/libavcodec/wavpack.c +++ b/libavcodec/wavpack.c @@ -1173,6 +1173,15 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, return samplecount * bpp; } +static void wavpack_decode_flush(AVCodecContext *avctx) +{ + WavpackContext *s = avctx->priv_data; + int i; + + for (i = 0; i < s->fdec_num; i++) + wv_reset_saved_context(s->fdec[i]); +} + static int wavpack_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) @@ -1205,11 +1214,14 @@ static int wavpack_decode_frame(AVCodecContext *avctx, if(frame_size < 0 || frame_size > buf_size){ 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; } if((samplecount = wavpack_decode_block(avctx, s->block, data, - data_size, buf, frame_size)) < 0) + data_size, buf, frame_size)) < 0) { + wavpack_decode_flush(avctx); return -1; + } s->block++; buf += frame_size; buf_size -= frame_size; } diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c index b0b98f1d98..03fb4a67e1 100644 --- a/libavcodec/wmaprodec.c +++ b/libavcodec/wmaprodec.c @@ -309,10 +309,6 @@ static av_cold int decode_init(AVCodecContext *avctx) s->samples_per_frame = 1 << ff_wma_get_frame_len_bits(avctx->sample_rate, 3, s->decode_flags); - /** init previous block len */ - for (i = 0; i < avctx->channels; i++) - s->channel[i].prev_block_len = s->samples_per_frame; - /** subframe info */ log2_max_num_subframes = ((s->decode_flags & 0x38) >> 3); s->max_num_subframes = 1 << log2_max_num_subframes; @@ -332,6 +328,18 @@ static av_cold int decode_init(AVCodecContext *avctx) s->num_channels = avctx->channels; + if (s->num_channels < 0) { + av_log(avctx, AV_LOG_ERROR, "invalid number of channels %d\n", s->num_channels); + return AVERROR_INVALIDDATA; + } else if (s->num_channels > WMAPRO_MAX_CHANNELS) { + av_log_ask_for_sample(avctx, "unsupported number of channels\n"); + return AVERROR_PATCHWELCOME; + } + + /** init previous block len */ + for (i = 0; i < s->num_channels; i++) + s->channel[i].prev_block_len = s->samples_per_frame; + /** extract lfe channel position */ s->lfe_channel = -1; @@ -343,14 +351,6 @@ static av_cold int decode_init(AVCodecContext *avctx) } } - if (s->num_channels < 0) { - av_log(avctx, AV_LOG_ERROR, "invalid number of channels %d\n", s->num_channels); - return AVERROR_INVALIDDATA; - } else if (s->num_channels > WMAPRO_MAX_CHANNELS) { - av_log_ask_for_sample(avctx, "unsupported number of channels\n"); - return AVERROR_PATCHWELCOME; - } - INIT_VLC_STATIC(&sf_vlc, SCALEVLCBITS, HUFF_SCALE_SIZE, scale_huffbits, 1, 1, scale_huffcodes, 2, 2, 616); diff --git a/libavcodec/wmavoice.c b/libavcodec/wmavoice.c index 002c529a30..c343080b36 100644 --- a/libavcodec/wmavoice.c +++ b/libavcodec/wmavoice.c @@ -401,6 +401,10 @@ static av_cold int wmavoice_decode_init(AVCodecContext *ctx) s->min_pitch_val = ((ctx->sample_rate << 8) / 400 + 50) >> 8; s->max_pitch_val = ((ctx->sample_rate << 8) * 37 / 2000 + 50) >> 8; pitch_range = s->max_pitch_val - s->min_pitch_val; + if (pitch_range <= 0) { + av_log(ctx, AV_LOG_ERROR, "Invalid pitch range; broken extradata?\n"); + return -1; + } s->pitch_nbits = av_ceil_log2(pitch_range); s->last_pitch_val = 40; s->last_acb_type = ACB_TYPE_NONE; @@ -422,6 +426,10 @@ static av_cold int wmavoice_decode_init(AVCodecContext *ctx) s->block_conv_table[2] = (pitch_range * 44) >> 6; s->block_conv_table[3] = s->max_pitch_val - 1; s->block_delta_pitch_hrange = (pitch_range >> 3) & ~0xF; + if (s->block_delta_pitch_hrange <= 0) { + av_log(ctx, AV_LOG_ERROR, "Invalid delta pitch hrange; broken extradata?\n"); + return -1; + } s->block_delta_pitch_nbits = 1 + av_ceil_log2(s->block_delta_pitch_hrange); s->block_pitch_range = s->block_conv_table[2] + s->block_conv_table[3] + 1 + @@ -1880,6 +1888,8 @@ static void copy_bits(PutBitContext *pb, rmn_bits = rmn_bytes = get_bits_left(gb); if (rmn_bits < nbits) return; + if (nbits > pb->size_in_bits - put_bits_count(pb)) + return; rmn_bits &= 7; rmn_bytes >>= 3; if ((rmn_bits = FFMIN(rmn_bits, nbits)) > 0) put_bits(pb, rmn_bits, get_bits(gb, rmn_bits)); diff --git a/libavcodec/ws-snd1.c b/libavcodec/ws-snd1.c index d6a60d441f..f92c3531e0 100644 --- a/libavcodec/ws-snd1.c +++ b/libavcodec/ws-snd1.c @@ -37,13 +37,16 @@ static const int8_t ws_adpcm_4bit[] = { -9, -8, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 8 }; -#define CLIP8(a) if(a>127)a=127;if(a<-128)a=-128; - static av_cold int ws_snd_decode_init(AVCodecContext * avctx) { // WSSNDContext *c = avctx->priv_data; - avctx->sample_fmt = AV_SAMPLE_FMT_S16; + if (avctx->channels != 1) { + av_log_ask_for_sample(avctx, "unsupported number of channels\n"); + return AVERROR(EINVAL); + } + + avctx->sample_fmt = AV_SAMPLE_FMT_U8; return 0; } @@ -56,15 +59,19 @@ static int ws_snd_decode_frame(AVCodecContext *avctx, // WSSNDContext *c = avctx->priv_data; int in_size, out_size; - int sample = 0; + int sample = 128; int i; - short *samples = data; + uint8_t *samples = data; if (!buf_size) return 0; + if (buf_size < 4) { + av_log(avctx, AV_LOG_ERROR, "packet is too small\n"); + return AVERROR(EINVAL); + } + out_size = AV_RL16(&buf[0]); - *data_size = out_size * 2; in_size = AV_RL16(&buf[2]); buf += 4; @@ -76,34 +83,54 @@ static int ws_snd_decode_frame(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "Frame data is larger than input buffer\n"); return -1; } + if (in_size == out_size) { for (i = 0; i < out_size; i++) - *samples++ = (*buf++ - 0x80) << 8; + *samples++ = *buf++; + *data_size = out_size; return buf_size; } - while (out_size > 0) { - int code; + while (out_size > 0 && buf - avpkt->data < buf_size) { + int code, smp, size; uint8_t count; code = (*buf) >> 6; count = (*buf) & 0x3F; buf++; + + /* make sure we don't write more than out_size samples */ + switch (code) { + case 0: smp = 4; break; + case 1: smp = 2; break; + case 2: smp = (count & 0x20) ? 1 : count + 1; break; + default: smp = count + 1; break; + } + if (out_size < smp) { + out_size = 0; + break; + } + + /* make sure we don't read past the input buffer */ + size = ((code == 2 && (count & 0x20)) || code == 3) ? 0 : count + 1; + if ((buf - avpkt->data) + size > buf_size) + break; + switch(code) { case 0: /* ADPCM 2-bit */ for (count++; count > 0; count--) { code = *buf++; sample += ws_adpcm_2bit[code & 0x3]; - CLIP8(sample); - *samples++ = sample << 8; + sample = av_clip_uint8(sample); + *samples++ = sample; sample += ws_adpcm_2bit[(code >> 2) & 0x3]; - CLIP8(sample); - *samples++ = sample << 8; + sample = av_clip_uint8(sample); + *samples++ = sample; sample += ws_adpcm_2bit[(code >> 4) & 0x3]; - CLIP8(sample); - *samples++ = sample << 8; + sample = av_clip_uint8(sample); + *samples++ = sample; sample += ws_adpcm_2bit[(code >> 6) & 0x3]; - CLIP8(sample); - *samples++ = sample << 8; + sample = av_clip_uint8(sample); + *samples++ = sample; out_size -= 4; } break; @@ -111,11 +138,11 @@ static int ws_snd_decode_frame(AVCodecContext *avctx, for (count++; count > 0; count--) { code = *buf++; sample += ws_adpcm_4bit[code & 0xF]; - CLIP8(sample); - *samples++ = sample << 8; + sample = av_clip_uint8(sample); + *samples++ = sample; sample += ws_adpcm_4bit[code >> 4]; - CLIP8(sample); - *samples++ = sample << 8; + sample = av_clip_uint8(sample); + *samples++ = sample; out_size -= 2; } break; @@ -125,24 +152,27 @@ static int ws_snd_decode_frame(AVCodecContext *avctx, t = count; t <<= 3; sample += t >> 3; - *samples++ = sample << 8; + sample = av_clip_uint8(sample); + *samples++ = sample; out_size--; } else { /* copy */ for (count++; count > 0; count--) { - *samples++ = (*buf++ - 0x80) << 8; + *samples++ = *buf++; out_size--; } - sample = buf[-1] - 0x80; + sample = buf[-1]; } break; default: /* run */ for(count++; count > 0; count--) { - *samples++ = sample << 8; + *samples++ = sample; out_size--; } } } + *data_size = samples - (uint8_t *)data; + return buf_size; } diff --git a/libavcodec/x86/fft_3dn2.c b/libavcodec/x86/fft_3dn2.c index 2abb8cfbd7..7a6cac14c4 100644 --- a/libavcodec/x86/fft_3dn2.c +++ b/libavcodec/x86/fft_3dn2.c @@ -23,7 +23,7 @@ #include "libavcodec/dsputil.h" #include "fft.h" -DECLARE_ALIGNED(8, static const int, m1m1)[2] = { 1<<31, 1<<31 }; +DECLARE_ALIGNED(8, static const unsigned int, m1m1)[2] = { 1U<<31, 1U<<31 }; #ifdef EMULATE_3DNOWEXT #define PSWAPD(s,d)\ @@ -70,7 +70,7 @@ void ff_imdct_half_3dn2(FFTContext *s, FFTSample *output, const FFTSample *input in1 = input; in2 = input + n2 - 1; #ifdef EMULATE_3DNOWEXT - __asm__ volatile("movd %0, %%mm7" ::"r"(1<<31)); + __asm__ volatile("movd %0, %%mm7" ::"r"(1U<<31)); #endif for(k = 0; k < n4; k++) { // FIXME a single block is faster, but gcc 2.95 and 3.4.x on 32bit can't compile it diff --git a/libavcodec/x86/fft_sse.c b/libavcodec/x86/fft_sse.c index 26b933c810..43f19fff3b 100644 --- a/libavcodec/x86/fft_sse.c +++ b/libavcodec/x86/fft_sse.c @@ -24,8 +24,8 @@ #include "fft.h" #include "config.h" -DECLARE_ASM_CONST(16, int, ff_m1m1m1m1)[4] = - { 1 << 31, 1 << 31, 1 << 31, 1 << 31 }; +DECLARE_ASM_CONST(16, unsigned int, ff_m1m1m1m1)[4] = + { 1U << 31, 1U << 31, 1U << 31, 1U << 31 }; void ff_fft_dispatch_sse(FFTComplex *z, int nbits); void ff_fft_dispatch_interleave_sse(FFTComplex *z, int nbits); diff --git a/libavcodec/xan.c b/libavcodec/xan.c index 357593bf2d..fe9eece61a 100644 --- a/libavcodec/xan.c +++ b/libavcodec/xan.c @@ -114,7 +114,10 @@ static int xan_huffman_decode(unsigned char *dest, int dest_len, init_get_bits(&gb, ptr, ptr_len * 8); while ( val != 0x16 ) { - val = src[val - 0x17 + get_bits1(&gb) * byte]; + unsigned idx = val - 0x17 + get_bits1(&gb) * byte; + if (idx >= 2 * byte) + return -1; + val = src[idx]; if ( val < 0x16 ) { if (dest >= dest_end) @@ -132,13 +135,16 @@ static int xan_huffman_decode(unsigned char *dest, int dest_len, * * @param dest destination buffer of dest_len, must be padded with at least 130 bytes */ -static void xan_unpack(unsigned char *dest, const unsigned char *src, int dest_len) +static void xan_unpack(unsigned char *dest, int dest_len, + const unsigned char *src, int src_len) { unsigned char opcode; int size; + unsigned char *dest_org = dest; unsigned char *dest_end = dest + dest_len; + const unsigned char *src_end = src + src_len; - while (dest < dest_end) { + while (dest < dest_end && src < src_end) { opcode = *src++; if (opcode < 0xe0) { @@ -163,9 +169,11 @@ static void xan_unpack(unsigned char *dest, const unsigned char *src, int dest_l back = ((opcode & 0x10) << 12) + bytestream_get_be16(&src) + 1; size2 = ((opcode & 0x0c) << 6) + *src++ + 5; - if (size + size2 > dest_end - dest) - return; } + if (dest_end - dest < size + size2 || + dest + size - dest_org < back || + src_end - src < size) + return; memcpy(dest, src, size); dest += size; src += size; av_memcpy_backptr(dest, back, size2); dest += size2; @@ -173,6 +181,8 @@ static void xan_unpack(unsigned char *dest, const unsigned char *src, int dest_l int finish = opcode >= 0xfc; size = finish ? opcode & 3 : ((opcode & 0x1f) << 2) + 4; + if (dest_end - dest < size || src_end - src < size) + return; memcpy(dest, src, size); dest += size; src += size; if (finish) return; @@ -220,15 +230,23 @@ static inline void xan_wc3_copy_pixel_run(XanContext *s, int width = s->avctx->width; unsigned char *palette_plane, *prev_palette_plane; + if ( y + motion_y < 0 || y + motion_y >= s->avctx->height || + x + motion_x < 0 || x + motion_x >= s->avctx->width) + return; + palette_plane = s->current_frame.data[0]; prev_palette_plane = s->last_frame.data[0]; + if (!prev_palette_plane) + prev_palette_plane = palette_plane; stride = s->current_frame.linesize[0]; line_inc = stride - width; curframe_index = y * stride + x; curframe_x = x; prevframe_index = (y + motion_y) * stride + x + motion_x; prevframe_x = x + motion_x; - while(pixel_count && (curframe_index < s->frame_size)) { + while(pixel_count && + curframe_index < s->frame_size && + prevframe_index < s->frame_size) { int count = FFMIN3(pixel_count, width - curframe_x, width - prevframe_x); memcpy(palette_plane + curframe_index, prev_palette_plane + prevframe_index, count); @@ -262,6 +280,7 @@ static int xan_wc3_decode_frame(XanContext *s) { int x, y; unsigned char *opcode_buffer = s->buffer1; + unsigned char *opcode_buffer_end = s->buffer1 + s->buffer1_size; int opcode_buffer_size = s->buffer1_size; const unsigned char *imagedata_buffer = s->buffer2; @@ -270,7 +289,7 @@ static int xan_wc3_decode_frame(XanContext *s) { const unsigned char *size_segment; const unsigned char *vector_segment; const unsigned char *imagedata_segment; - int huffman_offset, size_offset, vector_offset, imagedata_offset; + int huffman_offset, size_offset, vector_offset, imagedata_offset, imagedata_size; if (s->size < 8) return AVERROR_INVALIDDATA; @@ -295,14 +314,18 @@ static int xan_wc3_decode_frame(XanContext *s) { huffman_segment, s->size - huffman_offset) < 0) return AVERROR_INVALIDDATA; - if (imagedata_segment[0] == 2) - xan_unpack(s->buffer2, &imagedata_segment[1], s->buffer2_size); - else + if (imagedata_segment[0] == 2) { + xan_unpack(s->buffer2, s->buffer2_size, + &imagedata_segment[1], s->size - imagedata_offset - 1); + imagedata_size = s->buffer2_size; + } else { + imagedata_size = s->size - imagedata_offset - 1; imagedata_buffer = &imagedata_segment[1]; + } /* use the decoded data segments to build the frame */ x = y = 0; - while (total_pixels) { + while (total_pixels && opcode_buffer < opcode_buffer_end) { opcode = *opcode_buffer++; size = 0; @@ -351,6 +374,8 @@ static int xan_wc3_decode_frame(XanContext *s) { size_segment += 3; break; } + if (size > total_pixels) + break; if (opcode < 12) { flag ^= 1; @@ -359,8 +384,11 @@ static int xan_wc3_decode_frame(XanContext *s) { xan_wc3_copy_pixel_run(s, x, y, size, 0, 0); } else { /* output a run of pixels from imagedata_buffer */ + if (imagedata_size < size) + break; xan_wc3_output_pixel_run(s, imagedata_buffer, x, y, size); imagedata_buffer += size; + imagedata_size -= size; } } else { /* run-based motion compensation from last frame */ @@ -527,6 +555,9 @@ static int xan_decode_frame(AVCodecContext *avctx, } buf_size = buf_end - buf; } + if (s->palettes_count <= 0) + return AVERROR_INVALIDDATA; + if ((ret = avctx->get_buffer(avctx, &s->current_frame))) { av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; |