vaapi_encode_mpeg2: Fix width/height columns/rows confusion
[ffmpeg.git] / libavcodec / flicvideo.c
index fcfdb98..ba5bda4 100644 (file)
@@ -27,8 +27,7 @@
  * variations, visit:
  *   http://www.compuphase.com/flic.htm
  *
- * This decoder outputs PAL8/RGB555/RGB565 and maybe one day RGB24
- * colorspace data, depending on the FLC. To use this decoder, be
+ * This decoder outputs PAL8/RGB555/RGB565/BGR24. To use this decoder, be
  * sure that your demuxer sends the FLI file header to the decoder via
  * the extradata chunk in AVCodecContext. The chunk should be 128 bytes
  * large. The only exception is for FLI files from the game "Magic Carpet",
@@ -200,6 +199,9 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx,
     num_chunks = bytestream2_get_le16(&g2);
     bytestream2_skip(&g2, 8);  /* skip padding */
 
+    if (frame_size < 16)
+        return AVERROR_INVALIDDATA;
+
     frame_size -= 16;
 
     /* iterate through the chunks */
@@ -270,10 +272,14 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx,
             while (compressed_lines > 0) {
                 if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
                     break;
+                if (y_ptr > pixel_limit)
+                    return AVERROR_INVALIDDATA;
                 line_packets = bytestream2_get_le16(&g2);
                 if ((line_packets & 0xC000) == 0xC000) {
                     // line skip opcode
                     line_packets = -line_packets;
+                    if (line_packets > s->avctx->height)
+                        return AVERROR_INVALIDDATA;
                     y_ptr += line_packets * s->frame->linesize[0];
                 } else if ((line_packets & 0xC000) == 0x4000) {
                     av_log(avctx, AV_LOG_ERROR, "Undefined opcode (%x) in DELTA_FLI\n", line_packets);
@@ -322,6 +328,8 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx,
         case FLI_LC:
             /* line compressed */
             starting_line = bytestream2_get_le16(&g2);
+            if (starting_line >= s->avctx->height)
+                return AVERROR_INVALIDDATA;
             y_ptr = 0;
             y_ptr += starting_line * s->frame->linesize[0];
 
@@ -445,8 +453,12 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx,
             break;
         }
 
-        if (stream_ptr_after_chunk - bytestream2_tell(&g2) > 0)
+        if (stream_ptr_after_chunk - bytestream2_tell(&g2) >= 0) {
             bytestream2_skip(&g2, stream_ptr_after_chunk - bytestream2_tell(&g2));
+        } else {
+            av_log(avctx, AV_LOG_ERROR, "Chunk overread\n");
+            break;
+        }
 
         frame_size -= chunk_size;
         num_chunks--;
@@ -520,6 +532,8 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx,
     if (frame_size > buf_size)
         frame_size = buf_size;
 
+    if (frame_size < 16)
+        return AVERROR_INVALIDDATA;
     frame_size -= 16;
 
     /* iterate through the chunks */
@@ -556,9 +570,13 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx,
             while (compressed_lines > 0) {
                 if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
                     break;
+                if (y_ptr > pixel_limit)
+                    return AVERROR_INVALIDDATA;
                 line_packets = bytestream2_get_le16(&g2);
                 if (line_packets < 0) {
                     line_packets = -line_packets;
+                    if (line_packets > s->avctx->height)
+                        return AVERROR_INVALIDDATA;
                     y_ptr += line_packets * s->frame->linesize[0];
                 } else {
                     compressed_lines--;
@@ -743,6 +761,13 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx,
             break;
         }
 
+        if (stream_ptr_after_chunk - bytestream2_tell(&g2) >= 0) {
+            bytestream2_skip(&g2, stream_ptr_after_chunk - bytestream2_tell(&g2));
+        } else {
+            av_log(avctx, AV_LOG_ERROR, "Chunk overread\n");
+            break;
+        }
+
         frame_size -= chunk_size;
         num_chunks--;
     }
@@ -805,6 +830,8 @@ static int flic_decode_frame_24BPP(AVCodecContext *avctx,
     if (frame_size > buf_size)
         frame_size = buf_size;
 
+    if (frame_size < 16)
+        return AVERROR_INVALIDDATA;
     frame_size -= 16;
 
     /* iterate through the chunks */
@@ -841,9 +868,13 @@ static int flic_decode_frame_24BPP(AVCodecContext *avctx,
             while (compressed_lines > 0) {
                 if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
                     break;
+                if (y_ptr > pixel_limit)
+                    return AVERROR_INVALIDDATA;
                 line_packets = bytestream2_get_le16(&g2);
                 if (line_packets < 0) {
                     line_packets = -line_packets;
+                    if (line_packets > s->avctx->height)
+                        return AVERROR_INVALIDDATA;
                     y_ptr += line_packets * s->frame->linesize[0];
                 } else {
                     compressed_lines--;
@@ -1017,6 +1048,13 @@ static int flic_decode_frame_24BPP(AVCodecContext *avctx,
             break;
         }
 
+        if (stream_ptr_after_chunk - bytestream2_tell(&g2) >= 0) {
+            bytestream2_skip(&g2, stream_ptr_after_chunk - bytestream2_tell(&g2));
+        } else {
+            av_log(avctx, AV_LOG_ERROR, "Chunk overread\n");
+            break;
+        }
+
         frame_size -= chunk_size;
         num_chunks--;
     }