url.c: "<scheme>://" part at the beginning should not be URL decoded
When using the protocol git+ssh:// for example we do not want to decode the '+' as a space. The url decoding must take place only for the server name and parameters. This fixes a regression introduced in 9d2e942. Initial-fix-by: Pascal Obry <pascal.obry@gmail.com> Acked-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Junio C Hamano committed
Jun 23, 2010 at 10:27 UTC
ce83eda15554ffd859ecc9f4c427303d460dab60
1 file changed
+18
-10
url.c
+18
-10
@@ -67,12 +67,10 @@ static int url_decode_char(const char *q)
67
return val;
68
}
69
70
-static char *url_decode_internal(const char **query, const char *stop_at)
70
+static char *url_decode_internal(const char **query, const char *stop_at, struct strbuf *out)
71
{
72
const char *q = *query;
73
- struct strbuf out;
73
75
- strbuf_init(&out, 16);
74
do {
75
unsigned char c = *q;
76
@@ -86,33 +84,43 @@ static char *url_decode_internal(const char **query, const char *stop_at)
84
if (c == '%') {
85
int val = url_decode_char(q + 1);
86
if (0 <= val) {
89
- strbuf_addch(&out, val);
87
+ strbuf_addch(out, val);
88
q += 3;
89
continue;
90
}
91
}
92
93
if (c == '+')
96
- strbuf_addch(&out, ' ');
94
+ strbuf_addch(out, ' ');
95
else
98
- strbuf_addch(&out, c);
96
+ strbuf_addch(out, c);
97
q++;
98
} while (1);
99
*query = q;
102
- return strbuf_detach(&out, NULL);
100
+ return strbuf_detach(out, NULL);
101
}
102
103
char *url_decode(const char *url)
104
{
107
- return url_decode_internal(&url, NULL);
105
+ struct strbuf out = STRBUF_INIT;
106
+ const char *slash = strchr(url, '/');
107
+
108
+ /* Skip protocol part if present */
109
+ if (slash && url < slash) {
110
+ strbuf_add(&out, url, slash - url);
111
+ url = slash;
112
+ }
113
+ return url_decode_internal(&url, NULL, &out);
114
}
115
116
char *url_decode_parameter_name(const char **query)
117
{
112
- return url_decode_internal(query, "&=");
118
+ struct strbuf out = STRBUF_INIT;
119
+ return url_decode_internal(query, "&=", &out);
120
}
121
122
char *url_decode_parameter_value(const char **query)
123
{
117
- return url_decode_internal(query, "&");
124
+ struct strbuf out = STRBUF_INIT;
125
+ return url_decode_internal(query, "&", &out);
126
}