summaryrefslogtreecommitdiff
path: root/src/netops.c
diff options
context:
space:
mode:
authorBen Straub <bs@github.com>2013-11-04 12:04:17 -0800
committerBen Straub <bs@github.com>2013-11-04 12:04:17 -0800
commit16bffd1c26d8d22a61b5d99fd4063c2f71751317 (patch)
treeda28c57a3d7bc54817a8331b6165c1bde759f930 /src/netops.c
parentc227c173b84c8107a8933aeed947f16d82224377 (diff)
downloadlibgit2-16bffd1c26d8d22a61b5d99fd4063c2f71751317.tar.gz
Unescape url-encoded usernames and passwords
Diffstat (limited to 'src/netops.c')
-rw-r--r--src/netops.c28
1 files changed, 26 insertions, 2 deletions
diff --git a/src/netops.c b/src/netops.c
index 9653344fe..72172f39b 100644
--- a/src/netops.c
+++ b/src/netops.c
@@ -658,6 +658,29 @@ void gitno_connection_data_free_ptrs(gitno_connection_data *d)
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(
char **host,
char **port,
@@ -699,13 +722,14 @@ int gitno_extract_url_parts(
if (u.field_data[UF_USERINFO].len) {
const char *colon = strchr(_userinfo, ':');
if (colon && (colon - _userinfo) < u.field_data[UF_USERINFO].len) {
- *username = git__substrdup(_userinfo, colon - _userinfo);
- *password = git__substrdup(colon+1, u.field_data[UF_USERINFO].len - (colon+1-_userinfo));
+ *username = unescape(git__substrdup(_userinfo, colon - _userinfo));
+ *password = unescape(git__substrdup(colon+1, u.field_data[UF_USERINFO].len - (colon+1-_userinfo)));
GITERR_CHECK_ALLOC(*password);
} else {
*username = git__substrdup(_userinfo, u.field_data[UF_USERINFO].len);
}
GITERR_CHECK_ALLOC(*username);
+
}
return 0;