Commit 7e035908 by Ben Straub

Streamline url-parsing logic.

parent 567649f2
......@@ -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;
}
......@@ -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,
......
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