Browse code

dvbsubdec: Check for invalid clut selector.

Fail decoding if strict compliance is requested.

Signed-off-by: Reimar Döffinger <Reimar.Doeffinger@gmx.de>

Reimar Döffinger authored on 2013/09/19 02:55:40
Showing 1 changed files
... ...
@@ -933,7 +933,7 @@ static void dvbsub_parse_object_segment(AVCodecContext *avctx,
933 933
 
934 934
 }
935 935
 
936
-static void dvbsub_parse_clut_segment(AVCodecContext *avctx,
936
+static int dvbsub_parse_clut_segment(AVCodecContext *avctx,
937 937
                                         const uint8_t *buf, int buf_size)
938 938
 {
939 939
     DVBSubContext *ctx = avctx->priv_data;
... ...
@@ -986,7 +986,7 @@ static void dvbsub_parse_clut_segment(AVCodecContext *avctx,
986 986
 
987 987
         if (depth == 0) {
988 988
             av_log(avctx, AV_LOG_ERROR, "Invalid clut depth 0x%x!\n", *buf);
989
-            return;
989
+            return 0;
990 990
         }
991 991
 
992 992
         full_range = (*buf++) & 1;
... ...
@@ -1012,6 +1012,11 @@ static void dvbsub_parse_clut_segment(AVCodecContext *avctx,
1012 1012
         YUV_TO_RGB2_CCIR(r, g, b, y);
1013 1013
 
1014 1014
         av_dlog(avctx, "clut %d := (%d,%d,%d,%d)\n", entry_id, r, g, b, alpha);
1015
+        if (!!(depth & 0x80) + !!(depth & 0x40) + !!(depth & 0x20) > 1) {
1016
+            av_dlog(avctx, "More than one bit level marked: %x\n", depth);
1017
+            if (avctx->strict_std_compliance > FF_COMPLIANCE_NORMAL)
1018
+                return AVERROR_INVALIDDATA;
1019
+        }
1015 1020
 
1016 1021
         if (depth & 0x80)
1017 1022
             clut->clut4[entry_id] = RGBA(r,g,b,255 - alpha);
... ...
@@ -1021,6 +1026,7 @@ static void dvbsub_parse_clut_segment(AVCodecContext *avctx,
1021 1021
             clut->clut256[entry_id] = RGBA(r,g,b,255 - alpha);
1022 1022
     }
1023 1023
     }
1024
+    return 0;
1024 1025
 }
1025 1026
 
1026 1027
 
... ...
@@ -1456,6 +1462,7 @@ static int dvbsub_decode(AVCodecContext *avctx,
1456 1456
     int page_id;
1457 1457
     int segment_length;
1458 1458
     int i;
1459
+    int ret;
1459 1460
     int got_segment = 0;
1460 1461
 
1461 1462
     av_dlog(avctx, "DVB sub packet:\n");
... ...
@@ -1502,7 +1509,8 @@ static int dvbsub_decode(AVCodecContext *avctx,
1502 1502
                 got_segment |= 2;
1503 1503
                 break;
1504 1504
             case DVBSUB_CLUT_SEGMENT:
1505
-                dvbsub_parse_clut_segment(avctx, p, segment_length);
1505
+                ret = dvbsub_parse_clut_segment(avctx, p, segment_length);
1506
+                if (ret < 0) return ret;
1506 1507
                 got_segment |= 4;
1507 1508
                 break;
1508 1509
             case DVBSUB_OBJECT_SEGMENT: