diff options
author | Ben Straub <bs@github.com> | 2013-11-01 15:29:25 -0700 |
---|---|---|
committer | Ben Straub <bs@github.com> | 2013-11-01 15:29:25 -0700 |
commit | 7e0359084ef0faba8f458f9cccad2dc8f5baf800 (patch) | |
tree | 0f569028ea3c59592c10bee1a77107e86b7a995a | |
parent | 567649f2ada60e5c3009cc985af238b452b14a81 (diff) | |
download | libgit2-7e0359084ef0faba8f458f9cccad2dc8f5baf800.tar.gz |
Streamline url-parsing logic.
-rw-r--r-- | src/netops.c | 50 | ||||
-rw-r--r-- | tests-clar/network/urlparse.c | 10 |
2 files changed, 35 insertions, 25 deletions
diff --git a/src/netops.c b/src/netops.c index 7e13f12e7..0bf3a8f13 100644 --- a/src/netops.c +++ b/src/netops.c @@ -668,47 +668,47 @@ int gitno_extract_url_parts( const char *url, const char *default_port) { - char *colon, *slash, *at, *end; - const char *start; + char *colon, *slash, *at; /* * ==> [user[:pass]@]hostname.tld[:port]/resource */ - colon = strchr(url, ':'); - slash = strchr(url, '/'); + /* Check for user and maybe password */ at = strchr(url, '@'); + if (at) { + colon = strchr(url, ':'); + if (colon && colon < at) { + /* user:pass */ + *username = git__substrdup(url, colon-url); + *password = git__substrdup(colon+1, at-colon-1); + GITERR_CHECK_ALLOC(*password); + } else { + *username = git__substrdup(url, at-url); + } + GITERR_CHECK_ALLOC(*username); + url = at + 1; + } + /* Validate URL format. Colons shouldn't be in the path part. */ + slash = strchr(url, '/'); + colon = strchr(url, ':'); if (!slash || (colon && (slash < colon))) { giterr_set(GITERR_NET, "Malformed URL"); return GIT_EINVALIDSPEC; } - start = url; - if (at && at < slash) { - start = at+1; - *username = git__substrdup(url, at - url); - } - - if (colon && colon < at) { - git__free(*username); - *username = git__substrdup(url, colon-url); - *password = git__substrdup(colon+1, at-colon-1); - colon = strchr(at, ':'); - } - - if (colon == NULL) { - *port = git__strdup(default_port); + /* Check for hostname and maybe port */ + if (colon) { + *host = git__substrdup(url, colon-url); + *port = git__substrdup(colon+1, slash-colon-1); } else { - *port = git__substrdup(colon + 1, slash - colon - 1); + *host = git__substrdup(url, slash-url); + *port = git__strdup(default_port); } - GITERR_CHECK_ALLOC(*port); - - end = colon == NULL ? slash : colon; - - *host = git__substrdup(start, end - start); GITERR_CHECK_ALLOC(*host); + GITERR_CHECK_ALLOC(*port); return 0; } diff --git a/tests-clar/network/urlparse.c b/tests-clar/network/urlparse.c index 15e841b35..9fc304a07 100644 --- a/tests-clar/network/urlparse.c +++ b/tests-clar/network/urlparse.c @@ -38,6 +38,16 @@ void test_network_urlparse__bad_url(void) GIT_EINVALIDSPEC); } +void test_network_urlparse__weird_url(void) +{ + cl_git_pass(gitno_extract_url_parts(&host, &port, &user, &pass, + "arrbee:my/bad:password@github.com:1111/strange/words.git", "1")); + cl_assert_equal_s(host, "github.com"); + cl_assert_equal_s(port, "1111"); + cl_assert_equal_s(user, "arrbee"); + cl_assert_equal_s(pass, "my/bad:password"); +} + void test_network_urlparse__user(void) { cl_git_pass(gitno_extract_url_parts(&host, &port, &user, &pass, |