lib1560.c (70541B)
1 /*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 9 * 10 * This software is licensed as described in the file COPYING, which 11 * you should have received as part of this distribution. The terms 12 * are also available at https://curl.se/docs/copyright.html. 13 * 14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15 * copies of the Software, and permit persons to whom the Software is 16 * furnished to do so, under the terms of the COPYING file. 17 * 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 * KIND, either express or implied. 20 * 21 * SPDX-License-Identifier: curl 22 * 23 ***************************************************************************/ 24 25 /* 26 * Note: 27 * 28 * Since the URL parser by default only accepts schemes that *this instance* 29 * of libcurl supports, make sure that the test1560 file lists all the schemes 30 * that this test will assume to be present! 31 */ 32 33 #include "first.h" 34 #if defined(USE_LIBIDN2) || defined(USE_WIN32_IDN) || defined(USE_APPLE_IDN) 35 #define USE_IDN 36 #endif 37 38 #include "memdebug.h" /* LAST include file */ 39 40 static int checkparts(CURLU *u, const char *in, const char *wanted, 41 unsigned int getflags) 42 { 43 int i; 44 CURLUcode rc; 45 char buf[256]; 46 char *bufp = &buf[0]; 47 size_t len = sizeof(buf); 48 49 struct part { 50 CURLUPart part; 51 const char *name; 52 }; 53 54 struct part parts[] = { 55 {CURLUPART_SCHEME, "scheme"}, 56 {CURLUPART_USER, "user"}, 57 {CURLUPART_PASSWORD, "password"}, 58 {CURLUPART_OPTIONS, "options"}, 59 {CURLUPART_HOST, "host"}, 60 {CURLUPART_PORT, "port"}, 61 {CURLUPART_PATH, "path"}, 62 {CURLUPART_QUERY, "query"}, 63 {CURLUPART_FRAGMENT, "fragment"}, 64 {CURLUPART_URL, NULL} 65 }; 66 memset(buf, 0, sizeof(buf)); 67 68 for(i = 0; parts[i].name; i++) { 69 char *p = NULL; 70 size_t n; 71 rc = curl_url_get(u, parts[i].part, &p, getflags); 72 if(!rc && p) { 73 curl_msnprintf(bufp, len, "%s%s", buf[0]?" | ":"", p); 74 } 75 else 76 curl_msnprintf(bufp, len, "%s[%d]", buf[0]?" | ":"", (int)rc); 77 78 n = strlen(bufp); 79 bufp += n; 80 len -= n; 81 curl_free(p); 82 } 83 if(strcmp(buf, wanted)) { 84 curl_mfprintf(stderr, "in: %s\nwanted: %s\ngot: %s\n", in, wanted, buf); 85 return 1; 86 } 87 return 0; 88 } 89 90 struct redircase { 91 const char *in; 92 const char *set; 93 const char *out; 94 unsigned int urlflags; 95 unsigned int setflags; 96 CURLUcode ucode; 97 }; 98 99 struct setcase { 100 const char *in; 101 const char *set; 102 const char *out; 103 unsigned int urlflags; 104 unsigned int setflags; 105 CURLUcode ucode; /* for the main URL set */ 106 CURLUcode pcode; /* for updating parts */ 107 }; 108 109 struct setgetcase { 110 const char *in; 111 const char *set; 112 const char *out; 113 unsigned int urlflags; /* for setting the URL */ 114 unsigned int setflags; /* for updating parts */ 115 unsigned int getflags; /* for getting parts */ 116 CURLUcode pcode; /* for updating parts */ 117 }; 118 119 struct testcase { 120 const char *in; 121 const char *out; 122 unsigned int urlflags; 123 unsigned int getflags; 124 CURLUcode ucode; 125 }; 126 127 struct urltestcase { 128 const char *in; 129 const char *out; 130 unsigned int urlflags; /* pass to curl_url() */ 131 unsigned int getflags; /* pass to curl_url_get() */ 132 CURLUcode ucode; 133 }; 134 135 struct querycase { 136 const char *in; 137 const char *q; 138 const char *out; 139 unsigned int urlflags; /* pass to curl_url() */ 140 unsigned int qflags; /* pass to curl_url_get() */ 141 CURLUcode ucode; 142 }; 143 144 struct clearurlcase { 145 CURLUPart part; 146 const char *in; 147 const char *out; 148 CURLUcode ucode; 149 }; 150 151 static const struct testcase get_parts_list[] ={ 152 {"curl.se", 153 "[10] | [11] | [12] | [13] | curl.se | [15] | / | [16] | [17]", 154 CURLU_GUESS_SCHEME, CURLU_NO_GUESS_SCHEME, CURLUE_OK}, 155 {"https://curl.se:0/#", 156 "https | [11] | [12] | [13] | curl.se | 0 | / | [16] | ", 157 0, CURLU_GET_EMPTY, CURLUE_OK}, 158 {"https://curl.se/#", 159 "https | [11] | [12] | [13] | curl.se | [15] | / | [16] | ", 160 0, CURLU_GET_EMPTY, CURLUE_OK}, 161 {"https://curl.se/?#", 162 "https | [11] | [12] | [13] | curl.se | [15] | / | | ", 163 0, CURLU_GET_EMPTY, CURLUE_OK}, 164 {"https://curl.se/?", 165 "https | [11] | [12] | [13] | curl.se | [15] | / | | [17]", 166 0, CURLU_GET_EMPTY, CURLUE_OK}, 167 {"https://curl.se/?", 168 "https | [11] | [12] | [13] | curl.se | [15] | / | [16] | [17]", 169 0, 0, CURLUE_OK}, 170 {"https://curl.se/?#", 171 "https | [11] | [12] | [13] | curl.se | [15] | / | [16] | [17]", 172 0, 0, CURLUE_OK}, 173 {"https://curl.se/# ", 174 "https | [11] | [12] | [13] | curl.se | [15] | / | [16] | %20%20", 175 CURLU_URLENCODE|CURLU_ALLOW_SPACE, 0, CURLUE_OK}, 176 {"", "", 0, 0, CURLUE_MALFORMED_INPUT}, 177 {" ", "", 0, 0, CURLUE_MALFORMED_INPUT}, 178 {"1h://example.net", "", 0, 0, CURLUE_BAD_SCHEME}, 179 {"..://example.net", "", 0, 0, CURLUE_BAD_SCHEME}, 180 {"-ht://example.net", "", 0, 0, CURLUE_BAD_SCHEME}, 181 {"+ftp://example.net", "", 0, 0, CURLUE_BAD_SCHEME}, 182 {"hej.hej://example.net", 183 "hej.hej | [11] | [12] | [13] | example.net | [15] | / | [16] | [17]", 184 CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_OK}, 185 {"ht-tp://example.net", 186 "ht-tp | [11] | [12] | [13] | example.net | [15] | / | [16] | [17]", 187 CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_OK}, 188 {"ftp+more://example.net", 189 "ftp+more | [11] | [12] | [13] | example.net | [15] | / | [16] | [17]", 190 CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_OK}, 191 {"f1337://example.net", 192 "f1337 | [11] | [12] | [13] | example.net | [15] | / | [16] | [17]", 193 CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_OK}, 194 {"https://user@example.net?hello# space ", 195 "https | user | [12] | [13] | example.net | [15] | / | hello | %20space%20", 196 CURLU_ALLOW_SPACE|CURLU_URLENCODE, 0, CURLUE_OK}, 197 {"https://test%test", "", 0, 0, CURLUE_BAD_HOSTNAME}, 198 {"https://example.com%252f%40@example.net", 199 "https | example.com%2f@ | [12] | [13] | example.net | [15] | / " 200 "| [16] | [17]", 201 0, CURLU_URLDECODE, CURLUE_OK }, 202 #ifdef USE_IDN 203 /* 204 https://sv.wikipedia.org/wiki/R%c3%a4ksm%c3%b6rg%c3%a5s 205 https://codepoints.net/U+00E4 Latin Small Letter A with Diaeresis 206 https://codepoints.net/U+00F6 Latin Small Letter O with Diaeresis 207 https://codepoints.net/U+00E5 Latin Small Letter A with Ring Above 208 */ 209 {"https://r\xc3\xa4ksm\xc3\xb6rg\xc3\xa5s.se", 210 "https | [11] | [12] | [13] | xn--rksmrgs-5wao1o.se | " 211 "[15] | / | [16] | [17]", 0, CURLU_PUNYCODE, CURLUE_OK}, 212 {"https://xn--rksmrgs-5wao1o.se", 213 "https | [11] | [12] | [13] | r\xc3\xa4ksm\xc3\xb6rg\xc3\xa5s.se | " 214 "[15] | / | [16] | [17]", 0, CURLU_PUNY2IDN, CURLUE_OK}, 215 {"https://www.xn--rksmrgs-5wao1o.se", 216 "https | [11] | [12] | [13] | www.r\xc3\xa4ksm\xc3\xb6rg\xc3\xa5s.se | " 217 "[15] | / | [16] | [17]", 0, CURLU_PUNY2IDN, CURLUE_OK}, 218 {"https://www.r\xc3\xa4ksm\xc3\xb6rg\xc3\xa5s.se", 219 "https | [11] | [12] | [13] | www.r\xc3\xa4ksm\xc3\xb6rg\xc3\xa5s.se | " 220 "[15] | / | [16] | [17]", 0, CURLU_PUNY2IDN, CURLUE_OK}, 221 #else 222 {"https://r\xc3\xa4ksm\xc3\xb6rg\xc3\xa5s.se", 223 "https | [11] | [12] | [13] | [30] | [15] | / | [16] | [17]", 224 0, CURLU_PUNYCODE, CURLUE_OK}, 225 #endif 226 /* 227 https://codepoints.net/U+2102 Double-Struck Capital C 228 https://codepoints.net/U+1d64 Latin Subscript Small Letter U 229 https://codepoints.net/U+24c7 Circled Latin Capital Letter R 230 https://codepoints.net/U+2112 Script Capital L 231 https://codepoints.net/U+3002 Ideographic Full Stop 232 https://codepoints.net/U+1d412 Mathematical Bold Capital S 233 https://codepoints.net/U+1f134 Squared Latin Capital Letter E 234 */ 235 {"https://" 236 "%e2%84%82%e1%b5%a4%e2%93%87%e2%84%92%e3%80%82%f0%9d%90%92%f0%9f%84%b4", 237 "https | [11] | [12] | [13] | " 238 "\xe2\x84\x82\xe1\xb5\xa4\xe2\x93\x87\xe2\x84\x92" 239 "\xe3\x80\x82\xf0\x9d\x90\x92\xf0\x9f\x84\xb4" 240 " | [15] | / | [16] | [17]", 241 0, 0, CURLUE_OK}, 242 {"https://" 243 "%e2%84%82%e1%b5%a4%e2%93%87%e2%84%92%e3%80%82%f0%9d%90%92%f0%9f%84%b4", 244 "https | [11] | [12] | [13] | " 245 "%E2%84%82%E1%B5%A4%E2%93%87%E2%84%92%E3%80%82%F0%9D%90%92%F0%9F%84%B4 " 246 "| [15] | / | [16] | [17]", 247 0, CURLU_URLENCODE, CURLUE_OK}, 248 {"https://" 249 "\xe2\x84\x82\xe1\xb5\xa4\xe2\x93\x87\xe2\x84\x92" 250 "\xe3\x80\x82\xf0\x9d\x90\x92\xf0\x9f\x84\xb4", 251 "https | [11] | [12] | [13] | " 252 "%E2%84%82%E1%B5%A4%E2%93%87%E2%84%92%E3%80%82%F0%9D%90%92%F0%9F%84%B4 " 253 "| [15] | / | [16] | [17]", 254 0, CURLU_URLENCODE, CURLUE_OK}, 255 {"https://user@example.net?he l lo", 256 "https | user | [12] | [13] | example.net | [15] | / | he+l+lo | [17]", 257 CURLU_ALLOW_SPACE, CURLU_URLENCODE, CURLUE_OK}, 258 {"https://user@example.net?he l lo", 259 "https | user | [12] | [13] | example.net | [15] | / | he l lo | [17]", 260 CURLU_ALLOW_SPACE, 0, CURLUE_OK}, 261 {"https://exam{}[]ple.net", "", 0, 0, CURLUE_BAD_HOSTNAME}, 262 {"https://exam{ple.net", "", 0, 0, CURLUE_BAD_HOSTNAME}, 263 {"https://exam}ple.net", "", 0, 0, CURLUE_BAD_HOSTNAME}, 264 {"https://exam]ple.net", "", 0, 0, CURLUE_BAD_HOSTNAME}, 265 {"https://exam\\ple.net", "", 0, 0, CURLUE_BAD_HOSTNAME}, 266 {"https://exam$ple.net", "", 0, 0, CURLUE_BAD_HOSTNAME}, 267 {"https://exam'ple.net", "", 0, 0, CURLUE_BAD_HOSTNAME}, 268 {"https://exam\"ple.net", "", 0, 0, CURLUE_BAD_HOSTNAME}, 269 {"https://exam^ple.net", "", 0, 0, CURLUE_BAD_HOSTNAME}, 270 {"https://exam`ple.net", "", 0, 0, CURLUE_BAD_HOSTNAME}, 271 {"https://exam*ple.net", "", 0, 0, CURLUE_BAD_HOSTNAME}, 272 {"https://exam<ple.net", "", 0, 0, CURLUE_BAD_HOSTNAME}, 273 {"https://exam>ple.net", "", 0, 0, CURLUE_BAD_HOSTNAME}, 274 {"https://exam=ple.net", "", 0, 0, CURLUE_BAD_HOSTNAME}, 275 {"https://exam;ple.net", "", 0, 0, CURLUE_BAD_HOSTNAME}, 276 {"https://example,net", "", 0, 0, CURLUE_BAD_HOSTNAME}, 277 {"https://example&net", "", 0, 0, CURLUE_BAD_HOSTNAME}, 278 {"https://example+net", "", 0, 0, CURLUE_BAD_HOSTNAME}, 279 {"https://example(net", "", 0, 0, CURLUE_BAD_HOSTNAME}, 280 {"https://example)net", "", 0, 0, CURLUE_BAD_HOSTNAME}, 281 {"https://example.net/}", 282 "https | [11] | [12] | [13] | example.net | [15] | /} | [16] | [17]", 283 0, 0, CURLUE_OK}, 284 285 /* blank user is blank */ 286 {"https://:password@example.net", 287 "https | | password | [13] | example.net | [15] | / | [16] | [17]", 288 0, 0, CURLUE_OK}, 289 /* blank user + blank password */ 290 {"https://:@example.net", 291 "https | | | [13] | example.net | [15] | / | [16] | [17]", 292 0, 0, CURLUE_OK}, 293 /* user-only (no password) */ 294 {"https://user@example.net", 295 "https | user | [12] | [13] | example.net | [15] | / | [16] | [17]", 296 0, 0, CURLUE_OK}, 297 #ifndef CURL_DISABLE_WEBSOCKETS 298 {"ws://example.com/color/?green", 299 "ws | [11] | [12] | [13] | example.com | [15] | /color/ | green |" 300 " [17]", 301 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK }, 302 {"wss://example.com/color/?green", 303 "wss | [11] | [12] | [13] | example.com | [15] | /color/ | green |" 304 " [17]", 305 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK }, 306 #endif 307 308 {"https://user:password@example.net/get?this=and#but frag then", "", 309 CURLU_DEFAULT_SCHEME, 0, CURLUE_MALFORMED_INPUT}, 310 {"https://user:password@example.net/get?this=and what", "", 311 CURLU_DEFAULT_SCHEME, 0, CURLUE_MALFORMED_INPUT}, 312 {"https://user:password@example.net/ge t?this=and-what", "", 313 CURLU_DEFAULT_SCHEME, 0, CURLUE_MALFORMED_INPUT}, 314 {"https://user:pass word@example.net/get?this=and-what", "", 315 CURLU_DEFAULT_SCHEME, 0, CURLUE_MALFORMED_INPUT}, 316 {"https://u ser:password@example.net/get?this=and-what", "", 317 CURLU_DEFAULT_SCHEME, 0, CURLUE_MALFORMED_INPUT}, 318 {"imap://user:pass;opt ion@server/path", "", 319 CURLU_DEFAULT_SCHEME, 0, CURLUE_MALFORMED_INPUT}, 320 /* no space allowed in scheme */ 321 {"htt ps://user:password@example.net/get?this=and-what", "", 322 CURLU_NON_SUPPORT_SCHEME|CURLU_ALLOW_SPACE, 0, CURLUE_BAD_SCHEME}, 323 {"https://user:password@example.net/get?this=and what", 324 "https | user | password | [13] | example.net | [15] | /get | " 325 "this=and what | [17]", 326 CURLU_ALLOW_SPACE, 0, CURLUE_OK}, 327 {"https://user:password@example.net/ge t?this=and-what", 328 "https | user | password | [13] | example.net | [15] | /ge t | " 329 "this=and-what | [17]", 330 CURLU_ALLOW_SPACE, 0, CURLUE_OK}, 331 {"https://user:pass word@example.net/get?this=and-what", 332 "https | user | pass word | [13] | example.net | [15] | /get | " 333 "this=and-what | [17]", 334 CURLU_ALLOW_SPACE, 0, CURLUE_OK}, 335 {"https://u ser:password@example.net/get?this=and-what", 336 "https | u ser | password | [13] | example.net | [15] | /get | " 337 "this=and-what | [17]", 338 CURLU_ALLOW_SPACE, 0, CURLUE_OK}, 339 {"https://user:password@example.net/ge t?this=and-what", 340 "https | user | password | [13] | example.net | [15] | /ge%20t | " 341 "this=and-what | [17]", 342 CURLU_ALLOW_SPACE | CURLU_URLENCODE, 0, CURLUE_OK}, 343 {"[0:0:0:0:0:0:0:1]", 344 "http | [11] | [12] | [13] | [::1] | [15] | / | [16] | [17]", 345 CURLU_GUESS_SCHEME, 0, CURLUE_OK }, 346 {"[::1]", 347 "http | [11] | [12] | [13] | [::1] | [15] | / | [16] | [17]", 348 CURLU_GUESS_SCHEME, 0, CURLUE_OK }, 349 {"[::]", 350 "http | [11] | [12] | [13] | [::] | [15] | / | [16] | [17]", 351 CURLU_GUESS_SCHEME, 0, CURLUE_OK }, 352 {"https://[::1]", 353 "https | [11] | [12] | [13] | [::1] | [15] | / | [16] | [17]", 354 0, 0, CURLUE_OK }, 355 {"user:moo@ftp.example.com/color/#green?no-red", 356 "ftp | user | moo | [13] | ftp.example.com | [15] | /color/ | [16] | " 357 "green?no-red", 358 CURLU_GUESS_SCHEME, 0, CURLUE_OK }, 359 {"ftp.user:moo@example.com/color/#green?no-red", 360 "http | ftp.user | moo | [13] | example.com | [15] | /color/ | [16] | " 361 "green?no-red", 362 CURLU_GUESS_SCHEME, 0, CURLUE_OK }, 363 #ifdef _WIN32 364 {"file:/C:\\programs\\foo", 365 "file | [11] | [12] | [13] | [14] | [15] | C:\\programs\\foo | [16] | [17]", 366 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, 367 {"file://C:\\programs\\foo", 368 "file | [11] | [12] | [13] | [14] | [15] | C:\\programs\\foo | [16] | [17]", 369 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, 370 {"file:///C:\\programs\\foo", 371 "file | [11] | [12] | [13] | [14] | [15] | C:\\programs\\foo | [16] | [17]", 372 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, 373 {"file://host.example.com/Share/path/to/file.txt", 374 "file | [11] | [12] | [13] | host.example.com | [15] | " 375 "//host.example.com/Share/path/to/file.txt | [16] | [17]", 376 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, 377 #endif 378 {"https://example.com/color/#green?no-red", 379 "https | [11] | [12] | [13] | example.com | [15] | /color/ | [16] | " 380 "green?no-red", 381 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK }, 382 {"https://example.com/color/#green#no-red", 383 "https | [11] | [12] | [13] | example.com | [15] | /color/ | [16] | " 384 "green#no-red", 385 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK }, 386 {"https://example.com/color/?green#no-red", 387 "https | [11] | [12] | [13] | example.com | [15] | /color/ | green | " 388 "no-red", 389 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK }, 390 {"https://example.com/#color/?green#no-red", 391 "https | [11] | [12] | [13] | example.com | [15] | / | [16] | " 392 "color/?green#no-red", 393 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK }, 394 {"https://example.#com/color/?green#no-red", 395 "https | [11] | [12] | [13] | example. | [15] | / | [16] | " 396 "com/color/?green#no-red", 397 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK }, 398 {"http://[ab.be:1]/x", "", 399 CURLU_DEFAULT_SCHEME, 0, CURLUE_BAD_IPV6}, 400 {"http://[ab.be]/x", "", 401 CURLU_DEFAULT_SCHEME, 0, CURLUE_BAD_IPV6}, 402 /* URL without host name */ 403 {"http://a:b@/x", "", 404 CURLU_DEFAULT_SCHEME, 0, CURLUE_NO_HOST}, 405 {"boing:80", 406 "https | [11] | [12] | [13] | boing | 80 | / | [16] | [17]", 407 CURLU_DEFAULT_SCHEME|CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 408 {"http://[fd00:a41::50]:8080", 409 "http | [11] | [12] | [13] | [fd00:a41::50] | 8080 | / | [16] | [17]", 410 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, 411 {"http://[fd00:a41::50]/", 412 "http | [11] | [12] | [13] | [fd00:a41::50] | [15] | / | [16] | [17]", 413 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, 414 {"http://[fd00:a41::50]", 415 "http | [11] | [12] | [13] | [fd00:a41::50] | [15] | / | [16] | [17]", 416 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, 417 {"https://[::1%252]:1234", 418 "https | [11] | [12] | [13] | [::1] | 1234 | / | [16] | [17]", 419 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, 420 421 /* here's "bad" zone id */ 422 {"https://[fe80::20c:29ff:fe9c:409b%eth0]:1234", 423 "https | [11] | [12] | [13] | [fe80::20c:29ff:fe9c:409b] | 1234 " 424 "| / | [16] | [17]", 425 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, 426 {"https://127.0.0.1:443", 427 "https | [11] | [12] | [13] | 127.0.0.1 | [15] | / | [16] | [17]", 428 0, CURLU_NO_DEFAULT_PORT, CURLUE_OK}, 429 {"http://%3a:%3a@ex4mple/%3f+?+%3f+%23#+%23%3f%g7", 430 "http | : | : | [13] | ex4mple | [15] | /?+ | ? # | +#?%g7", 431 0, CURLU_URLDECODE, CURLUE_OK}, 432 {"http://%3a:%3a@ex4mple/%3f?%3f%35#%35%3f%g7", 433 "http | %3a | %3a | [13] | ex4mple | [15] | /%3f | %3f%35 | %35%3f%g7", 434 0, 0, CURLUE_OK}, 435 {"http://HO0_-st%41/", 436 "http | [11] | [12] | [13] | HO0_-stA | [15] | / | [16] | [17]", 437 0, 0, CURLUE_OK}, 438 {"file://hello.html", 439 "", 440 0, 0, CURLUE_BAD_FILE_URL}, 441 {"http://HO0_-st/", 442 "http | [11] | [12] | [13] | HO0_-st | [15] | / | [16] | [17]", 443 0, 0, CURLUE_OK}, 444 {"imap://user:pass;option@server/path", 445 "imap | user | pass | option | server | [15] | /path | [16] | [17]", 446 0, 0, CURLUE_OK}, 447 {"http://user:pass;option@server/path", 448 "http | user | pass;option | [13] | server | [15] | /path | [16] | [17]", 449 0, 0, CURLUE_OK}, 450 {"file:/hello.html", 451 "file | [11] | [12] | [13] | [14] | [15] | /hello.html | [16] | [17]", 452 0, 0, CURLUE_OK}, 453 {"file:/h", 454 "file | [11] | [12] | [13] | [14] | [15] | /h | [16] | [17]", 455 0, 0, CURLUE_OK}, 456 {"file:/", 457 "file | [11] | [12] | [13] | [14] | [15] | | [16] | [17]", 458 0, 0, CURLUE_BAD_FILE_URL}, 459 {"file://127.0.0.1/hello.html", 460 "file | [11] | [12] | [13] | [14] | [15] | /hello.html | [16] | [17]", 461 0, 0, CURLUE_OK}, 462 {"file:////hello.html", 463 "file | [11] | [12] | [13] | [14] | [15] | //hello.html | [16] | [17]", 464 0, 0, CURLUE_OK}, 465 {"file:///hello.html", 466 "file | [11] | [12] | [13] | [14] | [15] | /hello.html | [16] | [17]", 467 0, 0, CURLUE_OK}, 468 {"https://127.0.0.1", 469 "https | [11] | [12] | [13] | 127.0.0.1 | 443 | / | [16] | [17]", 470 0, CURLU_DEFAULT_PORT, CURLUE_OK}, 471 {"https://127.0.0.1", 472 "https | [11] | [12] | [13] | 127.0.0.1 | [15] | / | [16] | [17]", 473 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, 474 {"https://[::1]:1234", 475 "https | [11] | [12] | [13] | [::1] | 1234 | / | [16] | [17]", 476 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, 477 {"https://127abc.com", 478 "https | [11] | [12] | [13] | 127abc.com | [15] | / | [16] | [17]", 479 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, 480 {"https:// example.com?check", "", 481 CURLU_DEFAULT_SCHEME, 0, CURLUE_MALFORMED_INPUT}, 482 {"https://e x a m p l e.com?check", "", 483 CURLU_DEFAULT_SCHEME, 0, CURLUE_MALFORMED_INPUT}, 484 {"https://example.com?check", 485 "https | [11] | [12] | [13] | example.com | [15] | / | check | [17]", 486 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, 487 {"https://example.com:65536", 488 "", 489 CURLU_DEFAULT_SCHEME, 0, CURLUE_BAD_PORT_NUMBER}, 490 {"https://example.com:-1#moo", 491 "", 492 CURLU_DEFAULT_SCHEME, 0, CURLUE_BAD_PORT_NUMBER}, 493 {"https://example.com:0#moo", 494 "https | [11] | [12] | [13] | example.com | 0 | / | " 495 "[16] | moo", 496 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, 497 {"https://example.com:01#moo", 498 "https | [11] | [12] | [13] | example.com | 1 | / | " 499 "[16] | moo", 500 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, 501 {"https://example.com:1#moo", 502 "https | [11] | [12] | [13] | example.com | 1 | / | " 503 "[16] | moo", 504 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, 505 {"http://example.com#moo", 506 "http | [11] | [12] | [13] | example.com | [15] | / | " 507 "[16] | moo", 508 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, 509 {"http://example.com", 510 "http | [11] | [12] | [13] | example.com | [15] | / | " 511 "[16] | [17]", 512 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, 513 {"http://example.com/path/html", 514 "http | [11] | [12] | [13] | example.com | [15] | /path/html | " 515 "[16] | [17]", 516 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, 517 {"http://example.com/path/html?query=name", 518 "http | [11] | [12] | [13] | example.com | [15] | /path/html | " 519 "query=name | [17]", 520 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, 521 {"http://example.com/path/html?query=name#anchor", 522 "http | [11] | [12] | [13] | example.com | [15] | /path/html | " 523 "query=name | anchor", 524 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, 525 {"http://example.com:1234/path/html?query=name#anchor", 526 "http | [11] | [12] | [13] | example.com | 1234 | /path/html | " 527 "query=name | anchor", 528 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, 529 {"http:///user:password@example.com:1234/path/html?query=name#anchor", 530 "http | user | password | [13] | example.com | 1234 | /path/html | " 531 "query=name | anchor", 532 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, 533 {"https://user:password@example.com:1234/path/html?query=name#anchor", 534 "https | user | password | [13] | example.com | 1234 | /path/html | " 535 "query=name | anchor", 536 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, 537 {"http://user:password@example.com:1234/path/html?query=name#anchor", 538 "http | user | password | [13] | example.com | 1234 | /path/html | " 539 "query=name | anchor", 540 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, 541 {"http:/user:password@example.com:1234/path/html?query=name#anchor", 542 "http | user | password | [13] | example.com | 1234 | /path/html | " 543 "query=name | anchor", 544 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, 545 {"http:////user:password@example.com:1234/path/html?query=name#anchor", 546 "", 547 CURLU_DEFAULT_SCHEME, 0, CURLUE_BAD_SLASHES}, 548 {NULL, NULL, 0, 0, CURLUE_OK}, 549 }; 550 551 static const struct urltestcase get_url_list[] = { 552 {"018.0.0.0", "http://018.0.0.0/", CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 553 {"08", "http://08/", CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 554 {"0", "http://0.0.0.0/", CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 555 {"01", "http://0.0.0.1/", CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 556 {"02", "http://0.0.0.2/", CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 557 {"03", "http://0.0.0.3/", CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 558 {"04", "http://0.0.0.4/", CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 559 {"05", "http://0.0.0.5/", CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 560 {"06", "http://0.0.0.6/", CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 561 {"07", "http://0.0.0.7/", CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 562 {"07.1", "http://7.0.0.1/", CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 563 {"7.1", "http://7.0.0.1/", CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 564 {"0x7.1", "http://7.0.0.1/", CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 565 {"0x", "http://0x/", CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 566 {"0x1", "http://0.0.0.1/", CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 567 {"0x2", "http://0.0.0.2/", CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 568 {"0x3", "http://0.0.0.3/", CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 569 {"0x4", "http://0.0.0.4/", CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 570 {"0x5", "http://0.0.0.5/", CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 571 {"0x6", "http://0.0.0.6/", CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 572 {"0x7", "http://0.0.0.7/", CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 573 {"0x8", "http://0.0.0.8/", CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 574 {"0x9", "http://0.0.0.9/", CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 575 {"0xa", "http://0.0.0.10/", CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 576 {"0xb", "http://0.0.0.11/", CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 577 {"0xc", "http://0.0.0.12/", CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 578 {"0xd", "http://0.0.0.13/", CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 579 {"0xe", "http://0.0.0.14/", CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 580 {"0xf", "http://0.0.0.15/", CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 581 {"0xg", "http://0xg/", CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 582 {"https://0/", "https://0.0.0.0/", 0, 0, CURLUE_OK}, 583 {"https://0.0x0/", "https://0.0.0.0/", 0, 0, CURLUE_OK}, 584 {"https://0.000/", "https://0.0.0.0/", 0, 0, CURLUE_OK}, 585 {"example.com", 586 "example.com/", 587 CURLU_GUESS_SCHEME, CURLU_NO_GUESS_SCHEME, CURLUE_OK}, 588 {"http://user@example.com?#", 589 "http://user@example.com/?#", 590 0, CURLU_GET_EMPTY, CURLUE_OK}, 591 /* WHATWG disgrees, it wants "https:/0.0.0.0/" */ 592 {"https://0x.0x.0", "https://0x.0x.0/", 0, 0, CURLUE_OK}, 593 594 {"https://example.com:000000000000000000000443/foo", 595 "https://example.com/foo", 596 0, CURLU_NO_DEFAULT_PORT, CURLUE_OK}, 597 {"https://example.com:000000000000000000000/foo", 598 "https://example.com:0/foo", 599 0, CURLU_NO_DEFAULT_PORT, CURLUE_OK}, 600 {"https://192.0x0000A80001", "https://192.168.0.1/", 0, 0, CURLUE_OK}, 601 {"https://0xffffffff", "https://255.255.255.255/", 0, 0, CURLUE_OK}, 602 {"https://1.0x1000000", "https://1.0x1000000/", 0, 0, CURLUE_OK}, 603 {"https://0x7f.1", "https://127.0.0.1/", 0, 0, CURLUE_OK}, 604 {"https://1.2.3.256.com", "https://1.2.3.256.com/", 0, 0, CURLUE_OK}, 605 {"https://10.com", "https://10.com/", 0, 0, CURLUE_OK}, 606 {"https://1.2.com", "https://1.2.com/", 0, 0, CURLUE_OK}, 607 {"https://1.2.3.com", "https://1.2.3.com/", 0, 0, CURLUE_OK}, 608 {"https://1.2.com.99", "https://1.2.com.99/", 0, 0, CURLUE_OK}, 609 {"https://[fe80::0000:20c:29ff:fe9c:409b]:80/moo", 610 "https://[fe80::20c:29ff:fe9c:409b]:80/moo", 611 0, 0, CURLUE_OK}, 612 {"https://[fe80::020c:29ff:fe9c:409b]:80/moo", 613 "https://[fe80::20c:29ff:fe9c:409b]:80/moo", 614 0, 0, CURLUE_OK}, 615 {"https://[fe80:0000:0000:0000:020c:29ff:fe9c:409b]:80/moo", 616 "https://[fe80::20c:29ff:fe9c:409b]:80/moo", 617 0, 0, CURLUE_OK}, 618 {"https://[fe80:0:0:0:409b::]:80/moo", 619 "https://[fe80::409b:0:0:0]:80/moo", 620 0, 0, CURLUE_OK}, 621 /* normalize to lower case */ 622 {"https://[FE80:0:A:0:409B:0:0:0]:80/moo", 623 "https://[fe80:0:a:0:409b::]:80/moo", 624 0, 0, CURLUE_OK}, 625 {"https://[::%25fakeit];80/moo", 626 "", 627 0, 0, CURLUE_BAD_PORT_NUMBER}, 628 {"https://[fe80::20c:29ff:fe9c:409b]-80/moo", 629 "", 630 0, 0, CURLUE_BAD_PORT_NUMBER}, 631 #ifdef USE_IDN 632 {"https://r\xc3\xa4ksm\xc3\xb6rg\xc3\xa5s.se/path?q#frag", 633 "https://xn--rksmrgs-5wao1o.se/path?q#frag", 0, CURLU_PUNYCODE, CURLUE_OK}, 634 #endif 635 /* unsupported schemes with no guessing enabled */ 636 {"data:text/html;charset=utf-8;base64,PCFET0NUWVBFIEhUTUw+PG1ldGEgY", 637 "", 0, 0, CURLUE_UNSUPPORTED_SCHEME}, 638 {"d:anything-really", "", 0, 0, CURLUE_UNSUPPORTED_SCHEME}, 639 {"about:config", "", 0, 0, CURLUE_UNSUPPORTED_SCHEME}, 640 {"example://foo", "", 0, 0, CURLUE_UNSUPPORTED_SCHEME}, 641 {"mailto:infobot@example.com?body=send%20current-issue", "", 0, 0, 642 CURLUE_UNSUPPORTED_SCHEME}, 643 {"about:80", "https://about:80/", CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, 644 /* percent encoded host names */ 645 {"http://example.com%40127.0.0.1/", "", 0, 0, CURLUE_BAD_HOSTNAME}, 646 {"http://example.com%21127.0.0.1/", "", 0, 0, CURLUE_BAD_HOSTNAME}, 647 {"http://example.com%3f127.0.0.1/", "", 0, 0, CURLUE_BAD_HOSTNAME}, 648 {"http://example.com%23127.0.0.1/", "", 0, 0, CURLUE_BAD_HOSTNAME}, 649 {"http://example.com%3a127.0.0.1/", "", 0, 0, CURLUE_BAD_HOSTNAME}, 650 {"http://example.com%09127.0.0.1/", "", 0, 0, CURLUE_BAD_HOSTNAME}, 651 {"http://example.com%2F127.0.0.1/", "", 0, 0, CURLUE_BAD_HOSTNAME}, 652 {"https://%41", "https://A/", 0, 0, CURLUE_OK}, 653 {"https://%20", "", 0, 0, CURLUE_BAD_HOSTNAME}, 654 {"https://%41%0D", "", 0, 0, CURLUE_BAD_HOSTNAME}, 655 {"https://%25", "", 0, 0, CURLUE_BAD_HOSTNAME}, 656 {"https://_%c0_", "https://_\xC0_/", 0, 0, CURLUE_OK}, 657 {"https://_%c0_", "https://_%C0_/", 0, CURLU_URLENCODE, CURLUE_OK}, 658 659 /* IPv4 trickeries */ 660 {"https://16843009", "https://1.1.1.1/", 0, 0, CURLUE_OK}, 661 {"https://0177.1", "https://127.0.0.1/", 0, 0, CURLUE_OK}, 662 {"https://0111.02.0x3", "https://73.2.0.3/", 0, 0, CURLUE_OK}, 663 {"https://0111.02.0x3.", "https://0111.02.0x3./", 0, 0, CURLUE_OK}, 664 {"https://0111.02.030", "https://73.2.0.24/", 0, 0, CURLUE_OK}, 665 {"https://0111.02.030.", "https://0111.02.030./", 0, 0, CURLUE_OK}, 666 {"https://0xff.0xff.0377.255", "https://255.255.255.255/", 0, 0, CURLUE_OK}, 667 {"https://1.0xffffff", "https://1.255.255.255/", 0, 0, CURLUE_OK}, 668 /* IPv4 numerical overflows or syntax errors will not normalize */ 669 {"https://a127.0.0.1", "https://a127.0.0.1/", 0, 0, CURLUE_OK}, 670 {"https://\xff.127.0.0.1", "https://%FF.127.0.0.1/", 0, CURLU_URLENCODE, 671 CURLUE_OK}, 672 {"https://127.-0.0.1", "https://127.-0.0.1/", 0, 0, CURLUE_OK}, 673 {"https://127.0. 1", "https://127.0.0.1/", 0, 0, CURLUE_MALFORMED_INPUT}, 674 {"https://1.2.3.256", "https://1.2.3.256/", 0, 0, CURLUE_OK}, 675 {"https://1.2.3.256.", "https://1.2.3.256./", 0, 0, CURLUE_OK}, 676 {"https://1.2.3.4.5", "https://1.2.3.4.5/", 0, 0, CURLUE_OK}, 677 {"https://1.2.0x100.3", "https://1.2.0x100.3/", 0, 0, CURLUE_OK}, 678 {"https://4294967296", "https://4294967296/", 0, 0, CURLUE_OK}, 679 {"https://123host", "https://123host/", 0, 0, CURLUE_OK}, 680 /* 40 bytes scheme is the max allowed */ 681 {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA://hostname/path", 682 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa://hostname/path", 683 CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_OK}, 684 /* 41 bytes scheme is not allowed */ 685 {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA://hostname/path", 686 "", 687 CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_BAD_SCHEME}, 688 {"https://[fe80::20c:29ff:fe9c:409b%]:1234", 689 "", 690 0, 0, CURLUE_BAD_IPV6}, 691 {"https://[fe80::20c:29ff:fe9c:409b%25]:1234", 692 "https://[fe80::20c:29ff:fe9c:409b%2525]:1234/", 693 0, 0, CURLUE_OK}, 694 {"https://[fe80::20c:29ff:fe9c:409b%eth0]:1234", 695 "https://[fe80::20c:29ff:fe9c:409b%25eth0]:1234/", 696 0, 0, CURLUE_OK}, 697 {"https://[::%25fakeit]/moo", 698 "https://[::%25fakeit]/moo", 699 0, 0, CURLUE_OK}, 700 {"smtp.example.com/path/html", 701 "smtp://smtp.example.com/path/html", 702 CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 703 {"https.example.com/path/html", 704 "http://https.example.com/path/html", 705 CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 706 {"dict.example.com/path/html", 707 "dict://dict.example.com/path/html", 708 CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 709 {"pop3.example.com/path/html", 710 "pop3://pop3.example.com/path/html", 711 CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 712 {"ldap.example.com/path/html", 713 "ldap://ldap.example.com/path/html", 714 CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 715 {"imap.example.com/path/html", 716 "imap://imap.example.com/path/html", 717 CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 718 {"ftp.example.com/path/html", 719 "ftp://ftp.example.com/path/html", 720 CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 721 {"example.com/path/html", 722 "http://example.com/path/html", 723 CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 724 {"smtp.com/path/html", 725 "smtp://smtp.com/path/html", 726 CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 727 {"dict.com/path/html", 728 "dict://dict.com/path/html", 729 CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 730 {"pop3.com/path/html", 731 "pop3://pop3.com/path/html", 732 CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 733 {"ldap.com/path/html", 734 "ldap://ldap.com/path/html", 735 CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 736 {"imap.com/path/html", 737 "imap://imap.com/path/html", 738 CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 739 {"ftp.com/path/html", 740 "ftp://ftp.com/path/html", 741 CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 742 {"smtp/path/html", 743 "http://smtp/path/html", 744 CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 745 {"dict/path/html", 746 "http://dict/path/html", 747 CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 748 {"pop3/path/html", 749 "http://pop3/path/html", 750 CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 751 {"ldap/path/html", 752 "http://ldap/path/html", 753 CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 754 {"imap/path/html", 755 "http://imap/path/html", 756 CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 757 {"ftp/path/html", 758 "http://ftp/path/html", 759 CURLU_GUESS_SCHEME, 0, CURLUE_OK}, 760 {"HTTP://test/", "http://test/", 0, 0, CURLUE_OK}, 761 {"http://HO0_-st..~./", "http://HO0_-st..~./", 0, 0, CURLUE_OK}, 762 {"http:/@example.com: 123/", "", 0, 0, CURLUE_MALFORMED_INPUT}, 763 {"http:/@example.com:123 /", "", 0, 0, CURLUE_MALFORMED_INPUT}, 764 {"http:/@example.com:123a/", "", 0, 0, CURLUE_BAD_PORT_NUMBER}, 765 {"http://host/file\r", "", 0, 0, CURLUE_MALFORMED_INPUT}, 766 {"http://host/file\n\x03", "", 0, 0, CURLUE_MALFORMED_INPUT}, 767 {"htt\x02://host/file", "", 768 CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_MALFORMED_INPUT}, 769 {" http://host/file", "", 0, 0, CURLUE_MALFORMED_INPUT}, 770 /* here the password ends at the semicolon and options is 'word' */ 771 {"imap://user:pass;word@host/file", 772 "imap://user:pass;word@host/file", 773 0, 0, CURLUE_OK}, 774 /* here the password has the semicolon */ 775 {"http://user:pass;word@host/file", 776 "http://user:pass;word@host/file", 0, 0, CURLUE_OK}, 777 {"file:///file.txt#moo", "file:///file.txt#moo", 0, 0, CURLUE_OK}, 778 {"file:////file.txt", "file:////file.txt", 0, 0, CURLUE_OK}, 779 {"file:///file.txt", "file:///file.txt", 0, 0, CURLUE_OK}, 780 {"file:./", "file://", 0, 0, CURLUE_OK}, 781 {"http://example.com/hello/../here", 782 "http://example.com/hello/../here", 783 CURLU_PATH_AS_IS, 0, CURLUE_OK}, 784 {"http://example.com/hello/../here", 785 "http://example.com/here", 786 0, 0, CURLUE_OK}, 787 {"http://example.com:80", 788 "http://example.com/", 789 0, CURLU_NO_DEFAULT_PORT, CURLUE_OK}, 790 {"tp://example.com/path/html", 791 "", 792 0, 0, CURLUE_UNSUPPORTED_SCHEME}, 793 {"http://hello:fool@example.com", 794 "", 795 CURLU_DISALLOW_USER, 0, CURLUE_USER_NOT_ALLOWED}, 796 {"http:/@example.com:123", 797 "http://@example.com:123/", 798 0, 0, CURLUE_OK}, 799 {"http:/:password@example.com", 800 "http://:password@example.com/", 801 0, 0, CURLUE_OK}, 802 {"http://user@example.com?#", 803 "http://user@example.com/", 804 0, 0, CURLUE_OK}, 805 {"http://user@example.com?", 806 "http://user@example.com/", 807 0, 0, CURLUE_OK}, 808 {"http://user@example.com#anchor", 809 "http://user@example.com/#anchor", 810 0, 0, CURLUE_OK}, 811 {"example.com/path/html", 812 "https://example.com/path/html", 813 CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, 814 {"example.com/path/html", 815 "", 816 0, 0, CURLUE_BAD_SCHEME}, 817 {"http://user:password@example.com:1234/path/html?query=name#anchor", 818 "http://user:password@example.com:1234/path/html?query=name#anchor", 819 0, 0, CURLUE_OK}, 820 {"http://example.com:1234/path/html?query=name#anchor", 821 "http://example.com:1234/path/html?query=name#anchor", 822 0, 0, CURLUE_OK}, 823 {"http://example.com/path/html?query=name#anchor", 824 "http://example.com/path/html?query=name#anchor", 825 0, 0, CURLUE_OK}, 826 {"http://example.com/path/html?query=name", 827 "http://example.com/path/html?query=name", 828 0, 0, CURLUE_OK}, 829 {"http://example.com/path/html", 830 "http://example.com/path/html", 831 0, 0, CURLUE_OK}, 832 {"tp://example.com/path/html", 833 "tp://example.com/path/html", 834 CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_OK}, 835 {"custom-scheme://host?expected=test-good", 836 "custom-scheme://host/?expected=test-good", 837 CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_OK}, 838 {"custom-scheme://?expected=test-bad", 839 "", 840 CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_NO_HOST}, 841 {"custom-scheme://?expected=test-new-good", 842 "custom-scheme:///?expected=test-new-good", 843 CURLU_NON_SUPPORT_SCHEME | CURLU_NO_AUTHORITY, 0, CURLUE_OK}, 844 {"custom-scheme://host?expected=test-still-good", 845 "custom-scheme://host/?expected=test-still-good", 846 CURLU_NON_SUPPORT_SCHEME | CURLU_NO_AUTHORITY, 0, CURLUE_OK}, 847 {NULL, NULL, 0, 0, CURLUE_OK} 848 }; 849 850 static int checkurl(const char *org, const char *url, const char *out) 851 { 852 if(strcmp(out, url)) { 853 curl_mfprintf(stderr, 854 "Org: %s\n" 855 "Wanted: %s\n" 856 "Got : %s\n", 857 org, out, url); 858 return 1; 859 } 860 return 0; 861 } 862 863 /* 1. Set the URL 864 2. Set components 865 3. Extract all components (not URL) 866 */ 867 static const struct setgetcase setget_parts_list[] = { 868 {"https://example.com/", 869 "query=\"\",", 870 "https | [11] | [12] | [13] | example.com | [15] | / | | [17]", 871 0, 0, CURLU_GET_EMPTY, CURLUE_OK}, 872 {"https://example.com/", 873 "fragment=\"\",", 874 "https | [11] | [12] | [13] | example.com | [15] | / | [16] | ", 875 0, 0, CURLU_GET_EMPTY, CURLUE_OK}, 876 {"https://example.com/", 877 "query=\"\",", 878 "https | [11] | [12] | [13] | example.com | [15] | / | [16] | [17]", 879 0, 0, 0, CURLUE_OK}, 880 {"https://example.com", 881 "path=get,", 882 "https | [11] | [12] | [13] | example.com | [15] | /get | [16] | [17]", 883 0, 0, 0, CURLUE_OK}, 884 {"https://example.com", 885 "path=/get,", 886 "https | [11] | [12] | [13] | example.com | [15] | /get | [16] | [17]", 887 0, 0, 0, CURLUE_OK}, 888 {"https://example.com", 889 "path=g e t,", 890 "https | [11] | [12] | [13] | example.com | [15] | /g%20e%20t | " 891 "[16] | [17]", 892 0, CURLU_URLENCODE, 0, CURLUE_OK}, 893 {NULL, NULL, NULL, 0, 0, 0, CURLUE_OK} 894 }; 895 896 /* !checksrc! disable SPACEBEFORECOMMA 1 */ 897 static const struct setcase set_parts_list[] = { 898 {NULL, /* start fresh! */ 899 "scheme=https,path=/,url=\"\",", /* incomplete url, redirect to "" */ 900 "https://example.com/", 901 0, 0, CURLUE_OK, CURLUE_MALFORMED_INPUT}, 902 {NULL, /* start fresh! */ 903 "scheme=https,host=example.com,path=/,url=\"\",", /* redirect to "" */ 904 "https://example.com/", 905 0, 0, CURLUE_OK, CURLUE_OK}, 906 {"https://example.com/", 907 "path=one\ntwo,", 908 "https://example.com/one\ntwo", 909 0, 0, CURLUE_OK, CURLUE_OK}, 910 {"https://example.com/", 911 "path=one\rtwo,", 912 "https://example.com/one\rtwo", 913 0, 0, CURLUE_OK, CURLUE_OK}, 914 {"https://example.com/", 915 "path=one\ntwo,", 916 "https://example.com/one%0Atwo", 917 0, CURLU_URLENCODE, CURLUE_OK, CURLUE_OK}, 918 {"https://example.com/", 919 "path=one\rtwo,", 920 "https://example.com/one%0Dtwo", 921 0, CURLU_URLENCODE, CURLUE_OK, CURLUE_OK}, 922 {"https://example.com/", 923 "host=%43url.se,", 924 "https://%43url.se/", 925 0, 0, CURLUE_OK, CURLUE_OK}, 926 {"https://example.com/", 927 "host=%25url.se,", 928 "", 929 0, 0, CURLUE_OK, CURLUE_BAD_HOSTNAME}, 930 {"https://example.com/?param=value", 931 "query=\"\",", 932 "https://example.com/", 933 0, CURLU_APPENDQUERY | CURLU_URLENCODE, CURLUE_OK, CURLUE_OK}, 934 {"https://example.com/", 935 "host=\"\",", 936 "https://example.com/", 937 0, CURLU_URLENCODE, CURLUE_OK, CURLUE_BAD_HOSTNAME}, 938 {"https://example.com/", 939 "host=\"\",", 940 "https://example.com/", 941 0, 0, CURLUE_OK, CURLUE_BAD_HOSTNAME}, 942 {"https://example.com", 943 "path=get,", 944 "https://example.com/get", 945 0, 0, CURLUE_OK, CURLUE_OK}, 946 {"https://example.com/", 947 "scheme=ftp+-.123,", 948 "ftp+-.123://example.com/", 949 0, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK, CURLUE_OK}, 950 {"https://example.com/", 951 "scheme=1234,", 952 "https://example.com/", 953 0, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK, CURLUE_BAD_SCHEME}, 954 {"https://example.com/", 955 "scheme=1http,", 956 "https://example.com/", 957 0, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK, CURLUE_BAD_SCHEME}, 958 {"https://example.com/", 959 "scheme=-ftp,", 960 "https://example.com/", 961 0, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK, CURLUE_BAD_SCHEME}, 962 {"https://example.com/", 963 "scheme=+ftp,", 964 "https://example.com/", 965 0, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK, CURLUE_BAD_SCHEME}, 966 {"https://example.com/", 967 "scheme=.ftp,", 968 "https://example.com/", 969 0, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK, CURLUE_BAD_SCHEME}, 970 {"https://example.com/", 971 "host=example.com%2fmoo,", 972 "", 973 0, /* get */ 974 0, /* set */ 975 CURLUE_OK, CURLUE_BAD_HOSTNAME}, 976 {"https://example.com/", 977 "host=http://fake,", 978 "", 979 0, /* get */ 980 0, /* set */ 981 CURLUE_OK, CURLUE_BAD_HOSTNAME}, 982 {"https://example.com/", 983 "host=test%,", 984 "", 985 0, /* get */ 986 0, /* set */ 987 CURLUE_OK, CURLUE_BAD_HOSTNAME}, 988 {"https://example.com/", 989 "host=te st,", 990 "", 991 0, /* get */ 992 0, /* set */ 993 CURLUE_OK, CURLUE_BAD_HOSTNAME}, 994 {"https://example.com/", 995 "host=0xff,", /* '++' there's no automatic URL decode when setting this 996 part */ 997 "https://0xff/", 998 0, /* get */ 999 0, /* set */ 1000 CURLUE_OK, CURLUE_OK}, 1001 1002 {"https://example.com/", 1003 "query=Al2cO3tDkcDZ3EWE5Lh+LX8TPHs,", /* contains '+' */ 1004 "https://example.com/?Al2cO3tDkcDZ3EWE5Lh%2BLX8TPHs", 1005 CURLU_URLDECODE, /* decode on get */ 1006 CURLU_URLENCODE, /* encode on set */ 1007 CURLUE_OK, CURLUE_OK}, 1008 1009 {"https://example.com/", 1010 /* Set a bad scheme *including* :// */ 1011 "scheme=https://,", 1012 "https://example.com/", 1013 0, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK, CURLUE_BAD_SCHEME}, 1014 {"https://example.com/", 1015 /* Set a 41 bytes scheme. That's too long so the old scheme remains set. */ 1016 "scheme=bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc,", 1017 "https://example.com/", 1018 0, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK, CURLUE_BAD_SCHEME}, 1019 {"https://example.com/", 1020 /* set a 40 bytes scheme */ 1021 "scheme=bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,", 1022 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb://example.com/", 1023 0, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK, CURLUE_OK}, 1024 {"https://[::1%25fake]:1234/", 1025 "zoneid=NULL,", 1026 "https://[::1]:1234/", 1027 0, 0, CURLUE_OK, CURLUE_OK}, 1028 {"https://host:1234/", 1029 "port=NULL,", 1030 "https://host/", 1031 0, 0, CURLUE_OK, CURLUE_OK}, 1032 {"https://host:1234/", 1033 "port=\"\",", 1034 "https://host:1234/", 1035 0, 0, CURLUE_OK, CURLUE_BAD_PORT_NUMBER}, 1036 {"https://host:1234/", 1037 "port=56 78,", 1038 "https://host:1234/", 1039 0, 0, CURLUE_OK, CURLUE_BAD_PORT_NUMBER}, 1040 {"https://host:1234/", 1041 "port=0,", 1042 "https://host:0/", 1043 0, 0, CURLUE_OK, CURLUE_OK}, 1044 {"https://host:1234/", 1045 "port=65535,", 1046 "https://host:65535/", 1047 0, 0, CURLUE_OK, CURLUE_OK}, 1048 {"https://host:1234/", 1049 "port=65536,", 1050 "https://host:1234/", 1051 0, 0, CURLUE_OK, CURLUE_BAD_PORT_NUMBER}, 1052 {"https://host/", 1053 "path=%4A%4B%4C,", 1054 "https://host/%4a%4b%4c", 1055 0, 0, CURLUE_OK, CURLUE_OK}, 1056 {"https://host/mooo?q#f", 1057 "path=NULL,query=NULL,fragment=NULL,", 1058 "https://host/", 1059 0, 0, CURLUE_OK, CURLUE_OK}, 1060 {"https://user:secret@host/", 1061 "user=NULL,password=NULL,", 1062 "https://host/", 1063 0, 0, CURLUE_OK, CURLUE_OK}, 1064 {NULL, 1065 "scheme=https,user= @:,host=foobar,", 1066 "https://%20%20%20%40%3A@foobar/", 1067 0, CURLU_URLENCODE, CURLUE_OK, CURLUE_OK}, 1068 /* Setting a host name with spaces is not OK: */ 1069 {NULL, 1070 "scheme=https,host= ,path= ,user= ,password= ,query= ,fragment= ,", 1071 "[nothing]", 1072 0, CURLU_URLENCODE, CURLUE_OK, CURLUE_BAD_HOSTNAME}, 1073 {NULL, 1074 "scheme=https,host=foobar,path=/this /path /is /here,", 1075 "https://foobar/this%20/path%20/is%20/here", 1076 0, CURLU_URLENCODE, CURLUE_OK, CURLUE_OK}, 1077 {NULL, 1078 "scheme=https,host=foobar,path=\xc3\xa4\xc3\xb6\xc3\xbc,", 1079 "https://foobar/%C3%A4%C3%B6%C3%BC", 1080 0, CURLU_URLENCODE, CURLUE_OK, CURLUE_OK}, 1081 {"imap://user:secret;opt@host/", 1082 "options=updated,scheme=imaps,password=p4ssw0rd,", 1083 "imaps://user:p4ssw0rd;updated@host/", 1084 0, 0, CURLUE_NO_HOST, CURLUE_OK}, 1085 {"imap://user:secret;optit@host/", 1086 "scheme=https,", 1087 "https://user:secret@host/", 1088 0, 0, CURLUE_NO_HOST, CURLUE_OK}, 1089 {"file:///file#anchor", 1090 "scheme=https,host=example,", 1091 "https://example/file#anchor", 1092 0, 0, CURLUE_NO_HOST, CURLUE_OK}, 1093 {NULL, /* start fresh! */ 1094 "scheme=file,host=127.0.0.1,path=/no,user=anonymous,", 1095 "file:///no", 1096 0, 0, CURLUE_OK, CURLUE_OK}, 1097 {NULL, /* start fresh! */ 1098 "scheme=ftp,host=127.0.0.1,path=/no,user=anonymous,", 1099 "ftp://anonymous@127.0.0.1/no", 1100 0, 0, CURLUE_OK, CURLUE_OK}, 1101 {NULL, /* start fresh! */ 1102 "scheme=https,host=example.com,", 1103 "https://example.com/", 1104 0, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK, CURLUE_OK}, 1105 {"http://user:foo@example.com/path?query#frag", 1106 "fragment=changed,", 1107 "http://user:foo@example.com/path?query#changed", 1108 0, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK, CURLUE_OK}, 1109 {"http://example.com/", 1110 "scheme=foo,", /* not accepted */ 1111 "http://example.com/", 1112 0, 0, CURLUE_OK, CURLUE_UNSUPPORTED_SCHEME}, 1113 {"http://example.com/", 1114 "scheme=https,path=/hello,fragment=snippet,", 1115 "https://example.com/hello#snippet", 1116 0, 0, CURLUE_OK, CURLUE_OK}, 1117 {"http://example.com:80", 1118 "user=foo,port=1922,", 1119 "http://foo@example.com:1922/", 1120 0, 0, CURLUE_OK, CURLUE_OK}, 1121 {"http://example.com:80", 1122 "user=foo,password=bar,", 1123 "http://foo:bar@example.com:80/", 1124 0, 0, CURLUE_OK, CURLUE_OK}, 1125 {"http://example.com:80", 1126 "user=foo,", 1127 "http://foo@example.com:80/", 1128 0, 0, CURLUE_OK, CURLUE_OK}, 1129 {"http://example.com", 1130 "host=www.example.com,", 1131 "http://www.example.com/", 1132 0, 0, CURLUE_OK, CURLUE_OK}, 1133 {"http://example.com:80", 1134 "scheme=ftp,", 1135 "ftp://example.com:80/", 1136 0, 0, CURLUE_OK, CURLUE_OK}, 1137 {"custom-scheme://host", 1138 "host=\"\",", 1139 "custom-scheme://host/", 1140 CURLU_NON_SUPPORT_SCHEME, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK, 1141 CURLUE_BAD_HOSTNAME}, 1142 {"custom-scheme://host", 1143 "host=\"\",", 1144 "custom-scheme:///", 1145 CURLU_NON_SUPPORT_SCHEME, CURLU_NON_SUPPORT_SCHEME | CURLU_NO_AUTHORITY, 1146 CURLUE_OK, CURLUE_OK}, 1147 1148 {NULL, NULL, NULL, 0, 0, CURLUE_OK, CURLUE_OK} 1149 }; 1150 1151 static CURLUPart part2id(char *part) 1152 { 1153 if(!strcmp("url", part)) 1154 return CURLUPART_URL; 1155 if(!strcmp("scheme", part)) 1156 return CURLUPART_SCHEME; 1157 if(!strcmp("user", part)) 1158 return CURLUPART_USER; 1159 if(!strcmp("password", part)) 1160 return CURLUPART_PASSWORD; 1161 if(!strcmp("options", part)) 1162 return CURLUPART_OPTIONS; 1163 if(!strcmp("host", part)) 1164 return CURLUPART_HOST; 1165 if(!strcmp("port", part)) 1166 return CURLUPART_PORT; 1167 if(!strcmp("path", part)) 1168 return CURLUPART_PATH; 1169 if(!strcmp("query", part)) 1170 return CURLUPART_QUERY; 1171 if(!strcmp("fragment", part)) 1172 return CURLUPART_FRAGMENT; 1173 if(!strcmp("zoneid", part)) 1174 return CURLUPART_ZONEID; 1175 /* NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange) */ 1176 return (CURLUPart)9999; /* bad input => bad output */ 1177 } 1178 1179 static CURLUcode updateurl(CURLU *u, const char *cmd, unsigned int setflags) 1180 { 1181 const char *p = cmd; 1182 CURLUcode uc; 1183 1184 /* make sure the last command ends with a comma too! */ 1185 while(p) { 1186 char *e = strchr(p, ','); 1187 if(e) { 1188 size_t n = (size_t)(e - p); 1189 char buf[80]; 1190 char part[80]; 1191 char value[80]; 1192 1193 memset(part, 0, sizeof(part)); /* Avoid valgrind false positive. */ 1194 memset(value, 0, sizeof(value)); /* Avoid valgrind false positive. */ 1195 memcpy(buf, p, n); 1196 buf[n] = 0; 1197 if(2 == sscanf(buf, "%79[^=]=%79[^,]", part, value)) { 1198 CURLUPart what = part2id(part); 1199 #if 0 1200 /* for debugging this */ 1201 curl_mfprintf(stderr, "%s = \"%s\" [%d]\n", part, value, (int)what); 1202 #endif 1203 if(what > CURLUPART_ZONEID) 1204 curl_mfprintf(stderr, "UNKNOWN part '%s'\n", part); 1205 1206 if(!strcmp("NULL", value)) 1207 uc = curl_url_set(u, what, NULL, setflags); 1208 else if(!strcmp("\"\"", value)) 1209 uc = curl_url_set(u, what, "", setflags); 1210 else 1211 uc = curl_url_set(u, what, value, setflags); 1212 if(uc) 1213 return uc; 1214 } 1215 p = e + 1; 1216 continue; 1217 } 1218 break; 1219 } 1220 return CURLUE_OK; 1221 } 1222 1223 static const struct redircase set_url_list[] = { 1224 {"https://example.com", 1225 "", /* blank redirect */ 1226 "https://example.com/", 1227 0, 0, CURLUE_OK }, 1228 {"http://firstplace.example.com/want/1314", 1229 "//somewhere.example.com/reply/1314", 1230 "http://somewhere.example.com/reply/1314", 1231 0, 0, CURLUE_OK }, 1232 {"http://127.0.0.1:46383/want?uri=http://anything/276?secondq/276", 1233 "data/2760002.txt?coolsite=http://anotherurl/?a_second/2760002", 1234 "http://127.0.0.1:46383/" 1235 "data/2760002.txt?coolsite=http://anotherurl/?a_second/2760002", 1236 0, 0, CURLUE_OK }, 1237 {"file:///basic#", "#yay", 1238 "file:///basic#yay", 0, 0, CURLUE_OK}, 1239 {"file:///basic", "?yay", 1240 "file:///basic?yay", 0, 0, CURLUE_OK}, 1241 {"file:///basic?", "?yay", 1242 "file:///basic?yay", 0, 0, CURLUE_OK}, 1243 {"file:///basic?hello", "#frag", 1244 "file:///basic?hello#frag", 0, 0, CURLUE_OK}, 1245 {"file:///basic?hello", "?q", 1246 "file:///basic?q", 0, 0, CURLUE_OK}, 1247 {"http://example.org#withs/ash", "/moo#frag", 1248 "http://example.org/moo#frag", 1249 0, 0, CURLUE_OK}, 1250 {"http://example.org/", "../path/././../././../moo", 1251 "http://example.org/moo", 1252 0, 0, CURLUE_OK}, 1253 {"http://example.org/", ".%2e/path/././../%2E/./../moo", 1254 "http://example.org/moo", 1255 0, 0, CURLUE_OK}, 1256 {"http://example.org/", ".%2e/path/./%2e/.%2E/%2E/./%2e%2E/moo", 1257 "http://example.org/moo", 1258 0, 0, CURLUE_OK}, 1259 1260 {"http://example.org?bar/moo", "?weird", 1261 "http://example.org/?weird", 0, 0, CURLUE_OK}, 1262 {"http://example.org/foo?bar", "?weird", 1263 "http://example.org/foo?weird", 0, 0, CURLUE_OK}, 1264 {"http://example.org/foo", "?weird", 1265 "http://example.org/foo?weird", 0, 0, CURLUE_OK}, 1266 {"http://example.org", "?weird", 1267 "http://example.org/?weird", 0, 0, CURLUE_OK}, 1268 {"http://example.org/#original", "?weird#moo", 1269 "http://example.org/?weird#moo", 0, 0, CURLUE_OK}, 1270 1271 {"http://example.org?bar/moo#yes/path", "#new/slash", 1272 "http://example.org/?bar/moo#new/slash", 0, 0, CURLUE_OK}, 1273 {"http://example.org/foo?bar", "#weird", 1274 "http://example.org/foo?bar#weird", 0, 0, CURLUE_OK}, 1275 {"http://example.org/foo?bar#original", "#weird", 1276 "http://example.org/foo?bar#weird", 0, 0, CURLUE_OK}, 1277 {"http://example.org/foo#original", "#weird", 1278 "http://example.org/foo#weird", 0, 0, CURLUE_OK}, 1279 {"http://example.org/#original", "#weird", 1280 "http://example.org/#weird", 0, 0, CURLUE_OK}, 1281 {"http://example.org#original", "#weird", 1282 "http://example.org/#weird", 0, 0, CURLUE_OK}, 1283 {"http://example.org/foo?bar", "moo?hey#weird", 1284 "http://example.org/moo?hey#weird", 0, 0, CURLUE_OK}, 1285 {"http://example.org/", 1286 "../path/././../../moo", 1287 "http://example.org/moo", 1288 0, 0, CURLUE_OK}, 1289 {"http://example.org/", 1290 "//example.org/../path/../../", 1291 "http://example.org/", 1292 0, 0, CURLUE_OK}, 1293 {"http://example.org/", 1294 "///example.org/../path/../../", 1295 "http://example.org/", 1296 0, 0, CURLUE_OK}, 1297 {"http://example.org/foo/bar", 1298 ":23", 1299 "http://example.org/foo/:23", 1300 0, 0, CURLUE_OK}, 1301 {"http://example.org/foo/bar", 1302 "\\x", 1303 "http://example.org/foo/\\x", 1304 /* WHATWG disagrees */ 1305 0, 0, CURLUE_OK}, 1306 {"http://example.org/foo/bar", 1307 "#/", 1308 "http://example.org/foo/bar#/", 1309 0, 0, CURLUE_OK}, 1310 {"http://example.org/foo/bar", 1311 "?/", 1312 "http://example.org/foo/bar?/", 1313 0, 0, CURLUE_OK}, 1314 {"http://example.org/foo/bar", 1315 "#;?", 1316 "http://example.org/foo/bar#;?", 1317 0, 0, CURLUE_OK}, 1318 {"http://example.org/foo/bar", 1319 "#", 1320 "http://example.org/foo/bar", 1321 /* This happens because the parser removes empty fragments */ 1322 0, 0, CURLUE_OK}, 1323 {"http://example.org/foo/bar", 1324 "?", 1325 "http://example.org/foo/bar", 1326 /* This happens because the parser removes empty queries */ 1327 0, 0, CURLUE_OK}, 1328 {"http://example.org/foo/bar", 1329 "?#", 1330 "http://example.org/foo/bar", 1331 /* This happens because the parser removes empty queries and fragments */ 1332 0, 0, CURLUE_OK}, 1333 {"http://example.com/please/../gimme/%TESTNUMBER?foobar#hello", 1334 "http://example.net/there/it/is/../../tes t case=/%TESTNUMBER0002? yes no", 1335 "http://example.net/there/tes%20t%20case=/%TESTNUMBER0002?+yes+no", 1336 0, CURLU_URLENCODE|CURLU_ALLOW_SPACE, CURLUE_OK}, 1337 {"http://local.test?redirect=http://local.test:80?-321", 1338 "http://local.test:80?-123", 1339 "http://local.test:80/?-123", 1340 0, CURLU_URLENCODE|CURLU_ALLOW_SPACE, CURLUE_OK}, 1341 {"http://local.test?redirect=http://local.test:80?-321", 1342 "http://local.test:80?-123", 1343 "http://local.test:80/?-123", 1344 0, 0, CURLUE_OK}, 1345 {"http://example.org/static/favicon/wikipedia.ico", 1346 "//fake.example.com/licenses/by-sa/3.0/", 1347 "http://fake.example.com/licenses/by-sa/3.0/", 1348 0, 0, CURLUE_OK}, 1349 {"https://example.org/static/favicon/wikipedia.ico", 1350 "//fake.example.com/licenses/by-sa/3.0/", 1351 "https://fake.example.com/licenses/by-sa/3.0/", 1352 0, 0, CURLUE_OK}, 1353 {"file://localhost/path?query#frag", 1354 "foo#another", 1355 "file:///foo#another", 1356 0, 0, CURLUE_OK}, 1357 {"http://example.com/path?query#frag", 1358 "https://two.example.com/bradnew", 1359 "https://two.example.com/bradnew", 1360 0, 0, CURLUE_OK}, 1361 {"http://example.com/path?query#frag", 1362 "../../newpage#foo", 1363 "http://example.com/newpage#foo", 1364 0, 0, CURLUE_OK}, 1365 {"http://user:foo@example.com/path?query#frag", 1366 "../../newpage", 1367 "http://user:foo@example.com/newpage", 1368 0, 0, CURLUE_OK}, 1369 {"http://user:foo@example.com/path?query#frag", 1370 "../newpage", 1371 "http://user:foo@example.com/newpage", 1372 0, 0, CURLUE_OK}, 1373 {"http://user:foo@example.com/path?query#frag", 1374 "http://?hi", 1375 "http:///?hi", 1376 0, CURLU_NO_AUTHORITY, CURLUE_OK}, 1377 {NULL, NULL, NULL, 0, 0, CURLUE_OK} 1378 }; 1379 1380 static int set_url(void) 1381 { 1382 int i; 1383 int error = 0; 1384 1385 for(i = 0; set_url_list[i].in && !error; i++) { 1386 CURLUcode rc; 1387 CURLU *urlp = curl_url(); 1388 if(!urlp) 1389 break; 1390 rc = curl_url_set(urlp, CURLUPART_URL, set_url_list[i].in, 1391 set_url_list[i].urlflags); 1392 if(!rc) { 1393 rc = curl_url_set(urlp, CURLUPART_URL, set_url_list[i].set, 1394 set_url_list[i].setflags); 1395 if(rc) { 1396 curl_mfprintf(stderr, "%s:%d Set URL %s returned %d (%s)\n", 1397 __FILE__, __LINE__, set_url_list[i].set, 1398 (int)rc, curl_url_strerror(rc)); 1399 error++; 1400 } 1401 else { 1402 char *url = NULL; 1403 rc = curl_url_get(urlp, CURLUPART_URL, &url, 0); 1404 if(rc) { 1405 curl_mfprintf(stderr, "%s:%d Get URL returned %d (%s)\n", 1406 __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); 1407 error++; 1408 } 1409 else { 1410 if(checkurl(set_url_list[i].in, url, set_url_list[i].out)) { 1411 error++; 1412 } 1413 } 1414 curl_free(url); 1415 } 1416 } 1417 else if(rc != set_url_list[i].ucode) { 1418 curl_mfprintf(stderr, "Set URL\nin: %s\nreturned %d (expected %d)\n", 1419 set_url_list[i].in, (int)rc, set_url_list[i].ucode); 1420 error++; 1421 } 1422 curl_url_cleanup(urlp); 1423 } 1424 return error; 1425 } 1426 1427 /* 1. Set a URL 1428 2. Set one or more parts 1429 3. Extract and compare all parts - not the URL 1430 */ 1431 static int setget_parts(void) 1432 { 1433 int i; 1434 int error = 0; 1435 1436 for(i = 0; setget_parts_list[i].set && !error; i++) { 1437 CURLUcode rc; 1438 CURLU *urlp = curl_url(); 1439 if(!urlp) { 1440 error++; 1441 break; 1442 } 1443 if(setget_parts_list[i].in) 1444 rc = curl_url_set(urlp, CURLUPART_URL, setget_parts_list[i].in, 1445 setget_parts_list[i].urlflags); 1446 else 1447 rc = CURLUE_OK; 1448 if(!rc) { 1449 char *url = NULL; 1450 CURLUcode uc = updateurl(urlp, setget_parts_list[i].set, 1451 setget_parts_list[i].setflags); 1452 1453 if(uc != setget_parts_list[i].pcode) { 1454 curl_mfprintf(stderr, "updateurl\nin: %s\nreturned %d (expected %d)\n", 1455 setget_parts_list[i].set, 1456 (int)uc, setget_parts_list[i].pcode); 1457 error++; 1458 } 1459 if(!uc) { 1460 if(checkparts(urlp, setget_parts_list[i].set, setget_parts_list[i].out, 1461 setget_parts_list[i].getflags)) 1462 error++; /* add */ 1463 } 1464 curl_free(url); 1465 } 1466 else if(rc != CURLUE_OK) { 1467 curl_mfprintf(stderr, "Set parts\nin: %s\nreturned %d (expected %d)\n", 1468 setget_parts_list[i].in, (int)rc, 0); 1469 error++; 1470 } 1471 curl_url_cleanup(urlp); 1472 } 1473 return error; 1474 } 1475 1476 static int set_parts(void) 1477 { 1478 int i; 1479 int error = 0; 1480 1481 for(i = 0; set_parts_list[i].set && !error; i++) { 1482 CURLUcode rc; 1483 CURLU *urlp = curl_url(); 1484 if(!urlp) { 1485 error++; 1486 break; 1487 } 1488 if(set_parts_list[i].in) 1489 rc = curl_url_set(urlp, CURLUPART_URL, set_parts_list[i].in, 1490 set_parts_list[i].urlflags); 1491 else 1492 rc = CURLUE_OK; 1493 if(!rc) { 1494 char *url = NULL; 1495 CURLUcode uc = updateurl(urlp, set_parts_list[i].set, 1496 set_parts_list[i].setflags); 1497 1498 if(uc != set_parts_list[i].pcode) { 1499 curl_mfprintf(stderr, "updateurl\nin: %s\nreturned %d (expected %d)\n", 1500 set_parts_list[i].set, (int)uc, set_parts_list[i].pcode); 1501 error++; 1502 } 1503 if(!uc) { 1504 /* only do this if it worked */ 1505 rc = curl_url_get(urlp, CURLUPART_URL, &url, 0); 1506 1507 if(rc) { 1508 curl_mfprintf(stderr, "%s:%d Get URL returned %d (%s)\n", 1509 __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); 1510 error++; 1511 } 1512 else if(checkurl(set_parts_list[i].in, url, set_parts_list[i].out)) { 1513 error++; 1514 } 1515 } 1516 curl_free(url); 1517 } 1518 else if(rc != set_parts_list[i].ucode) { 1519 curl_mfprintf(stderr, "Set parts\nin: %s\nreturned %d (expected %d)\n", 1520 set_parts_list[i].in, (int)rc, set_parts_list[i].ucode); 1521 error++; 1522 } 1523 curl_url_cleanup(urlp); 1524 } 1525 return error; 1526 } 1527 1528 static int get_url(void) 1529 { 1530 int i; 1531 int error = 0; 1532 for(i = 0; get_url_list[i].in && !error; i++) { 1533 CURLUcode rc; 1534 CURLU *urlp = curl_url(); 1535 if(!urlp) { 1536 error++; 1537 break; 1538 } 1539 rc = curl_url_set(urlp, CURLUPART_URL, get_url_list[i].in, 1540 get_url_list[i].urlflags); 1541 if(!rc) { 1542 char *url = NULL; 1543 rc = curl_url_get(urlp, CURLUPART_URL, &url, get_url_list[i].getflags); 1544 1545 if(rc) { 1546 curl_mfprintf(stderr, "%s:%d returned %d (%s). URL: '%s'\n", 1547 __FILE__, __LINE__, (int)rc, curl_url_strerror(rc), 1548 get_url_list[i].in); 1549 error++; 1550 } 1551 else { 1552 if(checkurl(get_url_list[i].in, url, get_url_list[i].out)) { 1553 error++; 1554 } 1555 } 1556 curl_free(url); 1557 } 1558 if(rc != get_url_list[i].ucode) { 1559 curl_mfprintf(stderr, "Get URL\nin: %s\nreturned %d (expected %d)\n", 1560 get_url_list[i].in, (int)rc, get_url_list[i].ucode); 1561 error++; 1562 } 1563 curl_url_cleanup(urlp); 1564 } 1565 return error; 1566 } 1567 1568 static int get_parts(void) 1569 { 1570 int i; 1571 int error = 0; 1572 for(i = 0; get_parts_list[i].in && !error; i++) { 1573 CURLUcode rc; 1574 CURLU *urlp = curl_url(); 1575 if(!urlp) { 1576 error++; 1577 break; 1578 } 1579 rc = curl_url_set(urlp, CURLUPART_URL, 1580 get_parts_list[i].in, 1581 get_parts_list[i].urlflags); 1582 if(rc != get_parts_list[i].ucode) { 1583 curl_mfprintf(stderr, "Get parts\nin: %s\nreturned %d (expected %d)\n", 1584 get_parts_list[i].in, (int)rc, get_parts_list[i].ucode); 1585 error++; 1586 } 1587 else if(get_parts_list[i].ucode) { 1588 /* the expected error happened */ 1589 } 1590 else if(checkparts(urlp, get_parts_list[i].in, get_parts_list[i].out, 1591 get_parts_list[i].getflags)) 1592 error++; 1593 curl_url_cleanup(urlp); 1594 } 1595 return error; 1596 } 1597 1598 static const struct querycase append_list[] = { 1599 {"HTTP://test/?s", "name=joe\x02", "http://test/?s&name=joe%02", 1600 0, CURLU_URLENCODE, CURLUE_OK}, 1601 {"HTTP://test/?size=2#f", "name=joe=", "http://test/?size=2&name=joe%3D#f", 1602 0, CURLU_URLENCODE, CURLUE_OK}, 1603 {"HTTP://test/?size=2#f", "name=joe doe", 1604 "http://test/?size=2&name=joe+doe#f", 1605 0, CURLU_URLENCODE, CURLUE_OK}, 1606 {"HTTP://test/", "name=joe", "http://test/?name=joe", 0, 0, CURLUE_OK}, 1607 {"HTTP://test/?size=2", "name=joe", "http://test/?size=2&name=joe", 1608 0, 0, CURLUE_OK}, 1609 {"HTTP://test/?size=2&", "name=joe", "http://test/?size=2&name=joe", 1610 0, 0, CURLUE_OK}, 1611 {"HTTP://test/?size=2#f", "name=joe", "http://test/?size=2&name=joe#f", 1612 0, 0, CURLUE_OK}, 1613 {NULL, NULL, NULL, 0, 0, CURLUE_OK} 1614 }; 1615 1616 static int append(void) 1617 { 1618 int i; 1619 int error = 0; 1620 for(i = 0; append_list[i].in && !error; i++) { 1621 CURLUcode rc; 1622 CURLU *urlp = curl_url(); 1623 if(!urlp) { 1624 error++; 1625 break; 1626 } 1627 rc = curl_url_set(urlp, CURLUPART_URL, 1628 append_list[i].in, 1629 append_list[i].urlflags); 1630 if(rc) 1631 error++; 1632 else 1633 rc = curl_url_set(urlp, CURLUPART_QUERY, 1634 append_list[i].q, 1635 append_list[i].qflags | CURLU_APPENDQUERY); 1636 if(error) 1637 ; 1638 else if(rc != append_list[i].ucode) { 1639 curl_mfprintf(stderr, "Append\nin: %s\nreturned %d (expected %d)\n", 1640 append_list[i].in, (int)rc, append_list[i].ucode); 1641 error++; 1642 } 1643 else if(append_list[i].ucode) { 1644 /* the expected error happened */ 1645 } 1646 else { 1647 char *url; 1648 rc = curl_url_get(urlp, CURLUPART_URL, &url, 0); 1649 if(rc) { 1650 curl_mfprintf(stderr, "%s:%d Get URL returned %d (%s)\n", 1651 __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); 1652 error++; 1653 } 1654 else { 1655 if(checkurl(append_list[i].in, url, append_list[i].out)) { 1656 error++; 1657 } 1658 curl_free(url); 1659 } 1660 } 1661 curl_url_cleanup(urlp); 1662 } 1663 return error; 1664 } 1665 1666 static int scopeid(void) 1667 { 1668 CURLU *u = curl_url(); 1669 int error = 0; 1670 CURLUcode rc; 1671 char *url; 1672 1673 rc = curl_url_set(u, CURLUPART_URL, 1674 "https://[fe80::20c:29ff:fe9c:409b%25eth0]/hello.html", 0); 1675 if(rc != CURLUE_OK) { 1676 curl_mfprintf(stderr, "%s:%d curl_url_set returned %d (%s)\n", 1677 __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); 1678 error++; 1679 } 1680 1681 rc = curl_url_get(u, CURLUPART_HOST, &url, 0); 1682 if(rc != CURLUE_OK) { 1683 curl_mfprintf(stderr, 1684 "%s:%d curl_url_get CURLUPART_HOST returned %d (%s)\n", 1685 __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); 1686 error++; 1687 } 1688 else { 1689 curl_free(url); 1690 } 1691 1692 rc = curl_url_set(u, CURLUPART_HOST, "[::1]", 0); 1693 if(rc != CURLUE_OK) { 1694 curl_mfprintf(stderr, 1695 "%s:%d curl_url_set CURLUPART_HOST returned %d (%s)\n", 1696 __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); 1697 error++; 1698 } 1699 1700 rc = curl_url_get(u, CURLUPART_URL, &url, 0); 1701 if(rc != CURLUE_OK) { 1702 curl_mfprintf(stderr, 1703 "%s:%d curl_url_get CURLUPART_URL returned %d (%s)\n", 1704 __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); 1705 error++; 1706 } 1707 else { 1708 curl_free(url); 1709 } 1710 1711 rc = curl_url_set(u, CURLUPART_HOST, "example.com", 0); 1712 if(rc != CURLUE_OK) { 1713 curl_mfprintf(stderr, 1714 "%s:%d curl_url_set CURLUPART_HOST returned %d (%s)\n", 1715 __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); 1716 error++; 1717 } 1718 1719 rc = curl_url_get(u, CURLUPART_URL, &url, 0); 1720 if(rc != CURLUE_OK) { 1721 curl_mfprintf(stderr, 1722 "%s:%d curl_url_get CURLUPART_URL returned %d (%s)\n", 1723 __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); 1724 error++; 1725 } 1726 else { 1727 curl_free(url); 1728 } 1729 1730 rc = curl_url_set(u, CURLUPART_HOST, 1731 "[fe80::20c:29ff:fe9c:409b%25eth0]", 0); 1732 if(rc != CURLUE_OK) { 1733 curl_mfprintf(stderr, 1734 "%s:%d curl_url_set CURLUPART_HOST returned %d (%s)\n", 1735 __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); 1736 error++; 1737 } 1738 1739 rc = curl_url_get(u, CURLUPART_URL, &url, 0); 1740 if(rc != CURLUE_OK) { 1741 curl_mfprintf(stderr, 1742 "%s:%d curl_url_get CURLUPART_URL returned %d (%s)\n", 1743 __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); 1744 error++; 1745 } 1746 else { 1747 curl_free(url); 1748 } 1749 1750 rc = curl_url_get(u, CURLUPART_HOST, &url, 0); 1751 if(rc != CURLUE_OK) { 1752 curl_mfprintf(stderr, 1753 "%s:%d curl_url_get CURLUPART_HOST returned %d (%s)\n", 1754 __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); 1755 error++; 1756 } 1757 else { 1758 curl_free(url); 1759 } 1760 1761 rc = curl_url_get(u, CURLUPART_ZONEID, &url, 0); 1762 if(rc != CURLUE_OK) { 1763 curl_mfprintf(stderr, 1764 "%s:%d curl_url_get CURLUPART_ZONEID returned %d (%s)\n", 1765 __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); 1766 error++; 1767 } 1768 else { 1769 curl_free(url); 1770 } 1771 1772 rc = curl_url_set(u, CURLUPART_ZONEID, "clown", 0); 1773 if(rc != CURLUE_OK) { 1774 curl_mfprintf(stderr, 1775 "%s:%d curl_url_set CURLUPART_ZONEID returned %d (%s)\n", 1776 __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); 1777 error++; 1778 } 1779 1780 rc = curl_url_get(u, CURLUPART_URL, &url, 0); 1781 if(rc != CURLUE_OK) { 1782 curl_mfprintf(stderr, 1783 "%s:%d curl_url_get CURLUPART_URL returned %d (%s)\n", 1784 __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); 1785 error++; 1786 } 1787 else { 1788 curl_free(url); 1789 } 1790 1791 curl_url_cleanup(u); 1792 1793 return error; 1794 } 1795 1796 static int get_nothing(void) 1797 { 1798 CURLU *u = curl_url(); 1799 if(u) { 1800 char *p; 1801 CURLUcode rc; 1802 1803 rc = curl_url_get(u, CURLUPART_SCHEME, &p, 0); 1804 if(rc != CURLUE_NO_SCHEME) 1805 curl_mfprintf(stderr, "unexpected return code line %u\n", __LINE__); 1806 1807 rc = curl_url_get(u, CURLUPART_HOST, &p, 0); 1808 if(rc != CURLUE_NO_HOST) 1809 curl_mfprintf(stderr, "unexpected return code line %u\n", __LINE__); 1810 1811 rc = curl_url_get(u, CURLUPART_USER, &p, 0); 1812 if(rc != CURLUE_NO_USER) 1813 curl_mfprintf(stderr, "unexpected return code line %u\n", __LINE__); 1814 1815 rc = curl_url_get(u, CURLUPART_PASSWORD, &p, 0); 1816 if(rc != CURLUE_NO_PASSWORD) 1817 curl_mfprintf(stderr, "unexpected return code line %u\n", __LINE__); 1818 1819 rc = curl_url_get(u, CURLUPART_OPTIONS, &p, 0); 1820 if(rc != CURLUE_NO_OPTIONS) 1821 curl_mfprintf(stderr, "unexpected return code line %u\n", __LINE__); 1822 1823 rc = curl_url_get(u, CURLUPART_PATH, &p, 0); 1824 if(rc != CURLUE_OK) 1825 curl_mfprintf(stderr, "unexpected return code line %u\n", __LINE__); 1826 else 1827 curl_free(p); 1828 1829 rc = curl_url_get(u, CURLUPART_QUERY, &p, 0); 1830 if(rc != CURLUE_NO_QUERY) 1831 curl_mfprintf(stderr, "unexpected return code line %u\n", __LINE__); 1832 1833 rc = curl_url_get(u, CURLUPART_FRAGMENT, &p, 0); 1834 if(rc != CURLUE_NO_FRAGMENT) 1835 curl_mfprintf(stderr, "unexpected return code line %u\n", __LINE__); 1836 1837 rc = curl_url_get(u, CURLUPART_ZONEID, &p, 0); 1838 if(rc != CURLUE_NO_ZONEID) 1839 curl_mfprintf(stderr, "unexpected return code %u on line %u\n", (int)rc, 1840 __LINE__); 1841 1842 curl_url_cleanup(u); 1843 } 1844 return 0; 1845 } 1846 1847 static const struct clearurlcase clear_url_list[] ={ 1848 {CURLUPART_SCHEME, "http", NULL, CURLUE_NO_SCHEME}, 1849 {CURLUPART_USER, "user", NULL, CURLUE_NO_USER}, 1850 {CURLUPART_PASSWORD, "password", NULL, CURLUE_NO_PASSWORD}, 1851 {CURLUPART_OPTIONS, "options", NULL, CURLUE_NO_OPTIONS}, 1852 {CURLUPART_HOST, "host", NULL, CURLUE_NO_HOST}, 1853 {CURLUPART_ZONEID, "eth0", NULL, CURLUE_NO_ZONEID}, 1854 {CURLUPART_PORT, "1234", NULL, CURLUE_NO_PORT}, 1855 {CURLUPART_PATH, "/hello", "/", CURLUE_OK}, 1856 {CURLUPART_QUERY, "a=b", NULL, CURLUE_NO_QUERY}, 1857 {CURLUPART_FRAGMENT, "anchor", NULL, CURLUE_NO_FRAGMENT}, 1858 {CURLUPART_URL, NULL, NULL, CURLUE_OK}, 1859 }; 1860 1861 static int clear_url(void) 1862 { 1863 CURLU *u = curl_url(); 1864 int i, error = 0; 1865 if(u) { 1866 char *p = NULL; 1867 CURLUcode rc; 1868 1869 for(i = 0; clear_url_list[i].in && !error; i++) { 1870 rc = curl_url_set(u, clear_url_list[i].part, clear_url_list[i].in, 0); 1871 if(rc != CURLUE_OK) 1872 curl_mfprintf(stderr, "unexpected return code line %u\n", __LINE__); 1873 1874 rc = curl_url_set(u, CURLUPART_URL, NULL, 0); 1875 if(rc != CURLUE_OK) 1876 curl_mfprintf(stderr, "unexpected return code line %u\n", __LINE__); 1877 1878 rc = curl_url_get(u, clear_url_list[i].part, &p, 0); 1879 if(rc != clear_url_list[i].ucode || (clear_url_list[i].out && 1880 0 != strcmp(p, clear_url_list[i].out))) { 1881 1882 curl_mfprintf(stderr, "unexpected return code line %u\n", __LINE__); 1883 error++; 1884 } 1885 if(rc == CURLUE_OK) 1886 curl_free(p); 1887 } 1888 } 1889 1890 curl_url_cleanup(u); 1891 1892 return error; 1893 } 1894 1895 static char total[128000]; 1896 static char bigpart[120000]; 1897 1898 /* 1899 * verify ridiculous URL part sizes 1900 */ 1901 static int huge(void) 1902 { 1903 static const char *smallpart = "c"; 1904 int i; 1905 CURLU *urlp = curl_url(); 1906 CURLUcode rc; 1907 CURLUPart part[] = { 1908 CURLUPART_SCHEME, 1909 CURLUPART_USER, 1910 CURLUPART_PASSWORD, 1911 CURLUPART_HOST, 1912 CURLUPART_PATH, 1913 CURLUPART_QUERY, 1914 CURLUPART_FRAGMENT 1915 }; 1916 int error = 0; 1917 if(!urlp) 1918 return 1; 1919 bigpart[0] = '/'; /* for the path */ 1920 memset(&bigpart[1], 'a', sizeof(bigpart) - 2); 1921 bigpart[sizeof(bigpart) - 1] = 0; 1922 1923 for(i = 0; i < 7; i++) { 1924 char *partp; 1925 curl_msnprintf(total, sizeof(total), 1926 "%s://%s:%s@%s/%s?%s#%s", 1927 (i == 0) ? &bigpart[1] : smallpart, 1928 (i == 1) ? &bigpart[1] : smallpart, 1929 (i == 2) ? &bigpart[1] : smallpart, 1930 (i == 3) ? &bigpart[1] : smallpart, 1931 (i == 4) ? &bigpart[1] : smallpart, 1932 (i == 5) ? &bigpart[1] : smallpart, 1933 (i == 6) ? &bigpart[1] : smallpart); 1934 rc = curl_url_set(urlp, CURLUPART_URL, total, CURLU_NON_SUPPORT_SCHEME); 1935 if((!i && (rc != CURLUE_BAD_SCHEME)) || 1936 (i && rc)) { 1937 curl_mprintf("URL %u: failed to parse [%s]\n", i, total); 1938 error++; 1939 } 1940 1941 /* only extract if the parse worked */ 1942 if(!rc) { 1943 curl_url_get(urlp, part[i], &partp, 0); 1944 if(!partp || strcmp(partp, &bigpart[1 - (i == 4)])) { 1945 curl_mprintf("URL %u part %u: failure\n", i, part[i]); 1946 error++; 1947 } 1948 curl_free(partp); 1949 } 1950 } 1951 curl_url_cleanup(urlp); 1952 return error; 1953 } 1954 1955 static int urldup(void) 1956 { 1957 static const char *url[] = { 1958 "http://" 1959 "user:pwd@" 1960 "[2a04:4e42:e00::347%25eth0]" 1961 ":80" 1962 "/path" 1963 "?query" 1964 "#fraggie", 1965 "https://example.com", 1966 "https://user@example.com", 1967 "https://user.pwd@example.com", 1968 "https://user.pwd@example.com:1234", 1969 "https://example.com:1234", 1970 "example.com:1234", 1971 "https://user.pwd@example.com:1234/path?query#frag", 1972 NULL 1973 }; 1974 CURLU *copy = NULL; 1975 char *h_str = NULL, *copy_str = NULL; 1976 CURLU *h = curl_url(); 1977 int i; 1978 1979 if(!h) 1980 goto err; 1981 1982 for(i = 0; url[i]; i++) { 1983 CURLUcode rc = curl_url_set(h, CURLUPART_URL, url[i], 1984 CURLU_GUESS_SCHEME); 1985 if(rc) 1986 goto err; 1987 copy = curl_url_dup(h); 1988 1989 rc = curl_url_get(h, CURLUPART_URL, &h_str, 0); 1990 if(rc) 1991 goto err; 1992 1993 rc = curl_url_get(copy, CURLUPART_URL, ©_str, 0); 1994 if(rc) 1995 goto err; 1996 1997 if(strcmp(h_str, copy_str)) { 1998 curl_mprintf("Original: %s\nParsed: %s\nCopy: %s\n", 1999 url[i], h_str, copy_str); 2000 goto err; 2001 } 2002 curl_free(copy_str); 2003 curl_free(h_str); 2004 curl_url_cleanup(copy); 2005 copy_str = NULL; 2006 h_str = NULL; 2007 copy = NULL; 2008 } 2009 curl_url_cleanup(h); 2010 return 0; 2011 err: 2012 curl_free(copy_str); 2013 curl_free(h_str); 2014 curl_url_cleanup(copy); 2015 curl_url_cleanup(h); 2016 return 1; 2017 } 2018 2019 static CURLcode test_lib1560(char *URL) 2020 { 2021 (void)URL; /* not used */ 2022 2023 if(urldup()) 2024 return (CURLcode)11; 2025 2026 if(setget_parts()) 2027 return (CURLcode)10; 2028 2029 if(get_url()) 2030 return (CURLcode)3; 2031 2032 if(huge()) 2033 return (CURLcode)9; 2034 2035 if(get_nothing()) 2036 return (CURLcode)7; 2037 2038 if(scopeid()) 2039 return (CURLcode)6; 2040 2041 if(append()) 2042 return (CURLcode)5; 2043 2044 if(set_url()) 2045 return (CURLcode)1; 2046 2047 if(set_parts()) 2048 return (CURLcode)2; 2049 2050 if(get_parts()) 2051 return (CURLcode)4; 2052 2053 if(clear_url()) 2054 return (CURLcode)8; 2055 2056 curl_mprintf("success\n"); 2057 return CURLE_OK; 2058 }