[FFmpeg-devel,20/21] avformat/matroskadec: Redo EOF handling

Submitted by Oliver Collyer via ffmpeg-devel on March 27, 2019, 11:18 a.m.

Details

Message ID 20190327111852.3784-21-andreas.rheinhardt@googlemail.com
State New
Headers show

Commit Message

Oliver Collyer via ffmpeg-devel March 27, 2019, 11:18 a.m.
This commit adds a check and a corresponding warning whether there
is data beyond the Matroska segment (only reasonable for finite-sized
segments). If everything looks alright, then parsing is stopped as soon
as EOF is reached (in contrast, the current code would always call
matroska_resync at the end).

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@googlemail.com>
---
 libavformat/matroskadec.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

Patch hide | download patch | download mbox

diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index c1feb3f0a1..bd0dfee4db 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -3547,6 +3547,14 @@  static int matroska_parse_cluster(MatroskaDemuxContext *matroska)
     ebml_free(matroska_blockgroup, block);
     memset(block, 0, sizeof(*block));
     } else if (!matroska->num_levels) {
+        if (!avio_feof(matroska->ctx->pb)) {
+            avio_r8(matroska->ctx->pb);
+            if (!avio_feof(matroska->ctx->pb)) {
+                av_log(matroska->ctx, AV_LOG_WARNING, "File extends beyond "
+                       "end of segment.\n");
+                return AVERROR_INVALIDDATA;
+            }
+        }
         matroska->done = 1;
         return AVERROR_EOF;
     }
@@ -3560,10 +3568,11 @@  static int matroska_read_packet(AVFormatContext *s, AVPacket *pkt)
     int ret = 0;
 
     while (matroska_deliver_packet(matroska, pkt)) {
-        int64_t pos = avio_tell(matroska->ctx->pb);
+        int64_t pos;
         if (matroska->done)
             return (ret < 0) ? ret : AVERROR_EOF;
-        if (matroska_parse_cluster(matroska) < 0)
+        pos = avio_tell(matroska->ctx->pb);
+        if ((matroska_parse_cluster(matroska) < 0) && !matroska->done)
             ret = matroska_resync(matroska, pos);
     }