Skip to content

Commit c903985

Browse files
committed
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>
1 parent 83b08eb commit c903985

File tree

4 files changed

+19
-2
lines changed

4 files changed

+19
-2
lines changed

credential.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,8 @@ static void credential_format(struct credential *c, struct strbuf *out)
164164
strbuf_addch(out, '@');
165165
}
166166
if (c->host)
167-
strbuf_addstr(out, c->host);
167+
strbuf_add_percentencode(out, c->host,
168+
STRBUF_ENCODE_HOST_AND_PORT);
168169
if (c->path) {
169170
strbuf_addch(out, '/');
170171
strbuf_add_percentencode(out, c->path, 0);

strbuf.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,9 @@ void strbuf_add_percentencode(struct strbuf *dst, const char *src, int flags)
492492
unsigned char ch = src[i];
493493
if (ch <= 0x1F || ch >= 0x7F ||
494494
(ch == '/' && (flags & STRBUF_ENCODE_SLASH)) ||
495-
strchr(URL_UNSAFE_CHARS, ch))
495+
((flags & STRBUF_ENCODE_HOST_AND_PORT) ?
496+
!isalnum(ch) && !strchr("-.:[]", ch) :
497+
!!strchr(URL_UNSAFE_CHARS, ch)))
496498
strbuf_addf(dst, "%%%02X", (unsigned char)ch);
497499
else
498500
strbuf_addch(dst, ch);

strbuf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,7 @@ size_t strbuf_expand_dict_cb(struct strbuf *sb,
380380
void strbuf_addbuf_percentquote(struct strbuf *dst, const struct strbuf *src);
381381

382382
#define STRBUF_ENCODE_SLASH 1
383+
#define STRBUF_ENCODE_HOST_AND_PORT 2
383384

384385
/**
385386
* Append the contents of a string to a strbuf, percent-encoding any characters

t/t0300-credentials.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,19 @@ test_expect_success 'match percent-encoded values in username' '
514514
EOF
515515
'
516516

517+
test_expect_success 'match percent-encoded values in hostname' '
518+
test_config "credential.https://a%20b%20c/.helper" "$HELPER" &&
519+
check fill <<-\EOF
520+
url=https://a b c/
521+
--
522+
protocol=https
523+
host=a b c
524+
username=foo
525+
password=bar
526+
--
527+
EOF
528+
'
529+
517530
test_expect_success 'fetch with multiple path components' '
518531
test_unconfig credential.helper &&
519532
test_config credential.https://example.com/foo/repo.git.helper "verbatim foo bar" &&

0 commit comments

Comments
 (0)