xref: /curl/tests/unit/unit1653.c (revision f198d33e)
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 
31 static CURLU *u;
32 
33 static CURLcode
unit_setup(void)34 unit_setup(void)
35 {
36   return CURLE_OK;
37 }
38 
39 static void
unit_stop(void)40 unit_stop(void)
41 {
42   curl_global_cleanup();
43 }
44 
45 #define free_and_clear(x) free(x); x = NULL
46 
parse_port(CURLU * url,char * h,bool has_scheme)47 static 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 
60 UNITTEST_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");
227 fail:
228   free(ipv6port);
229   curl_url_cleanup(u);
230 
231 }
232 UNITTEST_STOP
233