summaryrefslogtreecommitdiff
path: root/libavformat/matroskadec.c
diff options
context:
space:
mode:
authorAndreas Rheinhardt <andreas.rheinhardt@gmail.com>2019-06-24 01:42:31 +0200
committerJames Almer <jamrial@gmail.com>2019-06-24 22:19:03 -0300
commitff5ea59f7b05cb4d37ba9e2c3ee383ff24a10ae0 (patch)
tree7f8ab030491b375862d8a4395a67366f920d58ab /libavformat/matroskadec.c
parenta569a7b3bb017315b954ca686e1e8add05f07f09 (diff)
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>
Diffstat (limited to 'libavformat/matroskadec.c')
-rw-r--r--libavformat/matroskadec.c24
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) {