diff mbox series

[FFmpeg-devel] Fix for avformat DHAV parsing issue.

Message ID CAOWMy3=Yc3gV+V0dVqns5TxEM347_NPYrT91QsZVFp8w3VPdVQ@mail.gmail.com
State New
Headers show
Series [FFmpeg-devel] Fix for avformat DHAV parsing issue.
Related show

Checks

Context Check Description
andriy/x86_make success Make finished
andriy/x86_make_fate success Make fate finished
andriy/PPC64_make success Make finished
andriy/PPC64_make_fate success Make fate finished

Commit Message

Idan Freiberg Jan. 13, 2021, 12:25 p.m. UTC
Hello FFmpeg developers,

Iv'e noticed some DAV files containing a 0xff's padding in between DHAV
chunks. This is possible when the Dahua DVR device generates a DAV file
which is concatenated from 2 different DAV files kept on the device hard
drive.

Here <https://www98.zippyshare.com/v/SjZCQwuv/file.html> is a 30 seconds
sample DAV file with such concatenation. The current code (master) fails to
parse frame at 11:00:12 (clock on frame) as it incorrectly skips valid DHAV
chunks in the file after detecting the padding.

Proposing a possible patch for this issue (git formatted patch is attached).
Will like to hear your thoughts and insights.

Thank you
diff mbox series

Patch

diff --git a/libavformat/dhav.c b/libavformat/dhav.c
index 00e0d8476e..6a6c235e65 100644
--- a/libavformat/dhav.c
+++ b/libavformat/dhav.c
@@ -173,18 +173,9 @@  static int read_chunk(AVFormatContext *s)
     if (avio_feof(s->pb))
         return AVERROR_EOF;
 
-    if (avio_rl32(s->pb) != MKTAG('D','H','A','V') && dhav->last_good_pos < INT64_MAX - 0x8000) {
-        dhav->last_good_pos += 0x8000;
-        avio_seek(s->pb, dhav->last_good_pos, SEEK_SET);
-
-        while (avio_rl32(s->pb) != MKTAG('D','H','A','V')) {
-            if (avio_feof(s->pb) || dhav->last_good_pos >= INT64_MAX - 0x8000)
-                return AVERROR_EOF;
-            dhav->last_good_pos += 0x8000;
-            ret = avio_skip(s->pb, 0x8000 - 4);
-            if (ret < 0)
-                return ret;
-        }
+    while (avio_r8(s->pb) != 'D' || avio_r8(s->pb) != 'H' || avio_r8(s->pb) != 'A' || avio_r8(s->pb) != 'V') {
+        if (avio_feof(s->pb))
+            return AVERROR_EOF;
     }
 
     start = avio_tell(s->pb) - 4;