| xf.li | 6c8fc1e | 2023-08-12 00:11:09 -0700 | [diff] [blame] | 1 | /*************************************************************************** | 
|  | 2 | *                                  _   _ ____  _ | 
|  | 3 | *  Project                     ___| | | |  _ \| | | 
|  | 4 | *                             / __| | | | |_) | | | 
|  | 5 | *                            | (__| |_| |  _ <| |___ | 
|  | 6 | *                             \___|\___/|_| \_\_____| | 
|  | 7 | * | 
|  | 8 | * Copyright (C) 1998 - 2022, 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 "test.h" | 
|  | 34 |  | 
|  | 35 | #include "testutil.h" | 
|  | 36 | #include "warnless.h" | 
|  | 37 | #include "memdebug.h" /* LAST include file */ | 
|  | 38 |  | 
|  | 39 | struct part { | 
|  | 40 | CURLUPart part; | 
|  | 41 | const char *name; | 
|  | 42 | }; | 
|  | 43 |  | 
|  | 44 |  | 
|  | 45 | static int checkparts(CURLU *u, const char *in, const char *wanted, | 
|  | 46 | unsigned int getflags) | 
|  | 47 | { | 
|  | 48 | int i; | 
|  | 49 | CURLUcode rc; | 
|  | 50 | char buf[256]; | 
|  | 51 | char *bufp = &buf[0]; | 
|  | 52 | size_t len = sizeof(buf); | 
|  | 53 | struct part parts[] = { | 
|  | 54 | {CURLUPART_SCHEME, "scheme"}, | 
|  | 55 | {CURLUPART_USER, "user"}, | 
|  | 56 | {CURLUPART_PASSWORD, "password"}, | 
|  | 57 | {CURLUPART_OPTIONS, "options"}, | 
|  | 58 | {CURLUPART_HOST, "host"}, | 
|  | 59 | {CURLUPART_PORT, "port"}, | 
|  | 60 | {CURLUPART_PATH, "path"}, | 
|  | 61 | {CURLUPART_QUERY, "query"}, | 
|  | 62 | {CURLUPART_FRAGMENT, "fragment"}, | 
|  | 63 | {CURLUPART_URL, NULL} | 
|  | 64 | }; | 
|  | 65 | memset(buf, 0, sizeof(buf)); | 
|  | 66 |  | 
|  | 67 | for(i = 0; parts[i].name; i++) { | 
|  | 68 | char *p = NULL; | 
|  | 69 | size_t n; | 
|  | 70 | rc = curl_url_get(u, parts[i].part, &p, getflags); | 
|  | 71 | if(!rc && p) { | 
|  | 72 | msnprintf(bufp, len, "%s%s", buf[0]?" | ":"", p); | 
|  | 73 | } | 
|  | 74 | else | 
|  | 75 | msnprintf(bufp, len, "%s[%d]", buf[0]?" | ":"", (int)rc); | 
|  | 76 |  | 
|  | 77 | n = strlen(bufp); | 
|  | 78 | bufp += n; | 
|  | 79 | len -= n; | 
|  | 80 | curl_free(p); | 
|  | 81 | } | 
|  | 82 | if(strcmp(buf, wanted)) { | 
|  | 83 | fprintf(stderr, "in: %s\nwanted: %s\ngot:    %s\n", in, wanted, buf); | 
|  | 84 | return 1; | 
|  | 85 | } | 
|  | 86 | return 0; | 
|  | 87 | } | 
|  | 88 |  | 
|  | 89 | struct redircase { | 
|  | 90 | const char *in; | 
|  | 91 | const char *set; | 
|  | 92 | const char *out; | 
|  | 93 | unsigned int urlflags; | 
|  | 94 | unsigned int setflags; | 
|  | 95 | CURLUcode ucode; | 
|  | 96 | }; | 
|  | 97 |  | 
|  | 98 | struct setcase { | 
|  | 99 | const char *in; | 
|  | 100 | const char *set; | 
|  | 101 | const char *out; | 
|  | 102 | unsigned int urlflags; | 
|  | 103 | unsigned int setflags; | 
|  | 104 | CURLUcode ucode; /* for the main URL set */ | 
|  | 105 | CURLUcode pcode; /* for updating parts */ | 
|  | 106 | }; | 
|  | 107 |  | 
|  | 108 | struct testcase { | 
|  | 109 | const char *in; | 
|  | 110 | const char *out; | 
|  | 111 | unsigned int urlflags; | 
|  | 112 | unsigned int getflags; | 
|  | 113 | CURLUcode ucode; | 
|  | 114 | }; | 
|  | 115 |  | 
|  | 116 | struct urltestcase { | 
|  | 117 | const char *in; | 
|  | 118 | const char *out; | 
|  | 119 | unsigned int urlflags; /* pass to curl_url() */ | 
|  | 120 | unsigned int getflags; /* pass to curl_url_get() */ | 
|  | 121 | CURLUcode ucode; | 
|  | 122 | }; | 
|  | 123 |  | 
|  | 124 | struct querycase { | 
|  | 125 | const char *in; | 
|  | 126 | const char *q; | 
|  | 127 | const char *out; | 
|  | 128 | unsigned int urlflags; /* pass to curl_url() */ | 
|  | 129 | unsigned int qflags; /* pass to curl_url_get() */ | 
|  | 130 | CURLUcode ucode; | 
|  | 131 | }; | 
|  | 132 |  | 
|  | 133 | struct clearurlcase { | 
|  | 134 | CURLUPart part; | 
|  | 135 | const char *in; | 
|  | 136 | const char *out; | 
|  | 137 | CURLUcode ucode; | 
|  | 138 | }; | 
|  | 139 |  | 
|  | 140 | static const struct testcase get_parts_list[] ={ | 
|  | 141 | {"https://user@example.net?he l lo", | 
|  | 142 | "https | user | [12] | [13] | example.net | [15] | / | he+l+lo | [17]", | 
|  | 143 | CURLU_ALLOW_SPACE, CURLU_URLENCODE, CURLUE_OK}, | 
|  | 144 | {"https://user@example.net?he l lo", | 
|  | 145 | "https | user | [12] | [13] | example.net | [15] | / | he l lo | [17]", | 
|  | 146 | CURLU_ALLOW_SPACE, 0, CURLUE_OK}, | 
|  | 147 | {"https://exam{}[]ple.net", "", 0, 0, CURLUE_BAD_HOSTNAME}, | 
|  | 148 | {"https://exam{ple.net", "", 0, 0, CURLUE_BAD_HOSTNAME}, | 
|  | 149 | {"https://exam}ple.net", "", 0, 0, CURLUE_BAD_HOSTNAME}, | 
|  | 150 | {"https://exam]ple.net", "", 0, 0, CURLUE_BAD_HOSTNAME}, | 
|  | 151 | {"https://exam\\ple.net", "", 0, 0, CURLUE_BAD_HOSTNAME}, | 
|  | 152 | {"https://exam$ple.net", "", 0, 0, CURLUE_BAD_HOSTNAME}, | 
|  | 153 | {"https://exam'ple.net", "", 0, 0, CURLUE_BAD_HOSTNAME}, | 
|  | 154 | {"https://exam\"ple.net", "", 0, 0, CURLUE_BAD_HOSTNAME}, | 
|  | 155 | {"https://exam^ple.net", "", 0, 0, CURLUE_BAD_HOSTNAME}, | 
|  | 156 | {"https://exam`ple.net", "", 0, 0, CURLUE_BAD_HOSTNAME}, | 
|  | 157 | {"https://exam*ple.net", "", 0, 0, CURLUE_BAD_HOSTNAME}, | 
|  | 158 | {"https://exam<ple.net", "", 0, 0, CURLUE_BAD_HOSTNAME}, | 
|  | 159 | {"https://exam>ple.net", "", 0, 0, CURLUE_BAD_HOSTNAME}, | 
|  | 160 | {"https://exam=ple.net", "", 0, 0, CURLUE_BAD_HOSTNAME}, | 
|  | 161 | {"https://exam;ple.net", "", 0, 0, CURLUE_BAD_HOSTNAME}, | 
|  | 162 | {"https://example,net", "", 0, 0, CURLUE_BAD_HOSTNAME}, | 
|  | 163 | {"https://example.net/}", | 
|  | 164 | "https | [11] | [12] | [13] | example.net | [15] | /} | [16] | [17]", | 
|  | 165 | 0, 0, CURLUE_OK}, | 
|  | 166 |  | 
|  | 167 | /* blank user is blank */ | 
|  | 168 | {"https://:password@example.net", | 
|  | 169 | "https |  | password | [13] | example.net | [15] | / | [16] | [17]", | 
|  | 170 | 0, 0, CURLUE_OK}, | 
|  | 171 | /* blank user + blank password */ | 
|  | 172 | {"https://:@example.net", | 
|  | 173 | "https |  |  | [13] | example.net | [15] | / | [16] | [17]", | 
|  | 174 | 0, 0, CURLUE_OK}, | 
|  | 175 | /* user-only (no password) */ | 
|  | 176 | {"https://user@example.net", | 
|  | 177 | "https | user | [12] | [13] | example.net | [15] | / | [16] | [17]", | 
|  | 178 | 0, 0, CURLUE_OK}, | 
|  | 179 | #ifdef USE_WEBSOCKETS | 
|  | 180 | {"ws://example.com/color/?green", | 
|  | 181 | "ws | [11] | [12] | [13] | example.com | [15] | /color/ | green |" | 
|  | 182 | " [17]", | 
|  | 183 | CURLU_DEFAULT_SCHEME, 0, CURLUE_OK }, | 
|  | 184 | {"wss://example.com/color/?green", | 
|  | 185 | "wss | [11] | [12] | [13] | example.com | [15] | /color/ | green |" | 
|  | 186 | " [17]", | 
|  | 187 | CURLU_DEFAULT_SCHEME, 0, CURLUE_OK }, | 
|  | 188 | #endif | 
|  | 189 |  | 
|  | 190 | {"https://user:password@example.net/get?this=and#but frag then", "", | 
|  | 191 | CURLU_DEFAULT_SCHEME, 0, CURLUE_BAD_FRAGMENT}, | 
|  | 192 | {"https://user:password@example.net/get?this=and what", "", | 
|  | 193 | CURLU_DEFAULT_SCHEME, 0, CURLUE_BAD_QUERY}, | 
|  | 194 | {"https://user:password@example.net/ge t?this=and-what", "", | 
|  | 195 | CURLU_DEFAULT_SCHEME, 0, CURLUE_BAD_PATH}, | 
|  | 196 | {"https://user:pass word@example.net/get?this=and-what", "", | 
|  | 197 | CURLU_DEFAULT_SCHEME, 0, CURLUE_BAD_PASSWORD}, | 
|  | 198 | {"https://u ser:password@example.net/get?this=and-what", "", | 
|  | 199 | CURLU_DEFAULT_SCHEME, 0, CURLUE_BAD_USER}, | 
|  | 200 | {"imap://user:pass;opt ion@server/path", "", | 
|  | 201 | CURLU_DEFAULT_SCHEME, 0, CURLUE_BAD_LOGIN}, | 
|  | 202 | /* no space allowed in scheme */ | 
|  | 203 | {"htt ps://user:password@example.net/get?this=and-what", "", | 
|  | 204 | CURLU_NON_SUPPORT_SCHEME|CURLU_ALLOW_SPACE, 0, CURLUE_BAD_SCHEME}, | 
|  | 205 | {"https://user:password@example.net/get?this=and what", | 
|  | 206 | "https | user | password | [13] | example.net | [15] | /get | " | 
|  | 207 | "this=and what | [17]", | 
|  | 208 | CURLU_ALLOW_SPACE, 0, CURLUE_OK}, | 
|  | 209 | {"https://user:password@example.net/ge t?this=and-what", | 
|  | 210 | "https | user | password | [13] | example.net | [15] | /ge t | " | 
|  | 211 | "this=and-what | [17]", | 
|  | 212 | CURLU_ALLOW_SPACE, 0, CURLUE_OK}, | 
|  | 213 | {"https://user:pass word@example.net/get?this=and-what", | 
|  | 214 | "https | user | pass word | [13] | example.net | [15] | /get | " | 
|  | 215 | "this=and-what | [17]", | 
|  | 216 | CURLU_ALLOW_SPACE, 0, CURLUE_OK}, | 
|  | 217 | {"https://u ser:password@example.net/get?this=and-what", | 
|  | 218 | "https | u ser | password | [13] | example.net | [15] | /get | " | 
|  | 219 | "this=and-what | [17]", | 
|  | 220 | CURLU_ALLOW_SPACE, 0, CURLUE_OK}, | 
|  | 221 | {"https://user:password@example.net/ge t?this=and-what", | 
|  | 222 | "https | user | password | [13] | example.net | [15] | /ge%20t | " | 
|  | 223 | "this=and-what | [17]", | 
|  | 224 | CURLU_ALLOW_SPACE | CURLU_URLENCODE, 0, CURLUE_OK}, | 
|  | 225 | {"[0:0:0:0:0:0:0:1]", | 
|  | 226 | "http | [11] | [12] | [13] | [::1] | [15] | / | [16] | [17]", | 
|  | 227 | CURLU_GUESS_SCHEME, 0, CURLUE_OK }, | 
|  | 228 | {"[::1]", | 
|  | 229 | "http | [11] | [12] | [13] | [::1] | [15] | / | [16] | [17]", | 
|  | 230 | CURLU_GUESS_SCHEME, 0, CURLUE_OK }, | 
|  | 231 | {"[::]", | 
|  | 232 | "http | [11] | [12] | [13] | [::] | [15] | / | [16] | [17]", | 
|  | 233 | CURLU_GUESS_SCHEME, 0, CURLUE_OK }, | 
|  | 234 | {"https://[::1]", | 
|  | 235 | "https | [11] | [12] | [13] | [::1] | [15] | / | [16] | [17]", | 
|  | 236 | 0, 0, CURLUE_OK }, | 
|  | 237 | {"user:moo@ftp.example.com/color/#green?no-red", | 
|  | 238 | "ftp | user | moo | [13] | ftp.example.com | [15] | /color/ | [16] | " | 
|  | 239 | "green?no-red", | 
|  | 240 | CURLU_GUESS_SCHEME, 0, CURLUE_OK }, | 
|  | 241 | {"ftp.user:moo@example.com/color/#green?no-red", | 
|  | 242 | "http | ftp.user | moo | [13] | example.com | [15] | /color/ | [16] | " | 
|  | 243 | "green?no-red", | 
|  | 244 | CURLU_GUESS_SCHEME, 0, CURLUE_OK }, | 
|  | 245 | #ifdef WIN32 | 
|  | 246 | {"file:/C:\\programs\\foo", | 
|  | 247 | "file | [11] | [12] | [13] | [14] | [15] | C:\\programs\\foo | [16] | [17]", | 
|  | 248 | CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, | 
|  | 249 | {"file://C:\\programs\\foo", | 
|  | 250 | "file | [11] | [12] | [13] | [14] | [15] | C:\\programs\\foo | [16] | [17]", | 
|  | 251 | CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, | 
|  | 252 | {"file:///C:\\programs\\foo", | 
|  | 253 | "file | [11] | [12] | [13] | [14] | [15] | C:\\programs\\foo | [16] | [17]", | 
|  | 254 | CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, | 
|  | 255 | {"file://host.example.com/Share/path/to/file.txt", | 
|  | 256 | "file | [11] | [12] | [13] | host.example.com | [15] | " | 
|  | 257 | "//host.example.com/Share/path/to/file.txt | [16] | [17]", | 
|  | 258 | CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, | 
|  | 259 | #endif | 
|  | 260 | {"https://example.com/color/#green?no-red", | 
|  | 261 | "https | [11] | [12] | [13] | example.com | [15] | /color/ | [16] | " | 
|  | 262 | "green?no-red", | 
|  | 263 | CURLU_DEFAULT_SCHEME, 0, CURLUE_OK }, | 
|  | 264 | {"https://example.com/color/#green#no-red", | 
|  | 265 | "https | [11] | [12] | [13] | example.com | [15] | /color/ | [16] | " | 
|  | 266 | "green#no-red", | 
|  | 267 | CURLU_DEFAULT_SCHEME, 0, CURLUE_OK }, | 
|  | 268 | {"https://example.com/color/?green#no-red", | 
|  | 269 | "https | [11] | [12] | [13] | example.com | [15] | /color/ | green | " | 
|  | 270 | "no-red", | 
|  | 271 | CURLU_DEFAULT_SCHEME, 0, CURLUE_OK }, | 
|  | 272 | {"https://example.com/#color/?green#no-red", | 
|  | 273 | "https | [11] | [12] | [13] | example.com | [15] | / | [16] | " | 
|  | 274 | "color/?green#no-red", | 
|  | 275 | CURLU_DEFAULT_SCHEME, 0, CURLUE_OK }, | 
|  | 276 | {"https://example.#com/color/?green#no-red", | 
|  | 277 | "https | [11] | [12] | [13] | example. | [15] | / | [16] | " | 
|  | 278 | "com/color/?green#no-red", | 
|  | 279 | CURLU_DEFAULT_SCHEME, 0, CURLUE_OK }, | 
|  | 280 | {"http://[ab.be:1]/x", "", | 
|  | 281 | CURLU_DEFAULT_SCHEME, 0, CURLUE_BAD_IPV6}, | 
|  | 282 | {"http://[ab.be]/x", "", | 
|  | 283 | CURLU_DEFAULT_SCHEME, 0, CURLUE_BAD_IPV6}, | 
|  | 284 | /* URL without host name */ | 
|  | 285 | {"http://a:b@/x", "", | 
|  | 286 | CURLU_DEFAULT_SCHEME, 0, CURLUE_NO_HOST}, | 
|  | 287 | {"boing:80", | 
|  | 288 | "https | [11] | [12] | [13] | boing | 80 | / | [16] | [17]", | 
|  | 289 | CURLU_DEFAULT_SCHEME|CURLU_GUESS_SCHEME, 0, CURLUE_OK}, | 
|  | 290 | {"http://[fd00:a41::50]:8080", | 
|  | 291 | "http | [11] | [12] | [13] | [fd00:a41::50] | 8080 | / | [16] | [17]", | 
|  | 292 | CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, | 
|  | 293 | {"http://[fd00:a41::50]/", | 
|  | 294 | "http | [11] | [12] | [13] | [fd00:a41::50] | [15] | / | [16] | [17]", | 
|  | 295 | CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, | 
|  | 296 | {"http://[fd00:a41::50]", | 
|  | 297 | "http | [11] | [12] | [13] | [fd00:a41::50] | [15] | / | [16] | [17]", | 
|  | 298 | CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, | 
|  | 299 | {"https://[::1%252]:1234", | 
|  | 300 | "https | [11] | [12] | [13] | [::1] | 1234 | / | [16] | [17]", | 
|  | 301 | CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, | 
|  | 302 |  | 
|  | 303 | /* here's "bad" zone id */ | 
|  | 304 | {"https://[fe80::20c:29ff:fe9c:409b%eth0]:1234", | 
|  | 305 | "https | [11] | [12] | [13] | [fe80::20c:29ff:fe9c:409b] | 1234 " | 
|  | 306 | "| / | [16] | [17]", | 
|  | 307 | CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, | 
|  | 308 | {"https://127.0.0.1:443", | 
|  | 309 | "https | [11] | [12] | [13] | 127.0.0.1 | [15] | / | [16] | [17]", | 
|  | 310 | 0, CURLU_NO_DEFAULT_PORT, CURLUE_OK}, | 
|  | 311 | {"http://%3a:%3a@ex4mple/%3f+?+%3f+%23#+%23%3f%g7", | 
|  | 312 | "http | : | : | [13] | ex4mple | [15] | /?+ |  ? # | +#?%g7", | 
|  | 313 | 0, CURLU_URLDECODE, CURLUE_OK}, | 
|  | 314 | {"http://%3a:%3a@ex4mple/%3f?%3f%35#%35%3f%g7", | 
|  | 315 | "http | %3a | %3a | [13] | ex4mple | [15] | /%3f | %3f%35 | %35%3f%g7", | 
|  | 316 | 0, 0, CURLUE_OK}, | 
|  | 317 | {"http://HO0_-st%41/", | 
|  | 318 | "http | [11] | [12] | [13] | HO0_-stA | [15] | / | [16] | [17]", | 
|  | 319 | 0, 0, CURLUE_OK}, | 
|  | 320 | {"file://hello.html", | 
|  | 321 | "", | 
|  | 322 | 0, 0, CURLUE_BAD_FILE_URL}, | 
|  | 323 | {"http://HO0_-st/", | 
|  | 324 | "http | [11] | [12] | [13] | HO0_-st | [15] | / | [16] | [17]", | 
|  | 325 | 0, 0, CURLUE_OK}, | 
|  | 326 | {"imap://user:pass;option@server/path", | 
|  | 327 | "imap | user | pass | option | server | [15] | /path | [16] | [17]", | 
|  | 328 | 0, 0, CURLUE_OK}, | 
|  | 329 | {"http://user:pass;option@server/path", | 
|  | 330 | "http | user | pass;option | [13] | server | [15] | /path | [16] | [17]", | 
|  | 331 | 0, 0, CURLUE_OK}, | 
|  | 332 | {"file:/hello.html", | 
|  | 333 | "file | [11] | [12] | [13] | [14] | [15] | /hello.html | [16] | [17]", | 
|  | 334 | 0, 0, CURLUE_OK}, | 
|  | 335 | {"file:/h", | 
|  | 336 | "file | [11] | [12] | [13] | [14] | [15] | /h | [16] | [17]", | 
|  | 337 | 0, 0, CURLUE_OK}, | 
|  | 338 | {"file:/", | 
|  | 339 | "file | [11] | [12] | [13] | [14] | [15] | | [16] | [17]", | 
|  | 340 | 0, 0, CURLUE_BAD_FILE_URL}, | 
|  | 341 | {"file://127.0.0.1/hello.html", | 
|  | 342 | "file | [11] | [12] | [13] | [14] | [15] | /hello.html | [16] | [17]", | 
|  | 343 | 0, 0, CURLUE_OK}, | 
|  | 344 | {"file:////hello.html", | 
|  | 345 | "file | [11] | [12] | [13] | [14] | [15] | //hello.html | [16] | [17]", | 
|  | 346 | 0, 0, CURLUE_OK}, | 
|  | 347 | {"file:///hello.html", | 
|  | 348 | "file | [11] | [12] | [13] | [14] | [15] | /hello.html | [16] | [17]", | 
|  | 349 | 0, 0, CURLUE_OK}, | 
|  | 350 | {"https://127.0.0.1", | 
|  | 351 | "https | [11] | [12] | [13] | 127.0.0.1 | 443 | / | [16] | [17]", | 
|  | 352 | 0, CURLU_DEFAULT_PORT, CURLUE_OK}, | 
|  | 353 | {"https://127.0.0.1", | 
|  | 354 | "https | [11] | [12] | [13] | 127.0.0.1 | [15] | / | [16] | [17]", | 
|  | 355 | CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, | 
|  | 356 | {"https://[::1]:1234", | 
|  | 357 | "https | [11] | [12] | [13] | [::1] | 1234 | / | [16] | [17]", | 
|  | 358 | CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, | 
|  | 359 | {"https://127abc.com", | 
|  | 360 | "https | [11] | [12] | [13] | 127abc.com | [15] | / | [16] | [17]", | 
|  | 361 | CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, | 
|  | 362 | {"https:// example.com?check", "", | 
|  | 363 | CURLU_DEFAULT_SCHEME, 0, CURLUE_BAD_HOSTNAME}, | 
|  | 364 | {"https://e x a m p l e.com?check", "", | 
|  | 365 | CURLU_DEFAULT_SCHEME, 0, CURLUE_BAD_HOSTNAME}, | 
|  | 366 | {"https://example.com?check", | 
|  | 367 | "https | [11] | [12] | [13] | example.com | [15] | / | check | [17]", | 
|  | 368 | CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, | 
|  | 369 | {"https://example.com:65536", | 
|  | 370 | "", | 
|  | 371 | CURLU_DEFAULT_SCHEME, 0, CURLUE_BAD_PORT_NUMBER}, | 
|  | 372 | {"https://example.com:-1#moo", | 
|  | 373 | "", | 
|  | 374 | CURLU_DEFAULT_SCHEME, 0, CURLUE_BAD_PORT_NUMBER}, | 
|  | 375 | {"https://example.com:0#moo", | 
|  | 376 | "https | [11] | [12] | [13] | example.com | 0 | / | " | 
|  | 377 | "[16] | moo", | 
|  | 378 | CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, | 
|  | 379 | {"https://example.com:01#moo", | 
|  | 380 | "https | [11] | [12] | [13] | example.com | 1 | / | " | 
|  | 381 | "[16] | moo", | 
|  | 382 | CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, | 
|  | 383 | {"https://example.com:1#moo", | 
|  | 384 | "https | [11] | [12] | [13] | example.com | 1 | / | " | 
|  | 385 | "[16] | moo", | 
|  | 386 | CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, | 
|  | 387 | {"http://example.com#moo", | 
|  | 388 | "http | [11] | [12] | [13] | example.com | [15] | / | " | 
|  | 389 | "[16] | moo", | 
|  | 390 | CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, | 
|  | 391 | {"http://example.com", | 
|  | 392 | "http | [11] | [12] | [13] | example.com | [15] | / | " | 
|  | 393 | "[16] | [17]", | 
|  | 394 | CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, | 
|  | 395 | {"http://example.com/path/html", | 
|  | 396 | "http | [11] | [12] | [13] | example.com | [15] | /path/html | " | 
|  | 397 | "[16] | [17]", | 
|  | 398 | CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, | 
|  | 399 | {"http://example.com/path/html?query=name", | 
|  | 400 | "http | [11] | [12] | [13] | example.com | [15] | /path/html | " | 
|  | 401 | "query=name | [17]", | 
|  | 402 | CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, | 
|  | 403 | {"http://example.com/path/html?query=name#anchor", | 
|  | 404 | "http | [11] | [12] | [13] | example.com | [15] | /path/html | " | 
|  | 405 | "query=name | anchor", | 
|  | 406 | CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, | 
|  | 407 | {"http://example.com:1234/path/html?query=name#anchor", | 
|  | 408 | "http | [11] | [12] | [13] | example.com | 1234 | /path/html | " | 
|  | 409 | "query=name | anchor", | 
|  | 410 | CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, | 
|  | 411 | {"http:///user:password@example.com:1234/path/html?query=name#anchor", | 
|  | 412 | "http | user | password | [13] | example.com | 1234 | /path/html | " | 
|  | 413 | "query=name | anchor", | 
|  | 414 | CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, | 
|  | 415 | {"https://user:password@example.com:1234/path/html?query=name#anchor", | 
|  | 416 | "https | user | password | [13] | example.com | 1234 | /path/html | " | 
|  | 417 | "query=name | anchor", | 
|  | 418 | CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, | 
|  | 419 | {"http://user:password@example.com:1234/path/html?query=name#anchor", | 
|  | 420 | "http | user | password | [13] | example.com | 1234 | /path/html | " | 
|  | 421 | "query=name | anchor", | 
|  | 422 | CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, | 
|  | 423 | {"http:/user:password@example.com:1234/path/html?query=name#anchor", | 
|  | 424 | "http | user | password | [13] | example.com | 1234 | /path/html | " | 
|  | 425 | "query=name | anchor", | 
|  | 426 | CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, | 
|  | 427 | {"http:////user:password@example.com:1234/path/html?query=name#anchor", | 
|  | 428 | "", | 
|  | 429 | CURLU_DEFAULT_SCHEME, 0, CURLUE_BAD_SLASHES}, | 
|  | 430 | {NULL, NULL, 0, 0, CURLUE_OK}, | 
|  | 431 | }; | 
|  | 432 |  | 
|  | 433 | static const struct urltestcase get_url_list[] = { | 
|  | 434 | /* unsupported schemes with no guessing enabled */ | 
|  | 435 | {"data:text/html;charset=utf-8;base64,PCFET0NUWVBFIEhUTUw+PG1ldGEgY", | 
|  | 436 | "", 0, 0, CURLUE_UNSUPPORTED_SCHEME}, | 
|  | 437 | {"d:anything-really", "", 0, 0, CURLUE_UNSUPPORTED_SCHEME}, | 
|  | 438 | {"about:config", "", 0, 0, CURLUE_UNSUPPORTED_SCHEME}, | 
|  | 439 | {"example://foo", "", 0, 0, CURLUE_UNSUPPORTED_SCHEME}, | 
|  | 440 | {"mailto:infobot@example.com?body=send%20current-issue", "", 0, 0, | 
|  | 441 | CURLUE_UNSUPPORTED_SCHEME}, | 
|  | 442 | {"about:80", "https://about:80/", CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, | 
|  | 443 | /* percent encoded host names */ | 
|  | 444 | {"http://example.com%40127.0.0.1/", "", 0, 0, CURLUE_BAD_HOSTNAME}, | 
|  | 445 | {"http://example.com%21127.0.0.1/", "", 0, 0, CURLUE_BAD_HOSTNAME}, | 
|  | 446 | {"http://example.com%3f127.0.0.1/", "", 0, 0, CURLUE_BAD_HOSTNAME}, | 
|  | 447 | {"http://example.com%23127.0.0.1/", "", 0, 0, CURLUE_BAD_HOSTNAME}, | 
|  | 448 | {"http://example.com%3a127.0.0.1/", "", 0, 0, CURLUE_BAD_HOSTNAME}, | 
|  | 449 | {"http://example.com%09127.0.0.1/", "", 0, 0, CURLUE_BAD_HOSTNAME}, | 
|  | 450 | {"http://example.com%2F127.0.0.1/", "", 0, 0, CURLUE_BAD_HOSTNAME}, | 
|  | 451 | {"https://%this", "https://%25this/", 0, 0, CURLUE_OK}, | 
|  | 452 | {"https://h%c", "https://h%25c/", 0, 0, CURLUE_OK}, | 
|  | 453 | {"https://%%%%%%", "https://%25%25%25%25%25%25/", 0, 0, CURLUE_OK}, | 
|  | 454 | {"https://%41", "https://A/", 0, 0, CURLUE_OK}, | 
|  | 455 | {"https://%20", "", 0, 0, CURLUE_BAD_HOSTNAME}, | 
|  | 456 | {"https://%41%0d", "", 0, 0, CURLUE_BAD_HOSTNAME}, | 
|  | 457 | {"https://%25", "https://%25/", 0, 0, CURLUE_OK}, | 
|  | 458 | {"https://_%c0_", "https://_\xC0_/", 0, 0, CURLUE_OK}, | 
|  | 459 | {"https://_%c0_", "https://_%C0_/", 0, CURLU_URLENCODE, CURLUE_OK}, | 
|  | 460 |  | 
|  | 461 | /* IPv4 trickeries */ | 
|  | 462 | {"https://16843009", "https://1.1.1.1/", 0, 0, CURLUE_OK}, | 
|  | 463 | {"https://0x7f.1", "https://127.0.0.1/", 0, 0, CURLUE_OK}, | 
|  | 464 | {"https://0177.1", "https://127.0.0.1/", 0, 0, CURLUE_OK}, | 
|  | 465 | {"https://0111.02.0x3", "https://73.2.0.3/", 0, 0, CURLUE_OK}, | 
|  | 466 | {"https://0xff.0xff.0377.255", "https://255.255.255.255/", 0, 0, CURLUE_OK}, | 
|  | 467 | {"https://1.0xffffff", "https://1.255.255.255/", 0, 0, CURLUE_OK}, | 
|  | 468 | /* IPv4 numerical overflows or syntax errors will not normalize */ | 
|  | 469 | {"https://+127.0.0.1", "https://+127.0.0.1/", 0, 0, CURLUE_OK}, | 
|  | 470 | {"https://+127.0.0.1", "https://%2B127.0.0.1/", 0, CURLU_URLENCODE, | 
|  | 471 | CURLUE_OK}, | 
|  | 472 | {"https://127.-0.0.1", "https://127.-0.0.1/", 0, 0, CURLUE_OK}, | 
|  | 473 | {"https://127.0. 1", "https://127.0.0.1/", 0, 0, CURLUE_BAD_HOSTNAME}, | 
|  | 474 | {"https://1.0x1000000", "https://1.0x1000000/", 0, 0, CURLUE_OK}, | 
|  | 475 | {"https://1.2.3.256", "https://1.2.3.256/", 0, 0, CURLUE_OK}, | 
|  | 476 | {"https://1.2.3.4.5", "https://1.2.3.4.5/", 0, 0, CURLUE_OK}, | 
|  | 477 | {"https://1.2.0x100.3", "https://1.2.0x100.3/", 0, 0, CURLUE_OK}, | 
|  | 478 | {"https://4294967296", "https://4294967296/", 0, 0, CURLUE_OK}, | 
|  | 479 | /* 40 bytes scheme is the max allowed */ | 
|  | 480 | {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA://hostname/path", | 
|  | 481 | "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa://hostname/path", | 
|  | 482 | CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_OK}, | 
|  | 483 | /* 41 bytes scheme is not allowed */ | 
|  | 484 | {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA://hostname/path", | 
|  | 485 | "", | 
|  | 486 | CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_BAD_SCHEME}, | 
|  | 487 | {"https://[fe80::20c:29ff:fe9c:409b%]:1234", | 
|  | 488 | "", | 
|  | 489 | 0, 0, CURLUE_BAD_IPV6}, | 
|  | 490 | {"https://[fe80::20c:29ff:fe9c:409b%25]:1234", | 
|  | 491 | "https://[fe80::20c:29ff:fe9c:409b%2525]:1234/", | 
|  | 492 | 0, 0, CURLUE_OK}, | 
|  | 493 | {"https://[fe80::20c:29ff:fe9c:409b%eth0]:1234", | 
|  | 494 | "https://[fe80::20c:29ff:fe9c:409b%25eth0]:1234/", | 
|  | 495 | 0, 0, CURLUE_OK}, | 
|  | 496 | {"https://[::%25fakeit]/moo", | 
|  | 497 | "https://[::%25fakeit]/moo", | 
|  | 498 | 0, 0, CURLUE_OK}, | 
|  | 499 | {"smtp.example.com/path/html", | 
|  | 500 | "smtp://smtp.example.com/path/html", | 
|  | 501 | CURLU_GUESS_SCHEME, 0, CURLUE_OK}, | 
|  | 502 | {"https.example.com/path/html", | 
|  | 503 | "http://https.example.com/path/html", | 
|  | 504 | CURLU_GUESS_SCHEME, 0, CURLUE_OK}, | 
|  | 505 | {"dict.example.com/path/html", | 
|  | 506 | "dict://dict.example.com/path/html", | 
|  | 507 | CURLU_GUESS_SCHEME, 0, CURLUE_OK}, | 
|  | 508 | {"pop3.example.com/path/html", | 
|  | 509 | "pop3://pop3.example.com/path/html", | 
|  | 510 | CURLU_GUESS_SCHEME, 0, CURLUE_OK}, | 
|  | 511 | {"ldap.example.com/path/html", | 
|  | 512 | "ldap://ldap.example.com/path/html", | 
|  | 513 | CURLU_GUESS_SCHEME, 0, CURLUE_OK}, | 
|  | 514 | {"imap.example.com/path/html", | 
|  | 515 | "imap://imap.example.com/path/html", | 
|  | 516 | CURLU_GUESS_SCHEME, 0, CURLUE_OK}, | 
|  | 517 | {"ftp.example.com/path/html", | 
|  | 518 | "ftp://ftp.example.com/path/html", | 
|  | 519 | CURLU_GUESS_SCHEME, 0, CURLUE_OK}, | 
|  | 520 | {"example.com/path/html", | 
|  | 521 | "http://example.com/path/html", | 
|  | 522 | CURLU_GUESS_SCHEME, 0, CURLUE_OK}, | 
|  | 523 | {"HTTP://test/", "http://test/", 0, 0, CURLUE_OK}, | 
|  | 524 | {"http://HO0_-st..~./", "http://HO0_-st..~./", 0, 0, CURLUE_OK}, | 
|  | 525 | {"http:/@example.com: 123/", "", 0, 0, CURLUE_BAD_PORT_NUMBER}, | 
|  | 526 | {"http:/@example.com:123 /", "", 0, 0, CURLUE_BAD_PORT_NUMBER}, | 
|  | 527 | {"http:/@example.com:123a/", "", 0, 0, CURLUE_BAD_PORT_NUMBER}, | 
|  | 528 | {"http://host/file\r", "", 0, 0, CURLUE_BAD_PATH}, | 
|  | 529 | {"http://host/file\n\x03", "", 0, 0, CURLUE_BAD_PATH}, | 
|  | 530 | {"htt\x02://host/file", "", | 
|  | 531 | CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_BAD_SCHEME}, | 
|  | 532 | {" http://host/file", "", 0, 0, CURLUE_BAD_SCHEME}, | 
|  | 533 | /* here the password ends at the semicolon and options is 'word' */ | 
|  | 534 | {"imap://user:pass;word@host/file", | 
|  | 535 | "imap://user:pass;word@host/file", | 
|  | 536 | 0, 0, CURLUE_OK}, | 
|  | 537 | /* here the password has the semicolon */ | 
|  | 538 | {"http://user:pass;word@host/file", | 
|  | 539 | "http://user:pass;word@host/file", | 
|  | 540 | 0, 0, CURLUE_OK}, | 
|  | 541 | {"file:///file.txt#moo", | 
|  | 542 | "file:///file.txt#moo", | 
|  | 543 | 0, 0, CURLUE_OK}, | 
|  | 544 | {"file:////file.txt", | 
|  | 545 | "file:////file.txt", | 
|  | 546 | 0, 0, CURLUE_OK}, | 
|  | 547 | {"file:///file.txt", | 
|  | 548 | "file:///file.txt", | 
|  | 549 | 0, 0, CURLUE_OK}, | 
|  | 550 | {"file:./", | 
|  | 551 | "file://", | 
|  | 552 | 0, 0, CURLUE_BAD_SCHEME}, | 
|  | 553 | {"http://example.com/hello/../here", | 
|  | 554 | "http://example.com/hello/../here", | 
|  | 555 | CURLU_PATH_AS_IS, 0, CURLUE_OK}, | 
|  | 556 | {"http://example.com/hello/../here", | 
|  | 557 | "http://example.com/here", | 
|  | 558 | 0, 0, CURLUE_OK}, | 
|  | 559 | {"http://example.com:80", | 
|  | 560 | "http://example.com/", | 
|  | 561 | 0, CURLU_NO_DEFAULT_PORT, CURLUE_OK}, | 
|  | 562 | {"tp://example.com/path/html", | 
|  | 563 | "", | 
|  | 564 | 0, 0, CURLUE_UNSUPPORTED_SCHEME}, | 
|  | 565 | {"http://hello:fool@example.com", | 
|  | 566 | "", | 
|  | 567 | CURLU_DISALLOW_USER, 0, CURLUE_USER_NOT_ALLOWED}, | 
|  | 568 | {"http:/@example.com:123", | 
|  | 569 | "http://@example.com:123/", | 
|  | 570 | 0, 0, CURLUE_OK}, | 
|  | 571 | {"http:/:password@example.com", | 
|  | 572 | "http://:password@example.com/", | 
|  | 573 | 0, 0, CURLUE_OK}, | 
|  | 574 | {"http://user@example.com?#", | 
|  | 575 | "http://user@example.com/", | 
|  | 576 | 0, 0, CURLUE_OK}, | 
|  | 577 | {"http://user@example.com?", | 
|  | 578 | "http://user@example.com/", | 
|  | 579 | 0, 0, CURLUE_OK}, | 
|  | 580 | {"http://user@example.com#anchor", | 
|  | 581 | "http://user@example.com/#anchor", | 
|  | 582 | 0, 0, CURLUE_OK}, | 
|  | 583 | {"example.com/path/html", | 
|  | 584 | "https://example.com/path/html", | 
|  | 585 | CURLU_DEFAULT_SCHEME, 0, CURLUE_OK}, | 
|  | 586 | {"example.com/path/html", | 
|  | 587 | "", | 
|  | 588 | 0, 0, CURLUE_BAD_SCHEME}, | 
|  | 589 | {"http://user:password@example.com:1234/path/html?query=name#anchor", | 
|  | 590 | "http://user:password@example.com:1234/path/html?query=name#anchor", | 
|  | 591 | 0, 0, CURLUE_OK}, | 
|  | 592 | {"http://example.com:1234/path/html?query=name#anchor", | 
|  | 593 | "http://example.com:1234/path/html?query=name#anchor", | 
|  | 594 | 0, 0, CURLUE_OK}, | 
|  | 595 | {"http://example.com/path/html?query=name#anchor", | 
|  | 596 | "http://example.com/path/html?query=name#anchor", | 
|  | 597 | 0, 0, CURLUE_OK}, | 
|  | 598 | {"http://example.com/path/html?query=name", | 
|  | 599 | "http://example.com/path/html?query=name", | 
|  | 600 | 0, 0, CURLUE_OK}, | 
|  | 601 | {"http://example.com/path/html", | 
|  | 602 | "http://example.com/path/html", | 
|  | 603 | 0, 0, CURLUE_OK}, | 
|  | 604 | {"tp://example.com/path/html", | 
|  | 605 | "tp://example.com/path/html", | 
|  | 606 | CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_OK}, | 
|  | 607 | {"custom-scheme://host?expected=test-good", | 
|  | 608 | "custom-scheme://host/?expected=test-good", | 
|  | 609 | CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_OK}, | 
|  | 610 | {"custom-scheme://?expected=test-bad", | 
|  | 611 | "", | 
|  | 612 | CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_NO_HOST}, | 
|  | 613 | {"custom-scheme://?expected=test-new-good", | 
|  | 614 | "custom-scheme:///?expected=test-new-good", | 
|  | 615 | CURLU_NON_SUPPORT_SCHEME | CURLU_NO_AUTHORITY, 0, CURLUE_OK}, | 
|  | 616 | {"custom-scheme://host?expected=test-still-good", | 
|  | 617 | "custom-scheme://host/?expected=test-still-good", | 
|  | 618 | CURLU_NON_SUPPORT_SCHEME | CURLU_NO_AUTHORITY, 0, CURLUE_OK}, | 
|  | 619 | {NULL, NULL, 0, 0, CURLUE_OK} | 
|  | 620 | }; | 
|  | 621 |  | 
|  | 622 | static int checkurl(const char *url, const char *out) | 
|  | 623 | { | 
|  | 624 | if(strcmp(out, url)) { | 
|  | 625 | fprintf(stderr, "Wanted: %s\nGot   : %s\n", | 
|  | 626 | out, url); | 
|  | 627 | return 1; | 
|  | 628 | } | 
|  | 629 | return 0; | 
|  | 630 | } | 
|  | 631 |  | 
|  | 632 | /* !checksrc! disable SPACEBEFORECOMMA 1 */ | 
|  | 633 | static const struct setcase set_parts_list[] = { | 
|  | 634 | {"https://example.com/", | 
|  | 635 | "host=++,", /* '++' there's no automatic URL decode when settin this | 
|  | 636 | part */ | 
|  | 637 | "https://++/", | 
|  | 638 | 0, /* get */ | 
|  | 639 | 0, /* set */ | 
|  | 640 | CURLUE_OK, CURLUE_OK}, | 
|  | 641 |  | 
|  | 642 | {"https://example.com/", | 
|  | 643 | "query=Al2cO3tDkcDZ3EWE5Lh+LX8TPHs,", /* contains '+' */ | 
|  | 644 | "https://example.com/?Al2cO3tDkcDZ3EWE5Lh%2bLX8TPHs", | 
|  | 645 | CURLU_URLDECODE, /* decode on get */ | 
|  | 646 | CURLU_URLENCODE, /* encode on set */ | 
|  | 647 | CURLUE_OK, CURLUE_OK}, | 
|  | 648 |  | 
|  | 649 | {"https://example.com/", | 
|  | 650 | /* Set a 41 bytes scheme. That's too long so the old scheme remains set. */ | 
|  | 651 | "scheme=bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc,", | 
|  | 652 | "https://example.com/", | 
|  | 653 | 0, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK, CURLUE_BAD_SCHEME}, | 
|  | 654 | {"https://example.com/", | 
|  | 655 | /* set a 40 bytes scheme */ | 
|  | 656 | "scheme=bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,", | 
|  | 657 | "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb://example.com/", | 
|  | 658 | 0, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK, CURLUE_OK}, | 
|  | 659 | {"https://[::1%25fake]:1234/", | 
|  | 660 | "zoneid=NULL,", | 
|  | 661 | "https://[::1]:1234/", | 
|  | 662 | 0, 0, CURLUE_OK, CURLUE_OK}, | 
|  | 663 | {"https://host:1234/", | 
|  | 664 | "port=NULL,", | 
|  | 665 | "https://host/", | 
|  | 666 | 0, 0, CURLUE_OK, CURLUE_OK}, | 
|  | 667 | {"https://host:1234/", | 
|  | 668 | "port=\"\",", | 
|  | 669 | "https://host:1234/", | 
|  | 670 | 0, 0, CURLUE_OK, CURLUE_BAD_PORT_NUMBER}, | 
|  | 671 | {"https://host:1234/", | 
|  | 672 | "port=56 78,", | 
|  | 673 | "https://host:1234/", | 
|  | 674 | 0, 0, CURLUE_OK, CURLUE_BAD_PORT_NUMBER}, | 
|  | 675 | {"https://host:1234/", | 
|  | 676 | "port=0,", | 
|  | 677 | "https://host:1234/", | 
|  | 678 | 0, 0, CURLUE_OK, CURLUE_BAD_PORT_NUMBER}, | 
|  | 679 | {"https://host:1234/", | 
|  | 680 | "port=65535,", | 
|  | 681 | "https://host:65535/", | 
|  | 682 | 0, 0, CURLUE_OK, CURLUE_OK}, | 
|  | 683 | {"https://host:1234/", | 
|  | 684 | "port=65536,", | 
|  | 685 | "https://host:1234/", | 
|  | 686 | 0, 0, CURLUE_OK, CURLUE_BAD_PORT_NUMBER}, | 
|  | 687 | {"https://host/", | 
|  | 688 | "path=%4A%4B%4C,", | 
|  | 689 | "https://host/%4a%4b%4c", | 
|  | 690 | 0, 0, CURLUE_OK, CURLUE_OK}, | 
|  | 691 | {"https://host/mooo?q#f", | 
|  | 692 | "path=NULL,query=NULL,fragment=NULL,", | 
|  | 693 | "https://host/", | 
|  | 694 | 0, 0, CURLUE_OK, CURLUE_OK}, | 
|  | 695 | {"https://user:secret@host/", | 
|  | 696 | "user=NULL,password=NULL,", | 
|  | 697 | "https://host/", | 
|  | 698 | 0, 0, CURLUE_OK, CURLUE_OK}, | 
|  | 699 | {NULL, | 
|  | 700 | "scheme=https,user=   @:,host=foobar,", | 
|  | 701 | "https://%20%20%20%40%3a@foobar/", | 
|  | 702 | 0, CURLU_URLENCODE, CURLUE_OK, CURLUE_OK}, | 
|  | 703 | /* Setting a host name with spaces is not OK: */ | 
|  | 704 | {NULL, | 
|  | 705 | "scheme=https,host=  ,path= ,user= ,password= ,query= ,fragment= ,", | 
|  | 706 | "[nothing]", | 
|  | 707 | 0, CURLU_URLENCODE, CURLUE_OK, CURLUE_BAD_HOSTNAME}, | 
|  | 708 | {NULL, | 
|  | 709 | "scheme=https,host=foobar,path=/this /path /is /here,", | 
|  | 710 | "https://foobar/this%20/path%20/is%20/here", | 
|  | 711 | 0, CURLU_URLENCODE, CURLUE_OK, CURLUE_OK}, | 
|  | 712 | {NULL, | 
|  | 713 | "scheme=https,host=foobar,path=\xc3\xa4\xc3\xb6\xc3\xbc,", | 
|  | 714 | "https://foobar/%c3%a4%c3%b6%c3%bc", | 
|  | 715 | 0, CURLU_URLENCODE, CURLUE_OK, CURLUE_OK}, | 
|  | 716 | {"imap://user:secret;opt@host/", | 
|  | 717 | "options=updated,scheme=imaps,password=p4ssw0rd,", | 
|  | 718 | "imaps://user:p4ssw0rd;updated@host/", | 
|  | 719 | 0, 0, CURLUE_NO_HOST, CURLUE_OK}, | 
|  | 720 | {"imap://user:secret;optit@host/", | 
|  | 721 | "scheme=https,", | 
|  | 722 | "https://user:secret@host/", | 
|  | 723 | 0, 0, CURLUE_NO_HOST, CURLUE_OK}, | 
|  | 724 | {"file:///file#anchor", | 
|  | 725 | "scheme=https,host=example,", | 
|  | 726 | "https://example/file#anchor", | 
|  | 727 | 0, 0, CURLUE_NO_HOST, CURLUE_OK}, | 
|  | 728 | {NULL, /* start fresh! */ | 
|  | 729 | "scheme=file,host=127.0.0.1,path=/no,user=anonymous,", | 
|  | 730 | "file:///no", | 
|  | 731 | 0, 0, CURLUE_OK, CURLUE_OK}, | 
|  | 732 | {NULL, /* start fresh! */ | 
|  | 733 | "scheme=ftp,host=127.0.0.1,path=/no,user=anonymous,", | 
|  | 734 | "ftp://anonymous@127.0.0.1/no", | 
|  | 735 | 0, 0, CURLUE_OK, CURLUE_OK}, | 
|  | 736 | {NULL, /* start fresh! */ | 
|  | 737 | "scheme=https,host=example.com,", | 
|  | 738 | "https://example.com/", | 
|  | 739 | 0, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK, CURLUE_OK}, | 
|  | 740 | {"http://user:foo@example.com/path?query#frag", | 
|  | 741 | "fragment=changed,", | 
|  | 742 | "http://user:foo@example.com/path?query#changed", | 
|  | 743 | 0, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK, CURLUE_OK}, | 
|  | 744 | {"http://example.com/", | 
|  | 745 | "scheme=foo,", /* not accepted */ | 
|  | 746 | "http://example.com/", | 
|  | 747 | 0, 0, CURLUE_OK, CURLUE_UNSUPPORTED_SCHEME}, | 
|  | 748 | {"http://example.com/", | 
|  | 749 | "scheme=https,path=/hello,fragment=snippet,", | 
|  | 750 | "https://example.com/hello#snippet", | 
|  | 751 | 0, 0, CURLUE_OK, CURLUE_OK}, | 
|  | 752 | {"http://example.com:80", | 
|  | 753 | "user=foo,port=1922,", | 
|  | 754 | "http://foo@example.com:1922/", | 
|  | 755 | 0, 0, CURLUE_OK, CURLUE_OK}, | 
|  | 756 | {"http://example.com:80", | 
|  | 757 | "user=foo,password=bar,", | 
|  | 758 | "http://foo:bar@example.com:80/", | 
|  | 759 | 0, 0, CURLUE_OK, CURLUE_OK}, | 
|  | 760 | {"http://example.com:80", | 
|  | 761 | "user=foo,", | 
|  | 762 | "http://foo@example.com:80/", | 
|  | 763 | 0, 0, CURLUE_OK, CURLUE_OK}, | 
|  | 764 | {"http://example.com", | 
|  | 765 | "host=www.example.com,", | 
|  | 766 | "http://www.example.com/", | 
|  | 767 | 0, 0, CURLUE_OK, CURLUE_OK}, | 
|  | 768 | {"http://example.com:80", | 
|  | 769 | "scheme=ftp,", | 
|  | 770 | "ftp://example.com:80/", | 
|  | 771 | 0, 0, CURLUE_OK, CURLUE_OK}, | 
|  | 772 | {"custom-scheme://host", | 
|  | 773 | "host=\"\",", | 
|  | 774 | "custom-scheme://host/", | 
|  | 775 | CURLU_NON_SUPPORT_SCHEME, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK, | 
|  | 776 | CURLUE_BAD_HOSTNAME}, | 
|  | 777 | {"custom-scheme://host", | 
|  | 778 | "host=\"\",", | 
|  | 779 | "custom-scheme:///", | 
|  | 780 | CURLU_NON_SUPPORT_SCHEME, CURLU_NON_SUPPORT_SCHEME | CURLU_NO_AUTHORITY, | 
|  | 781 | CURLUE_OK, CURLUE_OK}, | 
|  | 782 |  | 
|  | 783 | {NULL, NULL, NULL, 0, 0, CURLUE_OK, CURLUE_OK} | 
|  | 784 | }; | 
|  | 785 |  | 
|  | 786 | static CURLUPart part2id(char *part) | 
|  | 787 | { | 
|  | 788 | if(!strcmp("url", part)) | 
|  | 789 | return CURLUPART_URL; | 
|  | 790 | if(!strcmp("scheme", part)) | 
|  | 791 | return CURLUPART_SCHEME; | 
|  | 792 | if(!strcmp("user", part)) | 
|  | 793 | return CURLUPART_USER; | 
|  | 794 | if(!strcmp("password", part)) | 
|  | 795 | return CURLUPART_PASSWORD; | 
|  | 796 | if(!strcmp("options", part)) | 
|  | 797 | return CURLUPART_OPTIONS; | 
|  | 798 | if(!strcmp("host", part)) | 
|  | 799 | return CURLUPART_HOST; | 
|  | 800 | if(!strcmp("port", part)) | 
|  | 801 | return CURLUPART_PORT; | 
|  | 802 | if(!strcmp("path", part)) | 
|  | 803 | return CURLUPART_PATH; | 
|  | 804 | if(!strcmp("query", part)) | 
|  | 805 | return CURLUPART_QUERY; | 
|  | 806 | if(!strcmp("fragment", part)) | 
|  | 807 | return CURLUPART_FRAGMENT; | 
|  | 808 | if(!strcmp("zoneid", part)) | 
|  | 809 | return CURLUPART_ZONEID; | 
|  | 810 | return (CURLUPart)9999; /* bad input => bad output */ | 
|  | 811 | } | 
|  | 812 |  | 
|  | 813 | static CURLUcode updateurl(CURLU *u, const char *cmd, unsigned int setflags) | 
|  | 814 | { | 
|  | 815 | const char *p = cmd; | 
|  | 816 | CURLUcode uc; | 
|  | 817 |  | 
|  | 818 | /* make sure the last command ends with a comma too! */ | 
|  | 819 | while(p) { | 
|  | 820 | char *e = strchr(p, ','); | 
|  | 821 | if(e) { | 
|  | 822 | size_t n = e-p; | 
|  | 823 | char buf[80]; | 
|  | 824 | char part[80]; | 
|  | 825 | char value[80]; | 
|  | 826 |  | 
|  | 827 | memset(part, 0, sizeof(part)); /* Avoid valgrind false positive. */ | 
|  | 828 | memset(value, 0, sizeof(value)); /* Avoid valgrind false positive. */ | 
|  | 829 | memcpy(buf, p, n); | 
|  | 830 | buf[n] = 0; | 
|  | 831 | if(2 == sscanf(buf, "%79[^=]=%79[^,]", part, value)) { | 
|  | 832 | CURLUPart what = part2id(part); | 
|  | 833 | #if 0 | 
|  | 834 | /* for debugging this */ | 
|  | 835 | fprintf(stderr, "%s = \"%s\" [%d]\n", part, value, (int)what); | 
|  | 836 | #endif | 
|  | 837 | if(what > CURLUPART_ZONEID) | 
|  | 838 | fprintf(stderr, "UNKNOWN part '%s'\n", part); | 
|  | 839 |  | 
|  | 840 | if(!strcmp("NULL", value)) | 
|  | 841 | uc = curl_url_set(u, what, NULL, setflags); | 
|  | 842 | else if(!strcmp("\"\"", value)) | 
|  | 843 | uc = curl_url_set(u, what, "", setflags); | 
|  | 844 | else | 
|  | 845 | uc = curl_url_set(u, what, value, setflags); | 
|  | 846 | if(uc) | 
|  | 847 | return uc; | 
|  | 848 | } | 
|  | 849 | p = e + 1; | 
|  | 850 | continue; | 
|  | 851 | } | 
|  | 852 | break; | 
|  | 853 | } | 
|  | 854 | return CURLUE_OK; | 
|  | 855 | } | 
|  | 856 |  | 
|  | 857 | static const struct redircase set_url_list[] = { | 
|  | 858 | {"http://example.com/please/../gimme/%TESTNUMBER?foobar#hello", | 
|  | 859 | "http://example.net/there/it/is/../../tes t case=/%TESTNUMBER0002? yes no", | 
|  | 860 | "http://example.net/there/tes%20t%20case=/%TESTNUMBER0002?+yes+no", | 
|  | 861 | 0, CURLU_URLENCODE|CURLU_ALLOW_SPACE, CURLUE_OK}, | 
|  | 862 | {"http://local.test?redirect=http://local.test:80?-321", | 
|  | 863 | "http://local.test:80?-123", | 
|  | 864 | "http://local.test:80/?-123", | 
|  | 865 | 0, CURLU_URLENCODE|CURLU_ALLOW_SPACE, CURLUE_OK}, | 
|  | 866 | {"http://local.test?redirect=http://local.test:80?-321", | 
|  | 867 | "http://local.test:80?-123", | 
|  | 868 | "http://local.test:80/?-123", | 
|  | 869 | 0, 0, CURLUE_OK}, | 
|  | 870 | {"http://example.org/static/favicon/wikipedia.ico", | 
|  | 871 | "//fake.example.com/licenses/by-sa/3.0/", | 
|  | 872 | "http://fake.example.com/licenses/by-sa/3.0/", | 
|  | 873 | 0, 0, CURLUE_OK}, | 
|  | 874 | {"https://example.org/static/favicon/wikipedia.ico", | 
|  | 875 | "//fake.example.com/licenses/by-sa/3.0/", | 
|  | 876 | "https://fake.example.com/licenses/by-sa/3.0/", | 
|  | 877 | 0, 0, CURLUE_OK}, | 
|  | 878 | {"file://localhost/path?query#frag", | 
|  | 879 | "foo#another", | 
|  | 880 | "file:///foo#another", | 
|  | 881 | 0, 0, CURLUE_OK}, | 
|  | 882 | {"http://example.com/path?query#frag", | 
|  | 883 | "https://two.example.com/bradnew", | 
|  | 884 | "https://two.example.com/bradnew", | 
|  | 885 | 0, 0, CURLUE_OK}, | 
|  | 886 | {"http://example.com/path?query#frag", | 
|  | 887 | "../../newpage#foo", | 
|  | 888 | "http://example.com/newpage#foo", | 
|  | 889 | 0, 0, CURLUE_OK}, | 
|  | 890 | {"http://user:foo@example.com/path?query#frag", | 
|  | 891 | "../../newpage", | 
|  | 892 | "http://user:foo@example.com/newpage", | 
|  | 893 | 0, 0, CURLUE_OK}, | 
|  | 894 | {"http://user:foo@example.com/path?query#frag", | 
|  | 895 | "../newpage", | 
|  | 896 | "http://user:foo@example.com/newpage", | 
|  | 897 | 0, 0, CURLUE_OK}, | 
|  | 898 | {NULL, NULL, NULL, 0, 0, CURLUE_OK} | 
|  | 899 | }; | 
|  | 900 |  | 
|  | 901 | static int set_url(void) | 
|  | 902 | { | 
|  | 903 | int i; | 
|  | 904 | int error = 0; | 
|  | 905 |  | 
|  | 906 | for(i = 0; set_url_list[i].in && !error; i++) { | 
|  | 907 | CURLUcode rc; | 
|  | 908 | CURLU *urlp = curl_url(); | 
|  | 909 | if(!urlp) | 
|  | 910 | break; | 
|  | 911 | rc = curl_url_set(urlp, CURLUPART_URL, set_url_list[i].in, | 
|  | 912 | set_url_list[i].urlflags); | 
|  | 913 | if(!rc) { | 
|  | 914 | rc = curl_url_set(urlp, CURLUPART_URL, set_url_list[i].set, | 
|  | 915 | set_url_list[i].setflags); | 
|  | 916 | if(rc) { | 
|  | 917 | fprintf(stderr, "%s:%d Set URL %s returned %d (%s)\n", | 
|  | 918 | __FILE__, __LINE__, set_url_list[i].set, | 
|  | 919 | (int)rc, curl_url_strerror(rc)); | 
|  | 920 | error++; | 
|  | 921 | } | 
|  | 922 | else { | 
|  | 923 | char *url = NULL; | 
|  | 924 | rc = curl_url_get(urlp, CURLUPART_URL, &url, 0); | 
|  | 925 | if(rc) { | 
|  | 926 | fprintf(stderr, "%s:%d Get URL returned %d (%s)\n", | 
|  | 927 | __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); | 
|  | 928 | error++; | 
|  | 929 | } | 
|  | 930 | else { | 
|  | 931 | if(checkurl(url, set_url_list[i].out)) { | 
|  | 932 | error++; | 
|  | 933 | } | 
|  | 934 | } | 
|  | 935 | curl_free(url); | 
|  | 936 | } | 
|  | 937 | } | 
|  | 938 | else if(rc != set_url_list[i].ucode) { | 
|  | 939 | fprintf(stderr, "Set URL\nin: %s\nreturned %d (expected %d)\n", | 
|  | 940 | set_url_list[i].in, (int)rc, set_url_list[i].ucode); | 
|  | 941 | error++; | 
|  | 942 | } | 
|  | 943 | curl_url_cleanup(urlp); | 
|  | 944 | } | 
|  | 945 | return error; | 
|  | 946 | } | 
|  | 947 |  | 
|  | 948 | static int set_parts(void) | 
|  | 949 | { | 
|  | 950 | int i; | 
|  | 951 | int error = 0; | 
|  | 952 |  | 
|  | 953 | for(i = 0; set_parts_list[i].set && !error; i++) { | 
|  | 954 | CURLUcode rc; | 
|  | 955 | CURLU *urlp = curl_url(); | 
|  | 956 | if(!urlp) { | 
|  | 957 | error++; | 
|  | 958 | break; | 
|  | 959 | } | 
|  | 960 | if(set_parts_list[i].in) | 
|  | 961 | rc = curl_url_set(urlp, CURLUPART_URL, set_parts_list[i].in, | 
|  | 962 | set_parts_list[i].urlflags); | 
|  | 963 | else | 
|  | 964 | rc = CURLUE_OK; | 
|  | 965 | if(!rc) { | 
|  | 966 | char *url = NULL; | 
|  | 967 | CURLUcode uc = updateurl(urlp, set_parts_list[i].set, | 
|  | 968 | set_parts_list[i].setflags); | 
|  | 969 |  | 
|  | 970 | if(uc != set_parts_list[i].pcode) { | 
|  | 971 | fprintf(stderr, "updateurl\nin: %s\nreturned %d (expected %d)\n", | 
|  | 972 | set_parts_list[i].set, (int)uc, set_parts_list[i].pcode); | 
|  | 973 | error++; | 
|  | 974 | } | 
|  | 975 | if(!uc) { | 
|  | 976 | /* only do this if it worked */ | 
|  | 977 | rc = curl_url_get(urlp, CURLUPART_URL, &url, 0); | 
|  | 978 |  | 
|  | 979 | if(rc) { | 
|  | 980 | fprintf(stderr, "%s:%d Get URL returned %d (%s)\n", | 
|  | 981 | __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); | 
|  | 982 | error++; | 
|  | 983 | } | 
|  | 984 | else if(checkurl(url, set_parts_list[i].out)) { | 
|  | 985 | error++; | 
|  | 986 | } | 
|  | 987 | } | 
|  | 988 | curl_free(url); | 
|  | 989 | } | 
|  | 990 | else if(rc != set_parts_list[i].ucode) { | 
|  | 991 | fprintf(stderr, "Set parts\nin: %s\nreturned %d (expected %d)\n", | 
|  | 992 | set_parts_list[i].in, (int)rc, set_parts_list[i].ucode); | 
|  | 993 | error++; | 
|  | 994 | } | 
|  | 995 | curl_url_cleanup(urlp); | 
|  | 996 | } | 
|  | 997 | return error; | 
|  | 998 | } | 
|  | 999 |  | 
|  | 1000 | static int get_url(void) | 
|  | 1001 | { | 
|  | 1002 | int i; | 
|  | 1003 | int error = 0; | 
|  | 1004 | for(i = 0; get_url_list[i].in && !error; i++) { | 
|  | 1005 | CURLUcode rc; | 
|  | 1006 | CURLU *urlp = curl_url(); | 
|  | 1007 | if(!urlp) { | 
|  | 1008 | error++; | 
|  | 1009 | break; | 
|  | 1010 | } | 
|  | 1011 | rc = curl_url_set(urlp, CURLUPART_URL, get_url_list[i].in, | 
|  | 1012 | get_url_list[i].urlflags); | 
|  | 1013 | if(!rc) { | 
|  | 1014 | char *url = NULL; | 
|  | 1015 | rc = curl_url_get(urlp, CURLUPART_URL, &url, get_url_list[i].getflags); | 
|  | 1016 |  | 
|  | 1017 | if(rc) { | 
|  | 1018 | fprintf(stderr, "%s:%d returned %d (%s). URL: '%s'\n", | 
|  | 1019 | __FILE__, __LINE__, (int)rc, curl_url_strerror(rc), | 
|  | 1020 | get_url_list[i].in); | 
|  | 1021 | error++; | 
|  | 1022 | } | 
|  | 1023 | else { | 
|  | 1024 | if(checkurl(url, get_url_list[i].out)) { | 
|  | 1025 | error++; | 
|  | 1026 | } | 
|  | 1027 | } | 
|  | 1028 | curl_free(url); | 
|  | 1029 | } | 
|  | 1030 | else if(rc != get_url_list[i].ucode) { | 
|  | 1031 | fprintf(stderr, "Get URL\nin: %s\nreturned %d (expected %d)\n", | 
|  | 1032 | get_url_list[i].in, (int)rc, get_url_list[i].ucode); | 
|  | 1033 | error++; | 
|  | 1034 | } | 
|  | 1035 | curl_url_cleanup(urlp); | 
|  | 1036 | } | 
|  | 1037 | return error; | 
|  | 1038 | } | 
|  | 1039 |  | 
|  | 1040 | static int get_parts(void) | 
|  | 1041 | { | 
|  | 1042 | int i; | 
|  | 1043 | int error = 0; | 
|  | 1044 | for(i = 0; get_parts_list[i].in && !error; i++) { | 
|  | 1045 | CURLUcode rc; | 
|  | 1046 | CURLU *urlp = curl_url(); | 
|  | 1047 | if(!urlp) { | 
|  | 1048 | error++; | 
|  | 1049 | break; | 
|  | 1050 | } | 
|  | 1051 | rc = curl_url_set(urlp, CURLUPART_URL, | 
|  | 1052 | get_parts_list[i].in, | 
|  | 1053 | get_parts_list[i].urlflags); | 
|  | 1054 | if(rc != get_parts_list[i].ucode) { | 
|  | 1055 | fprintf(stderr, "Get parts\nin: %s\nreturned %d (expected %d)\n", | 
|  | 1056 | get_parts_list[i].in, (int)rc, get_parts_list[i].ucode); | 
|  | 1057 | error++; | 
|  | 1058 | } | 
|  | 1059 | else if(get_parts_list[i].ucode) { | 
|  | 1060 | /* the expected error happened */ | 
|  | 1061 | } | 
|  | 1062 | else if(checkparts(urlp, get_parts_list[i].in, get_parts_list[i].out, | 
|  | 1063 | get_parts_list[i].getflags)) | 
|  | 1064 | error++; | 
|  | 1065 | curl_url_cleanup(urlp); | 
|  | 1066 | } | 
|  | 1067 | return error; | 
|  | 1068 | } | 
|  | 1069 |  | 
|  | 1070 | static const struct querycase append_list[] = { | 
|  | 1071 | {"HTTP://test/?s", "name=joe\x02", "http://test/?s&name=joe%02", | 
|  | 1072 | 0, CURLU_URLENCODE, CURLUE_OK}, | 
|  | 1073 | {"HTTP://test/?size=2#f", "name=joe=", "http://test/?size=2&name=joe%3d#f", | 
|  | 1074 | 0, CURLU_URLENCODE, CURLUE_OK}, | 
|  | 1075 | {"HTTP://test/?size=2#f", "name=joe doe", | 
|  | 1076 | "http://test/?size=2&name=joe+doe#f", | 
|  | 1077 | 0, CURLU_URLENCODE, CURLUE_OK}, | 
|  | 1078 | {"HTTP://test/", "name=joe", "http://test/?name=joe", 0, 0, CURLUE_OK}, | 
|  | 1079 | {"HTTP://test/?size=2", "name=joe", "http://test/?size=2&name=joe", | 
|  | 1080 | 0, 0, CURLUE_OK}, | 
|  | 1081 | {"HTTP://test/?size=2&", "name=joe", "http://test/?size=2&name=joe", | 
|  | 1082 | 0, 0, CURLUE_OK}, | 
|  | 1083 | {"HTTP://test/?size=2#f", "name=joe", "http://test/?size=2&name=joe#f", | 
|  | 1084 | 0, 0, CURLUE_OK}, | 
|  | 1085 | {NULL, NULL, NULL, 0, 0, CURLUE_OK} | 
|  | 1086 | }; | 
|  | 1087 |  | 
|  | 1088 | static int append(void) | 
|  | 1089 | { | 
|  | 1090 | int i; | 
|  | 1091 | int error = 0; | 
|  | 1092 | for(i = 0; append_list[i].in && !error; i++) { | 
|  | 1093 | CURLUcode rc; | 
|  | 1094 | CURLU *urlp = curl_url(); | 
|  | 1095 | if(!urlp) { | 
|  | 1096 | error++; | 
|  | 1097 | break; | 
|  | 1098 | } | 
|  | 1099 | rc = curl_url_set(urlp, CURLUPART_URL, | 
|  | 1100 | append_list[i].in, | 
|  | 1101 | append_list[i].urlflags); | 
|  | 1102 | if(rc) | 
|  | 1103 | error++; | 
|  | 1104 | else | 
|  | 1105 | rc = curl_url_set(urlp, CURLUPART_QUERY, | 
|  | 1106 | append_list[i].q, | 
|  | 1107 | append_list[i].qflags | CURLU_APPENDQUERY); | 
|  | 1108 | if(error) | 
|  | 1109 | ; | 
|  | 1110 | else if(rc != append_list[i].ucode) { | 
|  | 1111 | fprintf(stderr, "Append\nin: %s\nreturned %d (expected %d)\n", | 
|  | 1112 | append_list[i].in, (int)rc, append_list[i].ucode); | 
|  | 1113 | error++; | 
|  | 1114 | } | 
|  | 1115 | else if(append_list[i].ucode) { | 
|  | 1116 | /* the expected error happened */ | 
|  | 1117 | } | 
|  | 1118 | else { | 
|  | 1119 | char *url; | 
|  | 1120 | rc = curl_url_get(urlp, CURLUPART_URL, &url, 0); | 
|  | 1121 | if(rc) { | 
|  | 1122 | fprintf(stderr, "%s:%d Get URL returned %d (%s)\n", | 
|  | 1123 | __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); | 
|  | 1124 | error++; | 
|  | 1125 | } | 
|  | 1126 | else { | 
|  | 1127 | if(checkurl(url, append_list[i].out)) { | 
|  | 1128 | error++; | 
|  | 1129 | } | 
|  | 1130 | curl_free(url); | 
|  | 1131 | } | 
|  | 1132 | } | 
|  | 1133 | curl_url_cleanup(urlp); | 
|  | 1134 | } | 
|  | 1135 | return error; | 
|  | 1136 | } | 
|  | 1137 |  | 
|  | 1138 | static int scopeid(void) | 
|  | 1139 | { | 
|  | 1140 | CURLU *u = curl_url(); | 
|  | 1141 | int error = 0; | 
|  | 1142 | CURLUcode rc; | 
|  | 1143 | char *url; | 
|  | 1144 |  | 
|  | 1145 | rc = curl_url_set(u, CURLUPART_URL, | 
|  | 1146 | "https://[fe80::20c:29ff:fe9c:409b%25eth0]/hello.html", 0); | 
|  | 1147 | if(rc != CURLUE_OK) { | 
|  | 1148 | fprintf(stderr, "%s:%d curl_url_set returned %d (%s)\n", | 
|  | 1149 | __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); | 
|  | 1150 | error++; | 
|  | 1151 | } | 
|  | 1152 |  | 
|  | 1153 | rc = curl_url_get(u, CURLUPART_HOST, &url, 0); | 
|  | 1154 | if(rc != CURLUE_OK) { | 
|  | 1155 | fprintf(stderr, "%s:%d curl_url_get CURLUPART_HOST returned %d (%s)\n", | 
|  | 1156 | __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); | 
|  | 1157 | error++; | 
|  | 1158 | } | 
|  | 1159 | else { | 
|  | 1160 | printf("we got %s\n", url); | 
|  | 1161 | curl_free(url); | 
|  | 1162 | } | 
|  | 1163 |  | 
|  | 1164 | rc = curl_url_set(u, CURLUPART_HOST, "[::1]", 0); | 
|  | 1165 | if(rc != CURLUE_OK) { | 
|  | 1166 | fprintf(stderr, "%s:%d curl_url_set CURLUPART_HOST returned %d (%s)\n", | 
|  | 1167 | __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); | 
|  | 1168 | error++; | 
|  | 1169 | } | 
|  | 1170 |  | 
|  | 1171 | rc = curl_url_get(u, CURLUPART_URL, &url, 0); | 
|  | 1172 | if(rc != CURLUE_OK) { | 
|  | 1173 | fprintf(stderr, "%s:%d curl_url_get CURLUPART_URL returned %d (%s)\n", | 
|  | 1174 | __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); | 
|  | 1175 | error++; | 
|  | 1176 | } | 
|  | 1177 | else { | 
|  | 1178 | printf("we got %s\n", url); | 
|  | 1179 | curl_free(url); | 
|  | 1180 | } | 
|  | 1181 |  | 
|  | 1182 | rc = curl_url_set(u, CURLUPART_HOST, "example.com", 0); | 
|  | 1183 | if(rc != CURLUE_OK) { | 
|  | 1184 | fprintf(stderr, "%s:%d curl_url_set CURLUPART_HOST returned %d (%s)\n", | 
|  | 1185 | __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); | 
|  | 1186 | error++; | 
|  | 1187 | } | 
|  | 1188 |  | 
|  | 1189 | rc = curl_url_get(u, CURLUPART_URL, &url, 0); | 
|  | 1190 | if(rc != CURLUE_OK) { | 
|  | 1191 | fprintf(stderr, "%s:%d curl_url_get CURLUPART_URL returned %d (%s)\n", | 
|  | 1192 | __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); | 
|  | 1193 | error++; | 
|  | 1194 | } | 
|  | 1195 | else { | 
|  | 1196 | printf("we got %s\n", url); | 
|  | 1197 | curl_free(url); | 
|  | 1198 | } | 
|  | 1199 |  | 
|  | 1200 | rc = curl_url_set(u, CURLUPART_HOST, | 
|  | 1201 | "[fe80::20c:29ff:fe9c:409b%25eth0]", 0); | 
|  | 1202 | if(rc != CURLUE_OK) { | 
|  | 1203 | fprintf(stderr, "%s:%d curl_url_set CURLUPART_HOST returned %d (%s)\n", | 
|  | 1204 | __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); | 
|  | 1205 | error++; | 
|  | 1206 | } | 
|  | 1207 |  | 
|  | 1208 | rc = curl_url_get(u, CURLUPART_URL, &url, 0); | 
|  | 1209 | if(rc != CURLUE_OK) { | 
|  | 1210 | fprintf(stderr, "%s:%d curl_url_get CURLUPART_URL returned %d (%s)\n", | 
|  | 1211 | __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); | 
|  | 1212 | error++; | 
|  | 1213 | } | 
|  | 1214 | else { | 
|  | 1215 | printf("we got %s\n", url); | 
|  | 1216 | curl_free(url); | 
|  | 1217 | } | 
|  | 1218 |  | 
|  | 1219 | rc = curl_url_get(u, CURLUPART_HOST, &url, 0); | 
|  | 1220 | if(rc != CURLUE_OK) { | 
|  | 1221 | fprintf(stderr, "%s:%d curl_url_get CURLUPART_HOST returned %d (%s)\n", | 
|  | 1222 | __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); | 
|  | 1223 | error++; | 
|  | 1224 | } | 
|  | 1225 | else { | 
|  | 1226 | printf("we got %s\n", url); | 
|  | 1227 | curl_free(url); | 
|  | 1228 | } | 
|  | 1229 |  | 
|  | 1230 | rc = curl_url_get(u, CURLUPART_ZONEID, &url, 0); | 
|  | 1231 | if(rc != CURLUE_OK) { | 
|  | 1232 | fprintf(stderr, "%s:%d curl_url_get CURLUPART_ZONEID returned %d (%s)\n", | 
|  | 1233 | __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); | 
|  | 1234 | error++; | 
|  | 1235 | } | 
|  | 1236 | else { | 
|  | 1237 | printf("we got %s\n", url); | 
|  | 1238 | curl_free(url); | 
|  | 1239 | } | 
|  | 1240 |  | 
|  | 1241 | rc = curl_url_set(u, CURLUPART_ZONEID, "clown", 0); | 
|  | 1242 | if(rc != CURLUE_OK) { | 
|  | 1243 | fprintf(stderr, "%s:%d curl_url_set CURLUPART_ZONEID returned %d (%s)\n", | 
|  | 1244 | __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); | 
|  | 1245 | error++; | 
|  | 1246 | } | 
|  | 1247 |  | 
|  | 1248 | rc = curl_url_get(u, CURLUPART_URL, &url, 0); | 
|  | 1249 | if(rc != CURLUE_OK) { | 
|  | 1250 | fprintf(stderr, "%s:%d curl_url_get CURLUPART_URL returned %d (%s)\n", | 
|  | 1251 | __FILE__, __LINE__, (int)rc, curl_url_strerror(rc)); | 
|  | 1252 | error++; | 
|  | 1253 | } | 
|  | 1254 | else { | 
|  | 1255 | printf("we got %s\n", url); | 
|  | 1256 | curl_free(url); | 
|  | 1257 | } | 
|  | 1258 |  | 
|  | 1259 | curl_url_cleanup(u); | 
|  | 1260 |  | 
|  | 1261 | return error; | 
|  | 1262 | } | 
|  | 1263 |  | 
|  | 1264 | static int get_nothing(void) | 
|  | 1265 | { | 
|  | 1266 | CURLU *u = curl_url(); | 
|  | 1267 | if(u) { | 
|  | 1268 | char *p; | 
|  | 1269 | CURLUcode rc; | 
|  | 1270 |  | 
|  | 1271 | rc = curl_url_get(u, CURLUPART_SCHEME, &p, 0); | 
|  | 1272 | if(rc != CURLUE_NO_SCHEME) | 
|  | 1273 | fprintf(stderr, "unexpected return code line %u\n", __LINE__); | 
|  | 1274 |  | 
|  | 1275 | rc = curl_url_get(u, CURLUPART_HOST, &p, 0); | 
|  | 1276 | if(rc != CURLUE_NO_HOST) | 
|  | 1277 | fprintf(stderr, "unexpected return code line %u\n", __LINE__); | 
|  | 1278 |  | 
|  | 1279 | rc = curl_url_get(u, CURLUPART_USER, &p, 0); | 
|  | 1280 | if(rc != CURLUE_NO_USER) | 
|  | 1281 | fprintf(stderr, "unexpected return code line %u\n", __LINE__); | 
|  | 1282 |  | 
|  | 1283 | rc = curl_url_get(u, CURLUPART_PASSWORD, &p, 0); | 
|  | 1284 | if(rc != CURLUE_NO_PASSWORD) | 
|  | 1285 | fprintf(stderr, "unexpected return code line %u\n", __LINE__); | 
|  | 1286 |  | 
|  | 1287 | rc = curl_url_get(u, CURLUPART_OPTIONS, &p, 0); | 
|  | 1288 | if(rc != CURLUE_NO_OPTIONS) | 
|  | 1289 | fprintf(stderr, "unexpected return code line %u\n", __LINE__); | 
|  | 1290 |  | 
|  | 1291 | rc = curl_url_get(u, CURLUPART_PATH, &p, 0); | 
|  | 1292 | if(rc != CURLUE_OK) | 
|  | 1293 | fprintf(stderr, "unexpected return code line %u\n", __LINE__); | 
|  | 1294 | else | 
|  | 1295 | curl_free(p); | 
|  | 1296 |  | 
|  | 1297 | rc = curl_url_get(u, CURLUPART_QUERY, &p, 0); | 
|  | 1298 | if(rc != CURLUE_NO_QUERY) | 
|  | 1299 | fprintf(stderr, "unexpected return code line %u\n", __LINE__); | 
|  | 1300 |  | 
|  | 1301 | rc = curl_url_get(u, CURLUPART_FRAGMENT, &p, 0); | 
|  | 1302 | if(rc != CURLUE_NO_FRAGMENT) | 
|  | 1303 | fprintf(stderr, "unexpected return code line %u\n", __LINE__); | 
|  | 1304 |  | 
|  | 1305 | rc = curl_url_get(u, CURLUPART_ZONEID, &p, 0); | 
|  | 1306 | if(rc != CURLUE_NO_ZONEID) | 
|  | 1307 | fprintf(stderr, "unexpected return code %u on line %u\n", (int)rc, | 
|  | 1308 | __LINE__); | 
|  | 1309 |  | 
|  | 1310 | curl_url_cleanup(u); | 
|  | 1311 | } | 
|  | 1312 | return 0; | 
|  | 1313 | } | 
|  | 1314 |  | 
|  | 1315 | static const struct clearurlcase clear_url_list[] ={ | 
|  | 1316 | {CURLUPART_SCHEME, "http", NULL, CURLUE_NO_SCHEME}, | 
|  | 1317 | {CURLUPART_USER, "user", NULL, CURLUE_NO_USER}, | 
|  | 1318 | {CURLUPART_PASSWORD, "password", NULL, CURLUE_NO_PASSWORD}, | 
|  | 1319 | {CURLUPART_OPTIONS, "options", NULL, CURLUE_NO_OPTIONS}, | 
|  | 1320 | {CURLUPART_HOST, "host", NULL, CURLUE_NO_HOST}, | 
|  | 1321 | {CURLUPART_ZONEID, "eth0", NULL, CURLUE_NO_ZONEID}, | 
|  | 1322 | {CURLUPART_PORT, "1234", NULL, CURLUE_NO_PORT}, | 
|  | 1323 | {CURLUPART_PATH, "/hello", "/", CURLUE_OK}, | 
|  | 1324 | {CURLUPART_QUERY, "a=b", NULL, CURLUE_NO_QUERY}, | 
|  | 1325 | {CURLUPART_FRAGMENT, "anchor", NULL, CURLUE_NO_FRAGMENT}, | 
|  | 1326 | {CURLUPART_URL, NULL, NULL, CURLUE_OK}, | 
|  | 1327 | }; | 
|  | 1328 |  | 
|  | 1329 | static int clear_url(void) | 
|  | 1330 | { | 
|  | 1331 | CURLU *u = curl_url(); | 
|  | 1332 | int i, error = 0; | 
|  | 1333 | if(u) { | 
|  | 1334 | char *p = NULL; | 
|  | 1335 | CURLUcode rc; | 
|  | 1336 |  | 
|  | 1337 | for(i = 0; clear_url_list[i].in && !error; i++) { | 
|  | 1338 | rc = curl_url_set(u, clear_url_list[i].part, clear_url_list[i].in, 0); | 
|  | 1339 | if(rc != CURLUE_OK) | 
|  | 1340 | fprintf(stderr, "unexpected return code line %u\n", __LINE__); | 
|  | 1341 |  | 
|  | 1342 | rc = curl_url_set(u, CURLUPART_URL, NULL, 0); | 
|  | 1343 | if(rc != CURLUE_OK) | 
|  | 1344 | fprintf(stderr, "unexpected return code line %u\n", __LINE__); | 
|  | 1345 |  | 
|  | 1346 | rc = curl_url_get(u, clear_url_list[i].part, &p, 0); | 
|  | 1347 | if(rc != clear_url_list[i].ucode || (clear_url_list[i].out && | 
|  | 1348 | 0 != strcmp(p, clear_url_list[i].out))) { | 
|  | 1349 |  | 
|  | 1350 | fprintf(stderr, "unexpected return code line %u\n", __LINE__); | 
|  | 1351 | error++; | 
|  | 1352 | } | 
|  | 1353 | if(rc == CURLUE_OK) | 
|  | 1354 | curl_free(p); | 
|  | 1355 | } | 
|  | 1356 | } | 
|  | 1357 |  | 
|  | 1358 | curl_url_cleanup(u); | 
|  | 1359 |  | 
|  | 1360 | return error; | 
|  | 1361 | } | 
|  | 1362 |  | 
|  | 1363 | int test(char *URL) | 
|  | 1364 | { | 
|  | 1365 | (void)URL; /* not used */ | 
|  | 1366 |  | 
|  | 1367 | if(get_nothing()) | 
|  | 1368 | return 7; | 
|  | 1369 |  | 
|  | 1370 | if(scopeid()) | 
|  | 1371 | return 6; | 
|  | 1372 |  | 
|  | 1373 | if(append()) | 
|  | 1374 | return 5; | 
|  | 1375 |  | 
|  | 1376 | if(set_url()) | 
|  | 1377 | return 1; | 
|  | 1378 |  | 
|  | 1379 | if(set_parts()) | 
|  | 1380 | return 2; | 
|  | 1381 |  | 
|  | 1382 | if(get_url()) | 
|  | 1383 | return 3; | 
|  | 1384 |  | 
|  | 1385 | if(get_parts()) | 
|  | 1386 | return 4; | 
|  | 1387 |  | 
|  | 1388 | if(clear_url()) | 
|  | 1389 | return 8; | 
|  | 1390 |  | 
|  | 1391 | printf("success\n"); | 
|  | 1392 | return 0; | 
|  | 1393 | } |