path: Teach UNC paths to git_path_dirname_r() Fix libgit2/libgit2sharp#256
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
diff --git a/src/path.c b/src/path.c
index 569101c..dd6bb70 100644
--- a/src/path.c
+++ b/src/path.c
@@ -19,6 +19,22 @@
#define LOOKS_LIKE_DRIVE_PREFIX(S) (git__isalpha((S)[0]) && (S)[1] == ':')
+static bool looks_like_network_computer_name(const char *path, int pos)
+{
+ if (pos < 3)
+ return false;
+
+ if (path[0] != '/' || path[1] != '/')
+ return false;
+
+ while (pos-- > 2) {
+ if (path[pos] == '/')
+ return false;
+ }
+
+ return true;
+}
+
/*
* Based on the Android implementation, BSD licensed.
* Check http://android.git.kernel.org/
@@ -111,6 +127,15 @@ int git_path_dirname_r(git_buf *buffer, const char *path)
len = 3;
goto Exit;
}
+
+ /* Similarly checks if we're dealing with a network computer name
+ '//computername/.git' will return '//computername/' */
+
+ if (looks_like_network_computer_name(path, len)) {
+ len++;
+ goto Exit;
+ }
+
#endif
Exit:
diff --git a/tests-clar/core/path.c b/tests-clar/core/path.c
index e2f78ea..894e81f 100644
--- a/tests-clar/core/path.c
+++ b/tests-clar/core/path.c
@@ -91,6 +91,10 @@ void test_core_path__00_dirname(void)
#ifdef GIT_WIN32
check_dirname("C:/path/", "C:/");
check_dirname("C:/path", "C:/");
+ check_dirname("//computername/path/", "//computername/");
+ check_dirname("//computername/path", "//computername/");
+ check_dirname("//computername/sub/path/", "//computername/sub");
+ check_dirname("//computername/sub/path", "//computername/sub");
#endif
}