mirror of
https://github.com/libgit2/libgit2.git
synced 2026-06-22 06:26:26 +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) {
|
} else if (strcmp(entry->value, "*") == 0) {
|
||||||
*data->is_safe = true;
|
*data->is_safe = true;
|
||||||
} else {
|
} else {
|
||||||
|
bool is_prefix = false, match;
|
||||||
|
|
||||||
if (git_str_sets(&data->tmp, entry->value) < 0)
|
if (git_str_sets(&data->tmp, entry->value) < 0)
|
||||||
return -1;
|
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)) {
|
if (!git_fs_path_is_root(data->tmp.ptr)) {
|
||||||
/* Input must not have trailing backslash. */
|
/* Input must not have trailing backslash. */
|
||||||
if (!data->tmp.size ||
|
if (!data->tmp.size ||
|
||||||
data->tmp.ptr[data->tmp.size - 1] == '/')
|
(!is_prefix && data->tmp.ptr[data->tmp.size - 1] == '/'))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (git_fs_path_to_dir(&data->tmp) < 0)
|
if (!is_prefix && git_fs_path_to_dir(&data->tmp) < 0)
|
||||||
return -1;
|
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)
|
if (strncmp(test_path, "%(prefix)//", strlen("%(prefix)//")) == 0)
|
||||||
test_path += strlen("%(prefix)/");
|
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;
|
*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("*"));
|
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)
|
void test_repo_open__can_allowlist_bare_gitdir(void)
|
||||||
{
|
{
|
||||||
git_str path = GIT_STR_INIT;
|
git_str path = GIT_STR_INIT;
|
||||||
@@ -669,6 +689,38 @@ void test_repo_open__can_allowlist_bare_gitdir(void)
|
|||||||
git_str_dispose(&path);
|
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)
|
void test_repo_open__can_wildcard_allowlist_bare_gitdir(void)
|
||||||
{
|
{
|
||||||
cl_git_pass(test_bare_safe_path("*"));
|
cl_git_pass(test_bare_safe_path("*"));
|
||||||
@@ -691,6 +743,23 @@ void test_repo_open__can_handle_prefixed_safe_paths(void)
|
|||||||
#endif
|
#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)
|
void test_repo_open__prefixed_safe_paths_must_have_two_slashes(void)
|
||||||
{
|
{
|
||||||
git_str path = GIT_STR_INIT;
|
git_str path = GIT_STR_INIT;
|
||||||
|
|||||||
Reference in New Issue
Block a user