From 501405a6eef4a19c63061ae7dd5927db30e6b088 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Sat, 11 Apr 2026 21:32:25 +0100 Subject: [PATCH] Recover damaged block headers. --- src/read.c | 10 ++++++++++ tests/erasure_coding.cpp | 16 +++++++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/read.c b/src/read.c index 274abb9..7ddbef7 100644 --- a/src/read.c +++ b/src/read.c @@ -607,6 +607,16 @@ AARU_EXPORT int32_t AARU_CALL aaruf_read_sector(void *context, const uint64_t se return AARUF_ERROR_CANNOT_READ_HEADER; } + /* Sanity check: if the cached/read block header looks corrupt, skip directly to EC recovery. + * A corrupt header will have garbage sectorSize, compression, or identifier fields. */ + if(block_header->identifier != DataBlock || + block_header->sectorSize == 0 || block_header->sectorSize > 65536) + { + TRACE("Block header at offset %" PRIu64 " appears corrupt (id=0x%08X sectorSize=%u)", + block_offset, block_header->identifier, block_header->sectorSize); + goto ec_try_recovery; + } + if(data == NULL || *length < block_header->sectorSize) { TRACE("Buffer too small for sector, required %u bytes", block_header->sectorSize); diff --git a/tests/erasure_coding.cpp b/tests/erasure_coding.cpp index 0cc00c2..f52d5c7 100644 --- a/tests/erasure_coding.cpp +++ b/tests/erasure_coding.cpp @@ -284,9 +284,19 @@ TEST_F(ErasureCodingTest, RecoverCorruptedDataBlock) */ TEST_F(ErasureCodingTest, RecoverCorruptedBlockHeader) { - /* NOTE: Corrupted BlockHeader recovery requires cache invalidation - * which is not yet implemented. Skipping for now. */ - GTEST_SKIP() << "BlockHeader corruption recovery requires cache invalidation (TODO)"; + uint64_t golden_crc = 0; + ASSERT_TRUE(create_ec_image("data/mf2hd.aif", "ec_test_output.aif", 4, 2, &golden_crc)); + + ASSERT_TRUE(copy_file("ec_test_output.aif", "ec_test_corrupt.aif")); + + /* Corrupt the first block's header at offset 512 (after alignment). + * Corrupt 32 bytes = entire BlockHeader, making identifier/compression/sectorSize garbage. */ + corrupt_file("ec_test_corrupt.aif", 512, 32); + + bool success = false; + uint64_t read_crc = compute_image_crc("ec_test_corrupt.aif", &success); + ASSERT_TRUE(success) << "EC recovery failed on corrupted BlockHeader"; + EXPECT_EQ(read_crc, golden_crc); } /**