]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/flicvideo.c
tinfoil patch: accept no widths that are no multiples of 4
[ffmpeg] / libavcodec / flicvideo.c
index 248fc843a3801d730268c9bac295b25c6b476457..72aeb6e66712c57c593ecb2bb2341ab1edb31a38 100644 (file)
 #define FLI_COPY      16
 #define FLI_MINI      18
 
-#define LE_16(x)  ((((uint8_t*)(x))[1] << 8) | ((uint8_t*)(x))[0])
-#define LE_32(x)  ((((uint8_t*)(x))[3] << 24) | \
-                   (((uint8_t*)(x))[2] << 16) | \
-                   (((uint8_t*)(x))[1] << 8) | \
-                    ((uint8_t*)(x))[0])
+#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;
@@ -126,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;
@@ -135,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 */
@@ -182,7 +185,7 @@ static int flic_decode_frame(AVCodecContext *avctx,
                 for (j = 0; j < color_changes; j++) {
 
                     /* wrap around, for good measure */
-                    if (palette_ptr >= 256)
+                    if ((unsigned)palette_ptr >= 256)
                         palette_ptr = 0;
 
                     r = buf[stream_ptr++] << color_shift;
@@ -224,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;
@@ -262,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;
@@ -269,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;
                             }
@@ -301,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--;
@@ -310,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;