aboutsummaryrefslogtreecommitdiff
path: root/src/zenstore/blockstore.cpp
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2025-05-02 15:33:58 +0200
committerGitHub Enterprise <[email protected]>2025-05-02 15:33:58 +0200
commita9c83b3c1299692923e2c16b696f5b9e211f5737 (patch)
tree21e9ea21386672d2b870baf3103ebde2b5fbbb76 /src/zenstore/blockstore.cpp
parentcbobject validation (#377) (diff)
downloadzen-a9c83b3c1299692923e2c16b696f5b9e211f5737.tar.xz
zen-a9c83b3c1299692923e2c16b696f5b9e211f5737.zip
iterate chunks crash fix (#376)
* Bugfix: Add explicit lambda capture in CasContainer::IterateChunks to avoid accessing state data references
Diffstat (limited to 'src/zenstore/blockstore.cpp')
-rw-r--r--src/zenstore/blockstore.cpp31
1 files changed, 21 insertions, 10 deletions
diff --git a/src/zenstore/blockstore.cpp b/src/zenstore/blockstore.cpp
index 7cc09be15..c58080e6a 100644
--- a/src/zenstore/blockstore.cpp
+++ b/src/zenstore/blockstore.cpp
@@ -735,6 +735,8 @@ BlockStore::IterateBlock(std::span<const BlockStoreLocation> ChunkLocations,
return true;
}
+ ZEN_ASSERT(ChunkLocations.size() >= InChunkIndexes.size());
+
if (LargeSizeLimit == 0)
{
LargeSizeLimit = DefaultIterateSmallChunkWindowSize;
@@ -746,7 +748,10 @@ BlockStore::IterateBlock(std::span<const BlockStoreLocation> ChunkLocations,
IterateSmallChunkWindowSize = Min((LargeSizeLimit + IterateSmallChunkMaxGapSize) * ChunkLocations.size(), IterateSmallChunkWindowSize);
- uint32_t BlockIndex = ChunkLocations[InChunkIndexes[0]].BlockIndex;
+ const size_t FirstLocationIndex = InChunkIndexes[0];
+ ZEN_ASSERT(FirstLocationIndex < ChunkLocations.size());
+
+ const uint32_t BlockIndex = ChunkLocations[FirstLocationIndex].BlockIndex;
std::vector<size_t> ChunkIndexes(InChunkIndexes.begin(), InChunkIndexes.end());
std::sort(ChunkIndexes.begin(), ChunkIndexes.end(), [&](size_t IndexA, size_t IndexB) -> bool {
return ChunkLocations[IndexA].Offset < ChunkLocations[IndexB].Offset;
@@ -756,8 +761,9 @@ BlockStore::IterateBlock(std::span<const BlockStoreLocation> ChunkLocations,
IterateSmallChunkWindowSize,
IterateSmallChunkMaxGapSize,
&ChunkLocations](uint64_t BlockFileSize, std::span<const size_t> ChunkIndexes, size_t StartIndexOffset) -> size_t {
- size_t ChunkCount = 0;
- size_t StartIndex = ChunkIndexes[StartIndexOffset];
+ size_t ChunkCount = 0;
+ size_t StartIndex = ChunkIndexes[StartIndexOffset];
+ ZEN_ASSERT(StartIndex < ChunkLocations.size());
const BlockStoreLocation& StartLocation = ChunkLocations[StartIndex];
uint64_t StartOffset = StartLocation.Offset;
uint64_t LastEnd = StartOffset + StartLocation.Size;
@@ -810,22 +816,26 @@ BlockStore::IterateBlock(std::span<const BlockStoreLocation> ChunkLocations,
ZEN_ASSERT(BlockFile);
InsertLock.ReleaseNow();
+ const size_t BlockSize = BlockFile->FileSize();
+
IoBuffer ReadBuffer;
void* BufferBase = nullptr;
size_t LocationIndexOffset = 0;
while (LocationIndexOffset < ChunkIndexes.size())
{
- size_t ChunkIndex = ChunkIndexes[LocationIndexOffset];
+ size_t ChunkIndex = ChunkIndexes[LocationIndexOffset];
+ ZEN_ASSERT(ChunkIndex < ChunkLocations.size());
const BlockStoreLocation& FirstLocation = ChunkLocations[ChunkIndex];
+ ZEN_ASSERT(FirstLocation.BlockIndex == BlockIndex);
- const size_t BlockSize = BlockFile->FileSize();
const size_t RangeCount = GetNextRange(BlockSize, ChunkIndexes, LocationIndexOffset);
if (RangeCount > 1)
{
- size_t LastChunkIndex = ChunkIndexes[LocationIndexOffset + RangeCount - 1];
- const BlockStoreLocation& LastLocation = ChunkLocations[LastChunkIndex];
- uint64_t Size = LastLocation.Offset + LastLocation.Size - FirstLocation.Offset;
+ size_t LastChunkIndex = ChunkIndexes[LocationIndexOffset + RangeCount - 1];
+ ZEN_ASSERT(LastChunkIndex < ChunkLocations.size());
+ const BlockStoreLocation& LastLocation = ChunkLocations[LastChunkIndex];
+ uint64_t Size = LastLocation.Offset + LastLocation.Size - FirstLocation.Offset;
if (ReadBuffer.GetSize() < Size)
{
ReadBuffer = IoBuffer(Min(Size * 2, IterateSmallChunkWindowSize));
@@ -834,8 +844,9 @@ BlockStore::IterateBlock(std::span<const BlockStoreLocation> ChunkLocations,
BlockFile->Read(BufferBase, Size, FirstLocation.Offset);
for (size_t RangeIndex = 0; RangeIndex < RangeCount; ++RangeIndex)
{
- size_t NextChunkIndex = ChunkIndexes[LocationIndexOffset + RangeIndex];
- const BlockStoreLocation& ChunkLocation = ChunkLocations[NextChunkIndex];
+ size_t NextChunkIndex = ChunkIndexes[LocationIndexOffset + RangeIndex];
+ ZEN_ASSERT(NextChunkIndex < ChunkLocations.size());
+ const BlockStoreLocation& ChunkLocation = ChunkLocations[NextChunkIndex];
if (ChunkLocation.Size == 0 || ((ChunkLocation.Offset + ChunkLocation.Size) > BlockSize))
{
ZEN_LOG_SCOPE("chunk [{},{}] out of bounds (block #{} file size = {})",