mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-03-28 12:32:17 +02:00
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>
This commit is contained in:
parent
38255cdcf8
commit
3ed2755baa
@ -1187,10 +1187,15 @@ static int ebml_parse(MatroskaDemuxContext *matroska,
|
|||||||
if (matroska->is_live)
|
if (matroska->is_live)
|
||||||
// in live mode, finish parsing if EOF is reached.
|
// in live mode, finish parsing if EOF is reached.
|
||||||
return 1;
|
return 1;
|
||||||
if (level && level->length == EBML_UNKNOWN_LENGTH && pos == avio_tell(pb)) {
|
if (level && pos == avio_tell(pb)) {
|
||||||
// Unknown-length levels automatically end at EOF.
|
if (level->length == EBML_UNKNOWN_LENGTH) {
|
||||||
matroska->num_levels--;
|
// Unknown-length levels automatically end at EOF.
|
||||||
return LEVEL_ENDED;
|
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;
|
return res;
|
||||||
@ -3622,6 +3627,14 @@ static int matroska_parse_cluster(MatroskaDemuxContext *matroska)
|
|||||||
ebml_free(matroska_blockgroup, block);
|
ebml_free(matroska_blockgroup, block);
|
||||||
memset(block, 0, sizeof(*block));
|
memset(block, 0, sizeof(*block));
|
||||||
} else if (!matroska->num_levels) {
|
} 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;
|
matroska->done = 1;
|
||||||
return AVERROR_EOF;
|
return AVERROR_EOF;
|
||||||
}
|
}
|
||||||
@ -3642,7 +3655,7 @@ static int matroska_read_packet(AVFormatContext *s, AVPacket *pkt)
|
|||||||
while (matroska_deliver_packet(matroska, pkt)) {
|
while (matroska_deliver_packet(matroska, pkt)) {
|
||||||
if (matroska->done)
|
if (matroska->done)
|
||||||
return (ret < 0) ? ret : AVERROR_EOF;
|
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);
|
ret = matroska_resync(matroska, matroska->resync_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user