Check pointers before writing to memory
authorRoberto Togni <r_togni@tiscali.it>
Sun, 23 Jan 2005 21:36:24 +0000 (21:36 +0000)
committerRoberto Togni <r_togni@tiscali.it>
Sun, 23 Jan 2005 21:36:24 +0000 (21:36 +0000)
Originally committed as revision 3874 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavcodec/qdrw.c
libavcodec/tscc.c

index 4fc9703..a12d450 100644 (file)
@@ -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;
index 11d8b83..e38ef7e 100644 (file)
@@ -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));