[FFmpeg-cvslog] avformat/matroskadec: Don't discard valid packets

Andreas Rheinhardt git at videolan.org
Wed May 20 12:16:07 EEST 2020


ffmpeg | branch: release/4.2 | Andreas Rheinhardt <andreas.rheinhardt at gmail.com> | Wed Mar 25 06:00:53 2020 +0100| [26d1e77923f35bcd959249dd5a351e30a93a65f0] | committer: Andreas Rheinhardt

avformat/matroskadec: Don't discard valid packets

A Block (meaning both a Block in a BlockGroup as well as a SimpleBlock)
must have at least three bytes after the field containing the encoded
TrackNumber. So if there are <= 3 bytes, the Matroska demuxer would
skip this block, believing it to be an empty, but valid Block.

This might discard valid nonempty Blocks, namely if the track uses header
stripping. And certain definitely spec-incompliant Blocks don't raise
errors: Those with two or less bytes left after the encoded TrackNumber
and those with three bytes left, but with flags indicating that the Block
uses lacing as then there has to be further data describing the lacing.

Furthermore, zero-sized packets were still possible because only the
size of the last entry of a lace was checked.

This commit fixes this. All spec-compliant Blocks that contain data
(even if side data only) are now returned to the caller; spec-compliant
Blocks that don't contain anything are not returned.

Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt at gmail.com>
(cherry picked from commit e471faf96230076f67e393df9d1a90a08c22a055)

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=26d1e77923f35bcd959249dd5a351e30a93a65f0
---

 libavformat/matroskadec.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index 36bd9c3848..3cf4296f8d 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -3023,7 +3023,9 @@ static int matroska_parse_laces(MatroskaDemuxContext *matroska, uint8_t **buf,
         return 0;
     }
 
-    av_assert0(size > 0);
+    if (size <= 0)
+        return AVERROR_INVALIDDATA;
+
     *laces    = *data + 1;
     data     += 1;
     size     -= 1;
@@ -3053,7 +3055,7 @@ static int matroska_parse_laces(MatroskaDemuxContext *matroska, uint8_t **buf,
                     break;
             }
         }
-        if (size <= total) {
+        if (size < total) {
             res = AVERROR_INVALIDDATA;
             break;
         }
@@ -3100,7 +3102,7 @@ static int matroska_parse_laces(MatroskaDemuxContext *matroska, uint8_t **buf,
             lace_size[n] = lace_size[n - 1] + snum;
             total       += lace_size[n];
         }
-        if (size <= total) {
+        if (size < total) {
             res = AVERROR_INVALIDDATA;
             break;
         }
@@ -3422,7 +3424,7 @@ static int matroska_parse_frame(MatroskaDemuxContext *matroska,
 {
     MatroskaTrackEncoding *encodings = track->encodings.elem;
     uint8_t *pkt_data = data;
-    int res;
+    int res = 0;
     AVPacket pktl, *pkt = &pktl;
 
     if (encodings && !encodings->type && encodings->scope & 1) {
@@ -3458,6 +3460,9 @@ static int matroska_parse_frame(MatroskaDemuxContext *matroska,
         pkt_data = pr_data;
     }
 
+    if (!pkt_size && !additional_size)
+        goto no_output;
+
     av_init_packet(pkt);
     if (pkt_data != data)
         pkt->buf = av_buffer_create(pkt_data, pkt_size + AV_INPUT_BUFFER_PADDING_SIZE,
@@ -3528,6 +3533,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
 
     return 0;
 
+no_output:
 fail:
     if (pkt_data != data)
         av_freep(&pkt_data);
@@ -3561,8 +3567,8 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, AVBufferRef *buf
         av_log(matroska->ctx, AV_LOG_INFO,
                "Invalid stream %"PRIu64"\n", num);
         return AVERROR_INVALIDDATA;
-    } else if (size <= 3)
-        return 0;
+    } else if (size < 3)
+        return AVERROR_INVALIDDATA;
     st = track->stream;
     if (st->discard >= AVDISCARD_ALL)
         return res;



More information about the ffmpeg-cvslog mailing list