summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Rheinhardt <andreas.rheinhardt@gmail.com>2019-05-17 00:30:11 +0200
committerJames Almer <jamrial@gmail.com>2019-07-16 16:16:59 -0300
commit3ed2755baaf3f8a9f088f8c7b9cc7bd8c629e8fb (patch)
tree1161e0b82d662b2ffcfd7d5835aca54b078429ca
parent38255cdcf815ff44bb0ab10cb16b96e409f2eeed (diff)
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>
-rw-r--r--libavformat/matroskadec.c23
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);
}