From de6dfa2bb82df916a67e5036b0ef96a944781ed3 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 14 Feb 2013 08:47:17 +0100 Subject: [PATCH 1/2] lagarith: avoid infinite loop in lag_rac_refill() range == 0 happens with corrupted files CC:libav-stable@libav.org --- libavcodec/lagarithrac.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavcodec/lagarithrac.h b/libavcodec/lagarithrac.h index aa36d38f85..e4f066e445 100644 --- a/libavcodec/lagarithrac.h +++ b/libavcodec/lagarithrac.h @@ -107,6 +107,9 @@ static inline uint8_t lag_get_rac(lag_rac *l) l->range -= range_scaled * l->prob[255]; } + if (!l->range) + l->range = 0x80; + l->low -= range_scaled * l->prob[val]; return val; From 067432c1c95882c7221e694f33d9f3bdbe46de7f Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 14 Feb 2013 09:08:35 +0100 Subject: [PATCH 2/2] loco: check that there is data left after decoding a plane. CC:libav-stable@libav.org --- libavcodec/loco.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/libavcodec/loco.c b/libavcodec/loco.c index d2b2e88f90..b1ad41ae46 100644 --- a/libavcodec/loco.c +++ b/libavcodec/loco.c @@ -190,43 +190,70 @@ static int decode_frame(AVCodecContext *avctx, case LOCO_CYUY2: case LOCO_YUY2: case LOCO_UYVY: decoded = loco_decode_plane(l, p->data[0], avctx->width, avctx->height, p->linesize[0], buf, buf_size, 1); + if (decoded >= buf_size) + goto buf_too_small; buf += decoded; buf_size -= decoded; + decoded = loco_decode_plane(l, p->data[1], avctx->width / 2, avctx->height, p->linesize[1], buf, buf_size, 1); + if (decoded >= buf_size) + goto buf_too_small; buf += decoded; buf_size -= decoded; + decoded = loco_decode_plane(l, p->data[2], avctx->width / 2, avctx->height, p->linesize[2], buf, buf_size, 1); break; case LOCO_CYV12: case LOCO_YV12: decoded = loco_decode_plane(l, p->data[0], avctx->width, avctx->height, p->linesize[0], buf, buf_size, 1); + if (decoded >= buf_size) + goto buf_too_small; buf += decoded; buf_size -= decoded; + decoded = loco_decode_plane(l, p->data[2], avctx->width / 2, avctx->height / 2, p->linesize[2], buf, buf_size, 1); + if (decoded >= buf_size) + goto buf_too_small; buf += decoded; buf_size -= decoded; + decoded = loco_decode_plane(l, p->data[1], avctx->width / 2, avctx->height / 2, p->linesize[1], buf, buf_size, 1); break; case LOCO_CRGB: case LOCO_RGB: decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1), avctx->width, avctx->height, -p->linesize[0], buf, buf_size, 3); + if (decoded >= buf_size) + goto buf_too_small; buf += decoded; buf_size -= decoded; + decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1) + 1, avctx->width, avctx->height, -p->linesize[0], buf, buf_size, 3); + if (decoded >= buf_size) + goto buf_too_small; buf += decoded; buf_size -= decoded; + decoded = loco_decode_plane(l, p->data[0] + p->linesize[0]*(avctx->height-1) + 2, avctx->width, avctx->height, -p->linesize[0], buf, buf_size, 3); break; case LOCO_RGBA: decoded = loco_decode_plane(l, p->data[0], avctx->width, avctx->height, p->linesize[0], buf, buf_size, 4); + if (decoded >= buf_size) + goto buf_too_small; buf += decoded; buf_size -= decoded; + decoded = loco_decode_plane(l, p->data[0] + 1, avctx->width, avctx->height, p->linesize[0], buf, buf_size, 4); + if (decoded >= buf_size) + goto buf_too_small; buf += decoded; buf_size -= decoded; + decoded = loco_decode_plane(l, p->data[0] + 2, avctx->width, avctx->height, p->linesize[0], buf, buf_size, 4); + if (decoded >= buf_size) + goto buf_too_small; buf += decoded; buf_size -= decoded; + decoded = loco_decode_plane(l, p->data[0] + 3, avctx->width, avctx->height, p->linesize[0], buf, buf_size, 4); break; @@ -236,6 +263,9 @@ static int decode_frame(AVCodecContext *avctx, *(AVFrame*)data = l->pic; return buf_size; +buf_too_small: + av_log(avctx, AV_LOG_ERROR, "Input data too small.\n"); + return AVERROR(EINVAL); } static av_cold int decode_init(AVCodecContext *avctx)