src: replace strto[u][ld] with curlx_str_ parsers

- Better error handling (no errno mess), better limit checks.

- Also removed all uses of curlx_strtoofft()

Closes #16634
This commit is contained in:
Daniel Stenberg 2025-03-09 12:49:24 +01:00
parent f3b599a7e2
commit 8dca3b0656
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
12 changed files with 150 additions and 205 deletions

View file

@ -85,7 +85,7 @@ static int multiply(curl_off_t *amount, curl_off_t with)
return 0;
}
static CURLcode glob_set(struct URLGlob *glob, char **patternp,
static CURLcode glob_set(struct URLGlob *glob, const char **patternp,
size_t *posp, curl_off_t *amount,
int globindex)
{
@ -95,8 +95,8 @@ static CURLcode glob_set(struct URLGlob *glob, char **patternp,
struct URLPattern *pat;
bool done = FALSE;
char *buf = glob->glob_buffer;
char *pattern = *patternp;
char *opattern = pattern;
const char *pattern = *patternp;
const char *opattern = pattern;
size_t opos = *posp-1;
pat = &glob->pattern[glob->size];
@ -180,7 +180,7 @@ static CURLcode glob_set(struct URLGlob *glob, char **patternp,
return CURLE_OK;
}
static CURLcode glob_range(struct URLGlob *glob, char **patternp,
static CURLcode glob_range(struct URLGlob *glob, const char **patternp,
size_t *posp, curl_off_t *amount,
int globindex)
{
@ -191,8 +191,8 @@ static CURLcode glob_range(struct URLGlob *glob, char **patternp,
expression is checked for well-formedness and collected until the next ']'
*/
struct URLPattern *pat;
char *pattern = *patternp;
char *c;
const char *pattern = *patternp;
const char *c;
pat = &glob->pattern[glob->size];
pat->globindex = globindex;
@ -214,13 +214,13 @@ static CURLcode glob_range(struct URLGlob *glob, char **patternp,
pmatch = TRUE;
if(end_c == ':') {
char *endp;
CURL_SETERRNO(0);
step = strtoul(&pattern[4], &endp, 10);
if(errno || &pattern[4] == endp || *endp != ']')
curl_off_t num;
const char *p = &pattern[4];
if(curlx_str_number(&p, &num, 256) || curlx_str_single(&p, ']'))
step = 0;
else
pattern = endp + 1;
step = (unsigned long)num;
pattern = p;
}
else if(end_c != ']')
/* then this is wrong */
@ -232,7 +232,7 @@ static CURLcode glob_range(struct URLGlob *glob, char **patternp,
*posp += (pattern - *patternp);
if(!pmatch || !step || step > (unsigned)INT_MAX ||
if(!pmatch || !step ||
(min_c == max_c && step != 1) ||
(min_c != max_c && (min_c > max_c || step > (unsigned)(max_c - min_c) ||
(max_c - min_c) > ('z' - 'a'))))
@ -251,10 +251,10 @@ static CURLcode glob_range(struct URLGlob *glob, char **patternp,
}
else if(ISDIGIT(*pattern)) {
/* numeric range detected */
unsigned long min_n;
unsigned long min_n = 0;
unsigned long max_n = 0;
unsigned long step_n = 0;
char *endp;
curl_off_t num;
pat->type = UPTNumRange;
pat->content.NumRange.padlength = 0;
@ -269,48 +269,27 @@ static CURLcode glob_range(struct URLGlob *glob, char **patternp,
}
}
CURL_SETERRNO(0);
min_n = strtoul(pattern, &endp, 10);
if(errno || (endp == pattern))
endp = NULL;
else {
if(*endp != '-')
endp = NULL;
else {
pattern = endp + 1;
while(ISBLANK(*pattern))
pattern++;
if(!ISDIGIT(*pattern)) {
endp = NULL;
goto fail;
if(!curlx_str_number(&pattern, &num, CURL_OFF_T_MAX)) {
min_n = (unsigned long)num;
if(!curlx_str_single(&pattern, '-')) {
curlx_str_passblanks(&pattern);
if(!curlx_str_number(&pattern, &num, CURL_OFF_T_MAX)) {
max_n = (unsigned long)num;
if(!curlx_str_single(&pattern, ']'))
step_n = 1;
else if(!curlx_str_single(&pattern, ':') &&
!curlx_str_number(&pattern, &num, CURL_OFF_T_MAX) &&
!curlx_str_single(&pattern, ']')) {
step_n = (unsigned long)num;
}
/* else bad syntax */
}
CURL_SETERRNO(0);
max_n = strtoul(pattern, &endp, 10);
if(errno)
/* overflow */
endp = NULL;
else if(*endp == ':') {
pattern = endp + 1;
CURL_SETERRNO(0);
step_n = strtoul(pattern, &endp, 10);
if(errno)
/* over/underflow situation */
endp = NULL;
}
else
step_n = 1;
if(endp && (*endp == ']')) {
pattern = endp + 1;
}
else
endp = NULL;
}
}
fail:
*posp += (pattern - *patternp);
if(!endp || !step_n ||
if(!step_n ||
(min_n == max_n && step_n != 1) ||
(min_n != max_n && (min_n > max_n || step_n > (max_n - min_n))))
/* the pattern is not well-formed */
@ -371,7 +350,7 @@ static bool peek_ipv6(const char *str, size_t *skip)
return rc ? FALSE : TRUE;
}
static CURLcode glob_parse(struct URLGlob *glob, char *pattern,
static CURLcode glob_parse(struct URLGlob *glob, const char *pattern,
size_t pos, curl_off_t *amount)
{
/* processes a literal string component of a URL
@ -626,10 +605,11 @@ CURLcode glob_next_url(char **globbed, struct URLGlob *glob)
#define MAX_OUTPUT_GLOB_LENGTH (10*1024)
CURLcode glob_match_url(char **result, char *filename, struct URLGlob *glob)
CURLcode glob_match_url(char **result, const char *filename,
struct URLGlob *glob)
{
char numbuf[18];
char *appendthis = (char *)"";
const char *appendthis = (char *)"";
size_t appendlen = 0;
struct curlx_dynbuf dyn;
@ -642,11 +622,11 @@ CURLcode glob_match_url(char **result, char *filename, struct URLGlob *glob)
while(*filename) {
if(*filename == '#' && ISDIGIT(filename[1])) {
char *ptr = filename;
unsigned long num = strtoul(&filename[1], &filename, 10);
const char *ptr = filename;
curl_off_t num;
struct URLPattern *pat = NULL;
if(num && (num < glob->size)) {
filename++;
if(!curlx_str_number(&filename, &num, glob->size) && num) {
unsigned long i;
num--; /* make it zero based */
/* find the correct glob entry */