diff options
author | Andreas Rheinhardt <andreas.rheinhardt@gmail.com> | 2019-06-24 01:42:31 +0200 |
---|---|---|
committer | James Almer <jamrial@gmail.com> | 2019-06-24 22:19:03 -0300 |
commit | ff5ea59f7b05cb4d37ba9e2c3ee383ff24a10ae0 (patch) | |
tree | 7f8ab030491b375862d8a4395a67366f920d58ab | |
parent | a569a7b3bb017315b954ca686e1e8add05f07f09 (diff) | |
download | ffmpeg-ff5ea59f7b05cb4d37ba9e2c3ee383ff24a10ae0.tar.gz |
avformat/matroskadec: Improve error/EOF checks III
Up until now, when an element was skipped, it was relied upon
ffio_limit to make sure that there is enough data available to skip.
ffio_limit itself relies upon the availability of the file's size. As
this needn't be available, the check has been refined: First one byte
less than intended is skipped, then another byte is read, followed by a
check of the error flags.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
-rw-r--r-- | libavformat/matroskadec.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 5a9acd5ba7..bc73bfed11 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -1258,13 +1258,23 @@ static int ebml_parse_elem(MatroskaDemuxContext *matroska, case EBML_STOP: return 1; default: - if (ffio_limit(pb, length) != length) { - // ffio_limit emits its own error message, - // so we don't have to. - return AVERROR(EIO); - } - res = avio_skip(pb, length); - res = res < 0 ? res : 0; + if (length) { + if (ffio_limit(pb, length) != length) { + // ffio_limit emits its own error message, + // so we don't have to. + return AVERROR(EIO); + } + if ((res = avio_skip(pb, length - 1)) >= 0) { + // avio_skip might take us past EOF. We check for this + // by skipping only length - 1 bytes, reading a byte and + // checking the error flags. This is done in order to check + // that the element has been properly skipped even when + // no filesize (that ffio_limit relies on) is available. + avio_r8(pb); + res = NEEDS_CHECKING; + } + } else + res = 0; } if (res) { if (res == NEEDS_CHECKING) { |