summaryrefslogtreecommitdiff
path: root/src/path.c
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@microsoft.com>2014-07-08 15:45:50 -0400
committerEdward Thomson <ethomson@microsoft.com>2014-07-11 18:46:00 -0400
commit529fd30d1f81cc711ce3ca3857d637e84a1ca6e4 (patch)
tree237ac8450787374eb3bbf7f202ad1ebb4dcaa588 /src/path.c
parent356b891e3ec53ed937db38b6827c6045fc1beff4 (diff)
downloadlibgit2-529fd30d1f81cc711ce3ca3857d637e84a1ca6e4.tar.gz
Handle local file:/// paths on Windows
Windows can't handle a path like `/c:/foo`; when turning file:/// URIs into local paths, we must strip the leading slash.
Diffstat (limited to 'src/path.c')
-rw-r--r--src/path.c54
1 files changed, 25 insertions, 29 deletions
diff --git a/src/path.c b/src/path.c
index 5beab97ed..6d0b3749b 100644
--- a/src/path.c
+++ b/src/path.c
@@ -377,26 +377,33 @@ static int error_invalid_local_file_uri(const char *uri)
return -1;
}
-int git_path_fromurl(git_buf *local_path_out, const char *file_url)
+static int local_file_url_prefixlen(const char *file_url)
{
- int offset = 0, len;
+ int len = -1;
- assert(local_path_out && file_url);
+ if (git__prefixcmp(file_url, "file://") == 0) {
+ if (file_url[7] == '/')
+ len = 8;
+ else if (git__prefixcmp(file_url + 7, "localhost/") == 0)
+ len = 17;
+ }
- if (git__prefixcmp(file_url, "file://") != 0)
- return error_invalid_local_file_uri(file_url);
+ return len;
+}
- offset += 7;
- len = (int)strlen(file_url);
+bool git_path_is_local_file_url(const char *file_url)
+{
+ return (local_file_url_prefixlen(file_url) > 0);
+}
- if (offset < len && file_url[offset] == '/')
- offset++;
- else if (offset < len && git__prefixcmp(file_url + offset, "localhost/") == 0)
- offset += 10;
- else
- return error_invalid_local_file_uri(file_url);
+int git_path_fromurl(git_buf *local_path_out, const char *file_url)
+{
+ int offset;
- if (offset >= len || file_url[offset] == '/')
+ assert(local_path_out && file_url);
+
+ if ((offset = local_file_url_prefixlen(file_url)) < 0 ||
+ file_url[offset] == '\0' || file_url[offset] == '/')
return error_invalid_local_file_uri(file_url);
#ifndef GIT_WIN32
@@ -404,7 +411,6 @@ int git_path_fromurl(git_buf *local_path_out, const char *file_url)
#endif
git_buf_clear(local_path_out);
-
return git__percent_decode(local_path_out, file_url + offset);
}
@@ -1130,18 +1136,8 @@ int git_path_dirload_with_stat(
int git_path_from_url_or_path(git_buf *local_path_out, const char *url_or_path)
{
- int error;
-
- /* If url_or_path begins with file:// treat it as a URL */
- if (!git__prefixcmp(url_or_path, "file://")) {
- if ((error = git_path_fromurl(local_path_out, url_or_path)) < 0) {
- return error;
- }
- } else { /* We assume url_or_path is already a path */
- if ((error = git_buf_sets(local_path_out, url_or_path)) < 0) {
- return error;
- }
- }
-
- return 0;
+ if (git_path_is_local_file_url(url_or_path))
+ return git_path_fromurl(local_path_out, url_or_path);
+ else
+ return git_buf_sets(local_path_out, url_or_path);
}