Skip to content

Commit da05cac

Browse files
committed
Merge branch 'js/partial-urlmatch-2.17'
Recent updates broke parsing of "credential.<url>.<key>" where <url> is not a full URL (e.g. [credential "https://"] helper = ...) stopped working, which has been corrected. * js/partial-urlmatch-2.17: credential: handle `credential.<partial-URL>.<key>` again credential: optionally allow partial URLs in credential_from_url_gently() credential: fix grammar
2 parents 1d7e9c4 + 9a121b0 commit da05cac

File tree

2 files changed

+84
-6
lines changed

2 files changed

+84
-6
lines changed

credential.c

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ int credential_match(const struct credential *want,
3737
#undef CHECK
3838
}
3939

40+
41+
static int credential_from_potentially_partial_url(struct credential *c,
42+
const char *url);
43+
4044
static int credential_config_callback(const char *var, const char *value,
4145
void *data)
4246
{
@@ -377,8 +381,31 @@ static int check_url_component(const char *url, int quiet,
377381
return -1;
378382
}
379383

380-
int credential_from_url_gently(struct credential *c, const char *url,
381-
int quiet)
384+
/*
385+
* Potentially-partial URLs can, but do not have to, contain
386+
*
387+
* - a protocol (or scheme) of the form "<protocol>://"
388+
*
389+
* - a host name (the part after the protocol and before the first slash after
390+
* that, if any)
391+
*
392+
* - a user name and potentially a password (as "<user>[:<password>]@" part of
393+
* the host name)
394+
*
395+
* - a path (the part after the host name, if any, starting with the slash)
396+
*
397+
* Missing parts will be left unset in `struct credential`. Thus, `https://`
398+
* will have only the `protocol` set, `example.com` only the host name, and
399+
* `/git` only the path.
400+
*
401+
* Note that an empty host name in an otherwise fully-qualified URL (e.g.
402+
* `cert:///path/to/cert.pem`) will be treated as unset if we expect the URL to
403+
* be potentially partial, and only then (otherwise, the empty string is used).
404+
*
405+
* The credential_from_url() function does not allow partial URLs.
406+
*/
407+
static int credential_from_url_1(struct credential *c, const char *url,
408+
int allow_partial_url, int quiet)
382409
{
383410
const char *at, *colon, *cp, *slash, *host, *proto_end;
384411

@@ -391,12 +418,12 @@ int credential_from_url_gently(struct credential *c, const char *url,
391418
* (3) proto://<user>:<pass>@<host>/...
392419
*/
393420
proto_end = strstr(url, "://");
394-
if (!proto_end || proto_end == url) {
421+
if (!allow_partial_url && (!proto_end || proto_end == url)) {
395422
if (!quiet)
396423
warning(_("url has no scheme: %s"), url);
397424
return -1;
398425
}
399-
cp = proto_end + 3;
426+
cp = proto_end ? proto_end + 3 : url;
400427
at = strchr(cp, '@');
401428
colon = strchr(cp, ':');
402429

@@ -427,8 +454,10 @@ int credential_from_url_gently(struct credential *c, const char *url,
427454
host = at + 1;
428455
}
429456

430-
c->protocol = xmemdupz(url, proto_end - url);
431-
c->host = url_decode_mem(host, slash - host);
457+
if (proto_end && proto_end - url > 0)
458+
c->protocol = xmemdupz(url, proto_end - url);
459+
if (!allow_partial_url || slash - host > 0)
460+
c->host = url_decode_mem(host, slash - host);
432461
/* Trim leading and trailing slashes from path */
433462
while (*slash == '/')
434463
slash++;
@@ -450,6 +479,17 @@ int credential_from_url_gently(struct credential *c, const char *url,
450479
return 0;
451480
}
452481

482+
static int credential_from_potentially_partial_url(struct credential *c,
483+
const char *url)
484+
{
485+
return credential_from_url_1(c, url, 1, 0);
486+
}
487+
488+
int credential_from_url_gently(struct credential *c, const char *url, int quiet)
489+
{
490+
return credential_from_url_1(c, url, 0, quiet);
491+
}
492+
453493
void credential_from_url(struct credential *c, const char *url)
454494
{
455495
if (credential_from_url_gently(c, url, 0) < 0)

t/t0300-credentials.sh

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,4 +654,42 @@ test_expect_success 'url parser not confused by encoded markers' '
654654
"example.com#?/" foo.git
655655
'
656656

657+
test_expect_success 'credential config with partial URLs' '
658+
echo "echo password=yep" | write_script git-credential-yep &&
659+
test_write_lines url=https://[email protected]/repo.git >stdin &&
660+
for partial in \
661+
example.com \
662+
663+
https:// \
664+
https://example.com \
665+
https://example.com/ \
666+
667+
https://[email protected]/ \
668+
https://example.com/repo.git \
669+
https://[email protected]/repo.git \
670+
/repo.git
671+
do
672+
git -c credential.$partial.helper=yep \
673+
credential fill <stdin >stdout &&
674+
grep yep stdout ||
675+
return 1
676+
done &&
677+
678+
for partial in \
679+
dont.use.this \
680+
http:// \
681+
/repo
682+
do
683+
git -c credential.$partial.helper=yep \
684+
credential fill <stdin >stdout &&
685+
! grep yep stdout ||
686+
return 1
687+
done &&
688+
689+
git -c credential.$partial.helper=yep \
690+
-c credential.with%0anewline.username=uh-oh \
691+
credential fill <stdin >stdout 2>stderr &&
692+
test_i18ngrep "skipping credential lookup for key" stderr
693+
'
694+
657695
test_done

0 commit comments

Comments
 (0)