diff --git a/CMakeLists.txt b/CMakeLists.txt index 00099e6..3de504d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -111,7 +111,8 @@ add_library(aaruformat SHARED include/aaruformat/consts.h include/aaruformat/enu include/internal.h src/index/index_v2.c src/blocks/data.c - src/ddt/ddt_v1.c) + src/ddt/ddt_v1.c + src/blocks/metadata.c) include_directories(include include/aaruformat) diff --git a/include/internal.h b/include/internal.h index cb7d9cc..89a9e30 100644 --- a/include/internal.h +++ b/include/internal.h @@ -27,5 +27,6 @@ UT_array *process_index_v2(aaruformatContext *ctx); int32_t verify_index_v2(aaruformatContext *ctx); int32_t process_data_block(aaruformatContext *ctx, IndexEntry *entry); int32_t process_ddt_v1(aaruformatContext *ctx, IndexEntry *entry, bool *foundUserDataDdt); +void process_metadata_block(aaruformatContext *ctx, IndexEntry *entry); #endif // LIBAARUFORMAT_INTERNAL_H diff --git a/src/blocks/metadata.c b/src/blocks/metadata.c new file mode 100644 index 0000000..75457f6 --- /dev/null +++ b/src/blocks/metadata.c @@ -0,0 +1,242 @@ +/* + * This file is part of the Aaru Data Preservation Suite. + * Copyright (c) 2019-2025 Natalia Portillo. + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of the + * License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include +#include +#include +#include + +#include "aaruformat.h" + +// Process the metadata block found while opening an AaruFormat file +void process_metadata_block(aaruformatContext *ctx, const IndexEntry *entry) +{ + int pos = 0; + size_t readBytes = 0; + + // Check if the context and image stream are valid + if(ctx == NULL || ctx->imageStream == NULL) + { + fprintf(stderr, "Invalid context or image stream.\n"); + return; + } + + // Seek to block + pos = fseek(ctx->imageStream, entry->offset, SEEK_SET); + if(pos < 0 || ftell(ctx->imageStream) != entry->offset) + { + fprintf(stderr, "libaaruformat: Could not seek to %" PRIu64 " as indicated by index entry...\n", entry->offset); + + return; + } + + // Even if those two checks shall have been done before + + readBytes = fread(&ctx->metadataBlockHeader, 1, sizeof(MetadataBlockHeader), ctx->imageStream); + + if(readBytes != sizeof(MetadataBlockHeader)) + { + memset(&ctx->metadataBlockHeader, 0, sizeof(MetadataBlockHeader)); + fprintf(stderr, "libaaruformat: Could not read metadata block header, continuing...\n"); + return; + } + + if(ctx->metadataBlockHeader.identifier != entry->blockType) + { + memset(&ctx->metadataBlockHeader, 0, sizeof(MetadataBlockHeader)); + fprintf(stderr, "libaaruformat: Incorrect identifier for data block at position %" PRIu64 "\n", entry->offset); + return; + } + + ctx->imageInfo.ImageSize += ctx->metadataBlockHeader.blockSize; + + ctx->metadataBlock = (uint8_t *)malloc(ctx->metadataBlockHeader.blockSize); + + if(ctx->metadataBlock == NULL) + { + memset(&ctx->metadataBlockHeader, 0, sizeof(MetadataBlockHeader)); + fprintf(stderr, "libaaruformat: Could not allocate memory for metadata block, continuing...\n"); + return; + } + + readBytes = fread(ctx->metadataBlock, 1, ctx->metadataBlockHeader.blockSize, ctx->imageStream); + + if(readBytes != ctx->metadataBlockHeader.blockSize) + { + memset(&ctx->metadataBlockHeader, 0, sizeof(MetadataBlockHeader)); + free(ctx->metadataBlock); + fprintf(stderr, "libaaruformat: Could not read metadata block, continuing...\n"); + } + + if(ctx->metadataBlockHeader.mediaSequence > 0 && ctx->metadataBlockHeader.lastMediaSequence > 0) + { + ctx->imageInfo.MediaSequence = ctx->metadataBlockHeader.mediaSequence; + ctx->imageInfo.LastMediaSequence = ctx->metadataBlockHeader.lastMediaSequence; + fprintf(stderr, "libaaruformat: Setting media sequence as %d of %d\n", ctx->imageInfo.MediaSequence, + ctx->imageInfo.LastMediaSequence); + } + + if(ctx->metadataBlockHeader.creatorLength > 0 && + ctx->metadataBlockHeader.creatorOffset + ctx->metadataBlockHeader.creatorLength <= + ctx->metadataBlockHeader.blockSize) + { + ctx->imageInfo.Creator = (uint8_t *)malloc(ctx->metadataBlockHeader.creatorLength); + if(ctx->imageInfo.Creator != NULL) + { + memcpy(ctx->imageInfo.Creator, ctx->metadataBlock + ctx->metadataBlockHeader.creatorOffset, + ctx->metadataBlockHeader.creatorLength); + } + } + + if(ctx->metadataBlockHeader.commentsLength > 0 && + ctx->metadataBlockHeader.commentsOffset + ctx->metadataBlockHeader.commentsLength <= + ctx->metadataBlockHeader.blockSize) + { + ctx->imageInfo.Comments = (uint8_t *)malloc(ctx->metadataBlockHeader.commentsLength); + if(ctx->imageInfo.Comments != NULL) + { + memcpy(ctx->imageInfo.Comments, ctx->metadataBlock + ctx->metadataBlockHeader.commentsOffset, + ctx->metadataBlockHeader.commentsLength); + } + } + + if(ctx->metadataBlockHeader.mediaTitleLength > 0 && + ctx->metadataBlockHeader.mediaTitleOffset + ctx->metadataBlockHeader.mediaTitleLength <= + ctx->metadataBlockHeader.blockSize) + { + ctx->imageInfo.MediaTitle = (uint8_t *)malloc(ctx->metadataBlockHeader.mediaTitleLength); + if(ctx->imageInfo.MediaTitle != NULL) + { + memcpy(ctx->imageInfo.MediaTitle, ctx->metadataBlock + ctx->metadataBlockHeader.mediaTitleOffset, + ctx->metadataBlockHeader.mediaTitleLength); + } + } + + if(ctx->metadataBlockHeader.mediaManufacturerLength > 0 && + ctx->metadataBlockHeader.mediaManufacturerOffset + ctx->metadataBlockHeader.mediaManufacturerLength <= + ctx->metadataBlockHeader.blockSize) + { + ctx->imageInfo.MediaManufacturer = (uint8_t *)malloc(ctx->metadataBlockHeader.mediaManufacturerLength); + if(ctx->imageInfo.MediaManufacturer != NULL) + { + memcpy(ctx->imageInfo.MediaManufacturer, + ctx->metadataBlock + ctx->metadataBlockHeader.mediaManufacturerOffset, + ctx->metadataBlockHeader.mediaManufacturerLength); + } + } + + if(ctx->metadataBlockHeader.mediaModelLength > 0 && + ctx->metadataBlockHeader.mediaModelOffset + ctx->metadataBlockHeader.mediaModelLength <= + ctx->metadataBlockHeader.blockSize) + { + ctx->imageInfo.MediaModel = (uint8_t *)malloc(ctx->metadataBlockHeader.mediaModelOffset); + if(ctx->imageInfo.MediaModel != NULL) + { + memcpy(ctx->imageInfo.MediaModel, ctx->metadataBlock + ctx->metadataBlockHeader.mediaModelOffset, + ctx->metadataBlockHeader.mediaModelLength); + } + } + + if(ctx->metadataBlockHeader.mediaSerialNumberLength > 0 && + ctx->metadataBlockHeader.mediaSerialNumberOffset + ctx->metadataBlockHeader.mediaSerialNumberLength <= + ctx->metadataBlockHeader.blockSize) + { + ctx->imageInfo.MediaSerialNumber = (uint8_t *)malloc(ctx->metadataBlockHeader.mediaSerialNumberLength); + if(ctx->imageInfo.MediaSerialNumber != NULL) + { + memcpy(ctx->imageInfo.MediaSerialNumber, + ctx->metadataBlock + ctx->metadataBlockHeader.mediaSerialNumberOffset, + ctx->metadataBlockHeader.mediaManufacturerLength); + } + } + + if(ctx->metadataBlockHeader.mediaBarcodeLength > 0 && + ctx->metadataBlockHeader.mediaBarcodeOffset + ctx->metadataBlockHeader.mediaBarcodeLength <= + ctx->metadataBlockHeader.blockSize) + { + ctx->imageInfo.MediaBarcode = (uint8_t *)malloc(ctx->metadataBlockHeader.mediaBarcodeLength); + if(ctx->imageInfo.MediaBarcode != NULL) + { + memcpy(ctx->imageInfo.MediaBarcode, ctx->metadataBlock + ctx->metadataBlockHeader.mediaBarcodeOffset, + ctx->metadataBlockHeader.mediaBarcodeLength); + } + } + + if(ctx->metadataBlockHeader.mediaPartNumberLength > 0 && + ctx->metadataBlockHeader.mediaPartNumberOffset + ctx->metadataBlockHeader.mediaPartNumberLength <= + ctx->metadataBlockHeader.blockSize) + { + ctx->imageInfo.MediaPartNumber = (uint8_t *)malloc(ctx->metadataBlockHeader.mediaPartNumberLength); + if(ctx->imageInfo.MediaPartNumber != NULL) + { + memcpy(ctx->imageInfo.MediaPartNumber, ctx->metadataBlock + ctx->metadataBlockHeader.mediaPartNumberOffset, + ctx->metadataBlockHeader.mediaPartNumberLength); + } + } + + if(ctx->metadataBlockHeader.driveManufacturerLength > 0 && + ctx->metadataBlockHeader.driveManufacturerOffset + ctx->metadataBlockHeader.driveManufacturerLength <= + ctx->metadataBlockHeader.blockSize) + { + ctx->imageInfo.DriveManufacturer = (uint8_t *)malloc(ctx->metadataBlockHeader.driveManufacturerLength); + if(ctx->imageInfo.DriveManufacturer != NULL) + { + memcpy(ctx->imageInfo.DriveManufacturer, + ctx->metadataBlock + ctx->metadataBlockHeader.driveManufacturerOffset, + ctx->metadataBlockHeader.driveManufacturerLength); + } + } + + if(ctx->metadataBlockHeader.driveModelLength > 0 && + ctx->metadataBlockHeader.driveModelOffset + ctx->metadataBlockHeader.driveModelLength <= + ctx->metadataBlockHeader.blockSize) + { + ctx->imageInfo.DriveModel = (uint8_t *)malloc(ctx->metadataBlockHeader.driveModelLength); + if(ctx->imageInfo.DriveModel != NULL) + { + memcpy(ctx->imageInfo.DriveModel, ctx->metadataBlock + ctx->metadataBlockHeader.driveModelOffset, + ctx->metadataBlockHeader.driveModelLength); + } + } + + if(ctx->metadataBlockHeader.driveSerialNumberLength > 0 && + ctx->metadataBlockHeader.driveSerialNumberOffset + ctx->metadataBlockHeader.driveSerialNumberLength <= + ctx->metadataBlockHeader.blockSize) + { + ctx->imageInfo.DriveSerialNumber = (uint8_t *)malloc(ctx->metadataBlockHeader.driveSerialNumberLength); + if(ctx->imageInfo.DriveSerialNumber != NULL) + { + memcpy(ctx->imageInfo.DriveSerialNumber, + ctx->metadataBlock + ctx->metadataBlockHeader.driveSerialNumberOffset, + ctx->metadataBlockHeader.driveSerialNumberLength); + } + } + + if(ctx->metadataBlockHeader.driveManufacturerLength > 0 && + ctx->metadataBlockHeader.driveFirmwareRevisionOffset + ctx->metadataBlockHeader.driveManufacturerLength <= + ctx->metadataBlockHeader.blockSize) + { + ctx->imageInfo.DriveFirmwareRevision = (uint8_t *)malloc(ctx->metadataBlockHeader.driveFirmwareRevisionLength); + if(ctx->imageInfo.DriveFirmwareRevision != NULL) + { + memcpy(ctx->imageInfo.DriveFirmwareRevision, + ctx->metadataBlock + ctx->metadataBlockHeader.driveFirmwareRevisionLength, + ctx->metadataBlockHeader.driveFirmwareRevisionLength); + } + } +} \ No newline at end of file diff --git a/src/open.c b/src/open.c index e82d60d..650b8db 100644 --- a/src/open.c +++ b/src/open.c @@ -248,214 +248,7 @@ void *aaruf_open(const char *filepath) break; // Metadata block case MetadataBlock: - readBytes = fread(&ctx->metadataBlockHeader, 1, sizeof(MetadataBlockHeader), ctx->imageStream); - - if(readBytes != sizeof(MetadataBlockHeader)) - { - memset(&ctx->metadataBlockHeader, 0, sizeof(MetadataBlockHeader)); - fprintf(stderr, "libaaruformat: Could not read metadata block header, continuing...\n"); - break; - } - - if(ctx->metadataBlockHeader.identifier != entry->blockType) - { - memset(&ctx->metadataBlockHeader, 0, sizeof(MetadataBlockHeader)); - fprintf(stderr, "libaaruformat: Incorrect identifier for data block at position %" PRIu64 "\n", - entry->offset); - break; - } - - ctx->imageInfo.ImageSize += ctx->metadataBlockHeader.blockSize; - - ctx->metadataBlock = (uint8_t *)malloc(ctx->metadataBlockHeader.blockSize); - - if(ctx->metadataBlock == NULL) - { - memset(&ctx->metadataBlockHeader, 0, sizeof(MetadataBlockHeader)); - fprintf(stderr, "libaaruformat: Could not allocate memory for metadata block, continuing...\n"); - break; - } - - readBytes = fread(ctx->metadataBlock, 1, ctx->metadataBlockHeader.blockSize, ctx->imageStream); - - if(readBytes != ctx->metadataBlockHeader.blockSize) - { - memset(&ctx->metadataBlockHeader, 0, sizeof(MetadataBlockHeader)); - free(ctx->metadataBlock); - fprintf(stderr, "libaaruformat: Could not read metadata block, continuing...\n"); - } - - if(ctx->metadataBlockHeader.mediaSequence > 0 && ctx->metadataBlockHeader.lastMediaSequence > 0) - { - ctx->imageInfo.MediaSequence = ctx->metadataBlockHeader.mediaSequence; - ctx->imageInfo.LastMediaSequence = ctx->metadataBlockHeader.lastMediaSequence; - fprintf(stderr, "libaaruformat: Setting media sequence as %d of %d\n", ctx->imageInfo.MediaSequence, - ctx->imageInfo.LastMediaSequence); - } - - if(ctx->metadataBlockHeader.creatorLength > 0 && - ctx->metadataBlockHeader.creatorOffset + ctx->metadataBlockHeader.creatorLength <= - ctx->metadataBlockHeader.blockSize) - { - ctx->imageInfo.Creator = (uint8_t *)malloc(ctx->metadataBlockHeader.creatorLength); - if(ctx->imageInfo.Creator != NULL) - { - memcpy(ctx->imageInfo.Creator, ctx->metadataBlock + ctx->metadataBlockHeader.creatorOffset, - ctx->metadataBlockHeader.creatorLength); - } - } - - if(ctx->metadataBlockHeader.commentsLength > 0 && - ctx->metadataBlockHeader.commentsOffset + ctx->metadataBlockHeader.commentsLength <= - ctx->metadataBlockHeader.blockSize) - { - ctx->imageInfo.Comments = (uint8_t *)malloc(ctx->metadataBlockHeader.commentsLength); - if(ctx->imageInfo.Comments != NULL) - { - memcpy(ctx->imageInfo.Comments, ctx->metadataBlock + ctx->metadataBlockHeader.commentsOffset, - ctx->metadataBlockHeader.commentsLength); - } - } - - if(ctx->metadataBlockHeader.mediaTitleLength > 0 && - ctx->metadataBlockHeader.mediaTitleOffset + ctx->metadataBlockHeader.mediaTitleLength <= - ctx->metadataBlockHeader.blockSize) - { - ctx->imageInfo.MediaTitle = (uint8_t *)malloc(ctx->metadataBlockHeader.mediaTitleLength); - if(ctx->imageInfo.MediaTitle != NULL) - { - memcpy(ctx->imageInfo.MediaTitle, - ctx->metadataBlock + ctx->metadataBlockHeader.mediaTitleOffset, - ctx->metadataBlockHeader.mediaTitleLength); - } - } - - if(ctx->metadataBlockHeader.mediaManufacturerLength > 0 && - ctx->metadataBlockHeader.mediaManufacturerOffset + - ctx->metadataBlockHeader.mediaManufacturerLength <= - ctx->metadataBlockHeader.blockSize) - { - ctx->imageInfo.MediaManufacturer = - (uint8_t *)malloc(ctx->metadataBlockHeader.mediaManufacturerLength); - if(ctx->imageInfo.MediaManufacturer != NULL) - { - memcpy(ctx->imageInfo.MediaManufacturer, - ctx->metadataBlock + ctx->metadataBlockHeader.mediaManufacturerOffset, - ctx->metadataBlockHeader.mediaManufacturerLength); - } - } - - if(ctx->metadataBlockHeader.mediaModelLength > 0 && - ctx->metadataBlockHeader.mediaModelOffset + ctx->metadataBlockHeader.mediaModelLength <= - ctx->metadataBlockHeader.blockSize) - { - ctx->imageInfo.MediaModel = (uint8_t *)malloc(ctx->metadataBlockHeader.mediaModelOffset); - if(ctx->imageInfo.MediaModel != NULL) - { - memcpy(ctx->imageInfo.MediaModel, - ctx->metadataBlock + ctx->metadataBlockHeader.mediaModelOffset, - ctx->metadataBlockHeader.mediaModelLength); - } - } - - if(ctx->metadataBlockHeader.mediaSerialNumberLength > 0 && - ctx->metadataBlockHeader.mediaSerialNumberOffset + - ctx->metadataBlockHeader.mediaSerialNumberLength <= - ctx->metadataBlockHeader.blockSize) - { - ctx->imageInfo.MediaSerialNumber = - (uint8_t *)malloc(ctx->metadataBlockHeader.mediaSerialNumberLength); - if(ctx->imageInfo.MediaSerialNumber != NULL) - { - memcpy(ctx->imageInfo.MediaSerialNumber, - ctx->metadataBlock + ctx->metadataBlockHeader.mediaSerialNumberOffset, - ctx->metadataBlockHeader.mediaManufacturerLength); - } - } - - if(ctx->metadataBlockHeader.mediaBarcodeLength > 0 && - ctx->metadataBlockHeader.mediaBarcodeOffset + ctx->metadataBlockHeader.mediaBarcodeLength <= - ctx->metadataBlockHeader.blockSize) - { - ctx->imageInfo.MediaBarcode = (uint8_t *)malloc(ctx->metadataBlockHeader.mediaBarcodeLength); - if(ctx->imageInfo.MediaBarcode != NULL) - { - memcpy(ctx->imageInfo.MediaBarcode, - ctx->metadataBlock + ctx->metadataBlockHeader.mediaBarcodeOffset, - ctx->metadataBlockHeader.mediaBarcodeLength); - } - } - - if(ctx->metadataBlockHeader.mediaPartNumberLength > 0 && - ctx->metadataBlockHeader.mediaPartNumberOffset + ctx->metadataBlockHeader.mediaPartNumberLength <= - ctx->metadataBlockHeader.blockSize) - { - ctx->imageInfo.MediaPartNumber = (uint8_t *)malloc(ctx->metadataBlockHeader.mediaPartNumberLength); - if(ctx->imageInfo.MediaPartNumber != NULL) - { - memcpy(ctx->imageInfo.MediaPartNumber, - ctx->metadataBlock + ctx->metadataBlockHeader.mediaPartNumberOffset, - ctx->metadataBlockHeader.mediaPartNumberLength); - } - } - - if(ctx->metadataBlockHeader.driveManufacturerLength > 0 && - ctx->metadataBlockHeader.driveManufacturerOffset + - ctx->metadataBlockHeader.driveManufacturerLength <= - ctx->metadataBlockHeader.blockSize) - { - ctx->imageInfo.DriveManufacturer = - (uint8_t *)malloc(ctx->metadataBlockHeader.driveManufacturerLength); - if(ctx->imageInfo.DriveManufacturer != NULL) - { - memcpy(ctx->imageInfo.DriveManufacturer, - ctx->metadataBlock + ctx->metadataBlockHeader.driveManufacturerOffset, - ctx->metadataBlockHeader.driveManufacturerLength); - } - } - - if(ctx->metadataBlockHeader.driveModelLength > 0 && - ctx->metadataBlockHeader.driveModelOffset + ctx->metadataBlockHeader.driveModelLength <= - ctx->metadataBlockHeader.blockSize) - { - ctx->imageInfo.DriveModel = (uint8_t *)malloc(ctx->metadataBlockHeader.driveModelLength); - if(ctx->imageInfo.DriveModel != NULL) - { - memcpy(ctx->imageInfo.DriveModel, - ctx->metadataBlock + ctx->metadataBlockHeader.driveModelOffset, - ctx->metadataBlockHeader.driveModelLength); - } - } - - if(ctx->metadataBlockHeader.driveSerialNumberLength > 0 && - ctx->metadataBlockHeader.driveSerialNumberOffset + - ctx->metadataBlockHeader.driveSerialNumberLength <= - ctx->metadataBlockHeader.blockSize) - { - ctx->imageInfo.DriveSerialNumber = - (uint8_t *)malloc(ctx->metadataBlockHeader.driveSerialNumberLength); - if(ctx->imageInfo.DriveSerialNumber != NULL) - { - memcpy(ctx->imageInfo.DriveSerialNumber, - ctx->metadataBlock + ctx->metadataBlockHeader.driveSerialNumberOffset, - ctx->metadataBlockHeader.driveSerialNumberLength); - } - } - - if(ctx->metadataBlockHeader.driveManufacturerLength > 0 && - ctx->metadataBlockHeader.driveFirmwareRevisionOffset + - ctx->metadataBlockHeader.driveManufacturerLength <= - ctx->metadataBlockHeader.blockSize) - { - ctx->imageInfo.DriveFirmwareRevision = - (uint8_t *)malloc(ctx->metadataBlockHeader.driveFirmwareRevisionLength); - if(ctx->imageInfo.DriveFirmwareRevision != NULL) - { - memcpy(ctx->imageInfo.DriveFirmwareRevision, - ctx->metadataBlock + ctx->metadataBlockHeader.driveFirmwareRevisionLength, - ctx->metadataBlockHeader.driveFirmwareRevisionLength); - } - } + process_metadata_block(ctx, entry); break; case TracksBlock: