summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Straub <bs@github.com>2013-11-01 15:29:25 -0700
committerBen Straub <bs@github.com>2013-11-01 15:29:25 -0700
commit7e0359084ef0faba8f458f9cccad2dc8f5baf800 (patch)
tree0f569028ea3c59592c10bee1a77107e86b7a995a
parent567649f2ada60e5c3009cc985af238b452b14a81 (diff)
downloadlibgit2-7e0359084ef0faba8f458f9cccad2dc8f5baf800.tar.gz
Streamline url-parsing logic.
-rw-r--r--src/netops.c50
-rw-r--r--tests-clar/network/urlparse.c10
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,