Skip to content

Commit dba9267

Browse files
committed
src/file_hdf5.c: add filesize detection (See PR #200)
1 parent e408f3d commit dba9267

1 file changed

Lines changed: 83 additions & 4 deletions

File tree

src/file_hdf5.c

Lines changed: 83 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,17 @@
3434
#include "types.h"
3535
#include "filegen.h"
3636
#include "common.h"
37-
#ifdef DEBUG_HDF
37+
#ifdef DEBUG_HDF5
3838
#include "log.h"
3939
#endif
4040

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

4444
const file_hint_t file_hint_hdf5= {
45-
.extension="hdf",
45+
.extension="h5",
4646
.description="Hierarchical Data Format 5",
47-
.max_filesize=PHOTOREC_MAX_SIZE_32,
47+
.max_filesize=PHOTOREC_MAX_FILE_SIZE,
4848
.recover=1,
4949
.enable_by_default=1,
5050
.register_header_check=&register_header_check_hdf5
@@ -54,7 +54,79 @@ struct hdf5_superblock
5454
{
5555
uint8_t signature[8];
5656
uint8_t version;
57-
};
57+
uint8_t version_global_free_space_storage;
58+
uint8_t version_root_group_symbol_table_entry;
59+
uint8_t reserved;
60+
uint8_t version_shared_header_message_format;
61+
uint8_t offsets_size;
62+
uint8_t lengths_size;
63+
} __attribute__ ((gcc_struct, __packed__));
64+
65+
/*@
66+
@ requires \separated(file_recovery, file_recovery->handle, &errno, &Frama_C_entropy_source, &__fc_heap_status);
67+
@ requires valid_file_check_param(file_recovery);
68+
@ ensures valid_file_check_result(file_recovery);
69+
@*/
70+
static void file_check_hdf5_0(file_recovery_t *file_recovery)
71+
{
72+
const uint8_t eof_address_offset = 0x18 + 2*8;
73+
FILE *handle = file_recovery->handle;
74+
uint64_t eof_address = 0;
75+
/* Get EOF Address */
76+
if (my_fseek(handle, eof_address_offset, SEEK_SET) < 0 ||
77+
fread(&eof_address, sizeof(eof_address), 1, handle) != 1)
78+
{
79+
#ifdef DEBUG_HDF5
80+
log_error("file_check_hdf5_0: Couldn't read HDF End of File Address");
81+
#endif
82+
file_recovery->file_size=0;
83+
return;
84+
}
85+
eof_address = le64(eof_address);
86+
#ifdef DEBUG_HDF5
87+
log_info("file_check_hdf5_0: dec eof_address = %lu\n", (long unsigned)eof_address);
88+
log_info("file_check_hdf5_0: hex eof_address = 0x%02lX\n", eof_address);
89+
#endif
90+
if(eof_address < eof_address_offset || eof_address < file_recovery->file_size)
91+
{
92+
file_recovery->file_size=0;
93+
return;
94+
}
95+
file_recovery->file_size=eof_address;
96+
}
97+
98+
/*@
99+
@ requires \separated(file_recovery, file_recovery->handle, &errno, &Frama_C_entropy_source, &__fc_heap_status);
100+
@ requires valid_file_check_param(file_recovery);
101+
@ ensures valid_file_check_result(file_recovery);
102+
@*/
103+
static void file_check_hdf5_1(file_recovery_t *file_recovery)
104+
{
105+
const uint8_t eof_address_offset = 0x1C + 2*0x8;
106+
FILE *handle = file_recovery->handle;
107+
uint64_t eof_address = 0;
108+
/* Get EOF Address */
109+
if (my_fseek(handle, eof_address_offset, SEEK_SET) < 0 ||
110+
fread(&eof_address, sizeof(eof_address), 1, handle) != 1)
111+
{
112+
#ifdef DEBUG_HDF5
113+
log_error("file_check_hdf5_1: Couldn't read HDF End of File Address");
114+
#endif
115+
file_recovery->file_size=0;
116+
return;
117+
}
118+
eof_address = le64(eof_address);
119+
#ifdef DEBUG_HDF5
120+
log_info("file_check_hdf5_1: dec eof_address = %lu\n", (long unsigned)eof_address);
121+
log_info("file_check_hdf5_1: hex eof_address = 0x%02lX\n", eof_address);
122+
#endif
123+
if(eof_address < eof_address_offset || eof_address < file_recovery->file_size)
124+
{
125+
file_recovery->file_size=0;
126+
return;
127+
}
128+
file_recovery->file_size=eof_address;
129+
}
58130

59131
/*@
60132
@ requires buffer_size >= sizeof(struct hdf5_superblock);
@@ -71,6 +143,13 @@ static int header_check_hdf5(const unsigned char *buffer, const unsigned int buf
71143
return 0;
72144
reset_file_recovery(file_recovery_new);
73145
file_recovery_new->extension=file_hint_hdf5.extension;
146+
if(sb->offsets_size != 8)
147+
return 1;
148+
/* Currently only handle 64-bits offsets */
149+
if(sb->version == 0)
150+
file_recovery_new->file_check=&file_check_hdf5_0;
151+
else
152+
file_recovery_new->file_check=&file_check_hdf5_1;
74153
return 1;
75154
}
76155

0 commit comments

Comments
 (0)