diff options
author | Anton Khirnov <anton@khirnov.net> | 2013-04-16 09:41:28 +0200 |
---|---|---|
committer | Reinhard Tartler <siretart@tauware.de> | 2013-04-18 22:04:53 +0200 |
commit | b0b33ce14806ac11860c982d701505538430437b (patch) | |
tree | 9929114329901ee97c630438896883f136c5044a | |
parent | fa4192e31f4b9d3b6bf68daa5702926ae521e4ea (diff) | |
download | ffmpeg-b0b33ce14806ac11860c982d701505538430437b.tar.gz |
indeo3: check motion vectors.
Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind
CC:libav-stable@libav.org
(cherry picked from commit a0a872d0733f60876b0c93f236bc4606f36fbf89)
Signed-off-by: Reinhard Tartler <siretart@tauware.de>
-rw-r--r-- | libavcodec/indeo3.c | 34 |
1 files changed, 29 insertions, 5 deletions
diff --git a/libavcodec/indeo3.c b/libavcodec/indeo3.c index 2d199971c4..a59d404860 100644 --- a/libavcodec/indeo3.c +++ b/libavcodec/indeo3.c @@ -223,7 +223,7 @@ static av_cold void free_frame_buffers(Indeo3DecodeContext *ctx) * @param plane pointer to the plane descriptor * @param cell pointer to the cell descriptor */ -static void copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell) +static int copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell) { int h, w, mv_x, mv_y, offset, offset_dst; uint8_t *src, *dst; @@ -233,6 +233,16 @@ static void copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell) dst = plane->pixels[ctx->buf_sel] + offset_dst; mv_y = cell->mv_ptr[0]; mv_x = cell->mv_ptr[1]; + + /* -1 because there is an extra line on top for prediction */ + if ((cell->ypos << 2) + mv_y < -1 || (cell->xpos << 2) + mv_x < 0 || + ((cell->ypos + cell->height) << 2) + mv_y >= plane->height || + ((cell->xpos + cell->width) << 2) + mv_x >= plane->width) { + av_log(ctx->avctx, AV_LOG_ERROR, + "Motion vectors point out of the frame.\n"); + return AVERROR_INVALIDDATA; + } + offset = offset_dst + mv_y * plane->pitch + mv_x; src = plane->pixels[ctx->buf_sel ^ 1] + offset; @@ -260,6 +270,8 @@ static void copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell) dst += 4; } } + + return 0; } @@ -585,11 +597,23 @@ static int decode_cell(Indeo3DecodeContext *ctx, AVCodecContext *avctx, } else if (mode >= 10) { /* for mode 10 and 11 INTER first copy the predicted cell into the current one */ /* so we don't need to do data copying for each RLE code later */ - copy_cell(ctx, plane, cell); + int ret = copy_cell(ctx, plane, cell); + if (ret < 0) + return ret; } else { /* set the pointer to the reference pixels for modes 0-4 INTER */ mv_y = cell->mv_ptr[0]; mv_x = cell->mv_ptr[1]; + + /* -1 because there is an extra line on top for prediction */ + if ((cell->ypos << 2) + mv_y < -1 || (cell->xpos << 2) + mv_x < 0 || + ((cell->ypos + cell->height) << 2) + mv_y >= plane->height || + ((cell->xpos + cell->width) << 2) + mv_x >= plane->width) { + av_log(ctx->avctx, AV_LOG_ERROR, + "Motion vectors point out of the frame.\n"); + return AVERROR_INVALIDDATA; + } + offset += mv_y * plane->pitch + mv_x; ref_block = plane->pixels[ctx->buf_sel ^ 1] + offset; } @@ -721,7 +745,7 @@ static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx, const int depth, const int strip_width) { Cell curr_cell; - int bytes_used; + int bytes_used, ret; if (depth <= 0) { av_log(avctx, AV_LOG_ERROR, "Stack overflow (corrupted binary tree)!\n"); @@ -772,8 +796,8 @@ static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx, CHECK_CELL if (!curr_cell.mv_ptr) return AVERROR_INVALIDDATA; - copy_cell(ctx, plane, &curr_cell); - return 0; + ret = copy_cell(ctx, plane, &curr_cell); + return ret; } break; case INTER_DATA: |