summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2022-06-17 13:47:39 -0400
committerEdward Thomson <ethomson@edwardthomson.com>2022-06-17 13:49:34 -0400
commit1ee9b1fb2d5bb60b1f02d3767282afa2b8c8c016 (patch)
tree8103a3945b473ffb2d8eccc38aa694c36e85a9db
parent373a3c9ab17ce9e7b9eb1cdc61390b78a61215e6 (diff)
downloadlibgit2-1ee9b1fb2d5bb60b1f02d3767282afa2b8c8c016.tar.gz
url: only allow @s in usernames for ssh urls
Enforce the RFC for other protocols; Google's questionable choices about malformed SSH protocols shouldn't impact our ability to properly parse HTTPS.
-rw-r--r--src/util/net.c13
-rw-r--r--tests/util/url/parse.c5
2 files changed, 15 insertions, 3 deletions
diff --git a/src/util/net.c b/src/util/net.c
index 9eddca916..43c7dc952 100644
--- a/src/util/net.c
+++ b/src/util/net.c
@@ -104,7 +104,8 @@ static int url_parse_authority(
const char **password_start, size_t *password_len,
const char **host_start, size_t *host_len,
const char **port_start, size_t *port_len,
- const char *authority_start, size_t len)
+ const char *authority_start, size_t len,
+ const char *scheme_start, size_t scheme_len)
{
const char *c, *hostport_end, *host_end = NULL,
*userpass_end, *user_end = NULL;
@@ -194,6 +195,10 @@ static int url_parse_authority(
return url_invalid("malformed hostname");
case USERPASS:
+ if (*c == '@' &&
+ strncasecmp(scheme_start, "ssh", scheme_len))
+ return url_invalid("malformed hostname");
+
if (*c == ':') {
*password_start = c + 1;
*password_len = userpass_end - *password_start;
@@ -307,7 +312,8 @@ int git_net_url_parse(git_net_url *url, const char *given)
&password_start,&password_len,
&host_start, &host_len,
&port_start, &port_len,
- authority_start, (c - authority_start))) < 0)
+ authority_start, (c - authority_start),
+ scheme_start, scheme_len)) < 0)
goto done;
/* fall through */
@@ -365,7 +371,8 @@ int git_net_url_parse(git_net_url *url, const char *given)
&password_start,&password_len,
&host_start, &host_len,
&port_start, &port_len,
- authority_start, (c - authority_start))) < 0)
+ authority_start, (c - authority_start),
+ scheme_start, scheme_len)) < 0)
goto done;
break;
case PATH_START:
diff --git a/tests/util/url/parse.c b/tests/util/url/parse.c
index 29b76c63b..631d9b456 100644
--- a/tests/util/url/parse.c
+++ b/tests/util/url/parse.c
@@ -749,6 +749,11 @@ void test_url_parse__empty_path_with_empty_authority(void)
cl_assert_equal_i(git_net_url_is_default_port(&conndata), 1);
}
+void test_url_parse__http_follows_the_rfc(void)
+{
+ cl_git_fail(git_net_url_parse(&conndata, "https://my.email.address@gmail.com@source.developers.google.com:4433/p/my-project/r/my-repository"));
+}
+
void test_url_parse__ssh_from_terrible_google_rfc_violating_products(void)
{
cl_git_pass(git_net_url_parse(&conndata, "ssh://my.email.address@gmail.com@source.developers.google.com:2022/p/my-project/r/my-repository"));