]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/dvbsubdec.c
fft: avoid a signed overflow
[ffmpeg] / libavcodec / dvbsubdec.c
index 8cc8d4fc8330c80fa2800009fd801623c65fcc13..aef2c08f30df9c9eeac33bfbd42373201439c25f 100644 (file)
@@ -2,20 +2,20 @@
  * DVB subtitle decoding for ffmpeg
  * Copyright (c) 2005 Ian Caulfield
  *
- * This file is part of FFmpeg.
+ * This file is part of Libav.
  *
- * FFmpeg is free software; you can redistribute it and/or
+ * Libav 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.
  *
- * FFmpeg is distributed in the hope that it will be useful,
+ * Libav 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 FFmpeg; if not, write to the Free Software
+ * License along with Libav; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "avcodec.h"
 #include "bytestream.h"
 #include "libavutil/colorspace.h"
 
-//#define DEBUG
-//#define DEBUG_PACKET_CONTENTS
-//#define DEBUG_SAVE_IMAGES
-
 #define DVBSUB_PAGE_SEGMENT     0x10
 #define DVBSUB_REGION_SEGMENT   0x11
 #define DVBSUB_CLUT_SEGMENT     0x12
@@ -37,8 +33,9 @@
 
 #define cm (ff_cropTbl + MAX_NEG_CROP)
 
-#ifdef DEBUG_SAVE_IMAGES
+#ifdef DEBUG
 #undef fprintf
+#undef perror
 #if 0
 static void png_save(const char *filename, uint8_t *bitmap, int w, int h,
                      uint32_t *rgba_palette)
@@ -53,7 +50,7 @@ static void png_save(const char *filename, uint8_t *bitmap, int w, int h,
     f = fopen(fname, "w");
     if (!f) {
         perror(fname);
-        exit(1);
+        return;
     }
     fprintf(f, "P6\n"
             "%d %d\n"
@@ -75,7 +72,7 @@ static void png_save(const char *filename, uint8_t *bitmap, int w, int h,
     f = fopen(fname2, "w");
     if (!f) {
         perror(fname2);
-        exit(1);
+        return;
     }
     fprintf(f, "P5\n"
             "%d %d\n"
@@ -109,7 +106,7 @@ static void png_save2(const char *filename, uint32_t *bitmap, int w, int h)
     f = fopen(fname, "w");
     if (!f) {
         perror(fname);
-        exit(1);
+        return;
     }
     fprintf(f, "P6\n"
             "%d %d\n"
@@ -131,7 +128,7 @@ static void png_save2(const char *filename, uint32_t *bitmap, int w, int h)
     f = fopen(fname2, "w");
     if (!f) {
         perror(fname2);
-        exit(1);
+        return;
     }
     fprintf(f, "P5\n"
             "%d %d\n"
@@ -750,20 +747,17 @@ static void dvbsub_parse_pixel_data_block(AVCodecContext *avctx, DVBSubObjectDis
     av_dlog(avctx, "DVB pixel block size %d, %s field:\n", buf_size,
             top_bottom ? "bottom" : "top");
 
-#ifdef DEBUG_PACKET_CONTENTS
     for (i = 0; i < buf_size; i++) {
         if (i % 16 == 0)
-            av_log(avctx, AV_LOG_INFO, "0x%08p: ", buf+i);
+            av_dlog(avctx, "0x%8p: ", buf+i);
 
-        av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]);
+        av_dlog(avctx, "%02x ", buf[i]);
         if (i % 16 == 15)
-            av_log(avctx, AV_LOG_INFO, "\n");
+            av_dlog(avctx, "\n");
     }
 
     if (i % 16)
-        av_log(avctx, AV_LOG_INFO, "\n");
-
-#endif
+        av_dlog(avctx, "\n");
 
     if (region == 0)
         return;
@@ -912,27 +906,22 @@ static void dvbsub_parse_clut_segment(AVCodecContext *avctx,
     DVBSubContext *ctx = avctx->priv_data;
 
     const uint8_t *buf_end = buf + buf_size;
-    int clut_id;
+    int i, clut_id;
     DVBSubCLUT *clut;
     int entry_id, depth , full_range;
     int y, cr, cb, alpha;
     int r, g, b, r_add, g_add, b_add;
 
-#ifdef DEBUG_PACKET_CONTENTS
-    int i;
-
-    av_log(avctx, AV_LOG_INFO, "DVB clut packet:\n");
+    av_dlog(avctx, "DVB clut packet:\n");
 
     for (i=0; i < buf_size; i++) {
-        av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]);
+        av_dlog(avctx, "%02x ", buf[i]);
         if (i % 16 == 15)
-            av_log(avctx, AV_LOG_INFO, "\n");
+            av_dlog(avctx, "\n");
     }
 
     if (i % 16)
-        av_log(avctx, AV_LOG_INFO, "\n");
-
-#endif
+        av_dlog(avctx, "\n");
 
     clut_id = *buf++;
     buf += 1;
@@ -1174,7 +1163,7 @@ static void dvbsub_parse_page_segment(AVCodecContext *avctx,
 }
 
 
-#ifdef DEBUG_SAVE_IMAGES
+#ifdef DEBUG
 static void save_display_set(DVBSubContext *ctx)
 {
     DVBSubRegion *region;
@@ -1387,7 +1376,7 @@ static int dvbsub_display_end_segment(AVCodecContext *avctx, const uint8_t *buf,
 
     sub->num_rects = i;
 
-#ifdef DEBUG_SAVE_IMAGES
+#ifdef DEBUG
     save_display_set(ctx);
 #endif
 
@@ -1406,30 +1395,28 @@ static int dvbsub_decode(AVCodecContext *avctx,
     int segment_type;
     int page_id;
     int segment_length;
-
-#ifdef DEBUG_PACKET_CONTENTS
     int i;
 
-    av_log(avctx, AV_LOG_INFO, "DVB sub packet:\n");
+    av_dlog(avctx, "DVB sub packet:\n");
 
     for (i=0; i < buf_size; i++) {
-        av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]);
+        av_dlog(avctx, "%02x ", buf[i]);
         if (i % 16 == 15)
-            av_log(avctx, AV_LOG_INFO, "\n");
+            av_dlog(avctx, "\n");
     }
 
     if (i % 16)
-        av_log(avctx, AV_LOG_INFO, "\n");
+        av_dlog(avctx, "\n");
 
-#endif
-
-    if (buf_size <= 2)
+    if (buf_size <= 6 || *buf != 0x0f) {
+        av_dlog(avctx, "incomplete or broken packet");
         return -1;
+    }
 
     p = buf;
     p_end = buf + buf_size;
 
-    while (p < p_end && *p == 0x0f) {
+    while (p_end - p >= 6 && *p == 0x0f) {
         p += 1;
         segment_type = *p++;
         page_id = AV_RB16(p);
@@ -1437,6 +1424,11 @@ static int dvbsub_decode(AVCodecContext *avctx,
         segment_length = AV_RB16(p);
         p += 2;
 
+        if (p_end - p < segment_length) {
+            av_dlog(avctx, "incomplete or broken packet");
+            return -1;
+        }
+
         if (page_id == ctx->composition_id || page_id == ctx->ancillary_id ||
             ctx->composition_id == -1 || ctx->ancillary_id == -1) {
             switch (segment_type) {
@@ -1467,23 +1459,17 @@ static int dvbsub_decode(AVCodecContext *avctx,
         p += segment_length;
     }
 
-    if (p != p_end) {
-        av_dlog(avctx, "Junk at end of packet\n");
-        return -1;
-    }
-
-    return buf_size;
+    return p - buf;
 }
 
 
 AVCodec ff_dvbsub_decoder = {
-    "dvbsub",
-    AVMEDIA_TYPE_SUBTITLE,
-    CODEC_ID_DVB_SUBTITLE,
-    sizeof(DVBSubContext),
-    dvbsub_init_decoder,
-    NULL,
-    dvbsub_close_decoder,
-    dvbsub_decode,
+    .name           = "dvbsub",
+    .type           = AVMEDIA_TYPE_SUBTITLE,
+    .id             = CODEC_ID_DVB_SUBTITLE,
+    .priv_data_size = sizeof(DVBSubContext),
+    .init           = dvbsub_init_decoder,
+    .close          = dvbsub_close_decoder,
+    .decode         = dvbsub_decode,
     .long_name = NULL_IF_CONFIG_SMALL("DVB subtitles"),
 };