diff options
| author | Edward Thomson <ethomson@edwardthomson.com> | 2023-02-20 20:53:28 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-02-20 20:53:28 +0000 |
| commit | 5561070c3787385ceca01cbde6bb26573d1c6292 (patch) | |
| tree | fc04ba8e49a8b4a317b1d829e857956c9fa66428 /src/libgit2 | |
| parent | 96e85df607863f94b55aba088c1395095b52bba7 (diff) | |
| parent | be3a78cc933169bab12dccdfcbb173cb48261103 (diff) | |
| download | libgit2-5561070c3787385ceca01cbde6bb26573d1c6292.tar.gz | |
Merge pull request #6493 from libgit2/ethomson/ownership
Handle Win32 shares
Diffstat (limited to 'src/libgit2')
| -rw-r--r-- | src/libgit2/repository.c | 48 |
1 files changed, 42 insertions, 6 deletions
diff --git a/src/libgit2/repository.c b/src/libgit2/repository.c index a3e7b9e13..8c41167a1 100644 --- a/src/libgit2/repository.c +++ b/src/libgit2/repository.c @@ -496,14 +496,47 @@ static int validate_ownership_cb(const git_config_entry *entry, void *payload) { validate_ownership_data *data = payload; - if (strcmp(entry->value, "") == 0) + if (strcmp(entry->value, "") == 0) { *data->is_safe = false; - - if (strcmp(entry->value, "*") == 0) - *data->is_safe = true; - else if (git_fs_path_prettify_dir(&data->tmp, entry->value, NULL) == 0 && - strcmp(data->tmp.ptr, data->repo_path) == 0) + } else if (strcmp(entry->value, "*") == 0) { *data->is_safe = true; + } else { + const char *test_path = entry->value; + +#ifdef GIT_WIN32 + /* + * Git for Windows does some truly bizarre things with + * paths that start with a forward slash; and expects you + * to escape that with `%(prefix)`. This syntax generally + * means to add the prefix that Git was installed to -- eg + * `/usr/local` -- unless it's an absolute path, in which + * case the leading `%(prefix)/` is just removed. And Git + * for Windows expects you to use this syntax for absolute + * Unix-style paths (in "Git Bash" or Windows Subsystem for + * Linux). + * + * Worse, the behavior used to be that a leading `/` was + * not absolute. It would indicate that Git for Windows + * should add the prefix. So `//` is required for absolute + * Unix-style paths. Yes, this is truly horrifying. + * + * Emulate that behavior, I guess, but only for absolute + * paths. We won't deal with the Git install prefix. Also, + * give WSL users an escape hatch where they don't have to + * think about this and can use the literal path that the + * filesystem APIs provide (`//wsl.localhost/...`). + */ + if (strncmp(test_path, "%(prefix)//", strlen("%(prefix)//")) == 0) + test_path += strlen("%(prefix)/"); + else if (strncmp(test_path, "//", 2) == 0 && + strncmp(test_path, "//wsl.localhost/", strlen("//wsl.localhost/")) != 0) + test_path++; +#endif + + if (git_fs_path_prettify_dir(&data->tmp, test_path, NULL) == 0 && + strcmp(data->tmp.ptr, data->repo_path) == 0) + *data->is_safe = true; + } return 0; } @@ -547,6 +580,9 @@ static int validate_ownership_path(bool *is_safe, const char *path) if (error == GIT_ENOTFOUND) { *is_safe = true; error = 0; + } else if (error == GIT_EINVALID) { + *is_safe = false; + error = 0; } return error; |
