lib: use Curl_str_number() for parsing decimal numbers
Instead of strtoul() and strtol() calls. Easier API with better integer overflow detection and built-in max check that now comes automatic everywhere this is used. Closes #16319
This commit is contained in:
parent
130b6891c8
commit
b696fc129b
21
lib/altsvc.c
21
lib/altsvc.c
@ -528,8 +528,7 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
|
|||||||
size_t dstlen = 0; /* destination hostname length */
|
size_t dstlen = 0; /* destination hostname length */
|
||||||
const char *value_ptr;
|
const char *value_ptr;
|
||||||
char option[32];
|
char option[32];
|
||||||
unsigned long num;
|
size_t num;
|
||||||
char *end_ptr;
|
|
||||||
bool quoted = FALSE;
|
bool quoted = FALSE;
|
||||||
time_t maxage = 24 * 3600; /* default is 24 hours */
|
time_t maxage = 24 * 3600; /* default is 24 hours */
|
||||||
bool persist = FALSE;
|
bool persist = FALSE;
|
||||||
@ -567,21 +566,14 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
|
|||||||
dstlen = strlen(srchost);
|
dstlen = strlen(srchost);
|
||||||
}
|
}
|
||||||
if(*p == ':') {
|
if(*p == ':') {
|
||||||
unsigned long port = 0;
|
size_t port = 0;
|
||||||
p++;
|
p++;
|
||||||
if(ISDIGIT(*p))
|
if(Curl_str_number(&p, &port, 0xffff) || (*p != '\"')) {
|
||||||
/* a port number */
|
|
||||||
port = strtoul(p, &end_ptr, 10);
|
|
||||||
else
|
|
||||||
end_ptr = (char *)p; /* not left uninitialized */
|
|
||||||
if(!port || port > USHRT_MAX || end_ptr == p || *end_ptr != '\"') {
|
|
||||||
infof(data, "Unknown alt-svc port number, ignoring.");
|
infof(data, "Unknown alt-svc port number, ignoring.");
|
||||||
valid = FALSE;
|
valid = FALSE;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
dstport = curlx_ultous(port);
|
dstport = (unsigned short)port;
|
||||||
p = end_ptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(*p++ != '\"')
|
if(*p++ != '\"')
|
||||||
break;
|
break;
|
||||||
@ -625,8 +617,7 @@ CURLcode Curl_altsvc_parse(struct Curl_easy *data,
|
|||||||
while(*p && !ISBLANK(*p) && *p!= ';' && *p != ',')
|
while(*p && !ISBLANK(*p) && *p!= ';' && *p != ',')
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
num = strtoul(value_ptr, &end_ptr, 10);
|
if(!Curl_str_number(&value_ptr, &num, SIZE_T_MAX)) {
|
||||||
if((end_ptr != value_ptr) && (num < ULONG_MAX)) {
|
|
||||||
if(strcasecompare("ma", option))
|
if(strcasecompare("ma", option))
|
||||||
maxage = (time_t)num;
|
maxage = (time_t)num;
|
||||||
else if(strcasecompare("persist", option) && (num == 1))
|
else if(strcasecompare("persist", option) && (num == 1))
|
||||||
|
|||||||
@ -83,6 +83,7 @@
|
|||||||
#include "share.h"
|
#include "share.h"
|
||||||
#include "strdup.h"
|
#include "strdup.h"
|
||||||
#include "version_win32.h"
|
#include "version_win32.h"
|
||||||
|
#include "strparse.h"
|
||||||
|
|
||||||
/* The last 3 #include files should be in this order */
|
/* The last 3 #include files should be in this order */
|
||||||
#include "curl_printf.h"
|
#include "curl_printf.h"
|
||||||
@ -741,10 +742,9 @@ static CURLcode bindlocal(struct Curl_easy *data, struct connectdata *conn,
|
|||||||
Curl_printable_address. The latter returns only numeric scope
|
Curl_printable_address. The latter returns only numeric scope
|
||||||
IDs and the former returns none at all. So the scope ID, if
|
IDs and the former returns none at all. So the scope ID, if
|
||||||
present, is known to be numeric */
|
present, is known to be numeric */
|
||||||
unsigned long scope_id = strtoul(scope_ptr, NULL, 10);
|
size_t scope_id;
|
||||||
if(scope_id > UINT_MAX)
|
if(Curl_str_number((const char **)&scope_ptr, &scope_id, UINT_MAX))
|
||||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||||
|
|
||||||
si6->sin6_scope_id = (unsigned int)scope_id;
|
si6->sin6_scope_id = (unsigned int)scope_id;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
62
lib/ftp.c
62
lib/ftp.c
@ -73,6 +73,7 @@
|
|||||||
#include "http_proxy.h"
|
#include "http_proxy.h"
|
||||||
#include "socks.h"
|
#include "socks.h"
|
||||||
#include "strdup.h"
|
#include "strdup.h"
|
||||||
|
#include "strparse.h"
|
||||||
/* The last 3 #include files should be in this order */
|
/* The last 3 #include files should be in this order */
|
||||||
#include "curl_printf.h"
|
#include "curl_printf.h"
|
||||||
#include "curl_memory.h"
|
#include "curl_memory.h"
|
||||||
@ -464,7 +465,7 @@ static CURLcode ftp_check_ctrl_on_data_wait(struct Curl_easy *data)
|
|||||||
if(response) {
|
if(response) {
|
||||||
infof(data, "Ctrl conn has data while waiting for data conn");
|
infof(data, "Ctrl conn has data while waiting for data conn");
|
||||||
if(pp->overflow > 3) {
|
if(pp->overflow > 3) {
|
||||||
char *r = Curl_dyn_ptr(&pp->recvbuf);
|
const char *r = Curl_dyn_ptr(&pp->recvbuf);
|
||||||
|
|
||||||
DEBUGASSERT((pp->overflow + pp->nfinal) <=
|
DEBUGASSERT((pp->overflow + pp->nfinal) <=
|
||||||
Curl_dyn_len(&pp->recvbuf));
|
Curl_dyn_len(&pp->recvbuf));
|
||||||
@ -472,8 +473,8 @@ static CURLcode ftp_check_ctrl_on_data_wait(struct Curl_easy *data)
|
|||||||
r += pp->nfinal;
|
r += pp->nfinal;
|
||||||
|
|
||||||
if(LASTLINE(r)) {
|
if(LASTLINE(r)) {
|
||||||
int status = curlx_sltosi(strtol(r, NULL, 10));
|
size_t status;
|
||||||
if(status == 226) {
|
if(!Curl_str_number(&r, &status, 999) && (status == 226)) {
|
||||||
/* funny timing situation where we get the final message on the
|
/* funny timing situation where we get the final message on the
|
||||||
control connection before traffic on the data connection has been
|
control connection before traffic on the data connection has been
|
||||||
noticed. Leave the 226 in there and use this as a trigger to read
|
noticed. Leave the 226 in there and use this as a trigger to read
|
||||||
@ -541,13 +542,14 @@ static CURLcode InitiateTransfer(struct Curl_easy *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool ftp_endofresp(struct Curl_easy *data, struct connectdata *conn,
|
static bool ftp_endofresp(struct Curl_easy *data, struct connectdata *conn,
|
||||||
char *line, size_t len, int *code)
|
const char *line, size_t len, int *code)
|
||||||
{
|
{
|
||||||
|
size_t status;
|
||||||
(void)data;
|
(void)data;
|
||||||
(void)conn;
|
(void)conn;
|
||||||
|
|
||||||
if((len > 3) && LASTLINE(line)) {
|
if((len > 3) && LASTLINE(line) && !Curl_str_number(&line, &status, 999)) {
|
||||||
*code = curlx_sltosi(strtol(line, NULL, 10));
|
*code = (int)status;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -925,13 +927,20 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
|
|||||||
|
|
||||||
/* parse the port */
|
/* parse the port */
|
||||||
if(ip_end) {
|
if(ip_end) {
|
||||||
char *port_sep = NULL;
|
const char *portp = strchr(ip_end, ':');
|
||||||
char *port_start = strchr(ip_end, ':');
|
if(portp) {
|
||||||
if(port_start) {
|
size_t start;
|
||||||
port_min = curlx_ultous(strtoul(port_start + 1, NULL, 10));
|
size_t end;
|
||||||
port_sep = strchr(port_start, '-');
|
portp++;
|
||||||
if(port_sep) {
|
if(!Curl_str_number(&portp, &start, 0xffff)) {
|
||||||
port_max = curlx_ultous(strtoul(port_sep + 1, NULL, 10));
|
/* got the first number */
|
||||||
|
port_min = (unsigned short)start;
|
||||||
|
if(!Curl_str_single(&portp, '-')) {
|
||||||
|
/* got the dash */
|
||||||
|
if(!Curl_str_number(&portp, &end, 0xffff))
|
||||||
|
/* got the second number */
|
||||||
|
port_max = (unsigned short)end;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
port_max = port_min;
|
port_max = port_min;
|
||||||
@ -1758,20 +1767,15 @@ static bool match_pasv_6nums(const char *p,
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for(i = 0; i < 6; i++) {
|
for(i = 0; i < 6; i++) {
|
||||||
unsigned long num;
|
size_t num;
|
||||||
char *endp;
|
|
||||||
if(i) {
|
if(i) {
|
||||||
if(*p != ',')
|
if(*p != ',')
|
||||||
return FALSE;
|
return FALSE;
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
if(!ISDIGIT(*p))
|
if(Curl_str_number(&p, &num, 0xff))
|
||||||
return FALSE;
|
|
||||||
num = strtoul(p, &endp, 10);
|
|
||||||
if(num > 255)
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
array[i] = (unsigned int)num;
|
array[i] = (unsigned int)num;
|
||||||
p = endp;
|
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -1804,20 +1808,16 @@ static CURLcode ftp_state_pasv_resp(struct Curl_easy *data,
|
|||||||
/* the ISDIGIT() check here is because strtoul() accepts leading minus
|
/* the ISDIGIT() check here is because strtoul() accepts leading minus
|
||||||
etc */
|
etc */
|
||||||
if((ptr[1] == sep) && (ptr[2] == sep) && ISDIGIT(ptr[3])) {
|
if((ptr[1] == sep) && (ptr[2] == sep) && ISDIGIT(ptr[3])) {
|
||||||
char *endp;
|
const char *p = &ptr[3];
|
||||||
unsigned long num = strtoul(&ptr[3], &endp, 10);
|
size_t num;
|
||||||
if(*endp != sep)
|
if(Curl_str_number(&p, &num, 0xffff) || (*p != sep)) {
|
||||||
ptr = NULL;
|
|
||||||
else if(num > 0xffff) {
|
|
||||||
failf(data, "Illegal port number in EPSV reply");
|
failf(data, "Illegal port number in EPSV reply");
|
||||||
return CURLE_FTP_WEIRD_PASV_REPLY;
|
return CURLE_FTP_WEIRD_PASV_REPLY;
|
||||||
}
|
}
|
||||||
if(ptr) {
|
ftpc->newport = (unsigned short)num;
|
||||||
ftpc->newport = (unsigned short)(num & 0xffff);
|
ftpc->newhost = strdup(control_address(conn));
|
||||||
ftpc->newhost = strdup(control_address(conn));
|
if(!ftpc->newhost)
|
||||||
if(!ftpc->newhost)
|
return CURLE_OUT_OF_MEMORY;
|
||||||
return CURLE_OUT_OF_MEMORY;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ptr = NULL;
|
ptr = NULL;
|
||||||
|
|||||||
@ -50,9 +50,12 @@
|
|||||||
#include "ftp.h"
|
#include "ftp.h"
|
||||||
#include "ftplistparser.h"
|
#include "ftplistparser.h"
|
||||||
#include "curl_fnmatch.h"
|
#include "curl_fnmatch.h"
|
||||||
#include "curl_memory.h"
|
|
||||||
#include "multiif.h"
|
#include "multiif.h"
|
||||||
/* The last #include file should be: */
|
#include "strparse.h"
|
||||||
|
|
||||||
|
/* The last 3 #include files should be in this order */
|
||||||
|
#include "curl_printf.h"
|
||||||
|
#include "curl_memory.h"
|
||||||
#include "memdebug.h"
|
#include "memdebug.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -543,13 +546,13 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
|
|||||||
case PL_UNIX_HLINKS_NUMBER:
|
case PL_UNIX_HLINKS_NUMBER:
|
||||||
parser->item_length ++;
|
parser->item_length ++;
|
||||||
if(c == ' ') {
|
if(c == ' ') {
|
||||||
char *p;
|
const char *p = &mem[parser->item_offset];
|
||||||
long int hlinks;
|
size_t hlinks;
|
||||||
mem[parser->item_offset + parser->item_length - 1] = 0;
|
mem[parser->item_offset + parser->item_length - 1] = 0;
|
||||||
hlinks = strtol(mem + parser->item_offset, &p, 10);
|
|
||||||
if(p[0] == '\0' && hlinks != LONG_MAX && hlinks != LONG_MIN) {
|
if(!Curl_str_number(&p, &hlinks, LONG_MAX)) {
|
||||||
parser->file_data->info.flags |= CURLFINFOFLAG_KNOWN_HLINKCOUNT;
|
parser->file_data->info.flags |= CURLFINFOFLAG_KNOWN_HLINKCOUNT;
|
||||||
parser->file_data->info.hardlinks = hlinks;
|
parser->file_data->info.hardlinks = (long)hlinks;
|
||||||
}
|
}
|
||||||
parser->item_length = 0;
|
parser->item_length = 0;
|
||||||
parser->item_offset = 0;
|
parser->item_offset = 0;
|
||||||
|
|||||||
42
lib/hostip.c
42
lib/hostip.c
@ -58,6 +58,8 @@
|
|||||||
#include "warnless.h"
|
#include "warnless.h"
|
||||||
#include "strcase.h"
|
#include "strcase.h"
|
||||||
#include "easy_lock.h"
|
#include "easy_lock.h"
|
||||||
|
#include "strparse.h"
|
||||||
|
|
||||||
/* The last 3 #include files should be in this order */
|
/* The last 3 #include files should be in this order */
|
||||||
#include "curl_printf.h"
|
#include "curl_printf.h"
|
||||||
#include "curl_memory.h"
|
#include "curl_memory.h"
|
||||||
@ -1122,7 +1124,7 @@ void Curl_hostcache_clean(struct Curl_easy *data,
|
|||||||
CURLcode Curl_loadhostpairs(struct Curl_easy *data)
|
CURLcode Curl_loadhostpairs(struct Curl_easy *data)
|
||||||
{
|
{
|
||||||
struct curl_slist *hostp;
|
struct curl_slist *hostp;
|
||||||
char *host_end;
|
const char *host_end;
|
||||||
|
|
||||||
/* Default is no wildcard found */
|
/* Default is no wildcard found */
|
||||||
data->state.wildcard_resolve = FALSE;
|
data->state.wildcard_resolve = FALSE;
|
||||||
@ -1132,15 +1134,15 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
|
|||||||
if(!hostp->data)
|
if(!hostp->data)
|
||||||
continue;
|
continue;
|
||||||
if(hostp->data[0] == '-') {
|
if(hostp->data[0] == '-') {
|
||||||
unsigned long num = 0;
|
size_t num = 0;
|
||||||
size_t entry_len;
|
size_t entry_len;
|
||||||
size_t hlen = 0;
|
size_t hlen = 0;
|
||||||
host_end = strchr(&hostp->data[1], ':');
|
host_end = strchr(&hostp->data[1], ':');
|
||||||
|
|
||||||
if(host_end) {
|
if(host_end) {
|
||||||
hlen = host_end - &hostp->data[1];
|
hlen = host_end - &hostp->data[1];
|
||||||
num = strtoul(++host_end, NULL, 10);
|
host_end++;
|
||||||
if(!hlen || (num > 0xffff))
|
if(Curl_str_number(&host_end, &num, 0xffff))
|
||||||
host_end = NULL;
|
host_end = NULL;
|
||||||
}
|
}
|
||||||
if(!host_end) {
|
if(!host_end) {
|
||||||
@ -1166,15 +1168,14 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
|
|||||||
size_t entry_len;
|
size_t entry_len;
|
||||||
char address[64];
|
char address[64];
|
||||||
#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||||
char *addresses = NULL;
|
const char *addresses = NULL;
|
||||||
#endif
|
#endif
|
||||||
char *addr_begin;
|
const char *addr_begin;
|
||||||
char *addr_end;
|
const char *addr_end;
|
||||||
char *port_ptr;
|
const char *port_ptr;
|
||||||
int port = 0;
|
size_t port = 0;
|
||||||
char *end_ptr;
|
const char *end_ptr;
|
||||||
bool permanent = TRUE;
|
bool permanent = TRUE;
|
||||||
unsigned long tmp_port;
|
|
||||||
bool error = TRUE;
|
bool error = TRUE;
|
||||||
char *host_begin = hostp->data;
|
char *host_begin = hostp->data;
|
||||||
size_t hlen = 0;
|
size_t hlen = 0;
|
||||||
@ -1189,11 +1190,11 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
|
|||||||
hlen = host_end - host_begin;
|
hlen = host_end - host_begin;
|
||||||
|
|
||||||
port_ptr = host_end + 1;
|
port_ptr = host_end + 1;
|
||||||
tmp_port = strtoul(port_ptr, &end_ptr, 10);
|
if(Curl_str_number(&port_ptr, &port, 0xffff) ||
|
||||||
if(tmp_port > USHRT_MAX || end_ptr == port_ptr || *end_ptr != ':')
|
(*port_ptr != ':'))
|
||||||
goto err;
|
goto err;
|
||||||
|
end_ptr = port_ptr;
|
||||||
|
|
||||||
port = (int)tmp_port;
|
|
||||||
#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||||
addresses = end_ptr + 1;
|
addresses = end_ptr + 1;
|
||||||
#endif
|
#endif
|
||||||
@ -1234,7 +1235,7 @@ CURLcode Curl_loadhostpairs(struct Curl_easy *data)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ai = Curl_str2addr(address, port);
|
ai = Curl_str2addr(address, (int)port);
|
||||||
if(!ai) {
|
if(!ai) {
|
||||||
infof(data, "Resolve address '%s' found illegal", address);
|
infof(data, "Resolve address '%s' found illegal", address);
|
||||||
goto err;
|
goto err;
|
||||||
@ -1262,7 +1263,7 @@ err:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Create an entry id, based upon the hostname and port */
|
/* Create an entry id, based upon the hostname and port */
|
||||||
entry_len = create_hostcache_id(host_begin, hlen, port,
|
entry_len = create_hostcache_id(host_begin, hlen, (int)port,
|
||||||
entry_id, sizeof(entry_id));
|
entry_id, sizeof(entry_id));
|
||||||
|
|
||||||
if(data->share)
|
if(data->share)
|
||||||
@ -1272,7 +1273,7 @@ err:
|
|||||||
dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len + 1);
|
dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len + 1);
|
||||||
|
|
||||||
if(dns) {
|
if(dns) {
|
||||||
infof(data, "RESOLVE %.*s:%d - old addresses discarded",
|
infof(data, "RESOLVE %.*s:%zd - old addresses discarded",
|
||||||
(int)hlen, host_begin, port);
|
(int)hlen, host_begin, port);
|
||||||
/* delete old entry, there are two reasons for this
|
/* delete old entry, there are two reasons for this
|
||||||
1. old entry may have different addresses.
|
1. old entry may have different addresses.
|
||||||
@ -1289,7 +1290,8 @@ err:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* put this new host in the cache */
|
/* put this new host in the cache */
|
||||||
dns = Curl_cache_addr(data, head, host_begin, hlen, port, permanent);
|
dns = Curl_cache_addr(data, head, host_begin, hlen, (int)port,
|
||||||
|
permanent);
|
||||||
if(dns) {
|
if(dns) {
|
||||||
/* release the returned reference; the cache itself will keep the
|
/* release the returned reference; the cache itself will keep the
|
||||||
* entry alive: */
|
* entry alive: */
|
||||||
@ -1304,14 +1306,14 @@ err:
|
|||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
#ifndef CURL_DISABLE_VERBOSE_STRINGS
|
||||||
infof(data, "Added %.*s:%d:%s to DNS cache%s",
|
infof(data, "Added %.*s:%zd:%s to DNS cache%s",
|
||||||
(int)hlen, host_begin, port, addresses,
|
(int)hlen, host_begin, port, addresses,
|
||||||
permanent ? "" : " (non-permanent)");
|
permanent ? "" : " (non-permanent)");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Wildcard hostname */
|
/* Wildcard hostname */
|
||||||
if((hlen == 1) && (host_begin[0] == '*')) {
|
if((hlen == 1) && (host_begin[0] == '*')) {
|
||||||
infof(data, "RESOLVE *:%d using wildcard", port);
|
infof(data, "RESOLVE *:%zd using wildcard", port);
|
||||||
data->state.wildcard_resolve = TRUE;
|
data->state.wildcard_resolve = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -242,7 +242,7 @@ static bool imap_matchresp(const char *line, size_t len, const char *cmd)
|
|||||||
* response which can be processed by the response handler.
|
* response which can be processed by the response handler.
|
||||||
*/
|
*/
|
||||||
static bool imap_endofresp(struct Curl_easy *data, struct connectdata *conn,
|
static bool imap_endofresp(struct Curl_easy *data, struct connectdata *conn,
|
||||||
char *line, size_t len, int *resp)
|
const char *line, size_t len, int *resp)
|
||||||
{
|
{
|
||||||
struct IMAP *imap = data->req.p.imap;
|
struct IMAP *imap = data->req.p.imap;
|
||||||
struct imap_conn *imapc = &conn->proto.imapc;
|
struct imap_conn *imapc = &conn->proto.imapc;
|
||||||
|
|||||||
@ -83,6 +83,7 @@
|
|||||||
#include "strcase.h"
|
#include "strcase.h"
|
||||||
#include "warnless.h"
|
#include "warnless.h"
|
||||||
#include "parsedate.h"
|
#include "parsedate.h"
|
||||||
|
#include "strparse.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* parsedate()
|
* parsedate()
|
||||||
@ -411,7 +412,7 @@ static int parsedate(const char *date, time_t *output)
|
|||||||
}
|
}
|
||||||
else if(ISDIGIT(*date)) {
|
else if(ISDIGIT(*date)) {
|
||||||
/* a digit */
|
/* a digit */
|
||||||
int val;
|
unsigned int val;
|
||||||
char *end;
|
char *end;
|
||||||
if((secnum == -1) &&
|
if((secnum == -1) &&
|
||||||
match_time(date, &hournum, &minnum, &secnum, &end)) {
|
match_time(date, &hournum, &minnum, &secnum, &end)) {
|
||||||
@ -419,29 +420,18 @@ static int parsedate(const char *date, time_t *output)
|
|||||||
date = end;
|
date = end;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
long lval;
|
size_t lval;
|
||||||
int error;
|
int num_digits = 0;
|
||||||
int old_errno;
|
const char *p = date;
|
||||||
|
if(Curl_str_number(&p, &lval, 99999999))
|
||||||
old_errno = errno;
|
|
||||||
errno = 0;
|
|
||||||
lval = strtol(date, &end, 10);
|
|
||||||
error = errno;
|
|
||||||
if(errno != old_errno)
|
|
||||||
errno = old_errno;
|
|
||||||
|
|
||||||
if(error)
|
|
||||||
return PARSEDATE_FAIL;
|
return PARSEDATE_FAIL;
|
||||||
|
|
||||||
#if LONG_MAX != INT_MAX
|
/* we know num_digits cannot be larger than 8 */
|
||||||
if((lval > (long)INT_MAX) || (lval < (long)INT_MIN))
|
num_digits = (int)(p - date);
|
||||||
return PARSEDATE_FAIL;
|
val = (unsigned int)lval;
|
||||||
#endif
|
|
||||||
|
|
||||||
val = curlx_sltosi(lval);
|
|
||||||
|
|
||||||
if((tzoff == -1) &&
|
if((tzoff == -1) &&
|
||||||
((end - date) == 4) &&
|
(num_digits == 4) &&
|
||||||
(val <= 1400) &&
|
(val <= 1400) &&
|
||||||
(indate < date) &&
|
(indate < date) &&
|
||||||
((date[-1] == '+' || date[-1] == '-'))) {
|
((date[-1] == '+' || date[-1] == '-'))) {
|
||||||
@ -461,10 +451,10 @@ static int parsedate(const char *date, time_t *output)
|
|||||||
tzoff = date[-1]=='+' ? -tzoff : tzoff;
|
tzoff = date[-1]=='+' ? -tzoff : tzoff;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(((end - date) == 8) &&
|
else if((num_digits == 8) &&
|
||||||
(yearnum == -1) &&
|
(yearnum == -1) &&
|
||||||
(monnum == -1) &&
|
(monnum == -1) &&
|
||||||
(mdaynum == -1)) {
|
(mdaynum == -1)) {
|
||||||
/* 8 digits, no year, month or day yet. This is YYYYMMDD */
|
/* 8 digits, no year, month or day yet. This is YYYYMMDD */
|
||||||
found = TRUE;
|
found = TRUE;
|
||||||
yearnum = val/10000;
|
yearnum = val/10000;
|
||||||
@ -496,7 +486,7 @@ static int parsedate(const char *date, time_t *output)
|
|||||||
if(!found)
|
if(!found)
|
||||||
return PARSEDATE_FAIL;
|
return PARSEDATE_FAIL;
|
||||||
|
|
||||||
date = end;
|
date = p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -69,7 +69,7 @@ struct pingpong {
|
|||||||
|
|
||||||
CURLcode (*statemachine)(struct Curl_easy *data, struct connectdata *conn);
|
CURLcode (*statemachine)(struct Curl_easy *data, struct connectdata *conn);
|
||||||
bool (*endofresp)(struct Curl_easy *data, struct connectdata *conn,
|
bool (*endofresp)(struct Curl_easy *data, struct connectdata *conn,
|
||||||
char *ptr, size_t len, int *code);
|
const char *ptr, size_t len, int *code);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PINGPONG_SETUP(pp,s,e) \
|
#define PINGPONG_SETUP(pp,s,e) \
|
||||||
|
|||||||
@ -244,7 +244,7 @@ static bool pop3_is_multiline(const char *cmdline)
|
|||||||
* types and allowed SASL mechanisms.
|
* types and allowed SASL mechanisms.
|
||||||
*/
|
*/
|
||||||
static bool pop3_endofresp(struct Curl_easy *data, struct connectdata *conn,
|
static bool pop3_endofresp(struct Curl_easy *data, struct connectdata *conn,
|
||||||
char *line, size_t len, int *resp)
|
const char *line, size_t len, int *resp)
|
||||||
{
|
{
|
||||||
struct pop3_conn *pop3c = &conn->proto.pop3c;
|
struct pop3_conn *pop3c = &conn->proto.pop3c;
|
||||||
(void)data;
|
(void)data;
|
||||||
|
|||||||
31
lib/rtsp.c
31
lib/rtsp.c
@ -40,6 +40,7 @@
|
|||||||
#include "connect.h"
|
#include "connect.h"
|
||||||
#include "cfilters.h"
|
#include "cfilters.h"
|
||||||
#include "strdup.h"
|
#include "strdup.h"
|
||||||
|
#include "strparse.h"
|
||||||
/* The last 3 #include files should be in this order */
|
/* The last 3 #include files should be in this order */
|
||||||
#include "curl_printf.h"
|
#include "curl_printf.h"
|
||||||
#include "curl_memory.h"
|
#include "curl_memory.h"
|
||||||
@ -925,21 +926,17 @@ CURLcode rtp_client_write(struct Curl_easy *data, const char *ptr, size_t len)
|
|||||||
CURLcode Curl_rtsp_parseheader(struct Curl_easy *data, const char *header)
|
CURLcode Curl_rtsp_parseheader(struct Curl_easy *data, const char *header)
|
||||||
{
|
{
|
||||||
if(checkprefix("CSeq:", header)) {
|
if(checkprefix("CSeq:", header)) {
|
||||||
long CSeq = 0;
|
size_t CSeq = 0;
|
||||||
char *endp;
|
struct RTSP *rtsp = data->req.p.rtsp;
|
||||||
const char *p = &header[5];
|
const char *p = &header[5];
|
||||||
while(ISBLANK(*p))
|
while(ISBLANK(*p))
|
||||||
p++;
|
p++;
|
||||||
CSeq = strtol(p, &endp, 10);
|
if(Curl_str_number(&p, &CSeq, LONG_MAX)) {
|
||||||
if(p != endp) {
|
|
||||||
struct RTSP *rtsp = data->req.p.rtsp;
|
|
||||||
rtsp->CSeq_recv = CSeq; /* mark the request */
|
|
||||||
data->state.rtsp_CSeq_recv = CSeq; /* update the handle */
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
failf(data, "Unable to read the CSeq header: [%s]", header);
|
failf(data, "Unable to read the CSeq header: [%s]", header);
|
||||||
return CURLE_RTSP_CSEQ_ERROR;
|
return CURLE_RTSP_CSEQ_ERROR;
|
||||||
}
|
}
|
||||||
|
rtsp->CSeq_recv = (long)CSeq; /* mark the request */
|
||||||
|
data->state.rtsp_CSeq_recv = (long)CSeq; /* update the handle */
|
||||||
}
|
}
|
||||||
else if(checkprefix("Session:", header)) {
|
else if(checkprefix("Session:", header)) {
|
||||||
const char *start, *end;
|
const char *start, *end;
|
||||||
@ -1010,25 +1007,21 @@ CURLcode rtsp_parse_transport(struct Curl_easy *data, const char *transport)
|
|||||||
start++;
|
start++;
|
||||||
end = strchr(start, ';');
|
end = strchr(start, ';');
|
||||||
if(checkprefix("interleaved=", start)) {
|
if(checkprefix("interleaved=", start)) {
|
||||||
long chan1, chan2, chan;
|
size_t chan1, chan2, chan;
|
||||||
char *endp;
|
|
||||||
const char *p = start + 12;
|
const char *p = start + 12;
|
||||||
chan1 = strtol(p, &endp, 10);
|
if(!Curl_str_number(&p, &chan1, 255)) {
|
||||||
if(p != endp && chan1 >= 0 && chan1 <= 255) {
|
|
||||||
unsigned char *rtp_channel_mask = data->state.rtp_channel_mask;
|
unsigned char *rtp_channel_mask = data->state.rtp_channel_mask;
|
||||||
chan2 = chan1;
|
chan2 = chan1;
|
||||||
if(*endp == '-') {
|
if(!Curl_str_single(&p, '-')) {
|
||||||
p = endp + 1;
|
if(Curl_str_number(&p, &chan2, 255)) {
|
||||||
chan2 = strtol(p, &endp, 10);
|
|
||||||
if(p == endp || chan2 < 0 || chan2 > 255) {
|
|
||||||
infof(data, "Unable to read the interleaved parameter from "
|
infof(data, "Unable to read the interleaved parameter from "
|
||||||
"Transport header: [%s]", transport);
|
"Transport header: [%s]", transport);
|
||||||
chan2 = chan1;
|
chan2 = chan1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(chan = chan1; chan <= chan2; chan++) {
|
for(chan = chan1; chan <= chan2; chan++) {
|
||||||
long idx = chan / 8;
|
int idx = (int)chan / 8;
|
||||||
long off = chan % 8;
|
int off = (int)chan % 8;
|
||||||
rtp_channel_mask[idx] |= (unsigned char)(1 << off);
|
rtp_channel_mask[idx] |= (unsigned char)(1 << off);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
13
lib/smtp.c
13
lib/smtp.c
@ -80,6 +80,8 @@
|
|||||||
#include "curl_sasl.h"
|
#include "curl_sasl.h"
|
||||||
#include "warnless.h"
|
#include "warnless.h"
|
||||||
#include "idn.h"
|
#include "idn.h"
|
||||||
|
#include "strparse.h"
|
||||||
|
|
||||||
/* The last 3 #include files should be in this order */
|
/* The last 3 #include files should be in this order */
|
||||||
#include "curl_printf.h"
|
#include "curl_printf.h"
|
||||||
#include "curl_memory.h"
|
#include "curl_memory.h"
|
||||||
@ -197,7 +199,7 @@ static const struct SASLproto saslsmtp = {
|
|||||||
* supported authentication mechanisms.
|
* supported authentication mechanisms.
|
||||||
*/
|
*/
|
||||||
static bool smtp_endofresp(struct Curl_easy *data, struct connectdata *conn,
|
static bool smtp_endofresp(struct Curl_easy *data, struct connectdata *conn,
|
||||||
char *line, size_t len, int *resp)
|
const char *line, size_t len, int *resp)
|
||||||
{
|
{
|
||||||
struct smtp_conn *smtpc = &conn->proto.smtpc;
|
struct smtp_conn *smtpc = &conn->proto.smtpc;
|
||||||
bool result = FALSE;
|
bool result = FALSE;
|
||||||
@ -213,11 +215,14 @@ static bool smtp_endofresp(struct Curl_easy *data, struct connectdata *conn,
|
|||||||
only send the response code instead as per Section 4.2. */
|
only send the response code instead as per Section 4.2. */
|
||||||
if(line[3] == ' ' || len == 5) {
|
if(line[3] == ' ' || len == 5) {
|
||||||
char tmpline[6];
|
char tmpline[6];
|
||||||
|
size_t code;
|
||||||
|
const char *p = tmpline;
|
||||||
result = TRUE;
|
result = TRUE;
|
||||||
memset(tmpline, '\0', sizeof(tmpline));
|
|
||||||
memcpy(tmpline, line, (len == 5 ? 5 : 3));
|
memcpy(tmpline, line, (len == 5 ? 5 : 3));
|
||||||
*resp = curlx_sltosi(strtol(tmpline, NULL, 10));
|
tmpline[len == 5 ? 5 : 3 ] = 0;
|
||||||
|
if(Curl_str_number(&p, &code, len == 5 ? 99999 : 999))
|
||||||
|
return FALSE;
|
||||||
|
*resp = (int) code;
|
||||||
|
|
||||||
/* Make sure real server never sends internal value */
|
/* Make sure real server never sends internal value */
|
||||||
if(*resp == 1)
|
if(*resp == 1)
|
||||||
|
|||||||
25
lib/telnet.c
25
lib/telnet.c
@ -58,6 +58,7 @@
|
|||||||
#include "select.h"
|
#include "select.h"
|
||||||
#include "strcase.h"
|
#include "strcase.h"
|
||||||
#include "warnless.h"
|
#include "warnless.h"
|
||||||
|
#include "strparse.h"
|
||||||
|
|
||||||
/* The last 3 #include files should be in this order */
|
/* The last 3 #include files should be in this order */
|
||||||
#include "curl_printf.h"
|
#include "curl_printf.h"
|
||||||
@ -862,22 +863,20 @@ static CURLcode check_telnet_options(struct Curl_easy *data)
|
|||||||
case 2:
|
case 2:
|
||||||
/* Window Size */
|
/* Window Size */
|
||||||
if(strncasecompare(option, "WS", 2)) {
|
if(strncasecompare(option, "WS", 2)) {
|
||||||
char *p;
|
const char *p = arg;
|
||||||
unsigned long x = strtoul(arg, &p, 10);
|
size_t x = 0;
|
||||||
unsigned long y = 0;
|
size_t y = 0;
|
||||||
if(x && (x <= 0xffff) && Curl_raw_tolower(*p) == 'x') {
|
if(Curl_str_number(&p, &x, 0xffff) ||
|
||||||
p++;
|
Curl_str_single(&p, 'x') ||
|
||||||
y = strtoul(p, NULL, 10);
|
Curl_str_number(&p, &y, 0xffff)) {
|
||||||
if(y && (y <= 0xffff)) {
|
|
||||||
tn->subopt_wsx = (unsigned short)x;
|
|
||||||
tn->subopt_wsy = (unsigned short)y;
|
|
||||||
tn->us_preferred[CURL_TELOPT_NAWS] = CURL_YES;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!y) {
|
|
||||||
failf(data, "Syntax error in telnet option: %s", head->data);
|
failf(data, "Syntax error in telnet option: %s", head->data);
|
||||||
result = CURLE_SETOPT_OPTION_SYNTAX;
|
result = CURLE_SETOPT_OPTION_SYNTAX;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
tn->subopt_wsx = (unsigned short)x;
|
||||||
|
tn->subopt_wsy = (unsigned short)y;
|
||||||
|
tn->us_preferred[CURL_TELOPT_NAWS] = CURL_YES;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
result = CURLE_UNKNOWN_OPTION;
|
result = CURLE_UNKNOWN_OPTION;
|
||||||
|
|||||||
42
lib/tftp.c
42
lib/tftp.c
@ -62,6 +62,7 @@
|
|||||||
#include "speedcheck.h"
|
#include "speedcheck.h"
|
||||||
#include "select.h"
|
#include "select.h"
|
||||||
#include "escape.h"
|
#include "escape.h"
|
||||||
|
#include "strparse.h"
|
||||||
|
|
||||||
/* The last 3 #include files should be in this order */
|
/* The last 3 #include files should be in this order */
|
||||||
#include "curl_printf.h"
|
#include "curl_printf.h"
|
||||||
@ -135,9 +136,9 @@ struct tftp_state_data {
|
|||||||
struct Curl_sockaddr_storage remote_addr;
|
struct Curl_sockaddr_storage remote_addr;
|
||||||
curl_socklen_t remote_addrlen;
|
curl_socklen_t remote_addrlen;
|
||||||
int rbytes;
|
int rbytes;
|
||||||
int sbytes;
|
size_t sbytes;
|
||||||
int blksize;
|
unsigned int blksize;
|
||||||
int requested_blksize;
|
unsigned int requested_blksize;
|
||||||
unsigned short block;
|
unsigned short block;
|
||||||
struct tftp_packet rpacket;
|
struct tftp_packet rpacket;
|
||||||
struct tftp_packet spacket;
|
struct tftp_packet spacket;
|
||||||
@ -330,19 +331,16 @@ static CURLcode tftp_parse_option_ack(struct tftp_state_data *state,
|
|||||||
infof(data, "got option=(%s) value=(%s)", option, value);
|
infof(data, "got option=(%s) value=(%s)", option, value);
|
||||||
|
|
||||||
if(checkprefix(TFTP_OPTION_BLKSIZE, option)) {
|
if(checkprefix(TFTP_OPTION_BLKSIZE, option)) {
|
||||||
long blksize;
|
size_t blksize;
|
||||||
|
if(Curl_str_number(&value, &blksize, TFTP_BLKSIZE_MAX)) {
|
||||||
blksize = strtol(value, NULL, 10);
|
|
||||||
|
|
||||||
if(!blksize) {
|
|
||||||
failf(data, "invalid blocksize value in OACK packet");
|
|
||||||
return CURLE_TFTP_ILLEGAL;
|
|
||||||
}
|
|
||||||
if(blksize > TFTP_BLKSIZE_MAX) {
|
|
||||||
failf(data, "%s (%d)", "blksize is larger than max supported",
|
failf(data, "%s (%d)", "blksize is larger than max supported",
|
||||||
TFTP_BLKSIZE_MAX);
|
TFTP_BLKSIZE_MAX);
|
||||||
return CURLE_TFTP_ILLEGAL;
|
return CURLE_TFTP_ILLEGAL;
|
||||||
}
|
}
|
||||||
|
if(!blksize) {
|
||||||
|
failf(data, "invalid blocksize value in OACK packet");
|
||||||
|
return CURLE_TFTP_ILLEGAL;
|
||||||
|
}
|
||||||
else if(blksize < TFTP_BLKSIZE_MIN) {
|
else if(blksize < TFTP_BLKSIZE_MIN) {
|
||||||
failf(data, "%s (%d)", "blksize is smaller than min supported",
|
failf(data, "%s (%d)", "blksize is smaller than min supported",
|
||||||
TFTP_BLKSIZE_MIN);
|
TFTP_BLKSIZE_MIN);
|
||||||
@ -352,28 +350,26 @@ static CURLcode tftp_parse_option_ack(struct tftp_state_data *state,
|
|||||||
/* could realloc pkt buffers here, but the spec does not call out
|
/* could realloc pkt buffers here, but the spec does not call out
|
||||||
* support for the server requesting a bigger blksize than the client
|
* support for the server requesting a bigger blksize than the client
|
||||||
* requests */
|
* requests */
|
||||||
failf(data, "%s (%ld)",
|
failf(data, "server requested blksize larger than allocated (%zd)",
|
||||||
"server requested blksize larger than allocated", blksize);
|
blksize);
|
||||||
return CURLE_TFTP_ILLEGAL;
|
return CURLE_TFTP_ILLEGAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
state->blksize = (int)blksize;
|
state->blksize = (int)blksize;
|
||||||
infof(data, "%s (%d) %s (%d)", "blksize parsed from OACK",
|
infof(data, "blksize parsed from OACK (%d) requested (%d)",
|
||||||
state->blksize, "requested", state->requested_blksize);
|
state->blksize, state->requested_blksize);
|
||||||
}
|
}
|
||||||
else if(checkprefix(TFTP_OPTION_TSIZE, option)) {
|
else if(checkprefix(TFTP_OPTION_TSIZE, option)) {
|
||||||
long tsize = 0;
|
size_t tsize = 0;
|
||||||
|
|
||||||
tsize = strtol(value, NULL, 10);
|
|
||||||
infof(data, "%s (%ld)", "tsize parsed from OACK", tsize);
|
|
||||||
|
|
||||||
/* tsize should be ignored on upload: Who cares about the size of the
|
/* tsize should be ignored on upload: Who cares about the size of the
|
||||||
remote file? */
|
remote file? */
|
||||||
if(!data->state.upload) {
|
if(!data->state.upload &&
|
||||||
|
!Curl_str_number(&value, &tsize, SIZE_T_MAX)) {
|
||||||
if(!tsize) {
|
if(!tsize) {
|
||||||
failf(data, "invalid tsize -:%s:- value in OACK packet", value);
|
failf(data, "invalid tsize -:%s:- value in OACK packet", value);
|
||||||
return CURLE_TFTP_ILLEGAL;
|
return CURLE_TFTP_ILLEGAL;
|
||||||
}
|
}
|
||||||
|
infof(data, "tsize parsed from OACK (%zd)", tsize);
|
||||||
Curl_pgrsSetDownloadSize(data, tsize);
|
Curl_pgrsSetDownloadSize(data, tsize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -776,7 +772,7 @@ static CURLcode tftp_tx(struct tftp_state_data *state, tftp_event_t event)
|
|||||||
&cb, &eos);
|
&cb, &eos);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
state->sbytes += (int)cb;
|
state->sbytes += cb;
|
||||||
bufptr += cb;
|
bufptr += cb;
|
||||||
} while(state->sbytes < state->blksize && cb);
|
} while(state->sbytes < state->blksize && cb);
|
||||||
|
|
||||||
|
|||||||
46
lib/url.c
46
lib/url.c
@ -119,7 +119,7 @@
|
|||||||
#include "altsvc.h"
|
#include "altsvc.h"
|
||||||
#include "dynbuf.h"
|
#include "dynbuf.h"
|
||||||
#include "headers.h"
|
#include "headers.h"
|
||||||
|
#include "strparse.h"
|
||||||
/* The last 3 #include files should be in this order */
|
/* The last 3 #include files should be in this order */
|
||||||
#include "curl_printf.h"
|
#include "curl_printf.h"
|
||||||
#include "curl_memory.h"
|
#include "curl_memory.h"
|
||||||
@ -1680,9 +1680,9 @@ static void zonefrom_url(CURLU *uh, struct Curl_easy *data,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(!uc && zoneid) {
|
if(!uc && zoneid) {
|
||||||
char *endp;
|
const char *p = zoneid;
|
||||||
unsigned long scope = strtoul(zoneid, &endp, 10);
|
size_t scope;
|
||||||
if(!*endp && (scope < UINT_MAX))
|
if(!Curl_str_number(&p, &scope, UINT_MAX))
|
||||||
/* A plain number, use it directly as a scope id. */
|
/* A plain number, use it directly as a scope id. */
|
||||||
conn->scope_id = (unsigned int)scope;
|
conn->scope_id = (unsigned int)scope;
|
||||||
#if defined(HAVE_IF_NAMETOINDEX)
|
#if defined(HAVE_IF_NAMETOINDEX)
|
||||||
@ -1919,10 +1919,17 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
|
|||||||
return CURLE_OUT_OF_MEMORY;
|
return CURLE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
unsigned long port = strtoul(data->state.up.port, NULL, 10);
|
size_t port;
|
||||||
conn->primary.remote_port = conn->remote_port =
|
bool valid = TRUE;
|
||||||
(data->set.use_port && data->state.allow_port) ?
|
if(data->set.use_port && data->state.allow_port)
|
||||||
data->set.use_port : curlx_ultous(port);
|
port = data->set.use_port;
|
||||||
|
else {
|
||||||
|
const char *p = data->state.up.port;
|
||||||
|
if(Curl_str_number(&p, &port, 0xffff))
|
||||||
|
valid = FALSE;
|
||||||
|
}
|
||||||
|
if(valid)
|
||||||
|
conn->primary.remote_port = conn->remote_port = (unsigned short)port;
|
||||||
}
|
}
|
||||||
|
|
||||||
(void)curl_url_get(uh, CURLUPART_QUERY, &data->state.up.query, 0);
|
(void)curl_url_get(uh, CURLUPART_QUERY, &data->state.up.query, 0);
|
||||||
@ -2251,7 +2258,10 @@ static CURLcode parse_proxy(struct Curl_easy *data,
|
|||||||
(void)curl_url_get(uhp, CURLUPART_PORT, &portptr, 0);
|
(void)curl_url_get(uhp, CURLUPART_PORT, &portptr, 0);
|
||||||
|
|
||||||
if(portptr) {
|
if(portptr) {
|
||||||
port = (int)strtol(portptr, NULL, 10);
|
size_t num;
|
||||||
|
const char *p = portptr;
|
||||||
|
if(!Curl_str_number(&p, &num, 0xffff))
|
||||||
|
port = (int)num;
|
||||||
free(portptr);
|
free(portptr);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -2889,19 +2899,18 @@ static CURLcode parse_connect_to_host_port(struct Curl_easy *data,
|
|||||||
/* Get port number off server.com:1080 */
|
/* Get port number off server.com:1080 */
|
||||||
host_portno = strchr(portptr, ':');
|
host_portno = strchr(portptr, ':');
|
||||||
if(host_portno) {
|
if(host_portno) {
|
||||||
char *endp = NULL;
|
|
||||||
*host_portno = '\0'; /* cut off number from hostname */
|
*host_portno = '\0'; /* cut off number from hostname */
|
||||||
host_portno++;
|
host_portno++;
|
||||||
if(*host_portno) {
|
if(*host_portno) {
|
||||||
long portparse = strtol(host_portno, &endp, 10);
|
size_t portparse;
|
||||||
if((endp && *endp) || (portparse < 0) || (portparse > 65535)) {
|
const char *p = host_portno;
|
||||||
|
if(Curl_str_number(&p, &portparse, 0xffff)) {
|
||||||
failf(data, "No valid port number in connect to host string (%s)",
|
failf(data, "No valid port number in connect to host string (%s)",
|
||||||
host_portno);
|
host_portno);
|
||||||
result = CURLE_SETOPT_OPTION_SYNTAX;
|
result = CURLE_SETOPT_OPTION_SYNTAX;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
else
|
port = (int)portparse; /* we know it will fit */
|
||||||
port = (int)portparse; /* we know it will fit */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2972,12 +2981,11 @@ static CURLcode parse_connect_to_string(struct Curl_easy *data,
|
|||||||
/* check whether the URL's port matches */
|
/* check whether the URL's port matches */
|
||||||
char *ptr_next = strchr(ptr, ':');
|
char *ptr_next = strchr(ptr, ':');
|
||||||
if(ptr_next) {
|
if(ptr_next) {
|
||||||
char *endp = NULL;
|
size_t port_to_match;
|
||||||
long port_to_match = strtol(ptr, &endp, 10);
|
if(!Curl_str_number(&ptr, &port_to_match, 0xffff) &&
|
||||||
if((endp == ptr_next) && (port_to_match == conn->remote_port)) {
|
(port_to_match == (size_t)conn->remote_port))
|
||||||
port_match = TRUE;
|
port_match = TRUE;
|
||||||
ptr = ptr_next + 1;
|
ptr = ptr_next + 1;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
25
lib/urlapi.c
25
lib/urlapi.c
@ -34,6 +34,7 @@
|
|||||||
#include "inet_ntop.h"
|
#include "inet_ntop.h"
|
||||||
#include "strdup.h"
|
#include "strdup.h"
|
||||||
#include "idn.h"
|
#include "idn.h"
|
||||||
|
#include "strparse.h"
|
||||||
|
|
||||||
/* The last 3 #include files should be in this order */
|
/* The last 3 #include files should be in this order */
|
||||||
#include "curl_printf.h"
|
#include "curl_printf.h"
|
||||||
@ -445,7 +446,7 @@ out:
|
|||||||
UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, struct dynbuf *host,
|
UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, struct dynbuf *host,
|
||||||
bool has_scheme)
|
bool has_scheme)
|
||||||
{
|
{
|
||||||
char *portptr;
|
const char *portptr;
|
||||||
char *hostname = Curl_dyn_ptr(host);
|
char *hostname = Curl_dyn_ptr(host);
|
||||||
/*
|
/*
|
||||||
* Find the end of an IPv6 address on the ']' ending bracket.
|
* Find the end of an IPv6 address on the ']' ending bracket.
|
||||||
@ -467,8 +468,7 @@ UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, struct dynbuf *host,
|
|||||||
portptr = strchr(hostname, ':');
|
portptr = strchr(hostname, ':');
|
||||||
|
|
||||||
if(portptr) {
|
if(portptr) {
|
||||||
char *rest = NULL;
|
size_t port;
|
||||||
unsigned long port;
|
|
||||||
size_t keep = portptr - hostname;
|
size_t keep = portptr - hostname;
|
||||||
|
|
||||||
/* Browser behavior adaptation. If there is a colon with no digits after,
|
/* Browser behavior adaptation. If there is a colon with no digits after,
|
||||||
@ -483,19 +483,13 @@ UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, struct dynbuf *host,
|
|||||||
if(!*portptr)
|
if(!*portptr)
|
||||||
return has_scheme ? CURLUE_OK : CURLUE_BAD_PORT_NUMBER;
|
return has_scheme ? CURLUE_OK : CURLUE_BAD_PORT_NUMBER;
|
||||||
|
|
||||||
if(!ISDIGIT(*portptr))
|
if(Curl_str_number(&portptr, &port, 0xffff) || *portptr)
|
||||||
return CURLUE_BAD_PORT_NUMBER;
|
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
port = strtoul(portptr, &rest, 10); /* Port number must be decimal */
|
|
||||||
|
|
||||||
if(errno || (port > 0xffff) || *rest)
|
|
||||||
return CURLUE_BAD_PORT_NUMBER;
|
return CURLUE_BAD_PORT_NUMBER;
|
||||||
|
|
||||||
u->portnum = (unsigned short) port;
|
u->portnum = (unsigned short) port;
|
||||||
/* generate a new port number string to get rid of leading zeroes etc */
|
/* generate a new port number string to get rid of leading zeroes etc */
|
||||||
free(u->port);
|
free(u->port);
|
||||||
u->port = aprintf("%ld", port);
|
u->port = aprintf("%zd", port);
|
||||||
if(!u->port)
|
if(!u->port)
|
||||||
return CURLUE_OUT_OF_MEMORY;
|
return CURLUE_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
@ -1751,14 +1745,11 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
|
|||||||
return CURLUE_BAD_PORT_NUMBER;
|
return CURLUE_BAD_PORT_NUMBER;
|
||||||
else {
|
else {
|
||||||
char *tmp;
|
char *tmp;
|
||||||
char *endp;
|
size_t port;
|
||||||
unsigned long port;
|
if(Curl_str_number(&part, &port, 0xffff) || *part)
|
||||||
errno = 0;
|
|
||||||
port = strtoul(part, &endp, 10); /* must be decimal */
|
|
||||||
if(errno || (port > 0xffff) || *endp)
|
|
||||||
/* weirdly provided number, not good! */
|
/* weirdly provided number, not good! */
|
||||||
return CURLUE_BAD_PORT_NUMBER;
|
return CURLUE_BAD_PORT_NUMBER;
|
||||||
tmp = strdup(part);
|
tmp = aprintf("%zd", port);
|
||||||
if(!tmp)
|
if(!tmp)
|
||||||
return CURLUE_OUT_OF_MEMORY;
|
return CURLUE_OUT_OF_MEMORY;
|
||||||
free(u->port);
|
free(u->port);
|
||||||
|
|||||||
@ -93,9 +93,9 @@ Curl_str_number
|
|||||||
6: ("00000000000000000000000000001234") 0, [1234] line 32
|
6: ("00000000000000000000000000001234") 0, [1234] line 32
|
||||||
7: ("0123 345") 0, [123] line 4
|
7: ("0123 345") 0, [123] line 4
|
||||||
8: ("0123O345") 0, [123] line 4
|
8: ("0123O345") 0, [123] line 4
|
||||||
9: ("-12") 0, [0] line 0
|
9: ("-12") 8, [0] line 0
|
||||||
10: (" 123") 0, [0] line 0
|
10: (" 123") 8, [0] line 0
|
||||||
11: ("") 0, [0] line 0
|
11: ("") 8, [0] line 0
|
||||||
Curl_str_number / max
|
Curl_str_number / max
|
||||||
0: ("9223372036854775808") 0, [9223372036854775808] line 19
|
0: ("9223372036854775808") 0, [9223372036854775808] line 19
|
||||||
1: ("9223372036854775809") 0, [9223372036854775809] line 19
|
1: ("9223372036854775809") 0, [9223372036854775809] line 19
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user