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
size_t dstlen = 0; /* destination hostname length */
const char *value_ptr;
char option[32];
- unsigned long num;
- char *end_ptr;
+ size_t num;
bool quoted = FALSE;
time_t maxage = 24 * 3600; /* default is 24 hours */
bool persist = FALSE;
dstlen = strlen(srchost);
}
if(*p == ':') {
- unsigned long port = 0;
+ size_t port = 0;
p++;
- if(ISDIGIT(*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 != '\"') {
+ if(Curl_str_number(&p, &port, 0xffff) || (*p != '\"')) {
infof(data, "Unknown alt-svc port number, ignoring.");
valid = FALSE;
}
- else {
- dstport = curlx_ultous(port);
- p = end_ptr;
- }
+ else
+ dstport = (unsigned short)port;
}
if(*p++ != '\"')
break;
while(*p && !ISBLANK(*p) && *p!= ';' && *p != ',')
p++;
}
- num = strtoul(value_ptr, &end_ptr, 10);
- if((end_ptr != value_ptr) && (num < ULONG_MAX)) {
+ if(!Curl_str_number(&value_ptr, &num, SIZE_T_MAX)) {
if(strcasecompare("ma", option))
maxage = (time_t)num;
else if(strcasecompare("persist", option) && (num == 1))
#include "share.h"
#include "strdup.h"
#include "version_win32.h"
+#include "strparse.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
Curl_printable_address. The latter returns only numeric scope
IDs and the former returns none at all. So the scope ID, if
present, is known to be numeric */
- unsigned long scope_id = strtoul(scope_ptr, NULL, 10);
- if(scope_id > UINT_MAX)
+ size_t scope_id;
+ if(Curl_str_number((const char **)&scope_ptr, &scope_id, UINT_MAX))
return CURLE_UNSUPPORTED_PROTOCOL;
-
si6->sin6_scope_id = (unsigned int)scope_id;
}
#endif
#include "http_proxy.h"
#include "socks.h"
#include "strdup.h"
+#include "strparse.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
if(response) {
infof(data, "Ctrl conn has data while waiting for data conn");
if(pp->overflow > 3) {
- char *r = Curl_dyn_ptr(&pp->recvbuf);
+ const char *r = Curl_dyn_ptr(&pp->recvbuf);
DEBUGASSERT((pp->overflow + pp->nfinal) <=
Curl_dyn_len(&pp->recvbuf));
r += pp->nfinal;
if(LASTLINE(r)) {
- int status = curlx_sltosi(strtol(r, NULL, 10));
- if(status == 226) {
+ size_t status;
+ if(!Curl_str_number(&r, &status, 999) && (status == 226)) {
/* funny timing situation where we get the final message on the
control connection before traffic on the data connection has been
noticed. Leave the 226 in there and use this as a trigger to read
}
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)conn;
- if((len > 3) && LASTLINE(line)) {
- *code = curlx_sltosi(strtol(line, NULL, 10));
+ if((len > 3) && LASTLINE(line) && !Curl_str_number(&line, &status, 999)) {
+ *code = (int)status;
return TRUE;
}
/* parse the port */
if(ip_end) {
- char *port_sep = NULL;
- char *port_start = strchr(ip_end, ':');
- if(port_start) {
- port_min = curlx_ultous(strtoul(port_start + 1, NULL, 10));
- port_sep = strchr(port_start, '-');
- if(port_sep) {
- port_max = curlx_ultous(strtoul(port_sep + 1, NULL, 10));
+ const char *portp = strchr(ip_end, ':');
+ if(portp) {
+ size_t start;
+ size_t end;
+ portp++;
+ if(!Curl_str_number(&portp, &start, 0xffff)) {
+ /* 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
port_max = port_min;
{
int i;
for(i = 0; i < 6; i++) {
- unsigned long num;
- char *endp;
+ size_t num;
if(i) {
if(*p != ',')
return FALSE;
p++;
}
- if(!ISDIGIT(*p))
- return FALSE;
- num = strtoul(p, &endp, 10);
- if(num > 255)
+ if(Curl_str_number(&p, &num, 0xff))
return FALSE;
array[i] = (unsigned int)num;
- p = endp;
}
return TRUE;
}
/* the ISDIGIT() check here is because strtoul() accepts leading minus
etc */
if((ptr[1] == sep) && (ptr[2] == sep) && ISDIGIT(ptr[3])) {
- char *endp;
- unsigned long num = strtoul(&ptr[3], &endp, 10);
- if(*endp != sep)
- ptr = NULL;
- else if(num > 0xffff) {
+ const char *p = &ptr[3];
+ size_t num;
+ if(Curl_str_number(&p, &num, 0xffff) || (*p != sep)) {
failf(data, "Illegal port number in EPSV reply");
return CURLE_FTP_WEIRD_PASV_REPLY;
}
- if(ptr) {
- ftpc->newport = (unsigned short)(num & 0xffff);
- ftpc->newhost = strdup(control_address(conn));
- if(!ftpc->newhost)
- return CURLE_OUT_OF_MEMORY;
- }
+ ftpc->newport = (unsigned short)num;
+ ftpc->newhost = strdup(control_address(conn));
+ if(!ftpc->newhost)
+ return CURLE_OUT_OF_MEMORY;
}
else
ptr = NULL;
#include "ftp.h"
#include "ftplistparser.h"
#include "curl_fnmatch.h"
-#include "curl_memory.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"
typedef enum {
case PL_UNIX_HLINKS_NUMBER:
parser->item_length ++;
if(c == ' ') {
- char *p;
- long int hlinks;
+ const char *p = &mem[parser->item_offset];
+ size_t hlinks;
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.hardlinks = hlinks;
+ parser->file_data->info.hardlinks = (long)hlinks;
}
parser->item_length = 0;
parser->item_offset = 0;
#include "warnless.h"
#include "strcase.h"
#include "easy_lock.h"
+#include "strparse.h"
+
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
CURLcode Curl_loadhostpairs(struct Curl_easy *data)
{
struct curl_slist *hostp;
- char *host_end;
+ const char *host_end;
/* Default is no wildcard found */
data->state.wildcard_resolve = FALSE;
if(!hostp->data)
continue;
if(hostp->data[0] == '-') {
- unsigned long num = 0;
+ size_t num = 0;
size_t entry_len;
size_t hlen = 0;
host_end = strchr(&hostp->data[1], ':');
if(host_end) {
hlen = host_end - &hostp->data[1];
- num = strtoul(++host_end, NULL, 10);
- if(!hlen || (num > 0xffff))
+ host_end++;
+ if(Curl_str_number(&host_end, &num, 0xffff))
host_end = NULL;
}
if(!host_end) {
size_t entry_len;
char address[64];
#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
- char *addresses = NULL;
+ const char *addresses = NULL;
#endif
- char *addr_begin;
- char *addr_end;
- char *port_ptr;
- int port = 0;
- char *end_ptr;
+ const char *addr_begin;
+ const char *addr_end;
+ const char *port_ptr;
+ size_t port = 0;
+ const char *end_ptr;
bool permanent = TRUE;
- unsigned long tmp_port;
bool error = TRUE;
char *host_begin = hostp->data;
size_t hlen = 0;
hlen = host_end - host_begin;
port_ptr = host_end + 1;
- tmp_port = strtoul(port_ptr, &end_ptr, 10);
- if(tmp_port > USHRT_MAX || end_ptr == port_ptr || *end_ptr != ':')
+ if(Curl_str_number(&port_ptr, &port, 0xffff) ||
+ (*port_ptr != ':'))
goto err;
+ end_ptr = port_ptr;
- port = (int)tmp_port;
#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
addresses = end_ptr + 1;
#endif
}
#endif
- ai = Curl_str2addr(address, port);
+ ai = Curl_str2addr(address, (int)port);
if(!ai) {
infof(data, "Resolve address '%s' found illegal", address);
goto err;
}
/* 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));
if(data->share)
dns = Curl_hash_pick(data->dns.hostcache, entry_id, entry_len + 1);
if(dns) {
- infof(data, "RESOLVE %.*s:%d - old addresses discarded",
+ infof(data, "RESOLVE %.*s:%zd - old addresses discarded",
(int)hlen, host_begin, port);
/* delete old entry, there are two reasons for this
1. old entry may have different addresses.
}
/* 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) {
/* release the returned reference; the cache itself will keep the
* entry alive: */
return CURLE_OUT_OF_MEMORY;
}
#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,
permanent ? "" : " (non-permanent)");
#endif
/* Wildcard hostname */
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;
}
}
* response which can be processed by the response handler.
*/
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_conn *imapc = &conn->proto.imapc;
#include "strcase.h"
#include "warnless.h"
#include "parsedate.h"
+#include "strparse.h"
/*
* parsedate()
}
else if(ISDIGIT(*date)) {
/* a digit */
- int val;
+ unsigned int val;
char *end;
if((secnum == -1) &&
match_time(date, &hournum, &minnum, &secnum, &end)) {
date = end;
}
else {
- long lval;
- int error;
- int old_errno;
-
- old_errno = errno;
- errno = 0;
- lval = strtol(date, &end, 10);
- error = errno;
- if(errno != old_errno)
- errno = old_errno;
-
- if(error)
+ size_t lval;
+ int num_digits = 0;
+ const char *p = date;
+ if(Curl_str_number(&p, &lval, 99999999))
return PARSEDATE_FAIL;
-#if LONG_MAX != INT_MAX
- if((lval > (long)INT_MAX) || (lval < (long)INT_MIN))
- return PARSEDATE_FAIL;
-#endif
-
- val = curlx_sltosi(lval);
+ /* we know num_digits cannot be larger than 8 */
+ num_digits = (int)(p - date);
+ val = (unsigned int)lval;
if((tzoff == -1) &&
- ((end - date) == 4) &&
+ (num_digits == 4) &&
(val <= 1400) &&
(indate < date) &&
((date[-1] == '+' || date[-1] == '-'))) {
tzoff = date[-1]=='+' ? -tzoff : tzoff;
}
- if(((end - date) == 8) &&
- (yearnum == -1) &&
- (monnum == -1) &&
- (mdaynum == -1)) {
+ else if((num_digits == 8) &&
+ (yearnum == -1) &&
+ (monnum == -1) &&
+ (mdaynum == -1)) {
/* 8 digits, no year, month or day yet. This is YYYYMMDD */
found = TRUE;
yearnum = val/10000;
if(!found)
return PARSEDATE_FAIL;
- date = end;
+ date = p;
}
}
CURLcode (*statemachine)(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) \
* types and allowed SASL mechanisms.
*/
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;
(void)data;
#include "connect.h"
#include "cfilters.h"
#include "strdup.h"
+#include "strparse.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
CURLcode Curl_rtsp_parseheader(struct Curl_easy *data, const char *header)
{
if(checkprefix("CSeq:", header)) {
- long CSeq = 0;
- char *endp;
+ size_t CSeq = 0;
+ struct RTSP *rtsp = data->req.p.rtsp;
const char *p = &header[5];
while(ISBLANK(*p))
p++;
- CSeq = strtol(p, &endp, 10);
- 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 {
+ if(Curl_str_number(&p, &CSeq, LONG_MAX)) {
failf(data, "Unable to read the CSeq header: [%s]", header);
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)) {
const char *start, *end;
start++;
end = strchr(start, ';');
if(checkprefix("interleaved=", start)) {
- long chan1, chan2, chan;
- char *endp;
+ size_t chan1, chan2, chan;
const char *p = start + 12;
- chan1 = strtol(p, &endp, 10);
- if(p != endp && chan1 >= 0 && chan1 <= 255) {
+ if(!Curl_str_number(&p, &chan1, 255)) {
unsigned char *rtp_channel_mask = data->state.rtp_channel_mask;
chan2 = chan1;
- if(*endp == '-') {
- p = endp + 1;
- chan2 = strtol(p, &endp, 10);
- if(p == endp || chan2 < 0 || chan2 > 255) {
+ if(!Curl_str_single(&p, '-')) {
+ if(Curl_str_number(&p, &chan2, 255)) {
infof(data, "Unable to read the interleaved parameter from "
"Transport header: [%s]", transport);
chan2 = chan1;
}
}
for(chan = chan1; chan <= chan2; chan++) {
- long idx = chan / 8;
- long off = chan % 8;
+ int idx = (int)chan / 8;
+ int off = (int)chan % 8;
rtp_channel_mask[idx] |= (unsigned char)(1 << off);
}
}
#include "curl_sasl.h"
#include "warnless.h"
#include "idn.h"
+#include "strparse.h"
+
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
* supported authentication mechanisms.
*/
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;
bool result = FALSE;
only send the response code instead as per Section 4.2. */
if(line[3] == ' ' || len == 5) {
char tmpline[6];
-
+ size_t code;
+ const char *p = tmpline;
result = TRUE;
- memset(tmpline, '\0', sizeof(tmpline));
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 */
if(*resp == 1)
#include "select.h"
#include "strcase.h"
#include "warnless.h"
+#include "strparse.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
case 2:
/* Window Size */
if(strncasecompare(option, "WS", 2)) {
- char *p;
- unsigned long x = strtoul(arg, &p, 10);
- unsigned long y = 0;
- if(x && (x <= 0xffff) && Curl_raw_tolower(*p) == 'x') {
- p++;
- y = strtoul(p, NULL, 10);
- 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) {
+ const char *p = arg;
+ size_t x = 0;
+ size_t y = 0;
+ if(Curl_str_number(&p, &x, 0xffff) ||
+ Curl_str_single(&p, 'x') ||
+ Curl_str_number(&p, &y, 0xffff)) {
failf(data, "Syntax error in telnet option: %s", head->data);
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
result = CURLE_UNKNOWN_OPTION;
#include "speedcheck.h"
#include "select.h"
#include "escape.h"
+#include "strparse.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
struct Curl_sockaddr_storage remote_addr;
curl_socklen_t remote_addrlen;
int rbytes;
- int sbytes;
- int blksize;
- int requested_blksize;
+ size_t sbytes;
+ unsigned int blksize;
+ unsigned int requested_blksize;
unsigned short block;
struct tftp_packet rpacket;
struct tftp_packet spacket;
infof(data, "got option=(%s) value=(%s)", option, value);
if(checkprefix(TFTP_OPTION_BLKSIZE, option)) {
- long blksize;
-
- blksize = strtol(value, NULL, 10);
-
- if(!blksize) {
- failf(data, "invalid blocksize value in OACK packet");
- return CURLE_TFTP_ILLEGAL;
- }
- if(blksize > TFTP_BLKSIZE_MAX) {
+ size_t blksize;
+ if(Curl_str_number(&value, &blksize, TFTP_BLKSIZE_MAX)) {
failf(data, "%s (%d)", "blksize is larger than max supported",
TFTP_BLKSIZE_MAX);
return CURLE_TFTP_ILLEGAL;
}
+ if(!blksize) {
+ failf(data, "invalid blocksize value in OACK packet");
+ return CURLE_TFTP_ILLEGAL;
+ }
else if(blksize < TFTP_BLKSIZE_MIN) {
failf(data, "%s (%d)", "blksize is smaller than min supported",
TFTP_BLKSIZE_MIN);
/* could realloc pkt buffers here, but the spec does not call out
* support for the server requesting a bigger blksize than the client
* requests */
- failf(data, "%s (%ld)",
- "server requested blksize larger than allocated", blksize);
+ failf(data, "server requested blksize larger than allocated (%zd)",
+ blksize);
return CURLE_TFTP_ILLEGAL;
}
state->blksize = (int)blksize;
- infof(data, "%s (%d) %s (%d)", "blksize parsed from OACK",
- state->blksize, "requested", state->requested_blksize);
+ infof(data, "blksize parsed from OACK (%d) requested (%d)",
+ state->blksize, state->requested_blksize);
}
else if(checkprefix(TFTP_OPTION_TSIZE, option)) {
- long tsize = 0;
-
- tsize = strtol(value, NULL, 10);
- infof(data, "%s (%ld)", "tsize parsed from OACK", tsize);
-
+ size_t tsize = 0;
/* tsize should be ignored on upload: Who cares about the size of the
remote file? */
- if(!data->state.upload) {
+ if(!data->state.upload &&
+ !Curl_str_number(&value, &tsize, SIZE_T_MAX)) {
if(!tsize) {
failf(data, "invalid tsize -:%s:- value in OACK packet", value);
return CURLE_TFTP_ILLEGAL;
}
+ infof(data, "tsize parsed from OACK (%zd)", tsize);
Curl_pgrsSetDownloadSize(data, tsize);
}
}
&cb, &eos);
if(result)
return result;
- state->sbytes += (int)cb;
+ state->sbytes += cb;
bufptr += cb;
} while(state->sbytes < state->blksize && cb);
#include "altsvc.h"
#include "dynbuf.h"
#include "headers.h"
-
+#include "strparse.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
#include "curl_memory.h"
#endif
if(!uc && zoneid) {
- char *endp;
- unsigned long scope = strtoul(zoneid, &endp, 10);
- if(!*endp && (scope < UINT_MAX))
+ const char *p = zoneid;
+ size_t scope;
+ if(!Curl_str_number(&p, &scope, UINT_MAX))
/* A plain number, use it directly as a scope id. */
conn->scope_id = (unsigned int)scope;
#if defined(HAVE_IF_NAMETOINDEX)
return CURLE_OUT_OF_MEMORY;
}
else {
- unsigned long port = strtoul(data->state.up.port, NULL, 10);
- conn->primary.remote_port = conn->remote_port =
- (data->set.use_port && data->state.allow_port) ?
- data->set.use_port : curlx_ultous(port);
+ size_t port;
+ bool valid = TRUE;
+ if(data->set.use_port && data->state.allow_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(uhp, CURLUPART_PORT, &portptr, 0);
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);
}
else {
/* Get port number off server.com:1080 */
host_portno = strchr(portptr, ':');
if(host_portno) {
- char *endp = NULL;
*host_portno = '\0'; /* cut off number from hostname */
host_portno++;
if(*host_portno) {
- long portparse = strtol(host_portno, &endp, 10);
- if((endp && *endp) || (portparse < 0) || (portparse > 65535)) {
+ size_t portparse;
+ const char *p = host_portno;
+ if(Curl_str_number(&p, &portparse, 0xffff)) {
failf(data, "No valid port number in connect to host string (%s)",
host_portno);
result = CURLE_SETOPT_OPTION_SYNTAX;
goto error;
}
- else
- port = (int)portparse; /* we know it will fit */
+ port = (int)portparse; /* we know it will fit */
}
}
/* check whether the URL's port matches */
char *ptr_next = strchr(ptr, ':');
if(ptr_next) {
- char *endp = NULL;
- long port_to_match = strtol(ptr, &endp, 10);
- if((endp == ptr_next) && (port_to_match == conn->remote_port)) {
+ size_t port_to_match;
+ if(!Curl_str_number(&ptr, &port_to_match, 0xffff) &&
+ (port_to_match == (size_t)conn->remote_port))
port_match = TRUE;
- ptr = ptr_next + 1;
- }
+ ptr = ptr_next + 1;
}
}
}
#include "inet_ntop.h"
#include "strdup.h"
#include "idn.h"
+#include "strparse.h"
/* The last 3 #include files should be in this order */
#include "curl_printf.h"
UNITTEST CURLUcode Curl_parse_port(struct Curl_URL *u, struct dynbuf *host,
bool has_scheme)
{
- char *portptr;
+ const char *portptr;
char *hostname = Curl_dyn_ptr(host);
/*
* Find the end of an IPv6 address on the ']' ending bracket.
portptr = strchr(hostname, ':');
if(portptr) {
- char *rest = NULL;
- unsigned long port;
+ size_t port;
size_t keep = portptr - hostname;
/* Browser behavior adaptation. If there is a colon with no digits after,
if(!*portptr)
return has_scheme ? CURLUE_OK : CURLUE_BAD_PORT_NUMBER;
- if(!ISDIGIT(*portptr))
- return CURLUE_BAD_PORT_NUMBER;
-
- errno = 0;
- port = strtoul(portptr, &rest, 10); /* Port number must be decimal */
-
- if(errno || (port > 0xffff) || *rest)
+ if(Curl_str_number(&portptr, &port, 0xffff) || *portptr)
return CURLUE_BAD_PORT_NUMBER;
u->portnum = (unsigned short) port;
/* generate a new port number string to get rid of leading zeroes etc */
free(u->port);
- u->port = aprintf("%ld", port);
+ u->port = aprintf("%zd", port);
if(!u->port)
return CURLUE_OUT_OF_MEMORY;
}
return CURLUE_BAD_PORT_NUMBER;
else {
char *tmp;
- char *endp;
- unsigned long port;
- errno = 0;
- port = strtoul(part, &endp, 10); /* must be decimal */
- if(errno || (port > 0xffff) || *endp)
+ size_t port;
+ if(Curl_str_number(&part, &port, 0xffff) || *part)
/* weirdly provided number, not good! */
return CURLUE_BAD_PORT_NUMBER;
- tmp = strdup(part);
+ tmp = aprintf("%zd", port);
if(!tmp)
return CURLUE_OUT_OF_MEMORY;
free(u->port);
6: ("00000000000000000000000000001234") 0, [1234] line 32
7: ("0123 345") 0, [123] line 4
8: ("0123O345") 0, [123] line 4
-9: ("-12") 0, [0] line 0
-10: (" 123") 0, [0] line 0
-11: ("") 0, [0] line 0
+9: ("-12") 8, [0] line 0
+10: (" 123") 8, [0] line 0
+11: ("") 8, [0] line 0
Curl_str_number / max
0: ("9223372036854775808") 0, [9223372036854775808] line 19
1: ("9223372036854775809") 0, [9223372036854775809] line 19