1/*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 9 * 10 * This software is licensed as described in the file COPYING, which 11 * you should have received as part of this distribution. The terms 12 * are also available at https://curl.se/docs/copyright.html. 13 * 14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15 * copies of the Software, and permit persons to whom the Software is 16 * furnished to do so, under the terms of the COPYING file. 17 * 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 * KIND, either express or implied. 20 * 21 * SPDX-License-Identifier: curl 22 * 23 ***************************************************************************/ 24#include "curlcheck.h" 25 26#include "urldata.h" 27#include "curl/urlapi.h" 28#include "urlapi-int.h" 29 30 31static CURLU *u; 32 33static CURLcode 34unit_setup(void) 35{ 36 return CURLE_OK; 37} 38 39static void 40unit_stop(void) 41{ 42 curl_global_cleanup(); 43} 44 45#define free_and_clear(x) free(x); x = NULL 46 47static CURLUcode parse_port(CURLU *url, 48 char *h, bool has_scheme) 49{ 50 struct dynbuf host; 51 CURLUcode ret; 52 Curl_dyn_init(&host, 10000); 53 if(Curl_dyn_add(&host, h)) 54 return CURLUE_OUT_OF_MEMORY; 55 ret = Curl_parse_port(url, &host, has_scheme); 56 Curl_dyn_free(&host); 57 return ret; 58} 59 60UNITTEST_START 61{ 62 CURLUcode ret; 63 char *ipv6port = NULL; 64 char *portnum; 65 66 /* Valid IPv6 */ 67 u = curl_url(); 68 if(!u) 69 goto fail; 70 ipv6port = strdup("[fe80::250:56ff:fea7:da15]"); 71 if(!ipv6port) 72 goto fail; 73 ret = parse_port(u, ipv6port, FALSE); 74 fail_unless(ret == CURLUE_OK, "parse_port returned error"); 75 ret = curl_url_get(u, CURLUPART_PORT, &portnum, CURLU_NO_DEFAULT_PORT); 76 fail_unless(ret != CURLUE_OK, "curl_url_get portnum returned something"); 77 free_and_clear(ipv6port); 78 curl_url_cleanup(u); 79 80 /* Invalid IPv6 */ 81 u = curl_url(); 82 if(!u) 83 goto fail; 84 ipv6port = strdup("[fe80::250:56ff:fea7:da15|"); 85 if(!ipv6port) 86 goto fail; 87 ret = parse_port(u, ipv6port, FALSE); 88 fail_unless(ret != CURLUE_OK, "parse_port true on error"); 89 free_and_clear(ipv6port); 90 curl_url_cleanup(u); 91 92 u = curl_url(); 93 if(!u) 94 goto fail; 95 ipv6port = strdup("[fe80::250:56ff;fea7:da15]:808"); 96 if(!ipv6port) 97 goto fail; 98 ret = parse_port(u, ipv6port, FALSE); 99 fail_unless(ret == CURLUE_OK, "parse_port returned error"); 100 ret = curl_url_get(u, CURLUPART_PORT, &portnum, 0); 101 fail_unless(ret == CURLUE_OK, "curl_url_get portnum returned error"); 102 fail_unless(portnum && !strcmp(portnum, "808"), "Check portnumber"); 103 104 curl_free(portnum); 105 free_and_clear(ipv6port); 106 curl_url_cleanup(u); 107 108 /* Valid IPv6 with zone index and port number */ 109 u = curl_url(); 110 if(!u) 111 goto fail; 112 ipv6port = strdup("[fe80::250:56ff:fea7:da15%25eth3]:80"); 113 if(!ipv6port) 114 goto fail; 115 ret = parse_port(u, ipv6port, FALSE); 116 fail_unless(ret == CURLUE_OK, "parse_port returned error"); 117 ret = curl_url_get(u, CURLUPART_PORT, &portnum, 0); 118 fail_unless(ret == CURLUE_OK, "curl_url_get portnum returned error"); 119 fail_unless(portnum && !strcmp(portnum, "80"), "Check portnumber"); 120 curl_free(portnum); 121 free_and_clear(ipv6port); 122 curl_url_cleanup(u); 123 124 /* Valid IPv6 with zone index without port number */ 125 u = curl_url(); 126 if(!u) 127 goto fail; 128 ipv6port = strdup("[fe80::250:56ff:fea7:da15%25eth3]"); 129 if(!ipv6port) 130 goto fail; 131 ret = parse_port(u, ipv6port, FALSE); 132 fail_unless(ret == CURLUE_OK, "parse_port returned error"); 133 free_and_clear(ipv6port); 134 curl_url_cleanup(u); 135 136 /* Valid IPv6 with port number */ 137 u = curl_url(); 138 if(!u) 139 goto fail; 140 ipv6port = strdup("[fe80::250:56ff:fea7:da15]:81"); 141 if(!ipv6port) 142 goto fail; 143 ret = parse_port(u, ipv6port, FALSE); 144 fail_unless(ret == CURLUE_OK, "parse_port returned error"); 145 ret = curl_url_get(u, CURLUPART_PORT, &portnum, 0); 146 fail_unless(ret == CURLUE_OK, "curl_url_get portnum returned error"); 147 fail_unless(portnum && !strcmp(portnum, "81"), "Check portnumber"); 148 curl_free(portnum); 149 free_and_clear(ipv6port); 150 curl_url_cleanup(u); 151 152 /* Valid IPv6 with syntax error in the port number */ 153 u = curl_url(); 154 if(!u) 155 goto fail; 156 ipv6port = strdup("[fe80::250:56ff:fea7:da15];81"); 157 if(!ipv6port) 158 goto fail; 159 ret = parse_port(u, ipv6port, FALSE); 160 fail_unless(ret != CURLUE_OK, "parse_port true on error"); 161 free_and_clear(ipv6port); 162 curl_url_cleanup(u); 163 164 u = curl_url(); 165 if(!u) 166 goto fail; 167 ipv6port = strdup("[fe80::250:56ff:fea7:da15]80"); 168 if(!ipv6port) 169 goto fail; 170 ret = parse_port(u, ipv6port, FALSE); 171 fail_unless(ret != CURLUE_OK, "parse_port true on error"); 172 free_and_clear(ipv6port); 173 curl_url_cleanup(u); 174 175 /* Valid IPv6 with no port after the colon, should use default if a scheme 176 was used in the URL */ 177 u = curl_url(); 178 if(!u) 179 goto fail; 180 ipv6port = strdup("[fe80::250:56ff:fea7:da15]:"); 181 if(!ipv6port) 182 goto fail; 183 ret = parse_port(u, ipv6port, TRUE); 184 fail_unless(ret == CURLUE_OK, "parse_port returned error"); 185 free_and_clear(ipv6port); 186 curl_url_cleanup(u); 187 188 /* Incorrect zone index syntax, but the port extractor doesn't care */ 189 u = curl_url(); 190 if(!u) 191 goto fail; 192 ipv6port = strdup("[fe80::250:56ff:fea7:da15!25eth3]:180"); 193 if(!ipv6port) 194 goto fail; 195 ret = parse_port(u, ipv6port, FALSE); 196 fail_unless(ret == CURLUE_OK, "parse_port returned error"); 197 ret = curl_url_get(u, CURLUPART_PORT, &portnum, 0); 198 fail_unless(ret == CURLUE_OK, "curl_url_get portnum returned error"); 199 fail_unless(portnum && !strcmp(portnum, "180"), "Check portnumber"); 200 curl_free(portnum); 201 free_and_clear(ipv6port); 202 curl_url_cleanup(u); 203 204 /* Non percent-encoded zone index */ 205 u = curl_url(); 206 if(!u) 207 goto fail; 208 ipv6port = strdup("[fe80::250:56ff:fea7:da15%eth3]:80"); 209 if(!ipv6port) 210 goto fail; 211 ret = parse_port(u, ipv6port, FALSE); 212 fail_unless(ret == CURLUE_OK, "parse_port returned error"); 213 free_and_clear(ipv6port); 214 curl_url_cleanup(u); 215 216 /* No scheme and no digits following the colon - not accepted. Because that 217 makes (a*50):// that looks like a scheme be an acceptable input. */ 218 u = curl_url(); 219 if(!u) 220 goto fail; 221 ipv6port = strdup("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 222 "aaaaaaaaaaaaaaaaaaaaaa:"); 223 if(!ipv6port) 224 goto fail; 225 ret = parse_port(u, ipv6port, FALSE); 226 fail_unless(ret == CURLUE_BAD_PORT_NUMBER, "parse_port did wrong"); 227fail: 228 free(ipv6port); 229 curl_url_cleanup(u); 230 231} 232UNITTEST_STOP 233