diff --git a/src/protocol/http/http.c b/src/protocol/http/http.c index 9f42b21a..7461c736 100644 --- a/src/protocol/http/http.c +++ b/src/protocol/http/http.c @@ -350,10 +350,22 @@ add_url_to_http_string(struct string *header, struct uri *uri, uri_component_T c * before. We should probably encode all URLs as early as * possible, and possibly decode them back in protocol * backends. --pasky */ - char *string = get_uri_string(uri, components); - char *data = string; + struct string encoded; + char *string; + char *data; - if (!string) return; + if (!init_string(&encoded)) { + return; + } + string = get_uri_string(uri, components); + + if (!string) { + done_string(&encoded); + return; + } + encode_uri_string_percent(&encoded, string, -1); + mem_free(string); + data = encoded.source; while (*data) { int len = strcspn(data, " \t\r\n\\"); @@ -369,8 +381,7 @@ add_url_to_http_string(struct string *header, struct uri *uri, uri_component_T c data += len; } - - mem_free(string); + done_string(&encoded); } /* Parse from @end - 1 to @start and set *@value to integer found. diff --git a/src/protocol/uri.c b/src/protocol/uri.c index 90d9df14..1e9c08c6 100644 --- a/src/protocol/uri.c +++ b/src/protocol/uri.c @@ -1422,6 +1422,29 @@ encode_uri_string(struct string *string, const char *name, int namelen, } } +void +encode_uri_string_percent(struct string *string, const char *name, int namelen) +{ + char n[4]; + const char *end; + + n[0] = '%'; + n[3] = '\0'; + + if (namelen < 0) namelen = strlen(name); + + for (end = name + namelen; name < end; name++) { + if (safe_char(*name) || (*name == '/') || (*name == '%')) { + add_char_to_string(string, *name); + } else { + /* Hex it. */ + n[1] = Hx((((int) *name) & 0xF0) >> 4); + n[2] = Hx(((int) *name) & 0xF); + add_bytes_to_string(string, n, sizeof(n) - 1); + } + } +} + void encode_win32_uri_string(struct string *string, char *name, int namelen) { diff --git a/src/protocol/uri.h b/src/protocol/uri.h index 837cd697..0337ae50 100644 --- a/src/protocol/uri.h +++ b/src/protocol/uri.h @@ -321,6 +321,8 @@ int get_uri_port(const struct uri *uri); void encode_uri_string(struct string *string, const char *name, int namelen, int convert_slashes); +void encode_uri_string_percent(struct string *string, const char *name, int namelen); + /* special version for Windows directory listing */ void encode_win32_uri_string(struct string *string, char *name, int namelen);