]> git.sesse.net Git - ffmpeg/commitdiff
avcodec/dvdsubdec: reject some broken packets
authorwm4 <nfxjfg@googlemail.com>
Mon, 21 Sep 2015 16:22:35 +0000 (18:22 +0200)
committerwm4 <nfxjfg@googlemail.com>
Tue, 22 Sep 2015 15:41:01 +0000 (17:41 +0200)
If cmd_pos is broken, this would just keep accumulating packets in the
reassembly buffer, until it fails and flushes the buffer on overflow.
Since packets are usually rather small, this will take a lot of subtitle
packets. The perceived effect is that subtitles are not displayed
anymore after the faulty packet was passed to the decoder.

I'm not terribly sure about this, but on the other hand this code is
active only when fragmented packets need to be reassembled.

Fixes sample file in trac issue #4872.

libavcodec/dvdsubdec.c

index 57eafbf2704119705e44d12959177cc30b23436f..b7285a428ab01f48c4d5bd17d4fefef4f4727749 100644 (file)
@@ -227,6 +227,7 @@ static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header,
     int date;
     int i;
     int is_menu = 0;
+    uint32_t size;
 
     if (buf_size < 10)
         return -1;
@@ -241,10 +242,16 @@ static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header,
         cmd_pos = 2;
     }
 
+    size = READ_OFFSET(buf + (big_offsets ? 2 : 0));
     cmd_pos = READ_OFFSET(buf + cmd_pos);
 
-    if (cmd_pos < 0 || cmd_pos > buf_size - 2 - offset_size)
+    if (cmd_pos < 0 || cmd_pos > buf_size - 2 - offset_size) {
+        if (cmd_pos > size) {
+            av_log(ctx, AV_LOG_ERROR, "Discarding invalid packet\n");
+            return 0;
+        }
         return AVERROR(EAGAIN);
+    }
 
     while (cmd_pos > 0 && cmd_pos < buf_size - 2 - offset_size) {
         date = AV_RB16(buf + cmd_pos);