From 81d7bd13be841f9eb3e200013871aa4f5ea2fb8f Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 15 Feb 2023 12:33:16 +0000 Subject: [PATCH] repository: warn on safe.directory handling Invoke the new warning callback for `safe.directory` failures. --- src/libgit2/repository.c | 4 ++- tests/libgit2/repo/open.c | 67 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/src/libgit2/repository.c b/src/libgit2/repository.c index a88217e65..97c267a26 100644 --- a/src/libgit2/repository.c +++ b/src/libgit2/repository.c @@ -34,6 +34,7 @@ #include "submodule.h" #include "worktree.h" #include "path.h" +#include "warning.h" #ifdef GIT_WIN32 # include "win32/w32_util.h" @@ -706,7 +707,8 @@ static int validate_ownership(git_repository *repo) &is_safe, validation_paths[0], repo->use_env)) < 0) goto done; - if (!is_safe) { + if (!is_safe && + git_warning(GIT_WARNING_SAFE_DIRECTORY, path) != GIT_WARNING_IGNORE) { size_t path_len = git_fs_path_is_root(path) ? strlen(path) : git_fs_path_dirlen(path); diff --git a/tests/libgit2/repo/open.c b/tests/libgit2/repo/open.c index d58551343..cafe33d6b 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 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) @@ -874,3 +876,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); +}