]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/bmv.c
mpegvideo: dont call draw edges on lowres
[ffmpeg] / libavcodec / bmv.c
index 37c844858f7676578c60cd3333faf88728044a35..5d33b910c999723681ca8e9f8f0774e7e2696091 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "avcodec.h"
 #include "bytestream.h"
+#include "libavutil/avassert.h"
 
 enum BMVFlags{
     BMV_NOP = 0,
@@ -52,7 +53,7 @@ typedef struct BMVDecContext {
 
 static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame, int frame_off)
 {
-    int val, saved_val = 0;
+    unsigned val, saved_val = 0;
     int tmplen = src_len;
     const uint8_t *src, *source_end = source + src_len;
     uint8_t *frame_end = frame + SCREEN_WIDE * SCREEN_HIGH;
@@ -98,6 +99,8 @@ static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame,
         }
         if (!(val & 0xC)) {
             for (;;) {
+                if(shift>22)
+                    return -1;
                 if (!read_two_nibbles) {
                     if (src < source || src >= source_end)
                         return -1;
@@ -131,6 +134,7 @@ static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame,
         }
         advance_mode = val & 1;
         len = (val >> 1) - 1;
+        av_assert0(len>0);
         mode += 1 + advance_mode;
         if (mode >= 4)
             mode -= 3;
@@ -140,7 +144,9 @@ static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame,
         case 1:
             if (forward) {
                 if (dst - frame + SCREEN_WIDE < frame_off ||
-                        frame_end - dst < frame_off + len)
+                        dst - frame + SCREEN_WIDE + frame_off < 0 ||
+                        frame_end - dst < frame_off + len ||
+                        frame_end - dst < len)
                     return -1;
                 for (i = 0; i < len; i++)
                     dst[i] = dst[frame_off + i];
@@ -148,7 +154,9 @@ static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame,
             } else {
                 dst -= len;
                 if (dst - frame + SCREEN_WIDE < frame_off ||
-                        frame_end - dst < frame_off + len)
+                        dst - frame + SCREEN_WIDE + frame_off < 0 ||
+                        frame_end - dst < frame_off + len ||
+                        frame_end - dst < len)
                     return -1;
                 for (i = len - 1; i >= 0; i--)
                     dst[i] = dst[frame_off + i];
@@ -264,6 +272,11 @@ static av_cold int decode_init(AVCodecContext *avctx)
     c->avctx = avctx;
     avctx->pix_fmt = PIX_FMT_PAL8;
 
+    if (avctx->width != SCREEN_WIDE || avctx->height != SCREEN_HIGH) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid dimension %dx%d\n", avctx->width, avctx->height);
+        return AVERROR_INVALIDDATA;
+    }
+
     c->pic.reference = 1;
     if (avctx->get_buffer(avctx, &c->pic) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
@@ -356,18 +369,19 @@ static int bmv_aud_decode_frame(AVCodecContext *avctx, void *data,
 AVCodec ff_bmv_video_decoder = {
     .name           = "bmv_video",
     .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = CODEC_ID_BMV_VIDEO,
+    .id             = AV_CODEC_ID_BMV_VIDEO,
     .priv_data_size = sizeof(BMVDecContext),
     .init           = decode_init,
     .close          = decode_end,
     .decode         = decode_frame,
+    .capabilities   = CODEC_CAP_DR1,
     .long_name      = NULL_IF_CONFIG_SMALL("Discworld II BMV video"),
 };
 
 AVCodec ff_bmv_audio_decoder = {
     .name           = "bmv_audio",
     .type           = AVMEDIA_TYPE_AUDIO,
-    .id             = CODEC_ID_BMV_AUDIO,
+    .id             = AV_CODEC_ID_BMV_AUDIO,
     .priv_data_size = sizeof(BMVAudioDecContext),
     .init           = bmv_aud_decode_init,
     .decode         = bmv_aud_decode_frame,