mirror of
https://github.com/aaru-dps/libaaruformat.git
synced 2025-12-16 19:24:40 +00:00
Enhance DDT processing in ddt_v1.c and ddt_v2.c with improved error handling for LZMA compression
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "errors.h"
|
||||
|
||||
#ifdef __linux__
|
||||
#include <sys/mman.h>
|
||||
@@ -141,6 +142,12 @@ int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *found_us
|
||||
{
|
||||
// TODO: Check CRC
|
||||
case Lzma:
|
||||
if(ddt_header.cmpLength <= LZMA_PROPERTIES_LENGTH)
|
||||
{
|
||||
FATAL("Compressed DDT payload too small (%" PRIu64 ") for LZMA properties.", ddt_header.cmpLength);
|
||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||
}
|
||||
|
||||
lzma_size = ddt_header.cmpLength - LZMA_PROPERTIES_LENGTH;
|
||||
|
||||
cmp_data = (uint8_t *)malloc(lzma_size);
|
||||
@@ -201,6 +208,9 @@ int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *found_us
|
||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||
}
|
||||
|
||||
free(cmp_data);
|
||||
cmp_data = NULL;
|
||||
|
||||
ctx->inMemoryDdt = true;
|
||||
*found_user_data_ddt = true;
|
||||
|
||||
@@ -239,6 +249,12 @@ int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *found_us
|
||||
{
|
||||
// TODO: Check CRC
|
||||
case Lzma:
|
||||
if(ddt_header.cmpLength <= LZMA_PROPERTIES_LENGTH)
|
||||
{
|
||||
FATAL("Compressed DDT payload too small (%" PRIu64 ") for LZMA properties.", ddt_header.cmpLength);
|
||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||
}
|
||||
|
||||
lzma_size = ddt_header.cmpLength - LZMA_PROPERTIES_LENGTH;
|
||||
|
||||
cmp_data = (uint8_t *)malloc(lzma_size);
|
||||
@@ -295,6 +311,9 @@ int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *found_us
|
||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||
}
|
||||
|
||||
free(cmp_data);
|
||||
cmp_data = NULL;
|
||||
|
||||
if(entry->dataType == CdSectorPrefixCorrected)
|
||||
ctx->sectorPrefixDdt = cd_ddt;
|
||||
else if(entry->dataType == CdSectorSuffixCorrected)
|
||||
@@ -397,10 +416,24 @@ int32_t decode_ddt_entry_v1(aaruformatContext *ctx, const uint64_t sector_addres
|
||||
return AARUF_ERROR_NOT_AARUFORMAT;
|
||||
}
|
||||
|
||||
const uint64_t ddt_entry = ctx->userDataDdt[sector_address];
|
||||
const uint32_t offset_mask = (uint32_t)((1 << ctx->shift) - 1);
|
||||
*offset = ddt_entry & offset_mask;
|
||||
*block_offset = ddt_entry >> ctx->shift;
|
||||
if(ctx->userDataDdt == NULL)
|
||||
{
|
||||
FATAL("User data DDT not loaded.");
|
||||
TRACE("Exiting decode_ddt_entry_v1() = AARUF_ERROR_NOT_AARUFORMAT");
|
||||
return AARUF_ERROR_NOT_AARUFORMAT;
|
||||
}
|
||||
|
||||
if(ctx->shift >= 64)
|
||||
{
|
||||
FATAL("Invalid DDT shift value %u", ctx->shift);
|
||||
TRACE("Exiting decode_ddt_entry_v1() = AARUF_ERROR_INCORRECT_DATA_SIZE");
|
||||
return AARUF_ERROR_INCORRECT_DATA_SIZE;
|
||||
}
|
||||
|
||||
const uint64_t ddt_entry = ctx->userDataDdt[sector_address];
|
||||
const uint64_t offset_mask64 = (UINT64_C(1) << ctx->shift) - UINT64_C(1);
|
||||
*offset = ddt_entry & offset_mask64;
|
||||
*block_offset = ddt_entry >> ctx->shift;
|
||||
|
||||
// Partially written image... as we can't know the real sector size just assume it's common :/
|
||||
if(ddt_entry == 0)
|
||||
|
||||
@@ -158,7 +158,14 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *found_us
|
||||
switch(ddt_header.compression)
|
||||
{
|
||||
case Lzma:
|
||||
lzma_size = ddt_header.cmpLength - LZMA_PROPERTIES_LENGTH;
|
||||
if(ddt_header.cmpLength <= LZMA_PROPERTIES_LENGTH)
|
||||
{
|
||||
FATAL("Compressed DDT payload too small (%" PRIu64 ") for LZMA properties.", ddt_header.cmpLength);
|
||||
TRACE("Exiting process_ddt_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
|
||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||
}
|
||||
|
||||
lzma_size = (size_t)(ddt_header.cmpLength - LZMA_PROPERTIES_LENGTH);
|
||||
|
||||
cmp_data = (uint8_t *)malloc(lzma_size);
|
||||
if(cmp_data == NULL)
|
||||
@@ -309,7 +316,14 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *found_us
|
||||
switch(ddt_header.compression)
|
||||
{
|
||||
case Lzma:
|
||||
lzma_size = ddt_header.cmpLength - LZMA_PROPERTIES_LENGTH;
|
||||
if(ddt_header.cmpLength <= LZMA_PROPERTIES_LENGTH)
|
||||
{
|
||||
FATAL("Compressed DDT payload too small (%" PRIu64 ") for LZMA properties.", ddt_header.cmpLength);
|
||||
TRACE("Exiting process_ddt_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
|
||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||
}
|
||||
|
||||
lzma_size = (size_t)(ddt_header.cmpLength - LZMA_PROPERTIES_LENGTH);
|
||||
|
||||
cmp_data = (uint8_t *)malloc(lzma_size);
|
||||
if(cmp_data == NULL)
|
||||
@@ -367,6 +381,9 @@ int32_t process_ddt_v2(aaruformatContext *ctx, IndexEntry *entry, bool *found_us
|
||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||
}
|
||||
|
||||
free(cmp_data);
|
||||
cmp_data = NULL;
|
||||
|
||||
crc64_context = aaruf_crc64_init();
|
||||
|
||||
if(crc64_context == NULL)
|
||||
@@ -825,14 +842,14 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_addres
|
||||
|
||||
if(read_bytes != sizeof(DdtHeader2))
|
||||
{
|
||||
FATAL("Could not read block header at %" PRIu64 "", secondaryDdtOffset);
|
||||
FATAL("Could not read block header at %" PRIu64 "", secondary_ddt_offset);
|
||||
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||
}
|
||||
|
||||
if(ddt_header.identifier != DeDuplicationTable2 || ddt_header.type != UserData)
|
||||
{
|
||||
FATAL("Invalid block header at %" PRIu64 "", secondaryDdtOffset);
|
||||
FATAL("Invalid block header at %" PRIu64 "", secondary_ddt_offset);
|
||||
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||
}
|
||||
@@ -841,7 +858,14 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_addres
|
||||
switch(ddt_header.compression)
|
||||
{
|
||||
case Lzma:
|
||||
lzma_size = ddt_header.cmpLength - LZMA_PROPERTIES_LENGTH;
|
||||
if(ddt_header.cmpLength <= LZMA_PROPERTIES_LENGTH)
|
||||
{
|
||||
FATAL("Compressed DDT payload too small (%" PRIu64 ") for LZMA properties.", ddt_header.cmpLength);
|
||||
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK");
|
||||
return AARUF_ERROR_CANNOT_DECOMPRESS_BLOCK;
|
||||
}
|
||||
|
||||
lzma_size = (size_t)(ddt_header.cmpLength - LZMA_PROPERTIES_LENGTH);
|
||||
|
||||
cmp_data = (uint8_t *)malloc(lzma_size);
|
||||
if(cmp_data == NULL)
|
||||
@@ -919,7 +943,7 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_addres
|
||||
|
||||
if(crc64 != ddt_header.crc64)
|
||||
{
|
||||
FATAL("Expected DDT CRC 0x%16lX but got 0x%16lX.", ddtHeader.crc64, crc64);
|
||||
FATAL("Expected DDT CRC 0x%16lX but got 0x%16lX.", ddt_header.crc64, crc64);
|
||||
free(buffer);
|
||||
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_INVALID_BLOCK_CRC");
|
||||
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
||||
@@ -968,7 +992,7 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_addres
|
||||
|
||||
if(crc64 != ddt_header.crc64)
|
||||
{
|
||||
FATAL("Expected DDT CRC 0x%16lX but got 0x%16lX.", ddtHeader.crc64, crc64);
|
||||
FATAL("Expected DDT CRC 0x%16lX but got 0x%16lX.", ddt_header.crc64, crc64);
|
||||
free(buffer);
|
||||
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_INVALID_BLOCK_CRC");
|
||||
return AARUF_ERROR_INVALID_BLOCK_CRC;
|
||||
@@ -983,7 +1007,7 @@ int32_t decode_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_addres
|
||||
|
||||
break;
|
||||
default:
|
||||
FATAL("Found unknown compression type %d, stopping...", ddtHeader.compression);
|
||||
FATAL("Found unknown compression type %d, stopping...", ddt_header.compression);
|
||||
TRACE("Exiting decode_ddt_multi_level_v2() = AARUF_ERROR_CANNOT_READ_BLOCK");
|
||||
return AARUF_ERROR_CANNOT_READ_BLOCK;
|
||||
}
|
||||
@@ -1719,7 +1743,7 @@ bool set_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_address, boo
|
||||
if(read_bytes != sizeof(DdtHeader2) || ddt_header.identifier != DeDuplicationTable2 ||
|
||||
ddt_header.type != UserData)
|
||||
{
|
||||
FATAL("Invalid secondary DDT header at %" PRIu64, secondaryDdtOffset);
|
||||
FATAL("Invalid secondary DDT header at %" PRIu64, secondary_ddt_offset);
|
||||
TRACE("Exiting set_ddt_multi_level_v2() = false");
|
||||
return false;
|
||||
}
|
||||
@@ -1757,7 +1781,7 @@ bool set_ddt_multi_level_v2(aaruformatContext *ctx, uint64_t sector_address, boo
|
||||
|
||||
if(crc64 != ddt_header.crc64)
|
||||
{
|
||||
FATAL("Secondary DDT CRC mismatch. Expected 0x%16lX but got 0x%16lX.", ddtHeader.crc64, crc64);
|
||||
FATAL("Secondary DDT CRC mismatch. Expected 0x%16lX but got 0x%16lX.", ddt_header.crc64, crc64);
|
||||
free(buffer);
|
||||
TRACE("Exiting set_ddt_multi_level_v2() = false");
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user