This makes decoding far more robust, since OggS, the ogg magic, 
can be commonly found randomly in streams, which previously made
the demuxer think there's a new stream or a change in such.

Patch attached.

>From 61759b6b1ef3ca813eb39ee9ace2342eb121b3b0 Mon Sep 17 00:00:00 2001
From: Lynne <d...@lynne.ee>
Date: Tue, 28 Apr 2020 12:52:11 +0100
Subject: [PATCH 2/3] oggdec: verify page checksum

This makes decoding far more robust, since OggS, the ogg magic,
can be commonly found randomly in streams, which previously made
the demuxer think there's a new stream or a change in such.
---
 libavformat/oggdec.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c
index f67cf42e82..05cea2528b 100644
--- a/libavformat/oggdec.c
+++ b/libavformat/oggdec.c
@@ -31,6 +31,7 @@
 #include <stdio.h>
 #include "libavutil/avassert.h"
 #include "libavutil/intreadwrite.h"
+#include "avio_internal.h"
 #include "oggdec.h"
 #include "avformat.h"
 #include "internal.h"
@@ -321,6 +322,7 @@ static int ogg_read_page(AVFormatContext *s, int *sid)
     int flags, nsegs;
     uint64_t gp;
     uint32_t serial;
+    uint32_t crc, crc_tmp;
     int size = 0, idx;
     int64_t page_pos;
     uint8_t sync[4];
@@ -359,6 +361,9 @@ static int ogg_read_page(AVFormatContext *s, int *sid)
         return AVERROR_INVALIDDATA;
     }
 
+    /* 0x4fa9b05f = av_crc(AV_CRC_32_IEEE, 0x0, "OggS", 4) */
+    ffio_init_checksum(bc, ff_crc04C11DB7_update, 0x4fa9b05f);
+
     if (avio_r8(bc) != 0) {      /* version */
         av_log (s, AV_LOG_ERROR, "ogg page, unsupported version\n");
         return AVERROR_INVALIDDATA;
@@ -367,7 +372,12 @@ static int ogg_read_page(AVFormatContext *s, int *sid)
     flags  = avio_r8(bc);
     gp     = avio_rl64(bc);
     serial = avio_rl32(bc);
-    avio_skip(bc, 8); /* seq, crc */
+    avio_skip(bc, 4); /* seq */
+
+    crc_tmp = ffio_get_checksum(bc);
+    crc     = avio_rb32(bc);
+    crc_tmp = ff_crc04C11DB7_update(crc_tmp, (uint8_t[4]){0}, 4);
+    ffio_init_checksum(bc, ff_crc04C11DB7_update, crc_tmp);
 
     nsegs = avio_r8(bc);
     page_pos = avio_tell(bc) - 27;
@@ -407,6 +417,15 @@ static int ogg_read_page(AVFormatContext *s, int *sid)
         return ret < 0 ? ret : AVERROR_EOF;
     }
 
+    if (crc ^ ffio_get_checksum(bc)) {
+        av_log(s, AV_LOG_ERROR, "CRC mismatch!\n");
+        if (idx < 0)
+            av_free(readout_buf);
+        avio_seek(bc, -size, SEEK_CUR);
+        return 0;
+    }
+
+    /* CRC is correct so we can be 99% sure there's an actual change here */
     if (idx < 0) {
         if (data_packets_seen(ogg))
             idx = ogg_replace_stream(s, serial, size);
-- 
2.26.2

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Reply via email to