tinfoil patch: make sure that pixel pointer does not go out of bounds
authorMike Melanson <mike@multimedia.cx>
Sat, 13 Aug 2005 16:59:01 +0000 (16:59 +0000)
committerMike Melanson <mike@multimedia.cx>
Sat, 13 Aug 2005 16:59:01 +0000 (16:59 +0000)
Originally committed as revision 4511 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavcodec/flicvideo.c

index 92cb8bd..72aeb6e 100644 (file)
 #define FLI_COPY      16
 #define FLI_MINI      18
 
+#define CHECK_PIXEL_PTR(n) \
+    if (pixel_ptr + n > pixel_limit) { \
+        av_log (s->avctx, AV_LOG_INFO, "Problem: pixel_ptr >= pixel_limit (%d >= %d)\n", \
+        pixel_ptr + n, pixel_limit); \
+        return -1; \
+    } \
+
 typedef struct FlicDecodeContext {
     AVCodecContext *avctx;
     AVFrame frame;
@@ -120,6 +127,7 @@ static int flic_decode_frame(AVCodecContext *avctx,
     int pixel_skip;
     int pixel_countdown;
     unsigned char *pixels;
+    int pixel_limit;
 
     s->frame.reference = 1;
     s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
@@ -129,6 +137,7 @@ static int flic_decode_frame(AVCodecContext *avctx,
     }
 
     pixels = s->frame.data[0];
+    pixel_limit = s->avctx->height * s->frame.linesize[0];
 
     frame_size = LE_32(&buf[stream_ptr]);
     stream_ptr += 6;  /* skip the magic number */
@@ -218,11 +227,13 @@ static int flic_decode_frame(AVCodecContext *avctx,
                             byte_run = -byte_run;
                             palette_idx1 = buf[stream_ptr++];
                             palette_idx2 = buf[stream_ptr++];
+                            CHECK_PIXEL_PTR(byte_run);
                             for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
                                 pixels[pixel_ptr++] = palette_idx1;
                                 pixels[pixel_ptr++] = palette_idx2;
                             }
                         } else {
+                            CHECK_PIXEL_PTR(byte_run * 2);
                             for (j = 0; j < byte_run * 2; j++, pixel_countdown--) {
                                 palette_idx1 = buf[stream_ptr++];
                                 pixels[pixel_ptr++] = palette_idx1;
@@ -256,6 +267,7 @@ static int flic_decode_frame(AVCodecContext *avctx,
                         pixel_countdown -= pixel_skip;
                         byte_run = buf[stream_ptr++];
                         if (byte_run > 0) {
+                            CHECK_PIXEL_PTR(byte_run);
                             for (j = 0; j < byte_run; j++, pixel_countdown--) {
                                 palette_idx1 = buf[stream_ptr++];
                                 pixels[pixel_ptr++] = palette_idx1;
@@ -263,6 +275,7 @@ static int flic_decode_frame(AVCodecContext *avctx,
                         } else {
                             byte_run = -byte_run;
                             palette_idx1 = buf[stream_ptr++];
+                            CHECK_PIXEL_PTR(byte_run);
                             for (j = 0; j < byte_run; j++, pixel_countdown--) {
                                 pixels[pixel_ptr++] = palette_idx1;
                             }
@@ -295,6 +308,7 @@ static int flic_decode_frame(AVCodecContext *avctx,
                     byte_run = buf[stream_ptr++];
                     if (byte_run > 0) {
                         palette_idx1 = buf[stream_ptr++];
+                        CHECK_PIXEL_PTR(byte_run);
                         for (j = 0; j < byte_run; j++) {
                             pixels[pixel_ptr++] = palette_idx1;
                             pixel_countdown--;
@@ -304,6 +318,7 @@ static int flic_decode_frame(AVCodecContext *avctx,
                         }
                     } else {  /* copy bytes if byte_run < 0 */
                         byte_run = -byte_run;
+                        CHECK_PIXEL_PTR(byte_run);
                         for (j = 0; j < byte_run; j++) {
                             palette_idx1 = buf[stream_ptr++];
                             pixels[pixel_ptr++] = palette_idx1;