diff options
author | Andreas Rheinhardt <andreas.rheinhardt@gmail.com> | 2019-05-17 00:30:11 +0200 |
---|---|---|
committer | James Almer <jamrial@gmail.com> | 2019-07-16 16:16:59 -0300 |
commit | 3ed2755baaf3f8a9f088f8c7b9cc7bd8c629e8fb (patch) | |
tree | 1161e0b82d662b2ffcfd7d5835aca54b078429ca /libavformat/matroskadec.c | |
parent | 38255cdcf815ff44bb0ab10cb16b96e409f2eeed (diff) | |
download | ffmpeg-3ed2755baaf3f8a9f088f8c7b9cc7bd8c629e8fb.tar.gz |
avformat/matroskadec: Redo EOF handling
This commit closes the last hole in the system of checks for a
known-length file ending too early: Now an error message is emitted
in case the file ends directly after an EBML element.
Furthermore, this commit adds a check and a corresponding warning
whether there is data beyond the Matroska segment (only reasonable for
known-length segments). If everything looks alright, then parsing is
stopped as soon as EOF is reached (in contrast, the earlier code would
always call matroska_resync at the end).
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
Diffstat (limited to 'libavformat/matroskadec.c')
-rw-r--r-- | libavformat/matroskadec.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 19eb5b0041..8ab233b8df 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -1187,10 +1187,15 @@ static int ebml_parse(MatroskaDemuxContext *matroska, if (matroska->is_live) // in live mode, finish parsing if EOF is reached. return 1; - if (level && level->length == EBML_UNKNOWN_LENGTH && pos == avio_tell(pb)) { - // Unknown-length levels automatically end at EOF. - matroska->num_levels--; - return LEVEL_ENDED; + if (level && pos == avio_tell(pb)) { + if (level->length == EBML_UNKNOWN_LENGTH) { + // Unknown-length levels automatically end at EOF. + matroska->num_levels--; + return LEVEL_ENDED; + } else { + av_log(matroska->ctx, AV_LOG_ERROR, "File ended prematurely " + "at pos. %"PRIu64" (0x%"PRIx64")\n", pos, pos); + } } } return res; @@ -3622,6 +3627,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; } @@ -3642,7 +3655,7 @@ static int matroska_read_packet(AVFormatContext *s, AVPacket *pkt) while (matroska_deliver_packet(matroska, pkt)) { if (matroska->done) return (ret < 0) ? ret : AVERROR_EOF; - if (matroska_parse_cluster(matroska) < 0) + if (matroska_parse_cluster(matroska) < 0 && !matroska->done) ret = matroska_resync(matroska, matroska->resync_pos); } |