diff options
-rw-r--r-- | include/git2/common.h | 8 | ||||
-rw-r--r-- | src/odb.c | 14 | ||||
-rw-r--r-- | src/odb.h | 2 | ||||
-rw-r--r-- | src/settings.c | 5 | ||||
-rw-r--r-- | tests/object/lookup.c | 5 |
5 files changed, 29 insertions, 5 deletions
diff --git a/include/git2/common.h b/include/git2/common.h index 6d2092028..d83e8c3a0 100644 --- a/include/git2/common.h +++ b/include/git2/common.h @@ -182,6 +182,7 @@ typedef enum { GIT_OPT_ENABLE_SYNCHRONOUS_OBJECT_CREATION, GIT_OPT_GET_WINDOWS_SHAREMODE, GIT_OPT_SET_WINDOWS_SHAREMODE, + GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION, } git_libgit2_opt_t; /** @@ -337,6 +338,13 @@ typedef enum { * > is written to permanent storage, not simply cached. This * > defaults to disabled. * + * opts(GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION, int enabled) + * + * > Enable strict verification of object hashsums when reading + * > objects from disk. This may impact performance due to an + * > additional checksum calculation on each object. This defaults + * > to enabled. + * * @param option Option key * @param ... value to set the option * @return 0 on success, <0 on failure @@ -31,6 +31,8 @@ #define GIT_ALTERNATES_MAX_DEPTH 5 +bool git_odb__strict_hash_verification = true; + typedef struct { git_odb_backend *backend; @@ -1027,12 +1029,14 @@ static int odb_read_1(git_odb_object **out, git_odb *db, const git_oid *id, if (!found) return GIT_ENOTFOUND; - if ((error = git_odb_hash(&hashed, raw.data, raw.len, raw.type)) < 0) - goto out; + if (git_odb__strict_hash_verification) { + if ((error = git_odb_hash(&hashed, raw.data, raw.len, raw.type)) < 0) + goto out; - if (!git_oid_equal(id, &hashed)) { - error = git_odb__error_mismatch(id, &hashed); - goto out; + if (!git_oid_equal(id, &hashed)) { + error = git_odb__error_mismatch(id, &hashed); + goto out; + } } giterr_clear(); @@ -20,6 +20,8 @@ #define GIT_OBJECT_DIR_MODE 0777 #define GIT_OBJECT_FILE_MODE 0444 +extern bool git_odb__strict_hash_verification; + /* DO NOT EXPORT */ typedef struct { void *data; /**< Raw, decompressed object data. */ diff --git a/src/settings.c b/src/settings.c index 07ac16a8f..169fcd51c 100644 --- a/src/settings.c +++ b/src/settings.c @@ -15,6 +15,7 @@ #include "cache.h" #include "global.h" #include "object.h" +#include "odb.h" #include "refs.h" #include "transports/smart.h" @@ -243,6 +244,10 @@ int git_libgit2_opts(int key, ...) #endif break; + case GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION: + git_odb__strict_hash_verification = (va_arg(ap, int) != 0); + break; + default: giterr_set(GITERR_INVALID, "invalid option key"); error = -1; diff --git a/tests/object/lookup.c b/tests/object/lookup.c index ed12f917a..277e2e0c0 100644 --- a/tests/object/lookup.c +++ b/tests/object/lookup.c @@ -111,6 +111,11 @@ void test_object_lookup__lookup_object_with_wrong_hash_returns_error(void) /* Verify that lookup fails due to a hashsum mismatch */ cl_git_fail_with(GIT_EMISMATCH, git_object_lookup(&object, g_repo, &oid, GIT_OBJ_COMMIT)); + /* Disable verification and try again */ + cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION, 0)); + cl_git_pass(git_object_lookup(&object, g_repo, &oid, GIT_OBJ_COMMIT)); + cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION, 1)); + git_buf_free(&oldpath); git_buf_free(&newpath); } |