diff --git a/cmdline/check.c b/cmdline/check.c index d3941a9c..d5f52c44 100644 --- a/cmdline/check.c +++ b/cmdline/check.c @@ -501,7 +501,7 @@ static int repair(struct snapraid_state* state, int rehash, unsigned pos, unsign /* try to fetch the old block using the old hash for CHG and DELETED blocks */ } else if ((block_state == BLOCK_STATE_CHG || block_state == BLOCK_STATE_DELETED) - && hash_is_real(failed[j].block->hash) + && hash_is_unique(failed[j].block->hash) && state_import_fetch(state, rehash, failed[j].block, buffer[failed[j].index]) == 0) { /* note that from now the buffer is definitively lost */ diff --git a/cmdline/elem.h b/cmdline/elem.h index a36a8286..48a05c15 100644 --- a/cmdline/elem.h +++ b/cmdline/elem.h @@ -536,11 +536,17 @@ int filter_content(tommy_list* contentlist, const char* path); * Check if the specified hash is invalid. * * An invalid hash is represented with all bytes at 0x00. + * + * If working with reduced hash lengths, this function always return 0. */ static inline int hash_is_invalid(const unsigned char* hash) { int i; + /* if the hash is reduced, we cannot grant that it's a specific kind of hash */ + if (BLOCK_HASH_SIZE != HASH_MAX) + return 0; + for (i = 0; i < BLOCK_HASH_SIZE; ++i) if (hash[i] != 0x00) return 0; @@ -552,11 +558,17 @@ static inline int hash_is_invalid(const unsigned char* hash) * Check if the specified hash represent the zero block. * * A zero hash is represented with all bytes at 0xFF. + * + * If working with reduced hash lengths, this function always return 0. */ static inline int hash_is_zero(const unsigned char* hash) { int i; + /* if the hash is reduced, we cannot grant that it's a specific kind of hash */ + if (BLOCK_HASH_SIZE != HASH_MAX) + return 0; + for (i = 0; i < BLOCK_HASH_SIZE; ++i) if (hash[i] != 0xFF) return 0; @@ -565,10 +577,16 @@ static inline int hash_is_zero(const unsigned char* hash) } /** - * Check if the specified hash is a real hash. + * Check if the specified hash is uniquievocally repesenting the data. + * + * If working with reduced hash lengths, this function always return 0. */ -static inline int hash_is_real(const unsigned char* hash) +static inline int hash_is_unique(const unsigned char* hash) { + /* if the hash is reduced, we cannot grant that it's a specific kind of hash */ + if (BLOCK_HASH_SIZE != HASH_MAX) + return 0; + return !hash_is_zero(hash) && !hash_is_invalid(hash); } diff --git a/cmdline/import.c b/cmdline/import.c index 916f76ca..f00a0910 100644 --- a/cmdline/import.c +++ b/cmdline/import.c @@ -310,6 +310,14 @@ void state_import(struct snapraid_state* state, const char* dir) msg_progress("Importing...\n"); + /* if the hash is not full */ + if (BLOCK_HASH_SIZE != HASH_MAX) { + /* LCOV_EXCL_START */ + log_fatal("You cannot import files when using a reduced hash.\n"); + exit(EXIT_FAILURE); + /* LCOV_EXCL_STOP */ + } + /* add the final slash */ pathimport(path, sizeof(path), dir); pathslash(path, sizeof(path)); diff --git a/cmdline/sync.c b/cmdline/sync.c index 063c973b..57961a98 100644 --- a/cmdline/sync.c +++ b/cmdline/sync.c @@ -982,8 +982,8 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari /* have "parity_needs_to_be_updated" already at 1 */ assert(block_state_get(block) == BLOCK_STATE_CHG); - /* if there is an hash */ - if (hash_is_real(block->hash)) { + /* if the hash represents the data uniquievocally */ + if (hash_is_unique(block->hash)) { /* check if the hash is changed */ if (memcmp(hash, block->hash, BLOCK_HASH_SIZE) != 0) { /* the block is different, and we must update parity */