From cca1a4265388eed91156216cec7ed5c8c9f8016d Mon Sep 17 00:00:00 2001 From: Roberto Togni Date: Sun, 23 Jan 2005 21:36:24 +0000 Subject: [PATCH] Check pointers before writing to memory Originally committed as revision 3874 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavcodec/qdrw.c | 18 ++++++++++++++---- libavcodec/tscc.c | 27 +++++++++++++++++++++------ 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/libavcodec/qdrw.c b/libavcodec/qdrw.c index 4fc9703..a12d450 100644 --- a/libavcodec/qdrw.c +++ b/libavcodec/qdrw.c @@ -65,10 +65,15 @@ static int decode_frame(AVCodecContext *avctx, } for (i = 0; i <= colors; i++) { - int idx; + unsigned int idx; idx = BE_16(buf); /* color index */ buf += 2; + if (idx > 255) { + av_log(avctx, AV_LOG_ERROR, "Palette index out of range: %u\n", idx); + buf += 6; + continue; + } a->palette[idx * 3 + 0] = *buf++; buf++; a->palette[idx * 3 + 1] = *buf++; @@ -77,9 +82,6 @@ static int decode_frame(AVCodecContext *avctx, buf++; } - if (colors) - a->pic.palette_has_changed = 1; - buf += 18; /* skip unneeded data */ for (i = 0; i < avctx->height; i++) { int size, left, code, pix; @@ -98,6 +100,8 @@ static int decode_frame(AVCodecContext *avctx, if (code & 0x80 ) { /* run */ int i; pix = *buf++; + if ((out + (257 - code) * 3) > (outdata + a->pic.linesize[0])) + break; for (i = 0; i < 257 - code; i++) { *out++ = a->palette[pix * 3 + 0]; *out++ = a->palette[pix * 3 + 1]; @@ -107,6 +111,8 @@ static int decode_frame(AVCodecContext *avctx, left -= 2; } else { /* copy */ int i, pix; + if ((out + code * 3) > (outdata + a->pic.linesize[0])) + break; for (i = 0; i <= code; i++) { pix = *buf++; *out++ = a->palette[pix * 3 + 0]; @@ -130,6 +136,10 @@ static int decode_frame(AVCodecContext *avctx, static int decode_init(AVCodecContext *avctx){ // QdrawContext * const a = avctx->priv_data; + if (avcodec_check_dimensions(avctx, avctx->height, avctx->width) < 0) { + return 1; + } + avctx->pix_fmt= PIX_FMT_RGB24; return 0; diff --git a/libavcodec/tscc.c b/libavcodec/tscc.c index 11d8b83..e38ef7e 100644 --- a/libavcodec/tscc.c +++ b/libavcodec/tscc.c @@ -72,19 +72,22 @@ typedef struct TsccContext { * */ -static int decode_rle(CamtasiaContext *c) +static int decode_rle(CamtasiaContext *c, unsigned int srcsize) { unsigned char *src = c->decomp_buf; - unsigned char *output; + unsigned char *output, *output_end; int p1, p2, line=c->height, pos=0, i; output = c->pic.data[0] + (c->height - 1) * c->pic.linesize[0]; - while(src < c->decomp_buf + c->decomp_size) { + output_end = c->pic.data[0] + (c->height) * c->pic.linesize[0]; + while(src < c->decomp_buf + srcsize) { p1 = *src++; if(p1 == 0) { //Escape code p2 = *src++; if(p2 == 0) { //End-of-line output = c->pic.data[0] + (--line) * c->pic.linesize[0]; + if (line < 0) + return -1; pos = 0; continue; } else if(p2 == 1) { //End-of-picture @@ -93,11 +96,17 @@ static int decode_rle(CamtasiaContext *c) p1 = *src++; p2 = *src++; line -= p2; + if (line < 0) + return -1; pos += p1; output = c->pic.data[0] + line * c->pic.linesize[0] + pos * (c->bpp / 8); continue; } // Copy data + if (output + p2 * (c->bpp / 8) > output_end) { + src += p2 * (c->bpp / 8); + continue; + } for(i = 0; i < p2 * (c->bpp / 8); i++) { *output++ = *src++; } @@ -119,6 +128,8 @@ static int decode_rle(CamtasiaContext *c) pix[2] = *src++; break; } + if (output + p1 * (c->bpp / 8) > output_end) + continue; for(i = 0; i < p1; i++) { switch(c->bpp){ case 8: *output++ = pix[0]; @@ -183,10 +194,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8 av_log(avctx, AV_LOG_ERROR, "Inflate error: %d\n", zret); return -1; } - encoded = c->decomp_buf; - len = c->decomp_size; + + if(zret != Z_DATA_ERROR) - decode_rle(c); + decode_rle(c, c->zstream.avail_out); /* make the palette available on the way out */ if (c->avctx->pix_fmt == PIX_FMT_PAL8) { @@ -227,6 +238,10 @@ static int decode_init(AVCodecContext *avctx) c->pic.data[0] = NULL; c->height = avctx->height; + if (avcodec_check_dimensions(avctx, avctx->height, avctx->width) < 0) { + return 1; + } + #ifdef CONFIG_ZLIB // Needed if zlib unused or init aborted before inflateInit memset(&(c->zstream), 0, sizeof(z_stream)); -- 2.7.4