99 lines
3.4 KiB
Diff
99 lines
3.4 KiB
Diff
From c903985bf7e772e2d08275c1a95c8a55ab011577 Mon Sep 17 00:00:00 2001
|
|
From: Johannes Schindelin <johannes.schindelin@gmx.de>
|
|
Date: Thu, 7 Nov 2024 08:57:52 +0100
|
|
Subject: [PATCH 1/2] credential_format(): also encode <host>[:<port>]
|
|
|
|
An upcoming change wants to sanitize the credential password prompt
|
|
where a URL is displayed that may potentially come from a `.gitmodules`
|
|
file. To this end, the `credential_format()` function is employed.
|
|
|
|
To sanitize the host name (and optional port) part of the URL, we need a
|
|
new mode of the `strbuf_add_percentencode()` function because the
|
|
current mode is both too strict and too lenient: too strict because it
|
|
encodes `:`, `[` and `]` (which should be left unencoded in
|
|
`<host>:<port>` and in IPv6 addresses), and too lenient because it does
|
|
not encode invalid host name characters `/`, `_` and `~`.
|
|
|
|
So let's introduce and use a new mode specifically to encode the host
|
|
name and optional port part of a URI, leaving alpha-numerical
|
|
characters, periods, colons and brackets alone and encoding all others.
|
|
|
|
This only leads to a change of behavior for URLs that contain invalid
|
|
host names.
|
|
|
|
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
|
|
---
|
|
credential.c | 3 ++-
|
|
strbuf.c | 4 +++-
|
|
strbuf.h | 1 +
|
|
t/t0300-credentials.sh | 13 +++++++++++++
|
|
4 files changed, 19 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/credential.c b/credential.c
|
|
index f32011343f..572f1785da 100644
|
|
--- a/credential.c
|
|
+++ b/credential.c
|
|
@@ -164,7 +164,8 @@ static void credential_format(struct credential *c, struct strbuf *out)
|
|
strbuf_addch(out, '@');
|
|
}
|
|
if (c->host)
|
|
- strbuf_addstr(out, c->host);
|
|
+ strbuf_add_percentencode(out, c->host,
|
|
+ STRBUF_ENCODE_HOST_AND_PORT);
|
|
if (c->path) {
|
|
strbuf_addch(out, '/');
|
|
strbuf_add_percentencode(out, c->path, 0);
|
|
diff --git a/strbuf.c b/strbuf.c
|
|
index c383f41a3c..756b96c561 100644
|
|
--- a/strbuf.c
|
|
+++ b/strbuf.c
|
|
@@ -492,7 +492,9 @@ void strbuf_add_percentencode(struct strbuf *dst, const char *src, int flags)
|
|
unsigned char ch = src[i];
|
|
if (ch <= 0x1F || ch >= 0x7F ||
|
|
(ch == '/' && (flags & STRBUF_ENCODE_SLASH)) ||
|
|
- strchr(URL_UNSAFE_CHARS, ch))
|
|
+ ((flags & STRBUF_ENCODE_HOST_AND_PORT) ?
|
|
+ !isalnum(ch) && !strchr("-.:[]", ch) :
|
|
+ !!strchr(URL_UNSAFE_CHARS, ch)))
|
|
strbuf_addf(dst, "%%%02X", (unsigned char)ch);
|
|
else
|
|
strbuf_addch(dst, ch);
|
|
diff --git a/strbuf.h b/strbuf.h
|
|
index f6dbb9681e..f9f8bb0381 100644
|
|
--- a/strbuf.h
|
|
+++ b/strbuf.h
|
|
@@ -380,6 +380,7 @@ size_t strbuf_expand_dict_cb(struct strbuf *sb,
|
|
void strbuf_addbuf_percentquote(struct strbuf *dst, const struct strbuf *src);
|
|
|
|
#define STRBUF_ENCODE_SLASH 1
|
|
+#define STRBUF_ENCODE_HOST_AND_PORT 2
|
|
|
|
/**
|
|
* Append the contents of a string to a strbuf, percent-encoding any characters
|
|
diff --git a/t/t0300-credentials.sh b/t/t0300-credentials.sh
|
|
index c66d91e82d..cb91be1427 100755
|
|
--- a/t/t0300-credentials.sh
|
|
+++ b/t/t0300-credentials.sh
|
|
@@ -514,6 +514,19 @@ test_expect_success 'match percent-encoded values in username' '
|
|
EOF
|
|
'
|
|
|
|
+test_expect_success 'match percent-encoded values in hostname' '
|
|
+ test_config "credential.https://a%20b%20c/.helper" "$HELPER" &&
|
|
+ check fill <<-\EOF
|
|
+ url=https://a b c/
|
|
+ --
|
|
+ protocol=https
|
|
+ host=a b c
|
|
+ username=foo
|
|
+ password=bar
|
|
+ --
|
|
+ EOF
|
|
+'
|
|
+
|
|
test_expect_success 'fetch with multiple path components' '
|
|
test_unconfig credential.helper &&
|
|
test_config credential.https://example.com/foo/repo.git.helper "verbatim foo bar" &&
|
|
--
|
|
2.47.1
|