Annotation of embedaddon/curl/tests/libtest/lib1560.c, revision 1.1

1.1     ! misho       1: /***************************************************************************
        !             2:  *                                  _   _ ____  _
        !             3:  *  Project                     ___| | | |  _ \| |
        !             4:  *                             / __| | | | |_) | |
        !             5:  *                            | (__| |_| |  _ <| |___
        !             6:  *                             \___|\___/|_| \_\_____|
        !             7:  *
        !             8:  * Copyright (C) 1998 - 2020, 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.haxx.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:  ***************************************************************************/
        !            22: 
        !            23: /*
        !            24:  * Note:
        !            25:  *
        !            26:  * Since the URL parser by default only accepts schemes that *this instance*
        !            27:  * of libcurl supports, make sure that the test1560 file lists all the schemes
        !            28:  * that this test will assume to be present!
        !            29:  */
        !            30: 
        !            31: #include "test.h"
        !            32: 
        !            33: #include "testutil.h"
        !            34: #include "warnless.h"
        !            35: #include "memdebug.h" /* LAST include file */
        !            36: 
        !            37: struct part {
        !            38:   CURLUPart part;
        !            39:   const char *name;
        !            40: };
        !            41: 
        !            42: 
        !            43: static int checkparts(CURLU *u, const char *in, const char *wanted,
        !            44:                       unsigned int getflags)
        !            45: {
        !            46:   int i;
        !            47:   CURLUcode rc;
        !            48:   char buf[256];
        !            49:   char *bufp = &buf[0];
        !            50:   size_t len = sizeof(buf);
        !            51:   struct part parts[] = {
        !            52:     {CURLUPART_SCHEME, "scheme"},
        !            53:     {CURLUPART_USER, "user"},
        !            54:     {CURLUPART_PASSWORD, "password"},
        !            55:     {CURLUPART_OPTIONS, "options"},
        !            56:     {CURLUPART_HOST, "host"},
        !            57:     {CURLUPART_PORT, "port"},
        !            58:     {CURLUPART_PATH, "path"},
        !            59:     {CURLUPART_QUERY, "query"},
        !            60:     {CURLUPART_FRAGMENT, "fragment"},
        !            61:     {0, NULL}
        !            62:   };
        !            63:   memset(buf, 0, sizeof(buf));
        !            64: 
        !            65:   for(i = 0; parts[i].name; i++) {
        !            66:     char *p = NULL;
        !            67:     size_t n;
        !            68:     rc = curl_url_get(u, parts[i].part, &p, getflags);
        !            69:     if(!rc && p) {
        !            70:       msnprintf(bufp, len, "%s%s", buf[0]?" | ":"", p);
        !            71:     }
        !            72:     else
        !            73:       msnprintf(bufp, len, "%s[%d]", buf[0]?" | ":"", (int)rc);
        !            74: 
        !            75:     n = strlen(bufp);
        !            76:     bufp += n;
        !            77:     len -= n;
        !            78:     curl_free(p);
        !            79:   }
        !            80:   if(strcmp(buf, wanted)) {
        !            81:     fprintf(stderr, "in: %s\nwanted: %s\ngot:    %s\n", in, wanted, buf);
        !            82:     return 1;
        !            83:   }
        !            84:   return 0;
        !            85: }
        !            86: 
        !            87: struct redircase {
        !            88:   const char *in;
        !            89:   const char *set;
        !            90:   const char *out;
        !            91:   unsigned int urlflags;
        !            92:   unsigned int setflags;
        !            93:   CURLUcode ucode;
        !            94: };
        !            95: 
        !            96: struct setcase {
        !            97:   const char *in;
        !            98:   const char *set;
        !            99:   const char *out;
        !           100:   unsigned int urlflags;
        !           101:   unsigned int setflags;
        !           102:   CURLUcode ucode; /* for the main URL set */
        !           103:   CURLUcode pcode; /* for updating parts */
        !           104: };
        !           105: 
        !           106: struct testcase {
        !           107:   const char *in;
        !           108:   const char *out;
        !           109:   unsigned int urlflags;
        !           110:   unsigned int getflags;
        !           111:   CURLUcode ucode;
        !           112: };
        !           113: 
        !           114: struct urltestcase {
        !           115:   const char *in;
        !           116:   const char *out;
        !           117:   unsigned int urlflags; /* pass to curl_url() */
        !           118:   unsigned int getflags; /* pass to curl_url_get() */
        !           119:   CURLUcode ucode;
        !           120: };
        !           121: 
        !           122: struct querycase {
        !           123:   const char *in;
        !           124:   const char *q;
        !           125:   const char *out;
        !           126:   unsigned int urlflags; /* pass to curl_url() */
        !           127:   unsigned int qflags; /* pass to curl_url_get() */
        !           128:   CURLUcode ucode;
        !           129: };
        !           130: 
        !           131: static struct testcase get_parts_list[] ={
        !           132:   {"user:moo@ftp.example.com/color/#green?no-black",
        !           133:    "ftp | user | moo | [13] | ftp.example.com | [15] | /color/ | [16] | "
        !           134:    "green?no-black",
        !           135:    CURLU_GUESS_SCHEME, 0, CURLUE_OK },
        !           136:   {"ftp.user:moo@example.com/color/#green?no-black",
        !           137:    "http | ftp.user | moo | [13] | example.com | [15] | /color/ | [16] | "
        !           138:    "green?no-black",
        !           139:    CURLU_GUESS_SCHEME, 0, CURLUE_OK },
        !           140: #ifdef WIN32
        !           141:   {"file:/C:\\programs\\foo",
        !           142:    "file | [11] | [12] | [13] | [14] | [15] | C:\\programs\\foo | [16] | [17]",
        !           143:    CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
        !           144:   {"file://C:\\programs\\foo",
        !           145:    "file | [11] | [12] | [13] | [14] | [15] | C:\\programs\\foo | [16] | [17]",
        !           146:    CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
        !           147:   {"file:///C:\\programs\\foo",
        !           148:    "file | [11] | [12] | [13] | [14] | [15] | C:\\programs\\foo | [16] | [17]",
        !           149:    CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
        !           150: #endif
        !           151:   {"https://example.com/color/#green?no-black",
        !           152:    "https | [11] | [12] | [13] | example.com | [15] | /color/ | [16] | "
        !           153:    "green?no-black",
        !           154:    CURLU_DEFAULT_SCHEME, 0, CURLUE_OK },
        !           155:   {"https://example.com/color/#green#no-black",
        !           156:    "https | [11] | [12] | [13] | example.com | [15] | /color/ | [16] | "
        !           157:    "green#no-black",
        !           158:    CURLU_DEFAULT_SCHEME, 0, CURLUE_OK },
        !           159:   {"https://example.com/color/?green#no-black",
        !           160:    "https | [11] | [12] | [13] | example.com | [15] | /color/ | green | "
        !           161:    "no-black",
        !           162:    CURLU_DEFAULT_SCHEME, 0, CURLUE_OK },
        !           163:   {"https://example.com/#color/?green#no-black",
        !           164:    "https | [11] | [12] | [13] | example.com | [15] | / | [16] | "
        !           165:    "color/?green#no-black",
        !           166:    CURLU_DEFAULT_SCHEME, 0, CURLUE_OK },
        !           167:   {"https://example.#com/color/?green#no-black",
        !           168:    "https | [11] | [12] | [13] | example. | [15] | / | [16] | "
        !           169:    "com/color/?green#no-black",
        !           170:    CURLU_DEFAULT_SCHEME, 0, CURLUE_OK },
        !           171:   {"http://[ab.be:1]/x", "",
        !           172:    CURLU_DEFAULT_SCHEME, 0, CURLUE_MALFORMED_INPUT},
        !           173:   {"http://[ab.be]/x", "",
        !           174:    CURLU_DEFAULT_SCHEME, 0, CURLUE_MALFORMED_INPUT},
        !           175:   /* URL without host name */
        !           176:   {"http://a:b@/x", "",
        !           177:    CURLU_DEFAULT_SCHEME, 0, CURLUE_NO_HOST},
        !           178:   {"boing:80",
        !           179:    "https | [11] | [12] | [13] | boing | 80 | / | [16] | [17]",
        !           180:    CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
        !           181:   {"http://[fd00:a41::50]:8080",
        !           182:    "http | [11] | [12] | [13] | [fd00:a41::50] | 8080 | / | [16] | [17]",
        !           183:    CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
        !           184:   {"http://[fd00:a41::50]/",
        !           185:    "http | [11] | [12] | [13] | [fd00:a41::50] | [15] | / | [16] | [17]",
        !           186:    CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
        !           187:   {"http://[fd00:a41::50]",
        !           188:    "http | [11] | [12] | [13] | [fd00:a41::50] | [15] | / | [16] | [17]",
        !           189:    CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
        !           190:   {"https://[::1%252]:1234",
        !           191:    "https | [11] | [12] | [13] | [::1] | 1234 | / | [16] | [17]",
        !           192:    CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
        !           193: 
        !           194:   /* here's "bad" zone id */
        !           195:   {"https://[fe80::20c:29ff:fe9c:409b%eth0]:1234",
        !           196:    "https | [11] | [12] | [13] | [fe80::20c:29ff:fe9c:409b] | 1234 "
        !           197:    "| / | [16] | [17]",
        !           198:    CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
        !           199:   {"https://127.0.0.1:443",
        !           200:    "https | [11] | [12] | [13] | 127.0.0.1 | [15] | / | [16] | [17]",
        !           201:    0, CURLU_NO_DEFAULT_PORT, CURLUE_OK},
        !           202:   {"http://%3a:%3a@ex%0ample/%3f+?+%3f+%23#+%23%3f%g7",
        !           203:    "http | : | : | [13] | [6] | [15] | /?+ |  ? # | +#?%g7",
        !           204:    0, CURLU_URLDECODE, CURLUE_OK},
        !           205:   {"http://%3a:%3a@ex%0ample/%3f?%3f%35#%35%3f%g7",
        !           206:    "http | %3a | %3a | [13] | ex%0ample | [15] | /%3f | %3f%35 | %35%3f%g7",
        !           207:    0, 0, CURLUE_OK},
        !           208:   {"http://HO0_-st%41/",
        !           209:    "http | [11] | [12] | [13] | HO0_-st%41 | [15] | / | [16] | [17]",
        !           210:    0, 0, CURLUE_OK},
        !           211:   {"file://hello.html",
        !           212:    "",
        !           213:    0, 0, CURLUE_MALFORMED_INPUT},
        !           214:   {"http://HO0_-st/",
        !           215:    "http | [11] | [12] | [13] | HO0_-st | [15] | / | [16] | [17]",
        !           216:    0, 0, CURLUE_OK},
        !           217:   {"imap://user:pass;option@server/path",
        !           218:    "imap | user | pass | option | server | [15] | /path | [16] | [17]",
        !           219:    0, 0, CURLUE_OK},
        !           220:   {"http://user:pass;option@server/path",
        !           221:    "http | user | pass;option | [13] | server | [15] | /path | [16] | [17]",
        !           222:    0, 0, CURLUE_OK},
        !           223:   {"file:/hello.html",
        !           224:    "file | [11] | [12] | [13] | [14] | [15] | /hello.html | [16] | [17]",
        !           225:    0, 0, CURLUE_OK},
        !           226:   {"file://127.0.0.1/hello.html",
        !           227:    "file | [11] | [12] | [13] | [14] | [15] | /hello.html | [16] | [17]",
        !           228:    0, 0, CURLUE_OK},
        !           229:   {"file:////hello.html",
        !           230:    "file | [11] | [12] | [13] | [14] | [15] | //hello.html | [16] | [17]",
        !           231:    0, 0, CURLUE_OK},
        !           232:   {"file:///hello.html",
        !           233:    "file | [11] | [12] | [13] | [14] | [15] | /hello.html | [16] | [17]",
        !           234:    0, 0, CURLUE_OK},
        !           235:   {"https://127.0.0.1",
        !           236:    "https | [11] | [12] | [13] | 127.0.0.1 | 443 | / | [16] | [17]",
        !           237:    0, CURLU_DEFAULT_PORT, CURLUE_OK},
        !           238:   {"https://127.0.0.1",
        !           239:    "https | [11] | [12] | [13] | 127.0.0.1 | [15] | / | [16] | [17]",
        !           240:    CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
        !           241:   {"https://[::1]:1234",
        !           242:    "https | [11] | [12] | [13] | [::1] | 1234 | / | [16] | [17]",
        !           243:    CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
        !           244:   {"https://127abc.com",
        !           245:    "https | [11] | [12] | [13] | 127abc.com | [15] | / | [16] | [17]",
        !           246:    CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
        !           247:   {"https:// example.com?check",
        !           248:    "",
        !           249:    CURLU_DEFAULT_SCHEME, 0, CURLUE_MALFORMED_INPUT},
        !           250:   {"https://e x a m p l e.com?check",
        !           251:    "",
        !           252:    CURLU_DEFAULT_SCHEME, 0, CURLUE_MALFORMED_INPUT},
        !           253:   {"https://example.com?check",
        !           254:    "https | [11] | [12] | [13] | example.com | [15] | / | check | [17]",
        !           255:    CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
        !           256:   {"https://example.com:65536",
        !           257:    "",
        !           258:    CURLU_DEFAULT_SCHEME, 0, CURLUE_BAD_PORT_NUMBER},
        !           259:   {"https://example.com:0#moo",
        !           260:    "",
        !           261:    CURLU_DEFAULT_SCHEME, 0, CURLUE_BAD_PORT_NUMBER},
        !           262:   {"https://example.com:01#moo",
        !           263:    "https | [11] | [12] | [13] | example.com | 1 | / | "
        !           264:    "[16] | moo",
        !           265:    CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
        !           266:   {"https://example.com:1#moo",
        !           267:    "https | [11] | [12] | [13] | example.com | 1 | / | "
        !           268:    "[16] | moo",
        !           269:    CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
        !           270:   {"http://example.com#moo",
        !           271:    "http | [11] | [12] | [13] | example.com | [15] | / | "
        !           272:    "[16] | moo",
        !           273:    CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
        !           274:   {"http://example.com",
        !           275:    "http | [11] | [12] | [13] | example.com | [15] | / | "
        !           276:    "[16] | [17]",
        !           277:    CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
        !           278:   {"http://example.com/path/html",
        !           279:    "http | [11] | [12] | [13] | example.com | [15] | /path/html | "
        !           280:    "[16] | [17]",
        !           281:    CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
        !           282:   {"http://example.com/path/html?query=name",
        !           283:    "http | [11] | [12] | [13] | example.com | [15] | /path/html | "
        !           284:    "query=name | [17]",
        !           285:    CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
        !           286:   {"http://example.com/path/html?query=name#anchor",
        !           287:    "http | [11] | [12] | [13] | example.com | [15] | /path/html | "
        !           288:    "query=name | anchor",
        !           289:    CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
        !           290:   {"http://example.com:1234/path/html?query=name#anchor",
        !           291:    "http | [11] | [12] | [13] | example.com | 1234 | /path/html | "
        !           292:    "query=name | anchor",
        !           293:    CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
        !           294:   {"http:///user:password@example.com:1234/path/html?query=name#anchor",
        !           295:    "http | user | password | [13] | example.com | 1234 | /path/html | "
        !           296:    "query=name | anchor",
        !           297:    CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
        !           298:   {"https://user:password@example.com:1234/path/html?query=name#anchor",
        !           299:    "https | user | password | [13] | example.com | 1234 | /path/html | "
        !           300:    "query=name | anchor",
        !           301:    CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
        !           302:   {"http://user:password@example.com:1234/path/html?query=name#anchor",
        !           303:    "http | user | password | [13] | example.com | 1234 | /path/html | "
        !           304:    "query=name | anchor",
        !           305:    CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
        !           306:   {"http:/user:password@example.com:1234/path/html?query=name#anchor",
        !           307:    "http | user | password | [13] | example.com | 1234 | /path/html | "
        !           308:    "query=name | anchor",
        !           309:    CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
        !           310:   {"http:////user:password@example.com:1234/path/html?query=name#anchor",
        !           311:    "",
        !           312:    CURLU_DEFAULT_SCHEME, 0, CURLUE_MALFORMED_INPUT},
        !           313:   {NULL, NULL, 0, 0, CURLUE_OK},
        !           314: };
        !           315: 
        !           316: static struct urltestcase get_url_list[] = {
        !           317:   /* 40 bytes scheme is the max allowed */
        !           318:   {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA://hostname/path",
        !           319:    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa://hostname/path",
        !           320:    CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_OK},
        !           321:   /* 41 bytes scheme is not allowed */
        !           322:   {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA://hostname/path",
        !           323:    "",
        !           324:    CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_MALFORMED_INPUT},
        !           325:   {"https://[fe80::20c:29ff:fe9c:409b%]:1234",
        !           326:    "",
        !           327:    0, 0, CURLUE_MALFORMED_INPUT},
        !           328:   {"https://[fe80::20c:29ff:fe9c:409b%25]:1234",
        !           329:    "https://[fe80::20c:29ff:fe9c:409b%2525]:1234/",
        !           330:    0, 0, CURLUE_OK},
        !           331:   {"https://[fe80::20c:29ff:fe9c:409b%eth0]:1234",
        !           332:    "https://[fe80::20c:29ff:fe9c:409b%25eth0]:1234/",
        !           333:    0, 0, CURLUE_OK},
        !           334:   {"https://[::%25fakeit]/moo",
        !           335:    "https://[::%25fakeit]/moo",
        !           336:    0, 0, CURLUE_OK},
        !           337:   {"smtp.example.com/path/html",
        !           338:    "smtp://smtp.example.com/path/html",
        !           339:    CURLU_GUESS_SCHEME, 0, CURLUE_OK},
        !           340:   {"https.example.com/path/html",
        !           341:    "http://https.example.com/path/html",
        !           342:    CURLU_GUESS_SCHEME, 0, CURLUE_OK},
        !           343:   {"dict.example.com/path/html",
        !           344:    "dict://dict.example.com/path/html",
        !           345:    CURLU_GUESS_SCHEME, 0, CURLUE_OK},
        !           346:   {"pop3.example.com/path/html",
        !           347:    "pop3://pop3.example.com/path/html",
        !           348:    CURLU_GUESS_SCHEME, 0, CURLUE_OK},
        !           349:   {"ldap.example.com/path/html",
        !           350:    "ldap://ldap.example.com/path/html",
        !           351:    CURLU_GUESS_SCHEME, 0, CURLUE_OK},
        !           352:   {"imap.example.com/path/html",
        !           353:    "imap://imap.example.com/path/html",
        !           354:    CURLU_GUESS_SCHEME, 0, CURLUE_OK},
        !           355:   {"ftp.example.com/path/html",
        !           356:    "ftp://ftp.example.com/path/html",
        !           357:    CURLU_GUESS_SCHEME, 0, CURLUE_OK},
        !           358:   {"example.com/path/html",
        !           359:    "http://example.com/path/html",
        !           360:    CURLU_GUESS_SCHEME, 0, CURLUE_OK},
        !           361:   {"HTTP://test/", "http://test/", 0, 0, CURLUE_OK},
        !           362:   {"http://HO0_-st..~./", "http://HO0_-st..~./", 0, 0, CURLUE_OK},
        !           363:   {"http:/@example.com: 123/", "", 0, 0, CURLUE_BAD_PORT_NUMBER},
        !           364:   {"http:/@example.com:123 /", "", 0, 0, CURLUE_BAD_PORT_NUMBER},
        !           365:   {"http:/@example.com:123a/", "", 0, 0, CURLUE_BAD_PORT_NUMBER},
        !           366:   {"http://host/file\r", "", 0, 0, CURLUE_MALFORMED_INPUT},
        !           367:   {"http://host/file\n\x03", "", 0, 0, CURLUE_MALFORMED_INPUT},
        !           368:   {"htt\x02://host/file", "",
        !           369:    CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_MALFORMED_INPUT},
        !           370:   {" http://host/file", "", 0, 0, CURLUE_MALFORMED_INPUT},
        !           371:   /* here the password ends at the semicolon and options is 'word' */
        !           372:   {"imap://user:pass;word@host/file",
        !           373:    "imap://user:pass;word@host/file",
        !           374:    0, 0, CURLUE_OK},
        !           375:   /* here the password has the semicolon */
        !           376:   {"http://user:pass;word@host/file",
        !           377:    "http://user:pass;word@host/file",
        !           378:    0, 0, CURLUE_OK},
        !           379:   {"file:///file.txt#moo",
        !           380:    "file:///file.txt#moo",
        !           381:    0, 0, CURLUE_OK},
        !           382:   {"file:////file.txt",
        !           383:    "file:////file.txt",
        !           384:    0, 0, CURLUE_OK},
        !           385:   {"file:///file.txt",
        !           386:    "file:///file.txt",
        !           387:    0, 0, CURLUE_OK},
        !           388:   {"file:./",
        !           389:    "file://",
        !           390:    0, 0, CURLUE_MALFORMED_INPUT},
        !           391:   {"http://example.com/hello/../here",
        !           392:    "http://example.com/hello/../here",
        !           393:    CURLU_PATH_AS_IS, 0, CURLUE_OK},
        !           394:   {"http://example.com/hello/../here",
        !           395:    "http://example.com/here",
        !           396:    0, 0, CURLUE_OK},
        !           397:   {"http://example.com:80",
        !           398:    "http://example.com/",
        !           399:    0, CURLU_NO_DEFAULT_PORT, CURLUE_OK},
        !           400:   {"tp://example.com/path/html",
        !           401:    "",
        !           402:    0, 0, CURLUE_UNSUPPORTED_SCHEME},
        !           403:   {"http://hello:fool@example.com",
        !           404:    "",
        !           405:    CURLU_DISALLOW_USER, 0, CURLUE_USER_NOT_ALLOWED},
        !           406:   {"http:/@example.com:123",
        !           407:    "http://example.com:123/",
        !           408:    0, 0, CURLUE_OK},
        !           409:   {"http:/:password@example.com",
        !           410:    "http://:password@example.com/",
        !           411:    0, 0, CURLUE_OK},
        !           412:   {"http://user@example.com?#",
        !           413:    "http://user@example.com/",
        !           414:    0, 0, CURLUE_OK},
        !           415:   {"http://user@example.com?",
        !           416:    "http://user@example.com/",
        !           417:    0, 0, CURLUE_OK},
        !           418:   {"http://user@example.com#anchor",
        !           419:    "http://user@example.com/#anchor",
        !           420:    0, 0, CURLUE_OK},
        !           421:   {"example.com/path/html",
        !           422:    "https://example.com/path/html",
        !           423:    CURLU_DEFAULT_SCHEME, 0, CURLUE_OK},
        !           424:   {"example.com/path/html",
        !           425:    "",
        !           426:    0, 0, CURLUE_MALFORMED_INPUT},
        !           427:   {"http://user:password@example.com:1234/path/html?query=name#anchor",
        !           428:    "http://user:password@example.com:1234/path/html?query=name#anchor",
        !           429:    0, 0, CURLUE_OK},
        !           430:   {"http://example.com:1234/path/html?query=name#anchor",
        !           431:    "http://example.com:1234/path/html?query=name#anchor",
        !           432:    0, 0, CURLUE_OK},
        !           433:   {"http://example.com/path/html?query=name#anchor",
        !           434:    "http://example.com/path/html?query=name#anchor",
        !           435:    0, 0, CURLUE_OK},
        !           436:   {"http://example.com/path/html?query=name",
        !           437:    "http://example.com/path/html?query=name",
        !           438:    0, 0, CURLUE_OK},
        !           439:   {"http://example.com/path/html",
        !           440:    "http://example.com/path/html",
        !           441:    0, 0, CURLUE_OK},
        !           442:   {"tp://example.com/path/html",
        !           443:    "tp://example.com/path/html",
        !           444:    CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_OK},
        !           445:   {"custom-scheme://host?expected=test-good",
        !           446:    "custom-scheme://host/?expected=test-good",
        !           447:    CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_OK},
        !           448:   {"custom-scheme://?expected=test-bad",
        !           449:    "",
        !           450:    CURLU_NON_SUPPORT_SCHEME, 0, CURLUE_MALFORMED_INPUT},
        !           451:   {"custom-scheme://?expected=test-new-good",
        !           452:    "custom-scheme:///?expected=test-new-good",
        !           453:    CURLU_NON_SUPPORT_SCHEME | CURLU_NO_AUTHORITY, 0, CURLUE_OK},
        !           454:   {"custom-scheme://host?expected=test-still-good",
        !           455:    "custom-scheme://host/?expected=test-still-good",
        !           456:    CURLU_NON_SUPPORT_SCHEME | CURLU_NO_AUTHORITY, 0, CURLUE_OK},
        !           457:   {NULL, NULL, 0, 0, 0}
        !           458: };
        !           459: 
        !           460: static int checkurl(const char *url, const char *out)
        !           461: {
        !           462:   if(strcmp(out, url)) {
        !           463:     fprintf(stderr, "Wanted: %s\nGot   : %s\n",
        !           464:             out, url);
        !           465:     return 1;
        !           466:   }
        !           467:   return 0;
        !           468: }
        !           469: 
        !           470: /* !checksrc! disable SPACEBEFORECOMMA 1 */
        !           471: static struct setcase set_parts_list[] = {
        !           472:   {"https://example.com/",
        !           473:    /* Set a 41 bytes scheme. That's too long so the old scheme remains set. */
        !           474:    "scheme=bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc,",
        !           475:    "https://example.com/",
        !           476:    0, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK, CURLUE_MALFORMED_INPUT},
        !           477:   {"https://example.com/",
        !           478:    /* set a 40 bytes scheme */
        !           479:    "scheme=bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,",
        !           480:    "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb://example.com/",
        !           481:    0, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK, CURLUE_OK},
        !           482:   {"https://[::1%25fake]:1234/",
        !           483:    "zoneid=NULL,",
        !           484:    "https://[::1]:1234/",
        !           485:    0, 0, CURLUE_OK, CURLUE_OK},
        !           486:   {"https://host:1234/",
        !           487:    "port=NULL,",
        !           488:    "https://host/",
        !           489:    0, 0, CURLUE_OK, CURLUE_OK},
        !           490:   {"https://host:1234/",
        !           491:    "port=\"\",",
        !           492:    "https://host:1234/",
        !           493:    0, 0, CURLUE_OK, CURLUE_BAD_PORT_NUMBER},
        !           494:   {"https://host:1234/",
        !           495:    "port=56 78,",
        !           496:    "https://host:1234/",
        !           497:    0, 0, CURLUE_OK, CURLUE_MALFORMED_INPUT},
        !           498:   {"https://host:1234/",
        !           499:    "port=0,",
        !           500:    "https://host:1234/",
        !           501:    0, 0, CURLUE_OK, CURLUE_BAD_PORT_NUMBER},
        !           502:   {"https://host:1234/",
        !           503:    "port=65535,",
        !           504:    "https://host:65535/",
        !           505:    0, 0, CURLUE_OK, CURLUE_OK},
        !           506:   {"https://host:1234/",
        !           507:    "port=65536,",
        !           508:    "https://host:1234/",
        !           509:    0, 0, CURLUE_OK, CURLUE_BAD_PORT_NUMBER},
        !           510:   {"https://host/",
        !           511:    "path=%4A%4B%4C,",
        !           512:    "https://host/%4a%4b%4c",
        !           513:    0, 0, CURLUE_OK, CURLUE_OK},
        !           514:   {"https://host/mooo?q#f",
        !           515:    "path=NULL,query=NULL,fragment=NULL,",
        !           516:    "https://host/",
        !           517:    0, 0, CURLUE_OK, CURLUE_OK},
        !           518:   {"https://user:secret@host/",
        !           519:    "user=NULL,password=NULL,",
        !           520:    "https://host/",
        !           521:    0, 0, CURLUE_OK, CURLUE_OK},
        !           522:   {NULL,
        !           523:    "scheme=https,user=   @:,host=foobar,",
        !           524:    "https://%20%20%20%40%3a@foobar/",
        !           525:    0, CURLU_URLENCODE, CURLUE_OK, CURLUE_OK},
        !           526:   {NULL,
        !           527:    "scheme=https,host=  ,path= ,user= ,password= ,query= ,fragment= ,",
        !           528:    "https://%20:%20@%20%20/%20?+#%20",
        !           529:    0, CURLU_URLENCODE, CURLUE_OK, CURLUE_OK},
        !           530:   {NULL,
        !           531:    "scheme=https,host=foobar,path=/this /path /is /here,",
        !           532:    "https://foobar/this%20/path%20/is%20/here",
        !           533:    0, CURLU_URLENCODE, CURLUE_OK, CURLUE_OK},
        !           534:   {NULL,
        !           535:    "scheme=https,host=foobar,path=\xc3\xa4\xc3\xb6\xc3\xbc,",
        !           536:    "https://foobar/%c3%a4%c3%b6%c3%bc",
        !           537:    0, CURLU_URLENCODE, CURLUE_OK, CURLUE_OK},
        !           538:   {"imap://user:secret;opt@host/",
        !           539:    "options=updated,scheme=imaps,password=p4ssw0rd,",
        !           540:    "imaps://user:p4ssw0rd;updated@host/",
        !           541:    0, 0, CURLUE_NO_HOST, CURLUE_OK},
        !           542:   {"imap://user:secret;optit@host/",
        !           543:    "scheme=https,",
        !           544:    "https://user:secret@host/",
        !           545:    0, 0, CURLUE_NO_HOST, CURLUE_OK},
        !           546:   {"file:///file#anchor",
        !           547:    "scheme=https,host=example,",
        !           548:    "https://example/file#anchor",
        !           549:    0, 0, CURLUE_NO_HOST, CURLUE_OK},
        !           550:   {NULL, /* start fresh! */
        !           551:    "scheme=file,host=127.0.0.1,path=/no,user=anonymous,",
        !           552:    "file:///no",
        !           553:    0, 0, CURLUE_OK, CURLUE_OK},
        !           554:   {NULL, /* start fresh! */
        !           555:    "scheme=ftp,host=127.0.0.1,path=/no,user=anonymous,",
        !           556:    "ftp://anonymous@127.0.0.1/no",
        !           557:    0, 0, CURLUE_OK, CURLUE_OK},
        !           558:   {NULL, /* start fresh! */
        !           559:    "scheme=https,host=example.com,",
        !           560:    "https://example.com/",
        !           561:    0, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK, CURLUE_OK},
        !           562:   {"http://user:foo@example.com/path?query#frag",
        !           563:    "fragment=changed,",
        !           564:    "http://user:foo@example.com/path?query#changed",
        !           565:    0, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK, CURLUE_OK},
        !           566:   {"http://example.com/",
        !           567:    "scheme=foo,", /* not accepted */
        !           568:    "http://example.com/",
        !           569:    0, 0, CURLUE_OK, CURLUE_UNSUPPORTED_SCHEME},
        !           570:   {"http://example.com/",
        !           571:    "scheme=https,path=/hello,fragment=snippet,",
        !           572:    "https://example.com/hello#snippet",
        !           573:    0, 0, CURLUE_OK, CURLUE_OK},
        !           574:   {"http://example.com:80",
        !           575:    "user=foo,port=1922,",
        !           576:    "http://foo@example.com:1922/",
        !           577:    0, 0, CURLUE_OK, CURLUE_OK},
        !           578:   {"http://example.com:80",
        !           579:    "user=foo,password=bar,",
        !           580:    "http://foo:bar@example.com:80/",
        !           581:    0, 0, CURLUE_OK, CURLUE_OK},
        !           582:   {"http://example.com:80",
        !           583:    "user=foo,",
        !           584:    "http://foo@example.com:80/",
        !           585:    0, 0, CURLUE_OK, CURLUE_OK},
        !           586:   {"http://example.com",
        !           587:    "host=www.example.com,",
        !           588:    "http://www.example.com/",
        !           589:    0, 0, CURLUE_OK, CURLUE_OK},
        !           590:   {"http://example.com:80",
        !           591:    "scheme=ftp,",
        !           592:    "ftp://example.com:80/",
        !           593:    0, 0, CURLUE_OK, CURLUE_OK},
        !           594:   {"custom-scheme://host",
        !           595:    "host=\"\",",
        !           596:    "custom-scheme://host/",
        !           597:    CURLU_NON_SUPPORT_SCHEME, CURLU_NON_SUPPORT_SCHEME, CURLUE_OK,
        !           598:    CURLUE_MALFORMED_INPUT},
        !           599:   {"custom-scheme://host",
        !           600:    "host=\"\",",
        !           601:    "custom-scheme:///",
        !           602:    CURLU_NON_SUPPORT_SCHEME, CURLU_NON_SUPPORT_SCHEME | CURLU_NO_AUTHORITY,
        !           603:    CURLUE_OK, CURLUE_OK},
        !           604: 
        !           605:   {NULL, NULL, NULL, 0, 0, 0, 0}
        !           606: };
        !           607: 
        !           608: static CURLUPart part2id(char *part)
        !           609: {
        !           610:   if(!strcmp("url", part))
        !           611:     return CURLUPART_URL;
        !           612:   if(!strcmp("scheme", part))
        !           613:     return CURLUPART_SCHEME;
        !           614:   if(!strcmp("user", part))
        !           615:     return CURLUPART_USER;
        !           616:   if(!strcmp("password", part))
        !           617:     return CURLUPART_PASSWORD;
        !           618:   if(!strcmp("options", part))
        !           619:     return CURLUPART_OPTIONS;
        !           620:   if(!strcmp("host", part))
        !           621:     return CURLUPART_HOST;
        !           622:   if(!strcmp("port", part))
        !           623:     return CURLUPART_PORT;
        !           624:   if(!strcmp("path", part))
        !           625:     return CURLUPART_PATH;
        !           626:   if(!strcmp("query", part))
        !           627:     return CURLUPART_QUERY;
        !           628:   if(!strcmp("fragment", part))
        !           629:     return CURLUPART_FRAGMENT;
        !           630:   if(!strcmp("zoneid", part))
        !           631:     return CURLUPART_ZONEID;
        !           632:   return 9999; /* bad input => bad output */
        !           633: }
        !           634: 
        !           635: static CURLUcode updateurl(CURLU *u, const char *cmd, unsigned int setflags)
        !           636: {
        !           637:   const char *p = cmd;
        !           638:   CURLUcode uc;
        !           639: 
        !           640:   /* make sure the last command ends with a comma too! */
        !           641:   while(p) {
        !           642:     char *e = strchr(p, ',');
        !           643:     if(e) {
        !           644:       size_t n = e-p;
        !           645:       char buf[80];
        !           646:       char part[80];
        !           647:       char value[80];
        !           648: 
        !           649:       memset(part, 0, sizeof(part)); /* Avoid valgrind false positive. */
        !           650:       memset(value, 0, sizeof(value)); /* Avoid valgrind false positive. */
        !           651:       memcpy(buf, p, n);
        !           652:       buf[n] = 0;
        !           653:       if(2 == sscanf(buf, "%79[^=]=%79[^,]", part, value)) {
        !           654:         CURLUPart what = part2id(part);
        !           655: #if 0
        !           656:         /* for debugging this */
        !           657:         fprintf(stderr, "%s = %s [%d]\n", part, value, (int)what);
        !           658: #endif
        !           659:         if(what > CURLUPART_ZONEID)
        !           660:           fprintf(stderr, "UNKNOWN part '%s'\n", part);
        !           661: 
        !           662:         if(!strcmp("NULL", value))
        !           663:           uc = curl_url_set(u, what, NULL, setflags);
        !           664:         else if(!strcmp("\"\"", value))
        !           665:           uc = curl_url_set(u, what, "", setflags);
        !           666:         else
        !           667:           uc = curl_url_set(u, what, value, setflags);
        !           668:         if(uc)
        !           669:           return uc;
        !           670:       }
        !           671:       p = e + 1;
        !           672:       continue;
        !           673:     }
        !           674:     break;
        !           675:   }
        !           676:   return CURLUE_OK;
        !           677: }
        !           678: 
        !           679: static struct redircase set_url_list[] = {
        !           680:   {"file://localhost/path?query#frag",
        !           681:    "foo#another",
        !           682:    "file:///foo#another",
        !           683:    0, 0, 0},
        !           684:   {"http://example.com/path?query#frag",
        !           685:    "https://two.example.com/bradnew",
        !           686:    "https://two.example.com/bradnew",
        !           687:    0, 0, 0},
        !           688:   {"http://example.com/path?query#frag",
        !           689:    "../../newpage#foo",
        !           690:    "http://example.com/newpage#foo",
        !           691:    0, 0, 0},
        !           692:   {"http://user:foo@example.com/path?query#frag",
        !           693:    "../../newpage",
        !           694:    "http://user:foo@example.com/newpage",
        !           695:    0, 0, 0},
        !           696:   {"http://user:foo@example.com/path?query#frag",
        !           697:    "../newpage",
        !           698:    "http://user:foo@example.com/newpage",
        !           699:    0, 0, 0},
        !           700:   {NULL, NULL, NULL, 0, 0, 0}
        !           701: };
        !           702: 
        !           703: static int set_url(void)
        !           704: {
        !           705:   int i;
        !           706:   int error = 0;
        !           707: 
        !           708:   for(i = 0; set_url_list[i].in && !error; i++) {
        !           709:     CURLUcode rc;
        !           710:     CURLU *urlp = curl_url();
        !           711:     if(!urlp)
        !           712:       break;
        !           713:     rc = curl_url_set(urlp, CURLUPART_URL, set_url_list[i].in,
        !           714:                       set_url_list[i].urlflags);
        !           715:     if(!rc) {
        !           716:       rc = curl_url_set(urlp, CURLUPART_URL, set_url_list[i].set,
        !           717:                         set_url_list[i].setflags);
        !           718:       if(rc) {
        !           719:         fprintf(stderr, "%s:%d Set URL %s returned %d\n",
        !           720:                 __FILE__, __LINE__, set_url_list[i].set,
        !           721:                 (int)rc);
        !           722:         error++;
        !           723:       }
        !           724:       else {
        !           725:         char *url = NULL;
        !           726:         rc = curl_url_get(urlp, CURLUPART_URL, &url, 0);
        !           727:         if(rc) {
        !           728:           fprintf(stderr, "%s:%d Get URL returned %d\n",
        !           729:                   __FILE__, __LINE__, (int)rc);
        !           730:           error++;
        !           731:         }
        !           732:         else {
        !           733:           if(checkurl(url, set_url_list[i].out)) {
        !           734:             error++;
        !           735:           }
        !           736:         }
        !           737:         curl_free(url);
        !           738:       }
        !           739:     }
        !           740:     else if(rc != set_url_list[i].ucode) {
        !           741:       fprintf(stderr, "Set URL\nin: %s\nreturned %d (expected %d)\n",
        !           742:               set_url_list[i].in, (int)rc, set_url_list[i].ucode);
        !           743:       error++;
        !           744:     }
        !           745:     curl_url_cleanup(urlp);
        !           746:   }
        !           747:   return error;
        !           748: }
        !           749: 
        !           750: static int set_parts(void)
        !           751: {
        !           752:   int i;
        !           753:   int error = 0;
        !           754: 
        !           755:   for(i = 0; set_parts_list[i].set && !error; i++) {
        !           756:     CURLUcode rc;
        !           757:     CURLU *urlp = curl_url();
        !           758:     if(!urlp) {
        !           759:       error++;
        !           760:       break;
        !           761:     }
        !           762:     if(set_parts_list[i].in)
        !           763:       rc = curl_url_set(urlp, CURLUPART_URL, set_parts_list[i].in,
        !           764:                         set_parts_list[i].urlflags);
        !           765:     else
        !           766:       rc = CURLUE_OK;
        !           767:     if(!rc) {
        !           768:       char *url = NULL;
        !           769:       CURLUcode uc = updateurl(urlp, set_parts_list[i].set,
        !           770:                                set_parts_list[i].setflags);
        !           771: 
        !           772:       if(uc != set_parts_list[i].pcode) {
        !           773:         fprintf(stderr, "updateurl\nin: %s\nreturned %d (expected %d)\n",
        !           774:                 set_parts_list[i].set, (int)uc, set_parts_list[i].pcode);
        !           775:         error++;
        !           776:       }
        !           777: 
        !           778:       rc = curl_url_get(urlp, CURLUPART_URL, &url, 0);
        !           779: 
        !           780:       if(rc) {
        !           781:         fprintf(stderr, "%s:%d Get URL returned %d\n",
        !           782:                 __FILE__, __LINE__, (int)rc);
        !           783:         error++;
        !           784:       }
        !           785:       else if(checkurl(url, set_parts_list[i].out)) {
        !           786:         error++;
        !           787:       }
        !           788:       curl_free(url);
        !           789:     }
        !           790:     else if(rc != set_parts_list[i].ucode) {
        !           791:       fprintf(stderr, "Set parts\nin: %s\nreturned %d (expected %d)\n",
        !           792:               set_parts_list[i].in, (int)rc, set_parts_list[i].ucode);
        !           793:       error++;
        !           794:     }
        !           795:     curl_url_cleanup(urlp);
        !           796:   }
        !           797:   return error;
        !           798: }
        !           799: 
        !           800: static int get_url(void)
        !           801: {
        !           802:   int i;
        !           803:   int error = 0;
        !           804:   for(i = 0; get_url_list[i].in && !error; i++) {
        !           805:     CURLUcode rc;
        !           806:     CURLU *urlp = curl_url();
        !           807:     if(!urlp) {
        !           808:       error++;
        !           809:       break;
        !           810:     }
        !           811:     rc = curl_url_set(urlp, CURLUPART_URL, get_url_list[i].in,
        !           812:                       get_url_list[i].urlflags);
        !           813:     if(!rc) {
        !           814:       char *url = NULL;
        !           815:       rc = curl_url_get(urlp, CURLUPART_URL, &url, get_url_list[i].getflags);
        !           816: 
        !           817:       if(rc) {
        !           818:         fprintf(stderr, "%s:%d returned %d\n",
        !           819:                 __FILE__, __LINE__, (int)rc);
        !           820:         error++;
        !           821:       }
        !           822:       else {
        !           823:         if(checkurl(url, get_url_list[i].out)) {
        !           824:           error++;
        !           825:         }
        !           826:       }
        !           827:       curl_free(url);
        !           828:     }
        !           829:     else if(rc != get_url_list[i].ucode) {
        !           830:       fprintf(stderr, "Get URL\nin: %s\nreturned %d (expected %d)\n",
        !           831:               get_url_list[i].in, (int)rc, get_url_list[i].ucode);
        !           832:       error++;
        !           833:     }
        !           834:     curl_url_cleanup(urlp);
        !           835:   }
        !           836:   return error;
        !           837: }
        !           838: 
        !           839: static int get_parts(void)
        !           840: {
        !           841:   int i;
        !           842:   int error = 0;
        !           843:   for(i = 0; get_parts_list[i].in && !error; i++) {
        !           844:     CURLUcode rc;
        !           845:     CURLU *urlp = curl_url();
        !           846:     if(!urlp) {
        !           847:       error++;
        !           848:       break;
        !           849:     }
        !           850:     rc = curl_url_set(urlp, CURLUPART_URL,
        !           851:                       get_parts_list[i].in,
        !           852:                       get_parts_list[i].urlflags);
        !           853:     if(rc != get_parts_list[i].ucode) {
        !           854:       fprintf(stderr, "Get parts\nin: %s\nreturned %d (expected %d)\n",
        !           855:               get_parts_list[i].in, (int)rc, get_parts_list[i].ucode);
        !           856:       error++;
        !           857:     }
        !           858:     else if(get_parts_list[i].ucode) {
        !           859:       /* the expected error happened */
        !           860:     }
        !           861:     else if(checkparts(urlp, get_parts_list[i].in, get_parts_list[i].out,
        !           862:                        get_parts_list[i].getflags))
        !           863:       error++;
        !           864:     curl_url_cleanup(urlp);
        !           865:   }
        !           866:   return error;
        !           867: }
        !           868: 
        !           869: static struct querycase append_list[] = {
        !           870:   {"HTTP://test/?s", "name=joe\x02", "http://test/?s&name=joe%02",
        !           871:    0, CURLU_URLENCODE, CURLUE_OK},
        !           872:   {"HTTP://test/?size=2#f", "name=joe=", "http://test/?size=2&name=joe%3d#f",
        !           873:    0, CURLU_URLENCODE, CURLUE_OK},
        !           874:   {"HTTP://test/?size=2#f", "name=joe doe",
        !           875:    "http://test/?size=2&name=joe+doe#f",
        !           876:    0, CURLU_URLENCODE, CURLUE_OK},
        !           877:   {"HTTP://test/", "name=joe", "http://test/?name=joe", 0, 0, CURLUE_OK},
        !           878:   {"HTTP://test/?size=2", "name=joe", "http://test/?size=2&name=joe",
        !           879:    0, 0, CURLUE_OK},
        !           880:   {"HTTP://test/?size=2&", "name=joe", "http://test/?size=2&name=joe",
        !           881:    0, 0, CURLUE_OK},
        !           882:   {"HTTP://test/?size=2#f", "name=joe", "http://test/?size=2&name=joe#f",
        !           883:    0, 0, CURLUE_OK},
        !           884:   {NULL, NULL, NULL, 0, 0, 0}
        !           885: };
        !           886: 
        !           887: static int append(void)
        !           888: {
        !           889:   int i;
        !           890:   int error = 0;
        !           891:   for(i = 0; append_list[i].in && !error; i++) {
        !           892:     CURLUcode rc;
        !           893:     CURLU *urlp = curl_url();
        !           894:     if(!urlp) {
        !           895:       error++;
        !           896:       break;
        !           897:     }
        !           898:     rc = curl_url_set(urlp, CURLUPART_URL,
        !           899:                       append_list[i].in,
        !           900:                       append_list[i].urlflags);
        !           901:     if(rc)
        !           902:       error++;
        !           903:     else
        !           904:       rc = curl_url_set(urlp, CURLUPART_QUERY,
        !           905:                         append_list[i].q,
        !           906:                         append_list[i].qflags | CURLU_APPENDQUERY);
        !           907:     if(error)
        !           908:       ;
        !           909:     else if(rc != append_list[i].ucode) {
        !           910:       fprintf(stderr, "Append\nin: %s\nreturned %d (expected %d)\n",
        !           911:               append_list[i].in, (int)rc, append_list[i].ucode);
        !           912:       error++;
        !           913:     }
        !           914:     else if(append_list[i].ucode) {
        !           915:       /* the expected error happened */
        !           916:     }
        !           917:     else {
        !           918:       char *url;
        !           919:       rc = curl_url_get(urlp, CURLUPART_URL, &url, 0);
        !           920:       if(rc) {
        !           921:         fprintf(stderr, "%s:%d Get URL returned %d\n",
        !           922:                 __FILE__, __LINE__, (int)rc);
        !           923:         error++;
        !           924:       }
        !           925:       else {
        !           926:         if(checkurl(url, append_list[i].out)) {
        !           927:           error++;
        !           928:         }
        !           929:         curl_free(url);
        !           930:       }
        !           931:     }
        !           932:     curl_url_cleanup(urlp);
        !           933:   }
        !           934:   return error;
        !           935: }
        !           936: 
        !           937: static int scopeid(void)
        !           938: {
        !           939:   CURLU *u = curl_url();
        !           940:   int error = 0;
        !           941:   CURLUcode rc;
        !           942:   char *url;
        !           943: 
        !           944:   rc = curl_url_set(u, CURLUPART_URL,
        !           945:                     "https://[fe80::20c:29ff:fe9c:409b%25eth0]/hello.html", 0);
        !           946:   if(rc != CURLUE_OK) {
        !           947:     fprintf(stderr, "%s:%d curl_url_set returned %d\n",
        !           948:             __FILE__, __LINE__, (int)rc);
        !           949:     error++;
        !           950:   }
        !           951: 
        !           952:   rc = curl_url_get(u, CURLUPART_HOST, &url, 0);
        !           953:   if(rc != CURLUE_OK) {
        !           954:     fprintf(stderr, "%s:%d curl_url_get CURLUPART_HOST returned %d\n",
        !           955:             __FILE__, __LINE__, (int)rc);
        !           956:     error++;
        !           957:   }
        !           958:   else {
        !           959:     printf("we got %s\n", url);
        !           960:     curl_free(url);
        !           961:   }
        !           962: 
        !           963:   rc = curl_url_set(u, CURLUPART_HOST, "[::1]", 0);
        !           964:   if(rc != CURLUE_OK) {
        !           965:     fprintf(stderr, "%s:%d curl_url_set CURLUPART_HOST returned %d\n",
        !           966:             __FILE__, __LINE__, (int)rc);
        !           967:     error++;
        !           968:   }
        !           969: 
        !           970:   rc = curl_url_get(u, CURLUPART_URL, &url, 0);
        !           971:   if(rc != CURLUE_OK) {
        !           972:     fprintf(stderr, "%s:%d curl_url_get CURLUPART_URL returned %d\n",
        !           973:             __FILE__, __LINE__, (int)rc);
        !           974:     error++;
        !           975:   }
        !           976:   else {
        !           977:     printf("we got %s\n", url);
        !           978:     curl_free(url);
        !           979:   }
        !           980: 
        !           981:   rc = curl_url_set(u, CURLUPART_HOST, "example.com", 0);
        !           982:   if(rc != CURLUE_OK) {
        !           983:     fprintf(stderr, "%s:%d curl_url_set CURLUPART_HOST returned %d\n",
        !           984:             __FILE__, __LINE__, (int)rc);
        !           985:     error++;
        !           986:   }
        !           987: 
        !           988:   rc = curl_url_get(u, CURLUPART_URL, &url, 0);
        !           989:   if(rc != CURLUE_OK) {
        !           990:     fprintf(stderr, "%s:%d curl_url_get CURLUPART_URL returned %d\n",
        !           991:             __FILE__, __LINE__, (int)rc);
        !           992:     error++;
        !           993:   }
        !           994:   else {
        !           995:     printf("we got %s\n", url);
        !           996:     curl_free(url);
        !           997:   }
        !           998: 
        !           999:   rc = curl_url_set(u, CURLUPART_HOST,
        !          1000:                     "[fe80::20c:29ff:fe9c:409b%25eth0]", 0);
        !          1001:   if(rc != CURLUE_OK) {
        !          1002:     fprintf(stderr, "%s:%d curl_url_set CURLUPART_HOST returned %d\n",
        !          1003:             __FILE__, __LINE__, (int)rc);
        !          1004:     error++;
        !          1005:   }
        !          1006: 
        !          1007:   rc = curl_url_get(u, CURLUPART_URL, &url, 0);
        !          1008:   if(rc != CURLUE_OK) {
        !          1009:     fprintf(stderr, "%s:%d curl_url_get CURLUPART_URL returned %d\n",
        !          1010:             __FILE__, __LINE__, (int)rc);
        !          1011:     error++;
        !          1012:   }
        !          1013:   else {
        !          1014:     printf("we got %s\n", url);
        !          1015:     curl_free(url);
        !          1016:   }
        !          1017: 
        !          1018:   rc = curl_url_get(u, CURLUPART_HOST, &url, 0);
        !          1019:   if(rc != CURLUE_OK) {
        !          1020:     fprintf(stderr, "%s:%d curl_url_get CURLUPART_HOST returned %d\n",
        !          1021:             __FILE__, __LINE__, (int)rc);
        !          1022:     error++;
        !          1023:   }
        !          1024:   else {
        !          1025:     printf("we got %s\n", url);
        !          1026:     curl_free(url);
        !          1027:   }
        !          1028: 
        !          1029:   rc = curl_url_get(u, CURLUPART_ZONEID, &url, 0);
        !          1030:   if(rc != CURLUE_OK) {
        !          1031:     fprintf(stderr, "%s:%d curl_url_get CURLUPART_ZONEID returned %d\n",
        !          1032:             __FILE__, __LINE__, (int)rc);
        !          1033:     error++;
        !          1034:   }
        !          1035:   else {
        !          1036:     printf("we got %s\n", url);
        !          1037:     curl_free(url);
        !          1038:   }
        !          1039: 
        !          1040:   rc = curl_url_set(u, CURLUPART_ZONEID, "clown", 0);
        !          1041:   if(rc != CURLUE_OK) {
        !          1042:     fprintf(stderr, "%s:%d curl_url_set CURLUPART_ZONEID returned %d\n",
        !          1043:             __FILE__, __LINE__, (int)rc);
        !          1044:     error++;
        !          1045:   }
        !          1046: 
        !          1047:   rc = curl_url_get(u, CURLUPART_URL, &url, 0);
        !          1048:   if(rc != CURLUE_OK) {
        !          1049:     fprintf(stderr, "%s:%d curl_url_get CURLUPART_URL returned %d\n",
        !          1050:             __FILE__, __LINE__, (int)rc);
        !          1051:     error++;
        !          1052:   }
        !          1053:   else {
        !          1054:     printf("we got %s\n", url);
        !          1055:     curl_free(url);
        !          1056:   }
        !          1057: 
        !          1058:   curl_url_cleanup(u);
        !          1059: 
        !          1060:   return error;
        !          1061: }
        !          1062: 
        !          1063: int test(char *URL)
        !          1064: {
        !          1065:   (void)URL; /* not used */
        !          1066: 
        !          1067:   if(scopeid())
        !          1068:     return 6;
        !          1069: 
        !          1070:   if(append())
        !          1071:     return 5;
        !          1072: 
        !          1073:   if(set_url())
        !          1074:     return 1;
        !          1075: 
        !          1076:   if(set_parts())
        !          1077:     return 2;
        !          1078: 
        !          1079:   if(get_url())
        !          1080:     return 3;
        !          1081: 
        !          1082:   if(get_parts())
        !          1083:     return 4;
        !          1084: 
        !          1085:   printf("success\n");
        !          1086:   return 0;
        !          1087: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>