aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRonald S. Bultje <rsbultje@gmail.com>2012-02-28 10:22:28 -0800
committerReinhard Tartler <siretart@tauware.de>2012-02-28 20:57:44 +0100
commit9dbd437da2bafbec540e38cb51bc7ce2b0101ee5 (patch)
treedf02337d361f2a72f61ae40314a952e077de5477
parent2510e1476e9a8bfcca0fe4e85a1380482aed0ab3 (diff)
downloadffmpeg-9dbd437da2bafbec540e38cb51bc7ce2b0101ee5.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 (cherry picked from commit fc9bc08dca9ac32526251e19fcf738d23b8c68d1) Signed-off-by: Reinhard Tartler <siretart@tauware.de>
-rw-r--r--libavcodec/indeo3.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/libavcodec/indeo3.c b/libavcodec/indeo3.c
index d2b01f469a..55b4ec7a7a 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);
}