diff options
author | Ronald S. Bultje <rsbultje@gmail.com> | 2012-02-28 10:22:28 -0800 |
---|---|---|
committer | Ronald S. Bultje <rsbultje@gmail.com> | 2012-02-28 10:34:35 -0800 |
commit | fc9bc08dca9ac32526251e19fcf738d23b8c68d1 (patch) | |
tree | 74bef8223db1f77784ae3bce1a832b48ed36d78b /libavcodec/indeo3.c | |
parent | bd7a647c0d3071456e066a2d2b6dc4ea807c6ffc (diff) | |
download | ffmpeg-fc9bc08dca9ac32526251e19fcf738d23b8c68d1.tar.gz |
Indeo3: fix crashes on corrupt bitstreams.
Splits at borders of cells are invalid, since it leaves one of the
cells with a width/height of zero. Also, propagate errors on buffer
allocation failures, so we don't continue decoding (which crashes).
Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind
CC: libav-stable@libav.org
Diffstat (limited to 'libavcodec/indeo3.c')
-rw-r--r-- | libavcodec/indeo3.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/libavcodec/indeo3.c b/libavcodec/indeo3.c index 4fbbfbbf51..ed3535adc7 100644 --- a/libavcodec/indeo3.c +++ b/libavcodec/indeo3.c @@ -724,6 +724,8 @@ static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx, SPLIT_CELL(ref_cell->height, curr_cell.height); ref_cell->ypos += curr_cell.height; ref_cell->height -= curr_cell.height; + if (ref_cell->height <= 0 || curr_cell.height <= 0) + return AVERROR_INVALIDDATA; } else if (code == V_SPLIT) { if (curr_cell.width > strip_width) { /* split strip */ @@ -732,6 +734,8 @@ static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx, SPLIT_CELL(ref_cell->width, curr_cell.width); ref_cell->xpos += curr_cell.width; ref_cell->width -= curr_cell.width; + if (ref_cell->width <= 0 || curr_cell.width <= 0) + return AVERROR_INVALIDDATA; } while (1) { /* loop until return */ @@ -887,13 +891,16 @@ static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx, return AVERROR_INVALIDDATA; if (width != ctx->width || height != ctx->height) { + int res; + av_dlog(avctx, "Frame dimensions changed!\n"); ctx->width = width; ctx->height = height; free_frame_buffers(ctx); - allocate_frame_buffers(ctx, avctx); + if ((res = allocate_frame_buffers(ctx, avctx)) < 0) + return res; avcodec_set_dimensions(avctx, width, height); } |