]> git.sesse.net Git - ffmpeg/commitdiff
avformat/matroskadec: Improve error/EOF checks III
authorAndreas Rheinhardt <andreas.rheinhardt@gmail.com>
Sun, 23 Jun 2019 23:42:31 +0000 (01:42 +0200)
committerJames Almer <jamrial@gmail.com>
Tue, 25 Jun 2019 01:19:03 +0000 (22:19 -0300)
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>
libavformat/matroskadec.c

index 5a9acd5ba746de489a78720d049cd9bfeb7d5c4b..bc73bfed1166932ce4c2d257748b72a6d5aa7534 100644 (file)
@@ -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) {