This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch master
in repository ffmpeg.

commit c764c4b8e47cd3764aff1de33b1d1f710dd34980
Author:     Niklas Haas <[email protected]>
AuthorDate: Sat Jul 11 13:01:53 2026 +0200
Commit:     Niklas Haas <[email protected]>
CommitDate: Sun Jul 19 10:20:04 2026 +0000

    avformat/shared: give up on cache file after too many corrupt blocks
    
    If we got 10 corrupt blocks in a row, chances are, the rest of the file is
    completely corrupt. I didn't bother making this user-configurable as it is
    already sort of a niche option to work around lack of a reliable filesystem.
    
    Sponsored-by: nxtedition AB
    Signed-off-by: Niklas Haas <[email protected]>
---
 libavformat/shared.c | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/libavformat/shared.c b/libavformat/shared.c
index ca33b7ddad..df72abff7f 100644
--- a/libavformat/shared.c
+++ b/libavformat/shared.c
@@ -62,6 +62,12 @@
 #define HEADER_MAGIC   MKTAG(u'\xFF', 'S', 'h', '$')
 #define HEADER_VERSION 3
 
+/**
+ * Hard watershed of consecutive failed blocks before we give up on the cache
+ * file altogether and assume it's entirely lost to us.
+ **/
+#define MAX_CORRUPT_BLOCKS 10
+
 static int hash_uri(uint8_t hash[HASH_SIZE], const char *uri)
 {
     struct AVHashContext *ctx = NULL;
@@ -161,6 +167,7 @@ typedef struct SharedContext {
     uint8_t *tmp_buf;
     int block_size;
     int write_err; ///< write error occurred
+    int num_corrupt;
 
     /* cache file */
     uint8_t *cache_data; ///< optional mmap of the cache file
@@ -610,6 +617,9 @@ static int shared_read(URLContext *h, unsigned char *buf, 
int size)
 retry:
     switch (state) {
     default:
+        if (s->num_corrupt >= MAX_CORRUPT_BLOCKS)
+            goto read_block; /* assume broken cache file */
+
         /* We always need to read the entire block to verify integrity */
         block_size = clamp_size(h, block_size, block_pos); /* filesize may 
have changed */
         if (s->cache_data) {
@@ -629,10 +639,13 @@ retry:
             av_log(h, AV_LOG_ERROR, "Cache corruption detected for block 
0x%"PRIx64" at "
                    "offset 0x%"PRIx64": expected CRC: 0x%08X, got: 0x%08X\n",
                    block_id, block_pos, state, crc);
-            if (s->retry_corrupt)
+            if (s->retry_corrupt) {
+                s->num_corrupt++;
                 goto read_block;
+            }
             return AVERROR(EIO);
-        }
+        } else
+            s->num_corrupt = 0; /* reset corrupt block count on success */
 
         tmp += (ptrdiff_t) offset;
         size = FFMIN(size, block_size - offset);
@@ -652,6 +665,13 @@ retry:
         return AVERROR(EIO);
 
 read_block:
+        if (s->num_corrupt == MAX_CORRUPT_BLOCKS) {
+            av_log(h, AV_LOG_ERROR, "Too many consecutive corrupt blocks; "
+                   "assuming cache file is completely broken.\n");
+            s->num_corrupt++; /* silence this log on subsequent reads */
+        }
+        av_fallthrough;
+
     case BLOCK_NONE:
         if (s->read_only)
             break; /* don't mark block as pending */

_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to