diff options
author | Edward Thomson <ethomson@edwardthomson.com> | 2022-06-17 13:47:39 -0400 |
---|---|---|
committer | Edward Thomson <ethomson@edwardthomson.com> | 2022-06-17 13:49:34 -0400 |
commit | 1ee9b1fb2d5bb60b1f02d3767282afa2b8c8c016 (patch) | |
tree | 8103a3945b473ffb2d8eccc38aa694c36e85a9db | |
parent | 373a3c9ab17ce9e7b9eb1cdc61390b78a61215e6 (diff) | |
download | libgit2-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.c | 13 | ||||
-rw-r--r-- | tests/util/url/parse.c | 5 |
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")); |