Skip to content

Commit 5561070

Browse files
authored
Merge pull request libgit2#6493 from libgit2/ethomson/ownership
Handle Win32 shares
2 parents 96e85df + be3a78c commit 5561070

2 files changed

Lines changed: 43 additions & 7 deletions

File tree

src/libgit2/repository.c

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -496,14 +496,47 @@ static int validate_ownership_cb(const git_config_entry *entry, void *payload)
496496
{
497497
validate_ownership_data *data = payload;
498498

499-
if (strcmp(entry->value, "") == 0)
499+
if (strcmp(entry->value, "") == 0) {
500500
*data->is_safe = false;
501-
502-
if (strcmp(entry->value, "*") == 0)
503-
*data->is_safe = true;
504-
else if (git_fs_path_prettify_dir(&data->tmp, entry->value, NULL) == 0 &&
505-
strcmp(data->tmp.ptr, data->repo_path) == 0)
501+
} else if (strcmp(entry->value, "*") == 0) {
506502
*data->is_safe = true;
503+
} else {
504+
const char *test_path = entry->value;
505+
506+
#ifdef GIT_WIN32
507+
/*
508+
* Git for Windows does some truly bizarre things with
509+
* paths that start with a forward slash; and expects you
510+
* to escape that with `%(prefix)`. This syntax generally
511+
* means to add the prefix that Git was installed to -- eg
512+
* `/usr/local` -- unless it's an absolute path, in which
513+
* case the leading `%(prefix)/` is just removed. And Git
514+
* for Windows expects you to use this syntax for absolute
515+
* Unix-style paths (in "Git Bash" or Windows Subsystem for
516+
* Linux).
517+
*
518+
* Worse, the behavior used to be that a leading `/` was
519+
* not absolute. It would indicate that Git for Windows
520+
* should add the prefix. So `//` is required for absolute
521+
* Unix-style paths. Yes, this is truly horrifying.
522+
*
523+
* Emulate that behavior, I guess, but only for absolute
524+
* paths. We won't deal with the Git install prefix. Also,
525+
* give WSL users an escape hatch where they don't have to
526+
* think about this and can use the literal path that the
527+
* filesystem APIs provide (`//wsl.localhost/...`).
528+
*/
529+
if (strncmp(test_path, "%(prefix)//", strlen("%(prefix)//")) == 0)
530+
test_path += strlen("%(prefix)/");
531+
else if (strncmp(test_path, "//", 2) == 0 &&
532+
strncmp(test_path, "//wsl.localhost/", strlen("//wsl.localhost/")) != 0)
533+
test_path++;
534+
#endif
535+
536+
if (git_fs_path_prettify_dir(&data->tmp, test_path, NULL) == 0 &&
537+
strcmp(data->tmp.ptr, data->repo_path) == 0)
538+
*data->is_safe = true;
539+
}
507540

508541
return 0;
509542
}
@@ -547,6 +580,9 @@ static int validate_ownership_path(bool *is_safe, const char *path)
547580
if (error == GIT_ENOTFOUND) {
548581
*is_safe = true;
549582
error = 0;
583+
} else if (error == GIT_EINVALID) {
584+
*is_safe = false;
585+
error = 0;
550586
}
551587

552588
return error;

src/util/fs_path.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1855,7 +1855,7 @@ static int file_owner_sid(PSID *out, const char *path)
18551855
PSECURITY_DESCRIPTOR descriptor = NULL;
18561856
PSID owner_sid;
18571857
DWORD ret;
1858-
int error = -1;
1858+
int error = GIT_EINVALID;
18591859

18601860
if (git_win32_path_from_utf8(path_w32, path) < 0)
18611861
return -1;

0 commit comments

Comments
 (0)