diff options
author | Edward Thomson <edward.thomson@vercel.com> | 2023-02-15 12:33:16 +0000 |
---|---|---|
committer | Edward Thomson <edward.thomson@vercel.com> | 2023-02-15 13:23:51 +0000 |
commit | 0642815f2018aee7a6d26d4e55d9b25cad950569 (patch) | |
tree | 9f2c207382ff0c952b61aebe87a32d414f4209c8 | |
parent | e9ee08f74fe745a4963b3c429192840b3b6fdf66 (diff) | |
download | libgit2-0642815f2018aee7a6d26d4e55d9b25cad950569.tar.gz |
repository: warn on safe.directory handlingethomson/warnings
Invoke the new warning callback for `safe.directory` failures.
-rw-r--r-- | src/libgit2/repository.c | 4 | ||||
-rw-r--r-- | tests/libgit2/repo/open.c | 67 |
2 files changed, 70 insertions, 1 deletions
diff --git a/src/libgit2/repository.c b/src/libgit2/repository.c index 489d627a0..9f583c4ad 100644 --- a/src/libgit2/repository.c +++ b/src/libgit2/repository.c @@ -34,6 +34,7 @@ #include "worktree.h" #include "path.h" #include "strmap.h" +#include "warning.h" #ifdef GIT_WIN32 # include "win32/w32_util.h" @@ -590,7 +591,8 @@ static int validate_ownership(git_repository *repo) (error = validate_ownership_config(&is_safe, validation_paths[0])) < 0) goto done; - if (!is_safe) { + if (!is_safe && + git_warning(GIT_WARNING_SAFE_DIRECTORY, path) != GIT_WARNING_IGNORE) { git_error_set(GIT_ERROR_CONFIG, "repository path '%s' is not owned by current user", path); diff --git a/tests/libgit2/repo/open.c b/tests/libgit2/repo/open.c index d835240b7..b1c2c69cf 100644 --- a/tests/libgit2/repo/open.c +++ b/tests/libgit2/repo/open.c @@ -1,6 +1,7 @@ #include "clar_libgit2.h" #include "futils.h" #include "sysdir.h" +#include "warning.h" #include <ctype.h> static int validate_ownership = 0; @@ -28,6 +29,7 @@ void test_repo_open__cleanup(void) git_buf_dispose(&config_path); cl_git_pass(git_libgit2_opts(GIT_OPT_SET_OWNER_VALIDATION, validate_ownership)); + cl_git_pass(git_libgit2_opts(GIT_OPT_SET_WARNING_CALLBACK, NULL, NULL)); } void test_repo_open__bare_empty_repo(void) @@ -757,3 +759,68 @@ void test_repo_open__can_reset_safe_directory_list(void) git_str_dispose(&config_filename); git_str_dispose(&config_data); } + +static int warning_ignore_cb(git_warning_t warning_type, void *data, ...) +{ + va_list ap; + const char *path; + + va_start(ap, data); + path = va_arg(ap, const char *); + + if (warning_type != GIT_WARNING_SAFE_DIRECTORY) + return GIT_WARNING_CONTINUE; + + cl_assert_equal_i(*((int *)data), 42); + cl_assert(strstr(path, "empty_standard_repo") != NULL); + + va_end(ap); + + return GIT_WARNING_IGNORE; +} + +static int warning_fail_cb(git_warning_t warning_type, void *data, ...) +{ + va_list ap; + const char *path; + + va_start(ap, data); + path = va_arg(ap, const char *); + + if (warning_type != GIT_WARNING_SAFE_DIRECTORY) + return GIT_WARNING_IGNORE; + + cl_assert_equal_i(*((int *)data), 42); + cl_assert(strstr(path, "empty_standard_repo") != NULL); + + va_end(ap); + + return GIT_WARNING_CONTINUE; +} + +void test_repo_open__can_ignore_safedirectory_with_warning_callback(void) +{ + git_repository *repo; + int data = 42; + + cl_git_pass(git_libgit2_opts(GIT_OPT_SET_OWNER_VALIDATION, 1)); + + cl_fixture_sandbox("empty_standard_repo"); + cl_git_pass(cl_rename("empty_standard_repo/.gitted", "empty_standard_repo/.git")); + + git_fs_path__set_owner(GIT_FS_PATH_OWNER_OTHER); + + /* When there's no warning callback, invalid ownership must fail. */ + cl_git_pass(git_libgit2_opts(GIT_OPT_SET_WARNING_CALLBACK, NULL, NULL)); + cl_git_fail_with(GIT_EOWNER, git_repository_open(&repo, "empty_standard_repo")); + + /* A warning callback can ignore invalid ownership. */ + cl_git_pass(git_libgit2_opts(GIT_OPT_SET_WARNING_CALLBACK, warning_ignore_cb, &data)); + cl_git_pass(git_repository_open(&repo, "empty_standard_repo")); + git_repository_free(repo); + + /* A warning callback can also enforce libgit2's opinion. */ + cl_git_pass(git_libgit2_opts(GIT_OPT_SET_WARNING_CALLBACK, warning_fail_cb, &data)); + cl_git_fail_with(GIT_EOWNER, git_repository_open(&repo, "empty_standard_repo")); + git_repository_free(repo); +} |