diff --git a/libaaruformat.nuspec b/libaaruformat.nuspec index 6a5480d..f5656f8 100644 --- a/libaaruformat.nuspec +++ b/libaaruformat.nuspec @@ -2,7 +2,7 @@ libaaruformat - 1.0.0-alpha.36 + 1.0.0-alpha.37 Library for management of AaruFormat images. claunia https://github.com/aaru-dps/libaaruformat diff --git a/src/erasure.c b/src/erasure.c index dd689b3..e91e009 100644 --- a/src/erasure.c +++ b/src/erasure.c @@ -96,11 +96,14 @@ AARU_EXPORT int32_t AARU_CALL aaruf_set_erasure_coding(void *context, uint8_t al /* Compute data shard size: max possible on-disk block size. * = sizeof(BlockHeader) + LZMA_PROPERTIES_LENGTH + (1 << dataShift) * sectorSize - * This is the worst case: uncompressed block + LZMA properties header. */ + * This is the worst case: uncompressed block + LZMA properties header. + * Use image_info.SectorSize (set by aaruf_create) since current_block_header.sectorSize + * may not be set yet if called before the first write. */ uint32_t sectors_per_block = 1U << ctx->user_data_ddt_header.dataShift; - uint32_t max_payload = sectors_per_block * ctx->current_block_header.sectorSize; - if(max_payload == 0) max_payload = sectors_per_block * 512; /* fallback if sectorSize not yet set */ - uint32_t shard_size = (uint32_t)sizeof(BlockHeader) + LZMA_PROPERTIES_LENGTH + max_payload; + uint32_t sector_size = ctx->image_info.SectorSize; + if(sector_size == 0) sector_size = 512; + uint32_t max_payload = sectors_per_block * sector_size; + uint32_t shard_size = (uint32_t)sizeof(BlockHeader) + LZMA_PROPERTIES_LENGTH + max_payload; /* Create RS codec */ rs_context *rs = rs_create(K, M); diff --git a/tests/erasure_coding.cpp b/tests/erasure_coding.cpp index f52d5c7..8d6f79a 100644 --- a/tests/erasure_coding.cpp +++ b/tests/erasure_coding.cpp @@ -385,3 +385,19 @@ TEST_F(ErasureCodingTest, BackupHeaderRecovery) ASSERT_TRUE(success) << "Backup header recovery failed — could not open/read corrupted image"; EXPECT_EQ(read_crc, golden_crc) << "CRC mismatch after backup header recovery"; } + +/** + * @test Create EC image from a CD image (2048-byte sectors) to exercise non-512 sector sizes. + * This catches the shard_size miscalculation that used current_block_header.sectorSize (0) + * instead of image_info.SectorSize, causing heap buffer overflow on CD images. + */ +TEST_F(ErasureCodingTest, CDSectorSizeImage) +{ + uint64_t golden_crc = 0; + ASSERT_TRUE(create_ec_image("data/cdmode1.aif", "ec_test_output.aif", 4, 2, &golden_crc)); + + bool success = false; + uint64_t read_crc = compute_image_crc("ec_test_output.aif", &success); + ASSERT_TRUE(success) << "Failed to read all sectors from CD EC image"; + EXPECT_EQ(read_crc, golden_crc) << "CRC mismatch on CD EC image"; +}