mirror of
https://github.com/curl/curl.git
synced 2026-08-25 21:23:32 +03:00
urlapi: allow setting port number zero
Also set and check errno when strtoul() parsing numbers for better error checking. Updated test 1560 Closes #13427
This commit is contained in:
parent
ac49152e26
commit
fe17c162d0
2 changed files with 37 additions and 35 deletions
65
lib/urlapi.c
65
lib/urlapi.c
|
|
@ -79,7 +79,7 @@ struct Curl_URL {
|
||||||
char *path;
|
char *path;
|
||||||
char *query;
|
char *query;
|
||||||
char *fragment;
|
char *fragment;
|
||||||
unsigned short portnum; /* the numerical version */
|
unsigned short portnum; /* the numerical version (if 'port' is set) */
|
||||||
BIT(query_present); /* to support blank */
|
BIT(query_present); /* to support blank */
|
||||||
BIT(fragment_present); /* to support blank */
|
BIT(fragment_present); /* to support blank */
|
||||||
};
|
};
|
||||||
|
|
@ -537,7 +537,7 @@ UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, struct dynbuf *host,
|
||||||
|
|
||||||
if(portptr) {
|
if(portptr) {
|
||||||
char *rest = NULL;
|
char *rest = NULL;
|
||||||
long port;
|
unsigned long port;
|
||||||
size_t keep = portptr - hostname;
|
size_t keep = portptr - hostname;
|
||||||
|
|
||||||
/* Browser behavior adaptation. If there's a colon with no digits after,
|
/* Browser behavior adaptation. If there's a colon with no digits after,
|
||||||
|
|
@ -555,12 +555,10 @@ UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, struct dynbuf *host,
|
||||||
if(!ISDIGIT(*portptr))
|
if(!ISDIGIT(*portptr))
|
||||||
return CURLUE_BAD_PORT_NUMBER;
|
return CURLUE_BAD_PORT_NUMBER;
|
||||||
|
|
||||||
port = strtol(portptr, &rest, 10); /* Port number must be decimal */
|
errno = 0;
|
||||||
|
port = strtoul(portptr, &rest, 10); /* Port number must be decimal */
|
||||||
|
|
||||||
if(port > 0xffff)
|
if(errno || (port > 0xffff) || *rest)
|
||||||
return CURLUE_BAD_PORT_NUMBER;
|
|
||||||
|
|
||||||
if(rest[0])
|
|
||||||
return CURLUE_BAD_PORT_NUMBER;
|
return CURLUE_BAD_PORT_NUMBER;
|
||||||
|
|
||||||
u->portnum = (unsigned short) port;
|
u->portnum = (unsigned short) port;
|
||||||
|
|
@ -685,6 +683,7 @@ static int ipv4_normalize(struct dynbuf *host)
|
||||||
if(*c == '[')
|
if(*c == '[')
|
||||||
return HOST_IPV6;
|
return HOST_IPV6;
|
||||||
|
|
||||||
|
errno = 0; /* for strtoul */
|
||||||
while(!done) {
|
while(!done) {
|
||||||
char *endp = NULL;
|
char *endp = NULL;
|
||||||
unsigned long l;
|
unsigned long l;
|
||||||
|
|
@ -692,6 +691,13 @@ static int ipv4_normalize(struct dynbuf *host)
|
||||||
/* most importantly this doesn't allow a leading plus or minus */
|
/* most importantly this doesn't allow a leading plus or minus */
|
||||||
return HOST_NAME;
|
return HOST_NAME;
|
||||||
l = strtoul(c, &endp, 0);
|
l = strtoul(c, &endp, 0);
|
||||||
|
if(errno)
|
||||||
|
return HOST_NAME;
|
||||||
|
#if SIZEOF_LONG > 4
|
||||||
|
/* a value larger than 32 bits */
|
||||||
|
if(l > UINT_MAX)
|
||||||
|
return HOST_NAME;
|
||||||
|
#endif
|
||||||
|
|
||||||
parts[n] = l;
|
parts[n] = l;
|
||||||
c = endp;
|
c = endp;
|
||||||
|
|
@ -711,16 +717,6 @@ static int ipv4_normalize(struct dynbuf *host)
|
||||||
default:
|
default:
|
||||||
return HOST_NAME;
|
return HOST_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* overflow */
|
|
||||||
if((l == ULONG_MAX) && (errno == ERANGE))
|
|
||||||
return HOST_NAME;
|
|
||||||
|
|
||||||
#if SIZEOF_LONG > 4
|
|
||||||
/* a value larger than 32 bits */
|
|
||||||
if(l > UINT_MAX)
|
|
||||||
return HOST_NAME;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(n) {
|
switch(n) {
|
||||||
|
|
@ -1707,7 +1703,6 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
|
||||||
const char *part, unsigned int flags)
|
const char *part, unsigned int flags)
|
||||||
{
|
{
|
||||||
char **storep = NULL;
|
char **storep = NULL;
|
||||||
long port = 0;
|
|
||||||
bool urlencode = (flags & CURLU_URLENCODE)? 1 : 0;
|
bool urlencode = (flags & CURLU_URLENCODE)? 1 : 0;
|
||||||
bool plusencode = FALSE;
|
bool plusencode = FALSE;
|
||||||
bool urlskipslash = FALSE;
|
bool urlskipslash = FALSE;
|
||||||
|
|
@ -1816,18 +1811,26 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
|
||||||
storep = &u->zoneid;
|
storep = &u->zoneid;
|
||||||
break;
|
break;
|
||||||
case CURLUPART_PORT:
|
case CURLUPART_PORT:
|
||||||
{
|
if(!ISDIGIT(part[0]))
|
||||||
char *endp;
|
/* not a number */
|
||||||
urlencode = FALSE; /* never */
|
|
||||||
port = strtol(part, &endp, 10); /* Port number must be decimal */
|
|
||||||
if((port <= 0) || (port > 0xffff))
|
|
||||||
return CURLUE_BAD_PORT_NUMBER;
|
return CURLUE_BAD_PORT_NUMBER;
|
||||||
if(*endp)
|
else {
|
||||||
/* weirdly provided number, not good! */
|
char *tmp;
|
||||||
return CURLUE_BAD_PORT_NUMBER;
|
char *endp;
|
||||||
storep = &u->port;
|
unsigned long port;
|
||||||
}
|
errno = 0;
|
||||||
break;
|
port = strtoul(part, &endp, 10); /* must be decimal */
|
||||||
|
if(errno || (port > 0xffff) || *endp)
|
||||||
|
/* weirdly provided number, not good! */
|
||||||
|
return CURLUE_BAD_PORT_NUMBER;
|
||||||
|
tmp = strdup(part);
|
||||||
|
if(!tmp)
|
||||||
|
return CURLUE_OUT_OF_MEMORY;
|
||||||
|
free(u->port);
|
||||||
|
u->port = tmp;
|
||||||
|
u->portnum = (unsigned short)port;
|
||||||
|
return CURLUE_OK;
|
||||||
|
}
|
||||||
case CURLUPART_PATH:
|
case CURLUPART_PATH:
|
||||||
urlskipslash = TRUE;
|
urlskipslash = TRUE;
|
||||||
leadingslash = TRUE; /* enforce */
|
leadingslash = TRUE; /* enforce */
|
||||||
|
|
@ -1990,9 +1993,5 @@ nomem:
|
||||||
free(*storep);
|
free(*storep);
|
||||||
*storep = (char *)newp;
|
*storep = (char *)newp;
|
||||||
}
|
}
|
||||||
/* set after the string, to make it not assigned if the allocation above
|
|
||||||
fails */
|
|
||||||
if(port)
|
|
||||||
u->portnum = (unsigned short)port;
|
|
||||||
return CURLUE_OK;
|
return CURLUE_OK;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,9 @@ struct clearurlcase {
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct testcase get_parts_list[] ={
|
static const struct testcase get_parts_list[] ={
|
||||||
|
{"https://curl.se:0/#",
|
||||||
|
"https | [11] | [12] | [13] | curl.se | 0 | / | [16] | ",
|
||||||
|
0, CURLU_GET_EMPTY, CURLUE_OK},
|
||||||
{"https://curl.se/#",
|
{"https://curl.se/#",
|
||||||
"https | [11] | [12] | [13] | curl.se | [15] | / | [16] | ",
|
"https | [11] | [12] | [13] | curl.se | [15] | / | [16] | ",
|
||||||
0, CURLU_GET_EMPTY, CURLUE_OK},
|
0, CURLU_GET_EMPTY, CURLUE_OK},
|
||||||
|
|
@ -941,8 +944,8 @@ static const struct setcase set_parts_list[] = {
|
||||||
0, 0, CURLUE_OK, CURLUE_BAD_PORT_NUMBER},
|
0, 0, CURLUE_OK, CURLUE_BAD_PORT_NUMBER},
|
||||||
{"https://host:1234/",
|
{"https://host:1234/",
|
||||||
"port=0,",
|
"port=0,",
|
||||||
"https://host:1234/",
|
"https://host:0/",
|
||||||
0, 0, CURLUE_OK, CURLUE_BAD_PORT_NUMBER},
|
0, 0, CURLUE_OK, CURLUE_OK},
|
||||||
{"https://host:1234/",
|
{"https://host:1234/",
|
||||||
"port=65535,",
|
"port=65535,",
|
||||||
"https://host:65535/",
|
"https://host:65535/",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue