This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit ca748964fe4a5638f1d127d6fb38604c270e3617 Author: Niklas Haas <[email protected]> AuthorDate: Fri Feb 20 14:16:20 2026 +0100 Commit: Niklas Haas <[email protected]> CommitDate: Thu Jun 4 17:48:12 2026 +0200 avformat/shared: implement 16-bit CRC check Decided to split this off from the previous commit in case we ever want to revert it, since it does double the overhead of the spacemap as well as adding extra overhead to both the read and write path. Bump the cache version to 2 to reflect the changed disk format. --- libavformat/shared.c | 70 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 16 deletions(-) diff --git a/libavformat/shared.c b/libavformat/shared.c index 8cb6f3040c..e0c06ef8b7 100644 --- a/libavformat/shared.c +++ b/libavformat/shared.c @@ -23,6 +23,7 @@ #include "libavutil/avassert.h" #include "libavutil/avstring.h" +#include "libavutil/crc.h" #include "libavutil/hash.h" #include "libavutil/file_open.h" #include "libavutil/mem.h" @@ -74,17 +75,35 @@ static int hash_uri(uint8_t hash[HASH_SIZE], const char *uri) } #define HEADER_MAGIC MKTAG(u'\xFF', 'S', 'h', '$') -#define HEADER_VERSION 1 +#define HEADER_VERSION 2 enum BlockState { - BLOCK_NONE, - BLOCK_CACHED, ///< block was cached successfully - BLOCK_PENDING, ///< a thread is currently trying to write this block - BLOCK_FAILED, ///< the underlying I/O source failed to read this block + /* Reserved block state values */ + BLOCK_NONE = 0, ///< block is not cached + BLOCK_PENDING, ///< a thread is currently trying to write this block + BLOCK_FAILED, ///< the underlying I/O source failed to read this block + + /** + * All other block states represent valid cached blocks, with the value + * being the CRC of the block data. + */ }; +static uint16_t get_block_crc(const uint8_t *block, size_t block_size) +{ + uint16_t crc = av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, block, block_size); + switch (crc) { + case BLOCK_NONE: + case BLOCK_FAILED: + case BLOCK_PENDING: + return ~crc; /* avoid reserved block states */ + default: + return crc; + } +} + typedef struct Block { - atomic_uchar state; /* enum BlockState */ + atomic_ushort state; /* enum BlockState */ } Block; typedef struct Spacemap { @@ -575,20 +594,37 @@ static int shared_read(URLContext *h, unsigned char *buf, int size) return ret; Block *const block = &s->spacemap->blocks[block_id]; - unsigned char state = atomic_load_explicit(&block->state, memory_order_acquire); + unsigned short state = atomic_load_explicit(&block->state, memory_order_acquire); int64_t pending_since = 0; retry: switch (state) { - case BLOCK_CACHED: - size = FFMIN(size, s->block_size - offset); - size = clamp_size(h, size, s->pos); /* filesize may have changed */ - ret = read_cache(s, buf, size, s->pos); - if (ret < 0) { - av_log(h, AV_LOG_ERROR, "Failed to read from cache file: %s\n", av_err2str(ret)); - return ret; + default: + /* 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) { + av_assert1(block_pos + block_size <= s->cache_size); + tmp = s->cache_data + block_pos; + } else { + tmp = s->tmp_buf; + ret = read_cache(s, tmp, block_size, block_pos); + if (ret < 0) { + av_log(h, AV_LOG_ERROR, "Failed to read from cache file: %s\n", av_err2str(ret)); + return ret; + } } + uint16_t crc = get_block_crc(tmp, block_size); + if (crc != state) { + av_log(h, AV_LOG_ERROR, "Cache corruption detected for block 0x%"PRIx64" at " + "offset 0x%"PRIx64": expected CRC: 0x%04X, got: 0x%04X\n", + block_id, block_pos, state, crc); + return AVERROR(EIO); + } + + size = FFMIN(size, block_size - offset); + memcpy(buf, tmp + offset, size); + s->nb_hit++; s->pos += size; return size; @@ -721,9 +757,11 @@ retry: memory_order_relaxed, memory_order_relaxed); } else { + uint16_t crc = get_block_crc(tmp, bytes_read); av_log(h, AV_LOG_TRACE, "Cached %d bytes to block 0x%"PRIx64" at " - "offset 0x%"PRIx64"\n", bytes_read, block_id, block_pos); - atomic_store_explicit(&block->state, BLOCK_CACHED, memory_order_release); + "offset 0x%"PRIx64", CRC 0x%04X\n", bytes_read, block_id, + block_pos, crc); + atomic_store_explicit(&block->state, crc, memory_order_release); } } else { return AVERROR_EOF; _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
