Commit ab44c62e548373c1494e967f54720faa06ce38b7

Vicent Martí 2013-11-01T04:22:12

Merge pull request #1928 from libgit2/parse-bad-urls Improve bad URL handling

diff --git a/src/netops.c b/src/netops.c
index 7a61ef8..7e13f12 100644
--- a/src/netops.c
+++ b/src/netops.c
@@ -679,9 +679,10 @@ int gitno_extract_url_parts(
 	slash = strchr(url, '/');
 	at = strchr(url, '@');
 
-	if (slash == NULL) {
-		giterr_set(GITERR_NET, "Malformed URL: missing /");
-		return -1;
+	if (!slash ||
+	    (colon && (slash < colon))) {
+		giterr_set(GITERR_NET, "Malformed URL");
+		return GIT_EINVALIDSPEC;
 	}
 
 	start = url;
diff --git a/src/transports/ssh.c b/src/transports/ssh.c
index 6ce673d..4e2834b 100644
--- a/src/transports/ssh.c
+++ b/src/transports/ssh.c
@@ -213,10 +213,6 @@ static int git_ssh_extract_url_parts(
 
 	colon = strchr(url, ':');
 
-	if (colon == NULL) {
-		giterr_set(GITERR_NET, "Malformed URL: missing :");
-		return -1;
-	}
 
 	at = strchr(url, '@');
 	if (at) {
@@ -228,6 +224,11 @@ static int git_ssh_extract_url_parts(
 		*username = NULL;
 	}
 
+	if (colon == NULL || (colon < start)) {
+		giterr_set(GITERR_NET, "Malformed URL");
+		return -1;
+	}
+
 	*host = git__substrdup(start, colon - start);
 	GITERR_CHECK_ALLOC(*host);
 
@@ -316,7 +317,7 @@ static int _git_ssh_setup_conn(
 	const char *cmd,
 	git_smart_subtransport_stream **stream)
 {
-	char *host, *port=NULL, *user=NULL, *pass=NULL;
+	char *host=NULL, *port=NULL, *user=NULL, *pass=NULL;
 	const char *default_port="22";
 	ssh_stream *s;
 	LIBSSH2_SESSION* session=NULL;
diff --git a/tests-clar/clone/nonetwork.c b/tests-clar/clone/nonetwork.c
index 9eb4bf9..a286e2a 100644
--- a/tests-clar/clone/nonetwork.c
+++ b/tests-clar/clone/nonetwork.c
@@ -56,13 +56,11 @@ void test_clone_nonetwork__bad_urls(void)
 	cl_assert(!git_path_exists("./foo"));
 
 	cl_git_fail(git_clone(&g_repo, "git://example.com:asdf", "./foo", &g_options));
-	cl_assert(!git_path_exists("./foo"));
-	cl_git_fail(git_clone(&g_repo, "git://example.com:asdf/foo", "./foo", &g_options));
-	cl_assert(!git_path_exists("./foo"));
-	cl_git_fail(git_clone(&g_repo, "https://example.com:asdf", "./foo", &g_options));
-	cl_assert(!git_path_exists("./foo"));
 	cl_git_fail(git_clone(&g_repo, "https://example.com:asdf/foo", "./foo", &g_options));
-	cl_assert(!git_path_exists("./foo"));
+	cl_git_fail(git_clone(&g_repo, "git://github.com/git://github.com/foo/bar.git.git",
+				"./foo", &g_options));
+	cl_git_fail(git_clone(&g_repo, "arrbee:my/bad:password@github.com:1111/strange:words.git",
+				"./foo", &g_options));
 }
 
 void test_clone_nonetwork__do_not_clean_existing_directory(void)
diff --git a/tests-clar/network/urlparse.c b/tests-clar/network/urlparse.c
index 274d7e9..15e841b 100644
--- a/tests-clar/network/urlparse.c
+++ b/tests-clar/network/urlparse.c
@@ -31,6 +31,13 @@ void test_network_urlparse__trivial(void)
 	cl_assert_equal_p(pass, NULL);
 }
 
+void test_network_urlparse__bad_url(void)
+{
+	cl_git_fail_with(gitno_extract_url_parts(&host, &port, &user, &pass,
+				"github.com/git://github.com/foo/bar.git.git", "443"),
+			GIT_EINVALIDSPEC);
+}
+
 void test_network_urlparse__user(void)
 {
 	cl_git_pass(gitno_extract_url_parts(&host, &port, &user, &pass,