UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, struct dynbuf *host,
bool has_scheme)
{
- char *portptr = NULL;
- char endbracket;
- int len;
+ char *portptr;
char *hostname = Curl_dyn_ptr(host);
/*
* Find the end of an IPv6 address, either on the ']' ending bracket or
* a percent-encoded zone index.
*/
- if(1 == sscanf(hostname, "[%*45[0123456789abcdefABCDEF:.]%c%n",
- &endbracket, &len)) {
- if(']' == endbracket)
- portptr = &hostname[len];
- else if('%' == endbracket) {
- int zonelen = len;
- if(1 == sscanf(hostname + zonelen, "%*[^]]%c%n", &endbracket, &len)) {
- if(']' != endbracket)
- return CURLUE_BAD_IPV6;
- portptr = &hostname[--zonelen + len + 1];
- }
- else
- return CURLUE_BAD_IPV6;
- }
- else
+ if(hostname[0] == '[') {
+ portptr = strchr(hostname, ']');
+ if(!portptr)
return CURLUE_BAD_IPV6;
-
+ portptr++;
/* this is a RFC2732-style specified IP-address */
- if(portptr && *portptr) {
+ if(*portptr) {
if(*portptr != ':')
- return CURLUE_BAD_IPV6;
+ return CURLUE_BAD_PORT_NUMBER;
}
else
portptr = NULL;
hostname++;
hlen -= 2;
- if(hostname[hlen] != ']')
- return CURLUE_BAD_IPV6;
-
- /* only valid letters are ok */
+ /* only valid IPv6 letters are ok */
len = strspn(hostname, l);
+
if(hlen != len) {
hlen = len;
if(hostname[len] == '%') {
while(*h && (*h != ']') && (i < 15))
zoneid[i++] = *h++;
if(!i || (']' != *h))
- /* impossible to reach? */
- return CURLUE_MALFORMED_INPUT;
+ return CURLUE_BAD_IPV6;
zoneid[i] = 0;
u->zoneid = strdup(zoneid);
if(!u->zoneid)
};
static const struct urltestcase get_url_list[] = {
+ {"https://[::%25fakeit];80/moo",
+ "",
+ 0, 0, CURLUE_BAD_PORT_NUMBER},
+ {"https://[fe80::20c:29ff:fe9c:409b]-80/moo",
+ "",
+ 0, 0, CURLUE_BAD_PORT_NUMBER},
#ifdef USE_IDN
{"https://räksmörgås.se/path?q#frag",
"https://xn--rksmrgs-5wao1o.se/path?q#frag", 0, CURLU_PUNYCODE, CURLUE_OK},
{NULL, NULL, 0, 0, CURLUE_OK}
};
-static int checkurl(const char *url, const char *out)
+static int checkurl(const char *org, const char *url, const char *out)
{
if(strcmp(out, url)) {
- fprintf(stderr, "Wanted: %s\nGot : %s\n",
- out, url);
+ fprintf(stderr,
+ "Org: %s\n"
+ "Wanted: %s\n"
+ "Got : %s\n",
+ org, out, url);
return 1;
}
return 0;
error++;
}
else {
- if(checkurl(url, set_url_list[i].out)) {
+ if(checkurl(set_url_list[i].in, url, set_url_list[i].out)) {
error++;
}
}
__FILE__, __LINE__, (int)rc, curl_url_strerror(rc));
error++;
}
- else if(checkurl(url, set_parts_list[i].out)) {
+ else if(checkurl(set_parts_list[i].in, url, set_parts_list[i].out)) {
error++;
}
}
error++;
}
else {
- if(checkurl(url, get_url_list[i].out)) {
+ if(checkurl(get_url_list[i].in, url, get_url_list[i].out)) {
error++;
}
}
error++;
}
else {
- if(checkurl(url, append_list[i].out)) {
+ if(checkurl(append_list[i].in, url, append_list[i].out)) {
error++;
}
curl_free(url);
u = curl_url();
if(!u)
goto fail;
- ipv6port = strdup("[fe80::250:56ff;fea7:da15]:80");
+ ipv6port = strdup("[fe80::250:56ff;fea7:da15]:808");
if(!ipv6port)
goto fail;
ret = parse_port(u, ipv6port, FALSE);
- fail_unless(ret != CURLUE_OK, "parse_port true on error");
+ fail_unless(ret == CURLUE_OK, "parse_port returned error");
+ ret = curl_url_get(u, CURLUPART_PORT, &portnum, 0);
+ fail_unless(ret == CURLUE_OK, "curl_url_get portnum returned error");
+ fail_unless(portnum && !strcmp(portnum, "808"), "Check portnumber");
+
+ curl_free(portnum);
free_and_clear(ipv6port);
curl_url_cleanup(u);
free_and_clear(ipv6port);
curl_url_cleanup(u);
- /* Incorrect zone index syntax */
+ /* Incorrect zone index syntax, but the port extractor doesn't care */
u = curl_url();
if(!u)
goto fail;
- ipv6port = strdup("[fe80::250:56ff:fea7:da15!25eth3]:80");
+ ipv6port = strdup("[fe80::250:56ff:fea7:da15!25eth3]:180");
if(!ipv6port)
goto fail;
ret = parse_port(u, ipv6port, FALSE);
- fail_unless(ret != CURLUE_OK, "parse_port returned non-error");
+ fail_unless(ret == CURLUE_OK, "parse_port returned error");
+ ret = curl_url_get(u, CURLUPART_PORT, &portnum, 0);
+ fail_unless(ret == CURLUE_OK, "curl_url_get portnum returned error");
+ fail_unless(portnum && !strcmp(portnum, "180"), "Check portnumber");
+ curl_free(portnum);
free_and_clear(ipv6port);
curl_url_cleanup(u);