mirror of
https://github.com/libgit2/libgit2.git
synced 2026-06-21 22:16:24 +00:00
Merge branch 'pr/7265'
This commit is contained in:
@@ -582,16 +582,27 @@ static int validate_ownership_cb(const git_config_entry *entry, void *payload)
|
||||
} else if (strcmp(entry->value, "*") == 0) {
|
||||
*data->is_safe = true;
|
||||
} else {
|
||||
bool is_prefix = false, match;
|
||||
|
||||
if (git_str_sets(&data->tmp, entry->value) < 0)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* A value ending with slash* is treated as a prefix match.
|
||||
* Strip only the '*', leaving the trailing slash in place.
|
||||
*/
|
||||
if (git__suffixcmp(data->tmp.ptr, "/*") == 0) {
|
||||
is_prefix = true;
|
||||
git_str_shorten(&data->tmp, 1);
|
||||
}
|
||||
|
||||
if (!git_fs_path_is_root(data->tmp.ptr)) {
|
||||
/* Input must not have trailing backslash. */
|
||||
if (!data->tmp.size ||
|
||||
data->tmp.ptr[data->tmp.size - 1] == '/')
|
||||
(!is_prefix && data->tmp.ptr[data->tmp.size - 1] == '/'))
|
||||
return 0;
|
||||
|
||||
if (git_fs_path_to_dir(&data->tmp) < 0)
|
||||
if (!is_prefix && git_fs_path_to_dir(&data->tmp) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -623,7 +634,11 @@ static int validate_ownership_cb(const git_config_entry *entry, void *payload)
|
||||
if (strncmp(test_path, "%(prefix)//", strlen("%(prefix)//")) == 0)
|
||||
test_path += strlen("%(prefix)/");
|
||||
|
||||
if (strcmp(test_path, data->repo_path) == 0)
|
||||
match = is_prefix ?
|
||||
(git__prefixcmp(data->repo_path, test_path) == 0) :
|
||||
(strcmp(test_path, data->repo_path) == 0);
|
||||
|
||||
if (match)
|
||||
*data->is_safe = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -659,6 +659,26 @@ void test_repo_open__can_wildcard_allowlist_with_problematic_ownership(void)
|
||||
cl_git_pass(test_safe_path("*"));
|
||||
}
|
||||
|
||||
void test_repo_open__can_allowlist_dirs_wildcard(void)
|
||||
{
|
||||
git_str path = GIT_STR_INIT;
|
||||
|
||||
cl_git_pass(git_str_printf(
|
||||
&path, "%s/*", clar_sandbox_path()));
|
||||
cl_git_pass(test_safe_path(path.ptr));
|
||||
git_str_dispose(&path);
|
||||
}
|
||||
|
||||
void test_repo_open__allowlist_dirs_cannot_have_wildcard_suffix(void)
|
||||
{
|
||||
git_str path = GIT_STR_INIT;
|
||||
|
||||
cl_git_pass(git_str_printf(
|
||||
&path, "%s/%s*", clar_sandbox_path(), "empty_standard_repo"));
|
||||
cl_git_fail_with(GIT_EOWNER, test_safe_path(path.ptr));
|
||||
git_str_dispose(&path);
|
||||
}
|
||||
|
||||
void test_repo_open__can_allowlist_bare_gitdir(void)
|
||||
{
|
||||
git_str path = GIT_STR_INIT;
|
||||
@@ -669,6 +689,38 @@ void test_repo_open__can_allowlist_bare_gitdir(void)
|
||||
git_str_dispose(&path);
|
||||
}
|
||||
|
||||
void test_repo_open__can_allowlist_bare_wildcard_gitdir(void)
|
||||
{
|
||||
git_str path = GIT_STR_INIT;
|
||||
|
||||
cl_git_pass(git_str_printf(
|
||||
&path, "%s/*", clar_sandbox_path()));
|
||||
cl_git_pass(test_bare_safe_path(path.ptr));
|
||||
|
||||
git_str_dispose(&path);
|
||||
}
|
||||
|
||||
void test_repo_open__allowlist_bare_dirs_cannot_have_wildcard_suffix(void)
|
||||
{
|
||||
git_str path = GIT_STR_INIT;
|
||||
|
||||
cl_git_pass(git_str_printf(
|
||||
&path, "%s/%s*", clar_sandbox_path(), "testrepo.git"));
|
||||
cl_git_fail_with(GIT_EOWNER, test_bare_safe_path(path.ptr));
|
||||
|
||||
git_str_dispose(&path);
|
||||
}
|
||||
|
||||
void test_repo_open__allowlist_relative_bare_dirs_cannot_have_wildcard_suffix(void)
|
||||
{
|
||||
git_str path = GIT_STR_INIT;
|
||||
|
||||
cl_git_pass(git_str_printf(&path, "%s*", clar_sandbox_path()));
|
||||
cl_git_fail_with(GIT_EOWNER, test_bare_safe_path(path.ptr));
|
||||
|
||||
git_str_dispose(&path);
|
||||
}
|
||||
|
||||
void test_repo_open__can_wildcard_allowlist_bare_gitdir(void)
|
||||
{
|
||||
cl_git_pass(test_bare_safe_path("*"));
|
||||
@@ -691,6 +743,23 @@ void test_repo_open__can_handle_prefixed_safe_paths(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_repo_open__can_handle_prefixed_wildcard_safe_paths(void)
|
||||
{
|
||||
#ifndef GIT_WIN32
|
||||
git_str path = GIT_STR_INIT;
|
||||
|
||||
/*
|
||||
* Using "%(prefix)/" becomes "%(prefix)//tmp/foo" - so
|
||||
* "%(prefix)/" is stripped and means the literal path
|
||||
* follows.
|
||||
*/
|
||||
cl_git_pass(git_str_printf(&path, "%%(prefix)/%s/*",
|
||||
clar_sandbox_path()));
|
||||
cl_git_pass(test_safe_path(path.ptr));
|
||||
git_str_dispose(&path);
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_repo_open__prefixed_safe_paths_must_have_two_slashes(void)
|
||||
{
|
||||
git_str path = GIT_STR_INIT;
|
||||
|
||||
Reference in New Issue
Block a user