Commit 683ff4f3 by Edward Thomson Committed by GitHub

Merge pull request #4111 from pks-t/pks/dos-prefix

dirname with DOS prefixes
parents 2b8163b8 3428a523
...@@ -111,13 +111,41 @@ Exit: ...@@ -111,13 +111,41 @@ Exit:
} }
/* /*
* Determine if the path is a Windows prefix and, if so, returns
* its actual lentgh. If it is not a prefix, returns -1.
*/
static int win32_prefix_length(const char *path, int len)
{
#ifndef GIT_WIN32
GIT_UNUSED(path);
GIT_UNUSED(len);
#else
/*
* Mimic unix behavior where '/.git' returns '/': 'C:/.git' will return
* 'C:/' here
*/
if (len == 2 && LOOKS_LIKE_DRIVE_PREFIX(path))
return 2;
/*
* Similarly checks if we're dealing with a network computer name
* '//computername/.git' will return '//computername/'
*/
if (looks_like_network_computer_name(path, len))
return len;
#endif
return -1;
}
/*
* Based on the Android implementation, BSD licensed. * Based on the Android implementation, BSD licensed.
* Check http://android.git.kernel.org/ * Check http://android.git.kernel.org/
*/ */
int git_path_dirname_r(git_buf *buffer, const char *path) int git_path_dirname_r(git_buf *buffer, const char *path)
{ {
const char *endp; const char *endp;
int result, len; int is_prefix = 0, len;
/* Empty or NULL string gets treated as "." */ /* Empty or NULL string gets treated as "." */
if (path == NULL || *path == '\0') { if (path == NULL || *path == '\0') {
...@@ -131,6 +159,11 @@ int git_path_dirname_r(git_buf *buffer, const char *path) ...@@ -131,6 +159,11 @@ int git_path_dirname_r(git_buf *buffer, const char *path)
while (endp > path && *endp == '/') while (endp > path && *endp == '/')
endp--; endp--;
if ((len = win32_prefix_length(path, endp - path + 1)) > 0) {
is_prefix = 1;
goto Exit;
}
/* Find the start of the dir */ /* Find the start of the dir */
while (endp > path && *endp != '/') while (endp > path && *endp != '/')
endp--; endp--;
...@@ -146,35 +179,23 @@ int git_path_dirname_r(git_buf *buffer, const char *path) ...@@ -146,35 +179,23 @@ int git_path_dirname_r(git_buf *buffer, const char *path)
endp--; endp--;
} while (endp > path && *endp == '/'); } while (endp > path && *endp == '/');
/* Cast is safe because max path < max int */ if ((len = win32_prefix_length(path, endp - path + 1)) > 0) {
len = (int)(endp - path + 1); is_prefix = 1;
#ifdef GIT_WIN32
/* Mimic unix behavior where '/.git' returns '/': 'C:/.git' will return
'C:/' here */
if (len == 2 && LOOKS_LIKE_DRIVE_PREFIX(path)) {
len = 3;
goto Exit; goto Exit;
} }
/* Similarly checks if we're dealing with a network computer name /* Cast is safe because max path < max int */
'//computername/.git' will return '//computername/' */ len = (int)(endp - path + 1);
if (looks_like_network_computer_name(path, len)) {
len++;
goto Exit;
}
#endif
Exit: Exit:
result = len; if (buffer) {
if (git_buf_set(buffer, path, len) < 0)
if (buffer != NULL && git_buf_set(buffer, path, len) < 0) return -1;
return -1; if (is_prefix && git_buf_putc(buffer, '/') < 0)
return -1;
}
return result; return len;
} }
......
...@@ -89,8 +89,12 @@ void test_core_path__00_dirname(void) ...@@ -89,8 +89,12 @@ void test_core_path__00_dirname(void)
check_dirname(REP16("/abc"), REP15("/abc")); check_dirname(REP16("/abc"), REP15("/abc"));
#ifdef GIT_WIN32 #ifdef GIT_WIN32
check_dirname("C:/", "C:/");
check_dirname("C:", "C:/");
check_dirname("C:/path/", "C:/"); check_dirname("C:/path/", "C:/");
check_dirname("C:/path", "C:/"); check_dirname("C:/path", "C:/");
check_dirname("//computername/", "//computername/");
check_dirname("//computername", "//computername/");
check_dirname("//computername/path/", "//computername/"); check_dirname("//computername/path/", "//computername/");
check_dirname("//computername/path", "//computername/"); check_dirname("//computername/path", "//computername/");
check_dirname("//computername/sub/path/", "//computername/sub"); check_dirname("//computername/sub/path/", "//computername/sub");
......
...@@ -199,3 +199,12 @@ void test_repo_discover__discovery_starting_at_file_succeeds(void) ...@@ -199,3 +199,12 @@ void test_repo_discover__discovery_starting_at_file_succeeds(void)
ensure_repository_discover(SUB_REPOSITORY_FOLDER "/file", ceiling_dirs.ptr, SUB_REPOSITORY_GITDIR); ensure_repository_discover(SUB_REPOSITORY_FOLDER "/file", ceiling_dirs.ptr, SUB_REPOSITORY_GITDIR);
} }
void test_repo_discover__discovery_starting_at_system_root_causes_no_hang(void)
{
#ifdef GIT_WIN32
git_buf out = GIT_BUF_INIT;
cl_git_fail(git_repository_discover(&out, "C:/", 0, NULL));
cl_git_fail(git_repository_discover(&out, "//localhost/", 0, NULL));
#endif
}
File mode changed from 100644 to 100755
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment