]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/xan.c
Merge commit 'c74f81786d434dfaf9b3dff06aa96bfd23d0127b'
[ffmpeg] / libavcodec / xan.c
index e6bfc0da068bc604fba5f17d49c8d1c32f0bea2a..bccbe24d85b7489c18f14c463abf52a882adef24 100644 (file)
@@ -2,20 +2,20 @@
  * Wing Commander/Xan Video Decoder
  * Copyright (C) 2003 the ffmpeg project
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -90,6 +90,8 @@ static av_cold int xan_decode_init(AVCodecContext *avctx)
         av_freep(&s->buffer1);
         return AVERROR(ENOMEM);
     }
+    avcodec_get_frame_defaults(&s->last_frame);
+    avcodec_get_frame_defaults(&s->current_frame);
 
     return 0;
 }
@@ -285,6 +287,7 @@ static int xan_wc3_decode_frame(XanContext *s) {
     const unsigned char *size_segment;
     const unsigned char *vector_segment;
     const unsigned char *imagedata_segment;
+    const unsigned char *buf_end = s->buf + s->size;
     int huffman_offset, size_offset, vector_offset, imagedata_offset,
         imagedata_size;
 
@@ -356,17 +359,29 @@ static int xan_wc3_decode_frame(XanContext *s) {
 
         case 9:
         case 19:
+            if (buf_end - size_segment < 1) {
+                av_log(s->avctx, AV_LOG_ERROR, "size_segment overread\n");
+                return AVERROR_INVALIDDATA;
+            }
             size = *size_segment++;
             break;
 
         case 10:
         case 20:
+            if (buf_end - size_segment < 2) {
+                av_log(s->avctx, AV_LOG_ERROR, "size_segment overread\n");
+                return AVERROR_INVALIDDATA;
+            }
             size = AV_RB16(&size_segment[0]);
             size_segment += 2;
             break;
 
         case 11:
         case 21:
+            if (buf_end - size_segment < 3) {
+                av_log(s->avctx, AV_LOG_ERROR, "size_segment overread\n");
+                return AVERROR_INVALIDDATA;
+            }
             size = AV_RB24(size_segment);
             size_segment += 3;
             break;
@@ -389,6 +404,10 @@ static int xan_wc3_decode_frame(XanContext *s) {
                 imagedata_size -= size;
             }
         } else {
+            if (vector_segment >= buf_end) {
+                av_log(s->avctx, AV_LOG_ERROR, "vector_segment overread\n");
+                return AVERROR_INVALIDDATA;
+            }
             /* run-based motion compensation from last frame */
             motion_x = sign_extend(*vector_segment >> 4,  4);
             motion_y = sign_extend(*vector_segment & 0xF, 4);
@@ -509,6 +528,10 @@ static int xan_decode_frame(AVCodecContext *avctx,
             int i;
             tag  = bytestream_get_le32(&buf);
             size = bytestream_get_be32(&buf);
+            if(size < 0) {
+                av_log(avctx, AV_LOG_ERROR, "Invalid tag size %d\n", size);
+                return AVERROR_INVALIDDATA;
+            }
             size = FFMIN(size, buf_end - buf);
             switch (tag) {
             case PALT_TAG:
@@ -532,7 +555,7 @@ static int xan_decode_frame(AVCodecContext *avctx,
                     int g = gamma_lookup[*buf++];
                     int b = gamma_lookup[*buf++];
 #endif
-                    *tmpptr++ = (r << 16) | (g << 8) | b;
+                    *tmpptr++ = (0xFFU << 24) | (r << 16) | (g << 8) | b;
                 }
                 s->palettes_count++;
                 break;