summaryrefslogtreecommitdiff
path: root/credential.c
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2020-04-14 21:43:04 (GMT)
committerJunio C Hamano <gitster@pobox.com>2020-04-15 17:31:03 (GMT)
commit4c5971e18a181c68aec03262fb467cb5d21a5b0d (patch)
treeb7873c08d07c94ddafbaeaf300ea17e2d7b5828e /credential.c
parentde49261b050d9cd8ec73842356077bc5b606640f (diff)
downloadgit-4c5971e18a181c68aec03262fb467cb5d21a5b0d.zip
git-4c5971e18a181c68aec03262fb467cb5d21a5b0d.tar.gz
git-4c5971e18a181c68aec03262fb467cb5d21a5b0d.tar.bz2
credential: treat "?" and "#" in URLs as end of host
It's unusual to see: https://example.com?query-parameters without an intervening slash, like: https://example.com/some-path?query-parameters or even: https://example.com/?query-parameters but it is a valid end to the hostname (actually "authority component") according to RFC 3986. Likewise for "#". And curl will parse the URL according to the standard, meaning it will contact example.com, but our credential code would ask about a bogus hostname with a "?" in it. Let's make sure we follow the standard, and more importantly ask about the same hosts that curl will be talking to. It would be nice if we could just ask curl to parse the URL for us. But it didn't grow a URL-parsing API until 7.62, so we'd be stuck with fallback code either way. Plus we'd need this code in the main Git binary, where we've tried to avoid having a link dependency on libcurl. But let's at least fix our parser. Moving to curl's parser would prevent other potential discrepancies, but this gives us immediate relief for the known problem, and would help our fallback code if we eventually use curl. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'credential.c')
-rw-r--r--credential.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/credential.c b/credential.c
index 21b3ba1..8aa9777 100644
--- a/credential.c
+++ b/credential.c
@@ -388,7 +388,14 @@ int credential_from_url_gently(struct credential *c, const char *url,
cp = proto_end + 3;
at = strchr(cp, '@');
colon = strchr(cp, ':');
- slash = strchrnul(cp, '/');
+
+ /*
+ * A query or fragment marker before the slash ends the host portion.
+ * We'll just continue to call this "slash" for simplicity. Notably our
+ * "trim leading slashes" part won't skip over this part of the path,
+ * but that's what we'd want.
+ */
+ slash = cp + strcspn(cp, "/?#");
if (!at || slash <= at) {
/* Case (1) */