Skip to content

Commit e4eabb0

Browse files
committed
fs_path: mock ownership checks
Provide a mock for file ownership for testability.
1 parent 62d492d commit e4eabb0

File tree

2 files changed

+56
-0
lines changed

2 files changed

+56
-0
lines changed

src/path.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2024,6 +2024,13 @@ bool git_path_supports_symlinks(const char *dir)
20242024
return supported;
20252025
}
20262026

2027+
static git_path__mock_owner_t mock_owner = GIT_PATH_MOCK_OWNER_NONE;
2028+
2029+
void git_path__set_owner(git_path__mock_owner_t owner)
2030+
{
2031+
mock_owner = owner;
2032+
}
2033+
20272034
#ifdef GIT_WIN32
20282035
static PSID *sid_dup(PSID sid)
20292036
{
@@ -2116,6 +2123,11 @@ int git_path_owner_is_current_user(bool *out, const char *path)
21162123
PSID owner_sid = NULL, user_sid = NULL;
21172124
int error = -1;
21182125

2126+
if (mock_owner) {
2127+
*out = (mock_owner == GIT_PATH_MOCK_OWNER_CURRENT_USER);
2128+
return 0;
2129+
}
2130+
21192131
if ((error = file_owner_sid(&owner_sid, path)) < 0 ||
21202132
(error = current_user_sid(&user_sid)) < 0)
21212133
goto done;
@@ -2133,6 +2145,11 @@ int git_path_owner_is_system(bool *out, const char *path)
21332145
{
21342146
PSID owner_sid;
21352147

2148+
if (mock_owner) {
2149+
*out = (mock_owner == GIT_PATH_MOCK_OWNER_SYSTEM);
2150+
return 0;
2151+
}
2152+
21362153
if (file_owner_sid(&owner_sid, path) < 0)
21372154
return -1;
21382155

@@ -2148,6 +2165,12 @@ int git_path_owner_is_system_or_current_user(bool *out, const char *path)
21482165
PSID owner_sid = NULL, user_sid = NULL;
21492166
int error = -1;
21502167

2168+
if (mock_owner) {
2169+
*out = (mock_owner == GIT_PATH_MOCK_OWNER_SYSTEM ||
2170+
mock_owner == GIT_PATH_MOCK_OWNER_CURRENT_USER);
2171+
return 0;
2172+
}
2173+
21512174
if (file_owner_sid(&owner_sid, path) < 0)
21522175
goto done;
21532176

@@ -2200,18 +2223,37 @@ static int path_owner_is(bool *out, const char *path, uid_t *uids, size_t uids_l
22002223
int git_path_owner_is_current_user(bool *out, const char *path)
22012224
{
22022225
uid_t userid = geteuid();
2226+
2227+
if (mock_owner) {
2228+
*out = (mock_owner == GIT_PATH_MOCK_OWNER_CURRENT_USER);
2229+
return 0;
2230+
}
2231+
22032232
return path_owner_is(out, path, &userid, 1);
22042233
}
22052234

22062235
int git_path_owner_is_system(bool *out, const char *path)
22072236
{
22082237
uid_t userid = 0;
2238+
2239+
if (mock_owner) {
2240+
*out = (mock_owner == GIT_PATH_MOCK_OWNER_SYSTEM);
2241+
return 0;
2242+
}
2243+
22092244
return path_owner_is(out, path, &userid, 1);
22102245
}
22112246

22122247
int git_path_owner_is_system_or_current_user(bool *out, const char *path)
22132248
{
22142249
uid_t userids[2] = { geteuid(), 0 };
2250+
2251+
if (mock_owner) {
2252+
*out = (mock_owner == GIT_PATH_MOCK_OWNER_SYSTEM ||
2253+
mock_owner == GIT_PATH_MOCK_OWNER_CURRENT_USER);
2254+
return 0;
2255+
}
2256+
22152257
return path_owner_is(out, path, userids, 2);
22162258
}
22172259

src/path.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,20 @@ int git_path_normalize_slashes(git_buf *out, const char *path);
722722

723723
bool git_path_supports_symlinks(const char *dir);
724724

725+
typedef enum {
726+
GIT_PATH_MOCK_OWNER_NONE = 0, /* do filesystem lookups as normal */
727+
GIT_PATH_MOCK_OWNER_SYSTEM = 1,
728+
GIT_PATH_MOCK_OWNER_CURRENT_USER = 2,
729+
GIT_PATH_MOCK_OWNER_OTHER = 3
730+
} git_path__mock_owner_t;
731+
732+
/**
733+
* Sets the mock ownership for files; subsequent calls to
734+
* `git_path_owner_is_*` functions will return this data until cleared
735+
* with `GIT_PATH_MOCK_OWNER_NONE`.
736+
*/
737+
void git_path__set_owner(git_path__mock_owner_t owner);
738+
725739
/**
726740
* Verify that the file in question is owned by an administrator or system
727741
* account.

0 commit comments

Comments
 (0)