Skip to content

Commit 730220d

Browse files
trastgitster
authored andcommitted
Do not unquote + into ' ' in URLs
Since 9d2e942 (decode file:// and ssh:// URLs, 2010-05-23) the URL logic unquotes escaped URLs. For the %2B type of escape, this is conformant with RFC 2396. However, it also unquotes + into a space character, which is only appropriate for the query strings in HTTP. This notably broke fetching from the gtk+ repository. We cannot just remove the corresponding code since the same url_decode_internal() is also used by the HTTP backend to decode query parameters. Introduce a new argument that controls whether the + decoding happens, and use it only in the (client-side) url_decode(). Reported-by: Jasper St. Pierre <[email protected]> Signed-off-by: Thomas Rast <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 64fdc08 commit 730220d

File tree

2 files changed

+14
-7
lines changed

2 files changed

+14
-7
lines changed

t/t5601-clone.sh

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,14 @@ test_expect_success 'clone respects global branch.autosetuprebase' '
178178

179179
test_expect_success 'respect url-encoding of file://' '
180180
git init x+y &&
181-
test_must_fail git clone "file://$PWD/x+y" xy-url &&
182-
git clone "file://$PWD/x%2By" xy-url
181+
git clone "file://$PWD/x+y" xy-url-1 &&
182+
git clone "file://$PWD/x%2By" xy-url-2
183+
'
184+
185+
test_expect_success 'do not query-string-decode + in URLs' '
186+
rm -rf x+y &&
187+
git init "x y" &&
188+
test_must_fail git clone "file://$PWD/x+y" xy-no-plus
183189
'
184190

185191
test_expect_success 'do not respect url-encoding of non-url path' '

url.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ static int url_decode_char(const char *q)
6767
return val;
6868
}
6969

70-
static char *url_decode_internal(const char **query, const char *stop_at, struct strbuf *out)
70+
static char *url_decode_internal(const char **query, const char *stop_at,
71+
struct strbuf *out, int decode_plus)
7172
{
7273
const char *q = *query;
7374

@@ -90,7 +91,7 @@ static char *url_decode_internal(const char **query, const char *stop_at, struct
9091
}
9192
}
9293

93-
if (c == '+')
94+
if (decode_plus && c == '+')
9495
strbuf_addch(out, ' ');
9596
else
9697
strbuf_addch(out, c);
@@ -110,17 +111,17 @@ char *url_decode(const char *url)
110111
strbuf_add(&out, url, colon - url);
111112
url = colon;
112113
}
113-
return url_decode_internal(&url, NULL, &out);
114+
return url_decode_internal(&url, NULL, &out, 0);
114115
}
115116

116117
char *url_decode_parameter_name(const char **query)
117118
{
118119
struct strbuf out = STRBUF_INIT;
119-
return url_decode_internal(query, "&=", &out);
120+
return url_decode_internal(query, "&=", &out, 1);
120121
}
121122

122123
char *url_decode_parameter_value(const char **query)
123124
{
124125
struct strbuf out = STRBUF_INIT;
125-
return url_decode_internal(query, "&", &out);
126+
return url_decode_internal(query, "&", &out, 1);
126127
}

0 commit comments

Comments
 (0)