|
2 | 2 | * This code is licensed under MIT license (see LICENSE for details) */ |
3 | 3 |
|
4 | 4 | #include "url.h" |
| 5 | +#include "utils/ascii.h" |
5 | 6 |
|
6 | | -#include <ctype.h> |
7 | 7 | #include <stdbool.h> |
8 | 8 | #include <stddef.h> |
9 | 9 | #include <stdint.h> |
@@ -102,33 +102,39 @@ escape(char *buf, size_t buf_size, const char *str, const size_t len, |
102 | 102 | return cap - buf_size; |
103 | 103 | } |
104 | 104 |
|
105 | | -static size_t escape_host( |
| 105 | +#define S_UNRESERVED "-_.~" |
| 106 | +#define S_SUB_DELIMS "!$&'()*+,;=" |
| 107 | +#define S_PCHAR S_UNRESERVED S_SUB_DELIMS ":@" |
| 108 | + |
| 109 | +static size_t escape_hostport( |
106 | 110 | char *buf, const size_t buf_size, const char *host, const size_t len) |
107 | 111 | { |
108 | 112 | /* RFC 1738, RFC 2732 */ |
109 | 113 | return escape( |
110 | | - buf, buf_size, host, len, "-_.~!$&'()*+,;=:[]<>\"", false); |
| 114 | + buf, buf_size, host, len, S_UNRESERVED S_SUB_DELIMS ":[]", |
| 115 | + false); |
111 | 116 | } |
112 | 117 |
|
113 | 118 | static size_t escape_userinfo( |
114 | 119 | char *buf, const size_t buf_size, const char *userinfo, |
115 | 120 | const size_t len) |
116 | 121 | { |
117 | | - return escape(buf, buf_size, userinfo, len, "-_.~$&+,;=", false); |
| 122 | + return escape( |
| 123 | + buf, buf_size, userinfo, len, S_UNRESERVED S_SUB_DELIMS ":", |
| 124 | + false); |
118 | 125 | } |
119 | 126 |
|
120 | 127 | static size_t escape_query( |
121 | 128 | char *buf, const size_t buf_size, const char *query, const size_t len) |
122 | 129 | { |
123 | | - return escape(buf, buf_size, query, len, "-_.~", true); |
| 130 | + return escape(buf, buf_size, query, len, S_PCHAR "/?", true); |
124 | 131 | } |
125 | 132 |
|
126 | 133 | static size_t escape_fragment( |
127 | 134 | char *buf, const size_t buf_size, const char *fragment, |
128 | 135 | const size_t len) |
129 | 136 | { |
130 | | - return escape( |
131 | | - buf, buf_size, fragment, len, "-_.~$&+,/:;=?@!()*", false); |
| 137 | + return escape(buf, buf_size, fragment, len, S_PCHAR "/?", false); |
132 | 138 | } |
133 | 139 |
|
134 | 140 | size_t |
@@ -208,7 +214,7 @@ size_t url_build(char *buf, size_t buf_size, const struct url *url) |
208 | 214 | APPEND(url->userinfo); |
209 | 215 | APPENDCH('@'); |
210 | 216 | } |
211 | | - APPENDN(escape_host( |
| 217 | + APPENDN(escape_hostport( |
212 | 218 | buf, buf_size, url->host, strlen(url->host))); |
213 | 219 | } |
214 | 220 | if (url->path != NULL) { |
@@ -274,14 +280,6 @@ static bool unescape(char *str, const bool space) |
274 | 280 | return true; |
275 | 281 | } |
276 | 282 |
|
277 | | -static inline char *strlower(char *restrict s) |
278 | | -{ |
279 | | - for (unsigned char *p = (unsigned char *)s; *p != '\0'; ++p) { |
280 | | - *p = tolower(*p); |
281 | | - } |
282 | | - return s; |
283 | | -} |
284 | | - |
285 | 283 | bool url_parse(char *raw, struct url *restrict url) |
286 | 284 | { |
287 | 285 | /* safety check */ |
|
0 commit comments