mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-26 03:42:28 +00:00
Unescape url-encoded usernames and passwords
This commit is contained in:
parent
c227c173b8
commit
16bffd1c26
28
src/netops.c
28
src/netops.c
@ -658,6 +658,29 @@ void gitno_connection_data_free_ptrs(gitno_connection_data *d)
|
|||||||
git__free(d->pass); d->pass = NULL;
|
git__free(d->pass); d->pass = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char unescape_hex(char *x)
|
||||||
|
{
|
||||||
|
char digit;
|
||||||
|
digit = ((x[0] >= 'A') ? ((x[0] & 0xdf) - 'A')+10 : (x[0] - '0'));
|
||||||
|
digit *= 16;
|
||||||
|
digit += ((x[1] >= 'A') ? ((x[1] & 0xdf) - 'A')+10 : (x[1] - '0'));
|
||||||
|
return digit;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char* unescape(char *str)
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
|
||||||
|
for (x=y=0; str[x]; ++x, ++y) {
|
||||||
|
if ((str[x] = str[y]) == '%') {
|
||||||
|
str[x] = unescape_hex(str+y+1);
|
||||||
|
y += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
str[x] = '\0';
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
int gitno_extract_url_parts(
|
int gitno_extract_url_parts(
|
||||||
char **host,
|
char **host,
|
||||||
char **port,
|
char **port,
|
||||||
@ -699,13 +722,14 @@ int gitno_extract_url_parts(
|
|||||||
if (u.field_data[UF_USERINFO].len) {
|
if (u.field_data[UF_USERINFO].len) {
|
||||||
const char *colon = strchr(_userinfo, ':');
|
const char *colon = strchr(_userinfo, ':');
|
||||||
if (colon && (colon - _userinfo) < u.field_data[UF_USERINFO].len) {
|
if (colon && (colon - _userinfo) < u.field_data[UF_USERINFO].len) {
|
||||||
*username = git__substrdup(_userinfo, colon - _userinfo);
|
*username = unescape(git__substrdup(_userinfo, colon - _userinfo));
|
||||||
*password = git__substrdup(colon+1, u.field_data[UF_USERINFO].len - (colon+1-_userinfo));
|
*password = unescape(git__substrdup(colon+1, u.field_data[UF_USERINFO].len - (colon+1-_userinfo)));
|
||||||
GITERR_CHECK_ALLOC(*password);
|
GITERR_CHECK_ALLOC(*password);
|
||||||
} else {
|
} else {
|
||||||
*username = git__substrdup(_userinfo, u.field_data[UF_USERINFO].len);
|
*username = git__substrdup(_userinfo, u.field_data[UF_USERINFO].len);
|
||||||
}
|
}
|
||||||
GITERR_CHECK_ALLOC(*username);
|
GITERR_CHECK_ALLOC(*username);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -33,7 +33,7 @@ void test_network_urlparse__trivial(void)
|
|||||||
cl_assert_equal_p(pass, NULL);
|
cl_assert_equal_p(pass, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_network_urlparse__weird_url(void)
|
void test_network_urlparse__encoded_password(void)
|
||||||
{
|
{
|
||||||
cl_git_pass(gitno_extract_url_parts(&host, &port, &path, &user, &pass,
|
cl_git_pass(gitno_extract_url_parts(&host, &port, &path, &user, &pass,
|
||||||
"https://user:pass%2fis%40bad@hostname.com:1234/", "1"));
|
"https://user:pass%2fis%40bad@hostname.com:1234/", "1"));
|
||||||
@ -41,7 +41,7 @@ void test_network_urlparse__weird_url(void)
|
|||||||
cl_assert_equal_s(port, "1234");
|
cl_assert_equal_s(port, "1234");
|
||||||
cl_assert_equal_s(path, "/");
|
cl_assert_equal_s(path, "/");
|
||||||
cl_assert_equal_s(user, "user");
|
cl_assert_equal_s(user, "user");
|
||||||
cl_assert_equal_s(pass, "pass%2fis%40bad");
|
cl_assert_equal_s(pass, "pass/is@bad");
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_network_urlparse__user(void)
|
void test_network_urlparse__user(void)
|
||||||
@ -127,6 +127,18 @@ void test_network_urlparse__connection_data_ssl(void)
|
|||||||
cl_assert_equal_i(conndata.use_ssl, true);
|
cl_assert_equal_i(conndata.use_ssl, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_network_urlparse__encoded_username_password(void)
|
||||||
|
{
|
||||||
|
cl_git_pass(gitno_connection_data_from_url(&conndata,
|
||||||
|
"https://user%2fname:pass%40word@example.com/foo/bar/baz", "bar/baz"));
|
||||||
|
cl_assert_equal_s(conndata.host, "example.com");
|
||||||
|
cl_assert_equal_s(conndata.port, "443");
|
||||||
|
cl_assert_equal_s(conndata.path, "/foo/");
|
||||||
|
cl_assert_equal_s(conndata.user, "user/name");
|
||||||
|
cl_assert_equal_s(conndata.pass, "pass@word");
|
||||||
|
cl_assert_equal_i(conndata.use_ssl, true);
|
||||||
|
}
|
||||||
|
|
||||||
void test_network_urlparse__connection_data_cross_host_redirect(void)
|
void test_network_urlparse__connection_data_cross_host_redirect(void)
|
||||||
{
|
{
|
||||||
conndata.host = git__strdup("bar.com");
|
conndata.host = git__strdup("bar.com");
|
||||||
|
Loading…
Reference in New Issue
Block a user