Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 82 additions & 7 deletions src/file_hdf5.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

*/

#if !defined(SINGLE_FORMAT) || defined(SINGLE_FORMAT_hdf5)
#ifdef HAVE_CONFIG_H
#include <config.h>
Expand All @@ -34,17 +34,17 @@
#include "types.h"
#include "filegen.h"
#include "common.h"
#ifdef DEBUG_HDF
#ifdef DEBUG_HDF5
#include "log.h"
#endif

/*@ requires valid_register_header_check(file_stat); */
static void register_header_check_hdf5(file_stat_t *file_stat);

const file_hint_t file_hint_hdf5= {
.extension="hdf",
.extension="h5",
.description="Hierarchical Data Format 5",
.max_filesize=PHOTOREC_MAX_SIZE_32,
.max_filesize=PHOTOREC_MAX_FILE_SIZE,
.recover=1,
.enable_by_default=1,
.register_header_check=&register_header_check_hdf5
Expand All @@ -54,7 +54,80 @@ struct hdf5_superblock
{
uint8_t signature[8];
uint8_t version;
};
uint8_t version_global_free_space_storage;
uint8_t version_root_group_symbol_table_entry;
uint8_t reserved;
uint8_t version_shared_header_message_format;
uint8_t offsets_size;
uint8_t lengths_size;
// if version == 0, Base Address etc start at offset 24, if version >1 at offset 28
// Offset Base Address = (bool)version*4 + 24 + 0*offsets_size
// Offset Address of Global Free-Space Heap = (bool)version*4 + 24 + 1*offset_size
// Offset End of File Address = (bool)version*4 + 24 + 2*offset_size
// Size of End of File Address = offset_size
} __attribute__ ((gcc_struct, __packed__));

/*@
@ requires \separated(file_recovery, file_recovery->handle, &errno, &Frama_C_entropy_source, &__fc_heap_status);
@ requires valid_file_check_param(file_recovery);
@ ensures valid_file_check_result(file_recovery);
@*/
static void file_check_hdf5(file_recovery_t *file_recovery)
{
FILE *handle = file_recovery->handle;
uint8_t sb_version_offset = 8;
uint8_t sb_offsets_size_offset = 0x0D;
uint8_t sb_meta_base_address_offset = 0x18;
uint8_t sb_version = 0;
uint8_t sb_offsets_size = 0;
uint8_t eof_address_offset;
uint64_t eof_address = 0;
/* Get superblock version */
if (my_fseek(handle, sb_version_offset, SEEK_SET) < 0 ||
fread(&sb_version, 1, 1, handle) != 1)
{
#ifdef DEBUG_HDF5
log_error("HDF5: Couldn't read superblock version");
#endif
return;
}
#ifdef DEBUG_HDF5
log_info("HDF5: superblock version = %u\n", sb_version);
#endif
/* Adjust sb_meta_base_address_offset if hdf5 version is >0 */
if (sb_version)
sb_meta_base_address_offset = 0x1C;
#ifdef DEBUG_HDF5
log_info("HDF5: sb_meta_base_address_offset = 0x%02X\n", sb_meta_base_address_offset);
#endif
/* Get size of offsets */
if (my_fseek(handle, sb_offsets_size_offset, SEEK_SET) < 0 ||
fread(&sb_offsets_size, 1, 1, handle) != 1)
{
#ifdef DEBUG_HDF5
log_error("HDF5: Couldn't read HDF Size of Offsets");
#endif
return;
}
#ifdef DEBUG_HDF5
log_info("HDF5: sb_offsets_size = %u\n", sb_offsets_size);
#endif
/* Get EOF Address */
eof_address_offset = sb_meta_base_address_offset + 2*sb_offsets_size;
if (my_fseek(handle, eof_address_offset, SEEK_SET) < 0 ||
fread(&eof_address, sb_offsets_size, 1, handle) != 1)
{
#ifdef DEBUG_HDF5
log_error("HDF5: Couldn't read HDF End of File Address");
#endif
return;
}
#ifdef DEBUG_HDF5
log_info("HDF5: dec eof_address = %lu\n", (long unsigned)eof_address);
log_info("HDF5: hex eof_address = 0x%02lX\n", eof_address);
#endif
file_recovery->file_size=eof_address;
}

/*@
@ requires buffer_size >= sizeof(struct hdf5_superblock);
Expand All @@ -66,11 +139,13 @@ struct hdf5_superblock
static int header_check_hdf5(const unsigned char *buffer, const unsigned int buffer_size, const unsigned int safe_header_only, const file_recovery_t *file_recovery, file_recovery_t *file_recovery_new)
{
const struct hdf5_superblock *sb=(const struct hdf5_superblock*)&buffer[0];
/*@ assert \valid_read(sb); */
if(sb->version > 2)
const uint8_t sb_version=sb->version;
if (sb_version > 1) {
return 0;
}
reset_file_recovery(file_recovery_new);
file_recovery_new->extension=file_hint_hdf5.extension;
file_recovery_new->file_check=&file_check_hdf5;
return 1;
}

Expand Down