summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <edward.thomson@vercel.com>2023-02-15 12:33:16 +0000
committerEdward Thomson <edward.thomson@vercel.com>2023-02-15 13:23:51 +0000
commit0642815f2018aee7a6d26d4e55d9b25cad950569 (patch)
tree9f2c207382ff0c952b61aebe87a32d414f4209c8
parente9ee08f74fe745a4963b3c429192840b3b6fdf66 (diff)
downloadlibgit2-ethomson/warnings.tar.gz
repository: warn on safe.directory handlingethomson/warnings
Invoke the new warning callback for `safe.directory` failures.
-rw-r--r--src/libgit2/repository.c4
-rw-r--r--tests/libgit2/repo/open.c67
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);
+}