Check pointers before writing to memory, fix possible integer overflows
[ffmpeg.git] / libavcodec / 8bps.c
index 9509f42..9adf496 100644 (file)
@@ -61,7 +61,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8
 {
        EightBpsContext * const c = (EightBpsContext *)avctx->priv_data;
        unsigned char *encoded = (unsigned char *)buf;
-       unsigned char *pixptr;
+       unsigned char *pixptr, *pixptr_end;
        unsigned int height = avctx->height; // Real image height
        unsigned int dlen, p, row;
        unsigned char *lp, *dp;
@@ -101,18 +101,23 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, uint8
                /* Decode a plane */
                for(row = 0; row < height; row++) {
                        pixptr = c->pic.data[0] + row * c->pic.linesize[0] + planemap[p];
+                       pixptr_end = pixptr + c->pic.linesize[0];
                        dlen = be2me_16(*(unsigned short *)(lp+row*2));
                        /* Decode a row of this plane */
                        while(dlen > 0) {
                                if ((count = *dp++) <= 127) {
                                        count++;
                                        dlen -= count + 1;
+                                       if (pixptr + count * px_inc > pixptr_end)
+                                           break;
                                        while(count--) {
                                                *pixptr = *dp++;
                                                pixptr += px_inc;
                                        }
                                } else {
                                        count = 257 - count;
+                                       if (pixptr + count * px_inc > pixptr_end)
+                                           break;
                                        while(count--) {
                                                *pixptr = *dp;
                                                pixptr += px_inc;
@@ -155,6 +160,12 @@ static int decode_init(AVCodecContext *avctx)
 
        c->pic.data[0] = NULL;
 
+    // FIXME: find a better way to prevent integer overflow
+    if (((unsigned int)avctx->width > 32000) || ((unsigned int)avctx->height > 32000)) {
+        av_log(avctx, AV_LOG_ERROR, "Bad image size (w = %d, h = %d).\n", avctx->width, avctx->height);
+        return 1;
+    }
+
        switch (avctx->bits_per_sample) {
                case 8:
                        avctx->pix_fmt = PIX_FMT_PAL8;