diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c index dc13e936fd..0b617061eb 100644 --- a/libavcodec/cavsdec.c +++ b/libavcodec/cavsdec.c @@ -609,12 +609,21 @@ static int decode_pic(AVSContext *h) { static int decode_seq_header(AVSContext *h) { MpegEncContext *s = &h->s; int frame_rate_code; + int width, height; h->profile = get_bits(&s->gb,8); h->level = get_bits(&s->gb,8); skip_bits1(&s->gb); //progressive sequence - s->width = get_bits(&s->gb,14); - s->height = get_bits(&s->gb,14); + + width = get_bits(&s->gb, 14); + height = get_bits(&s->gb, 14); + if ((s->width || s->height) && (s->width != width || s->height != height)) { + av_log_missing_feature(s, "Width/height changing in CAVS is", 0); + return AVERROR_PATCHWELCOME; + } + s->width = width; + s->height = height; + skip_bits(&s->gb,2); //chroma format skip_bits(&s->gb,3); //sample_precision h->aspect_ratio = get_bits(&s->gb,4); diff --git a/libavcodec/indeo3.c b/libavcodec/indeo3.c index 6e9a31e080..5479c55a32 100644 --- a/libavcodec/indeo3.c +++ b/libavcodec/indeo3.c @@ -419,6 +419,9 @@ static int decode_cell_data(Cell *cell, uint8_t *block, uint8_t *ref_block, blk_row_offset = (row_offset << (2 + v_zoom)) - (cell->width << 2); line_offset = v_zoom ? row_offset : 0; + if (cell->height & v_zoom || cell->width & h_zoom) + return IV3_BAD_DATA; + for (y = 0; y < cell->height; is_first_row = 0, y += 1 + v_zoom) { for (x = 0; x < cell->width; x += 1 + h_zoom) { ref = ref_block; diff --git a/libavcodec/indeo5.c b/libavcodec/indeo5.c index c5a04c8a43..1d5824faf7 100644 --- a/libavcodec/indeo5.c +++ b/libavcodec/indeo5.c @@ -309,8 +309,12 @@ static int decode_pic_hdr(IVI45DecContext *ctx, AVCodecContext *avctx) ctx->frame_num = get_bits(&ctx->gb, 8); if (ctx->frame_type == FRAMETYPE_INTRA) { - if (decode_gop_header(ctx, avctx)) - return -1; + ctx->gop_invalid = 1; + if (decode_gop_header(ctx, avctx)) { + av_log(avctx, AV_LOG_ERROR, "Invalid GOP header, skipping frames.\n"); + return AVERROR_INVALIDDATA; + } + ctx->gop_invalid = 0; } if (ctx->frame_type != FRAMETYPE_NULL) { @@ -431,6 +435,12 @@ static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band, ((band->qdelta_present && band->inherit_qdelta) || band->inherit_mv)) return AVERROR_INVALIDDATA; + if (tile->num_MBs != IVI_MBs_PER_TILE(tile->width, tile->height, band->mb_size)) { + av_log(avctx, AV_LOG_ERROR, "Allocated tile size %d mismatches parameters %d\n", + tile->num_MBs, IVI_MBs_PER_TILE(tile->width, tile->height, band->mb_size)); + return AVERROR_INVALIDDATA; + } + /* scale factor for motion vectors */ mv_scale = (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3); mv_x = mv_y = 0; diff --git a/libavcodec/ivi_common.c b/libavcodec/ivi_common.c index 5af7c91b63..e3b16e1ffb 100644 --- a/libavcodec/ivi_common.c +++ b/libavcodec/ivi_common.c @@ -493,8 +493,17 @@ int ff_ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile) return 0; } -void ff_ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, - IVITile *tile, int32_t mv_scale) +/** + * Handle empty tiles by performing data copying and motion + * compensation respectively. + * + * @param[in] avctx ptr to the AVCodecContext + * @param[in] band pointer to the band descriptor + * @param[in] tile pointer to the tile descriptor + * @param[in] mv_scale scaling factor for motion vectors + */ +static int ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, + IVITile *tile, int32_t mv_scale) { int x, y, need_mc, mbn, blk, num_blocks, mv_x, mv_y, mc_type; int offs, mb_offset, row_offset; @@ -504,6 +513,13 @@ void ff_ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, void (*mc_no_delta_func)(int16_t *buf, const int16_t *ref_buf, uint32_t pitch, int mc_type); + if (tile->num_MBs != IVI_MBs_PER_TILE(tile->width, tile->height, band->mb_size)) { + av_log(avctx, AV_LOG_ERROR, "Allocated tile size %d mismatches " + "parameters %d in ivi_process_empty_tile()\n", + tile->num_MBs, IVI_MBs_PER_TILE(tile->width, tile->height, band->mb_size)); + return AVERROR_INVALIDDATA; + } + offs = tile->ypos * band->pitch + tile->xpos; mb = tile->mbs; ref_mb = tile->ref_mbs; @@ -584,6 +600,8 @@ void ff_ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, dst += band->pitch; } } + + return 0; } @@ -698,8 +716,10 @@ static int decode_band(IVI45DecContext *ctx, int plane_num, } tile->is_empty = get_bits1(&ctx->gb); if (tile->is_empty) { - ff_ivi_process_empty_tile(avctx, band, tile, + result = ivi_process_empty_tile(avctx, band, tile, (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3)); + if (result < 0) + break; av_dlog(avctx, "Empty tile encountered!\n"); } else { tile->data_size = ff_ivi_dec_tile_data_size(&ctx->gb); @@ -764,6 +784,8 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *data_size, "Error while decoding picture header: %d\n", result); return -1; } + if (ctx->gop_invalid) + return AVERROR_INVALIDDATA; if (ctx->gop_flags & IVI5_IS_PROTECTED) { av_log(avctx, AV_LOG_ERROR, "Password-protected clip!\n"); @@ -803,6 +825,7 @@ int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *data_size, avctx->release_buffer(avctx, &ctx->frame); ctx->frame.reference = 0; + avcodec_set_dimensions(avctx, ctx->planes[0].width, ctx->planes[0].height); if ((result = avctx->get_buffer(avctx, &ctx->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return result; diff --git a/libavcodec/ivi_common.h b/libavcodec/ivi_common.h index 79895efed8..af99afc60a 100644 --- a/libavcodec/ivi_common.h +++ b/libavcodec/ivi_common.h @@ -248,6 +248,8 @@ typedef struct IVI45DecContext { int (*decode_mb_info) (struct IVI45DecContext *ctx, IVIBandDesc *band, IVITile *tile, AVCodecContext *avctx); void (*switch_buffers) (struct IVI45DecContext *ctx); int (*is_nonnull_frame)(struct IVI45DecContext *ctx); + + int gop_invalid; } IVI45DecContext; /** compare some properties of two pictures */ @@ -373,18 +375,6 @@ int ff_ivi_dec_tile_data_size(GetBitContext *gb); */ int ff_ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile); -/** - * Handle empty tiles by performing data copying and motion - * compensation respectively. - * - * @param[in] avctx ptr to the AVCodecContext - * @param[in] band pointer to the band descriptor - * @param[in] tile pointer to the tile descriptor - * @param[in] mv_scale scaling factor for motion vectors - */ -void ff_ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, - IVITile *tile, int32_t mv_scale); - /** * Convert and output the current plane. * This conversion is done by adding back the bias value of 128 diff --git a/libavcodec/lagarith.c b/libavcodec/lagarith.c index 729b9d0f88..22becdfc37 100644 --- a/libavcodec/lagarith.c +++ b/libavcodec/lagarith.c @@ -326,6 +326,11 @@ static int lag_decode_zero_run_line(LagarithContext *l, uint8_t *dst, output_zeros: if (l->zeros_rem) { count = FFMIN(l->zeros_rem, width - i); + if (end - dst < count) { + av_log(l->avctx, AV_LOG_ERROR, "Too many zeros remaining.\n"); + return AVERROR_INVALIDDATA; + } + memset(dst, 0, count); l->zeros_rem -= count; dst += count; diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c index eccfb55432..a5255074d4 100644 --- a/libavcodec/wmaprodec.c +++ b/libavcodec/wmaprodec.c @@ -1166,7 +1166,12 @@ static int decode_subframe(WMAProDecodeCtx *s) int num_bits = av_log2((s->subframe_len + 3)/4) + 1; for (i = 0; i < s->channels_for_cur_subframe; i++) { int c = s->channel_indexes_for_cur_subframe[i]; - s->channel[c].num_vec_coeffs = get_bits(&s->gb, num_bits) << 2; + int num_vec_coeffs = get_bits(&s->gb, num_bits) << 2; + if (num_vec_coeffs > WMAPRO_BLOCK_MAX_SIZE) { + av_log(s->avctx, AV_LOG_ERROR, "num_vec_coeffs %d is too large\n", num_vec_coeffs); + return AVERROR_INVALIDDATA; + } + s->channel[c].num_vec_coeffs = num_vec_coeffs; } } else { for (i = 0; i < s->channels_for_cur_subframe; i++) { diff --git a/libavformat/avidec.c b/libavformat/avidec.c index 72aa60731f..0a0ee013ba 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -1199,7 +1199,7 @@ resync: } ast->frame_offset += get_duration(ast, pkt->size); } - ast->remaining -= size; + ast->remaining -= err; if(!ast->remaining){ avi->stream_index= -1; ast->packet_size= 0; diff --git a/libavformat/wav.c b/libavformat/wav.c index ab4b3b42e7..9d4b0708b8 100644 --- a/libavformat/wav.c +++ b/libavformat/wav.c @@ -508,7 +508,7 @@ static int wav_read_header(AVFormatContext *s, case MKTAG('L', 'I', 'S', 'T'): list_type = avio_rl32(pb); if (size < 4) { - av_log(s, AV_LOG_ERROR, "too short LIST tag\n"); + av_log(s, AV_LOG_ERROR, "too short LIST"); return AVERROR_INVALIDDATA; } switch (list_type) {