Skip to content

Commit c0b7f88

Browse files
committed
fs_path: mock ownership checks
Provide a mock for file ownership for testability.
1 parent c0dfd1a commit c0b7f88

File tree

2 files changed

+56
-0
lines changed

2 files changed

+56
-0
lines changed

src/util/fs_path.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1785,6 +1785,13 @@ bool git_fs_path_supports_symlinks(const char *dir)
17851785
return supported;
17861786
}
17871787

1788+
static git_fs_path__mock_owner_t mock_owner = GIT_FS_PATH_MOCK_OWNER_NONE;
1789+
1790+
void git_fs_path__set_owner(git_fs_path__mock_owner_t owner)
1791+
{
1792+
mock_owner = owner;
1793+
}
1794+
17881795
#ifdef GIT_WIN32
17891796
static PSID *sid_dup(PSID sid)
17901797
{
@@ -1877,6 +1884,11 @@ int git_fs_path_owner_is_current_user(bool *out, const char *path)
18771884
PSID owner_sid = NULL, user_sid = NULL;
18781885
int error = -1;
18791886

1887+
if (mock_owner) {
1888+
*out = (mock_owner == GIT_FS_PATH_MOCK_OWNER_CURRENT_USER);
1889+
return 0;
1890+
}
1891+
18801892
if ((error = file_owner_sid(&owner_sid, path)) < 0 ||
18811893
(error = current_user_sid(&user_sid)) < 0)
18821894
goto done;
@@ -1894,6 +1906,11 @@ int git_fs_path_owner_is_system(bool *out, const char *path)
18941906
{
18951907
PSID owner_sid;
18961908

1909+
if (mock_owner) {
1910+
*out = (mock_owner == GIT_FS_PATH_MOCK_OWNER_SYSTEM);
1911+
return 0;
1912+
}
1913+
18971914
if (file_owner_sid(&owner_sid, path) < 0)
18981915
return -1;
18991916

@@ -1909,6 +1926,12 @@ int git_fs_path_owner_is_system_or_current_user(bool *out, const char *path)
19091926
PSID owner_sid = NULL, user_sid = NULL;
19101927
int error = -1;
19111928

1929+
if (mock_owner) {
1930+
*out = (mock_owner == GIT_FS_PATH_MOCK_OWNER_SYSTEM ||
1931+
mock_owner == GIT_FS_PATH_MOCK_OWNER_CURRENT_USER);
1932+
return 0;
1933+
}
1934+
19121935
if (file_owner_sid(&owner_sid, path) < 0)
19131936
goto done;
19141937

@@ -1961,18 +1984,37 @@ static int fs_path_owner_is(bool *out, const char *path, uid_t *uids, size_t uid
19611984
int git_fs_path_owner_is_current_user(bool *out, const char *path)
19621985
{
19631986
uid_t userid = geteuid();
1987+
1988+
if (mock_owner) {
1989+
*out = (mock_owner == GIT_FS_PATH_MOCK_OWNER_CURRENT_USER);
1990+
return 0;
1991+
}
1992+
19641993
return fs_path_owner_is(out, path, &userid, 1);
19651994
}
19661995

19671996
int git_fs_path_owner_is_system(bool *out, const char *path)
19681997
{
19691998
uid_t userid = 0;
1999+
2000+
if (mock_owner) {
2001+
*out = (mock_owner == GIT_FS_PATH_MOCK_OWNER_SYSTEM);
2002+
return 0;
2003+
}
2004+
19702005
return fs_path_owner_is(out, path, &userid, 1);
19712006
}
19722007

19732008
int git_fs_path_owner_is_system_or_current_user(bool *out, const char *path)
19742009
{
19752010
uid_t userids[2] = { geteuid(), 0 };
2011+
2012+
if (mock_owner) {
2013+
*out = (mock_owner == GIT_FS_PATH_MOCK_OWNER_SYSTEM ||
2014+
mock_owner == GIT_FS_PATH_MOCK_OWNER_CURRENT_USER);
2015+
return 0;
2016+
}
2017+
19762018
return fs_path_owner_is(out, path, userids, 2);
19772019
}
19782020

src/util/fs_path.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,20 @@ int git_fs_path_normalize_slashes(git_str *out, const char *path);
731731

732732
bool git_fs_path_supports_symlinks(const char *dir);
733733

734+
typedef enum {
735+
GIT_FS_PATH_MOCK_OWNER_NONE = 0, /* do filesystem lookups as normal */
736+
GIT_FS_PATH_MOCK_OWNER_SYSTEM = 1,
737+
GIT_FS_PATH_MOCK_OWNER_CURRENT_USER = 2,
738+
GIT_FS_PATH_MOCK_OWNER_OTHER = 3
739+
} git_fs_path__mock_owner_t;
740+
741+
/**
742+
* Sets the mock ownership for files; subsequent calls to
743+
* `git_fs_path_owner_is_*` functions will return this data until cleared
744+
* with `GIT_FS_PATH_MOCK_OWNER_NONE`.
745+
*/
746+
void git_fs_path__set_owner(git_fs_path__mock_owner_t owner);
747+
734748
/**
735749
* Verify that the file in question is owned by an administrator or system
736750
* account.

0 commit comments

Comments
 (0)