mirror of
https://github.com/moparisthebest/curl
synced 2024-11-15 14:05:03 -05:00
cmdline: parse numerical options stricter
1 - str2offset() no longer accepts negative numbers since offsets are by nature positive. 2 - introduced str2unum() for the command line parser that accepts numericals which are not supposed to be negative, so that it will properly complain on apparent bad uses and mistakes. Bug: http://curl.haxx.se/mail/archive-2012-07/0013.html
This commit is contained in:
parent
e5843470e8
commit
f2b6ebed7b
@ -397,8 +397,9 @@ ParameterError getparameter(char *flag, /* f or -long-flag */
|
|||||||
GetStr(&config->egd_file, nextarg);
|
GetStr(&config->egd_file, nextarg);
|
||||||
break;
|
break;
|
||||||
case 'c': /* connect-timeout */
|
case 'c': /* connect-timeout */
|
||||||
if(str2num(&config->connecttimeout, nextarg))
|
rc=str2unum(&config->connecttimeout, nextarg);
|
||||||
return PARAM_BAD_NUMERIC;
|
if(rc)
|
||||||
|
return rc;
|
||||||
break;
|
break;
|
||||||
case 'd': /* ciphers */
|
case 'd': /* ciphers */
|
||||||
GetStr(&config->cipher_list, nextarg);
|
GetStr(&config->cipher_list, nextarg);
|
||||||
@ -541,8 +542,12 @@ ParameterError getparameter(char *flag, /* f or -long-flag */
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 's': /* --max-redirs */
|
case 's': /* --max-redirs */
|
||||||
/* specified max no of redirects (http(s)) */
|
/* specified max no of redirects (http(s)), this accepts -1 as a
|
||||||
if(str2num(&config->maxredirs, nextarg))
|
special condition */
|
||||||
|
rc = str2num(&config->maxredirs, nextarg);
|
||||||
|
if(rc)
|
||||||
|
return rc;
|
||||||
|
if(config->maxredirs < -1)
|
||||||
return PARAM_BAD_NUMERIC;
|
return PARAM_BAD_NUMERIC;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -586,8 +591,9 @@ ParameterError getparameter(char *flag, /* f or -long-flag */
|
|||||||
return PARAM_LIBCURL_DOESNT_SUPPORT;
|
return PARAM_LIBCURL_DOESNT_SUPPORT;
|
||||||
break;
|
break;
|
||||||
case 'y': /* --max-filesize */
|
case 'y': /* --max-filesize */
|
||||||
if(str2offset(&config->max_filesize, nextarg))
|
rc = str2offset(&config->max_filesize, nextarg);
|
||||||
return PARAM_BAD_NUMERIC;
|
if(rc)
|
||||||
|
return rc;
|
||||||
break;
|
break;
|
||||||
case 'z': /* --disable-eprt */
|
case 'z': /* --disable-eprt */
|
||||||
config->disable_eprt = toggle;
|
config->disable_eprt = toggle;
|
||||||
@ -663,16 +669,19 @@ ParameterError getparameter(char *flag, /* f or -long-flag */
|
|||||||
config->proxybasic = toggle;
|
config->proxybasic = toggle;
|
||||||
break;
|
break;
|
||||||
case 'g': /* --retry */
|
case 'g': /* --retry */
|
||||||
if(str2num(&config->req_retry, nextarg))
|
rc = str2unum(&config->req_retry, nextarg);
|
||||||
return PARAM_BAD_NUMERIC;
|
if(rc)
|
||||||
|
return rc;
|
||||||
break;
|
break;
|
||||||
case 'h': /* --retry-delay */
|
case 'h': /* --retry-delay */
|
||||||
if(str2num(&config->retry_delay, nextarg))
|
rc = str2unum(&config->retry_delay, nextarg);
|
||||||
return PARAM_BAD_NUMERIC;
|
if(rc)
|
||||||
|
return rc;
|
||||||
break;
|
break;
|
||||||
case 'i': /* --retry-max-time */
|
case 'i': /* --retry-max-time */
|
||||||
if(str2num(&config->retry_maxtime, nextarg))
|
rc = str2unum(&config->retry_maxtime, nextarg);
|
||||||
return PARAM_BAD_NUMERIC;
|
if(rc)
|
||||||
|
return rc;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'k': /* --proxy-negotiate */
|
case 'k': /* --proxy-negotiate */
|
||||||
@ -759,8 +768,9 @@ ParameterError getparameter(char *flag, /* f or -long-flag */
|
|||||||
config->nokeepalive = (!toggle)?TRUE:FALSE;
|
config->nokeepalive = (!toggle)?TRUE:FALSE;
|
||||||
break;
|
break;
|
||||||
case '3': /* --keepalive-time */
|
case '3': /* --keepalive-time */
|
||||||
if(str2num(&config->alivetime, nextarg))
|
rc = str2unum(&config->alivetime, nextarg);
|
||||||
return PARAM_BAD_NUMERIC;
|
if(rc)
|
||||||
|
return rc;
|
||||||
break;
|
break;
|
||||||
case '4': /* --post302 */
|
case '4': /* --post302 */
|
||||||
config->post302 = toggle;
|
config->post302 = toggle;
|
||||||
@ -786,7 +796,9 @@ ParameterError getparameter(char *flag, /* f or -long-flag */
|
|||||||
config->proxyver = CURLPROXY_HTTP_1_0;
|
config->proxyver = CURLPROXY_HTTP_1_0;
|
||||||
break;
|
break;
|
||||||
case '9': /* --tftp-blksize */
|
case '9': /* --tftp-blksize */
|
||||||
str2num(&config->tftp_blksize, nextarg);
|
rc = str2unum(&config->tftp_blksize, nextarg);
|
||||||
|
if(rc)
|
||||||
|
return rc;
|
||||||
break;
|
break;
|
||||||
case 'A': /* --mail-from */
|
case 'A': /* --mail-from */
|
||||||
GetStr(&config->mail_from, nextarg);
|
GetStr(&config->mail_from, nextarg);
|
||||||
@ -911,8 +923,9 @@ ParameterError getparameter(char *flag, /* f or -long-flag */
|
|||||||
case 'C':
|
case 'C':
|
||||||
/* This makes us continue an ftp transfer at given position */
|
/* This makes us continue an ftp transfer at given position */
|
||||||
if(!curlx_strequal(nextarg, "-")) {
|
if(!curlx_strequal(nextarg, "-")) {
|
||||||
if(str2offset(&config->resume_from, nextarg))
|
rc = str2offset(&config->resume_from, nextarg);
|
||||||
return PARAM_BAD_NUMERIC;
|
if(rc)
|
||||||
|
return rc;
|
||||||
config->resume_from_current = FALSE;
|
config->resume_from_current = FALSE;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1303,8 +1316,9 @@ ParameterError getparameter(char *flag, /* f or -long-flag */
|
|||||||
break;
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
/* specified max time */
|
/* specified max time */
|
||||||
if(str2num(&config->timeout, nextarg))
|
rc = str2unum(&config->timeout, nextarg);
|
||||||
return PARAM_BAD_NUMERIC;
|
if(rc)
|
||||||
|
return rc;
|
||||||
break;
|
break;
|
||||||
case 'M': /* M for manual, huge help */
|
case 'M': /* M for manual, huge help */
|
||||||
if(toggle) { /* --no-manual shows no manual... */
|
if(toggle) { /* --no-manual shows no manual... */
|
||||||
@ -1618,15 +1632,17 @@ ParameterError getparameter(char *flag, /* f or -long-flag */
|
|||||||
break;
|
break;
|
||||||
case 'y':
|
case 'y':
|
||||||
/* low speed time */
|
/* low speed time */
|
||||||
if(str2num(&config->low_speed_time, nextarg))
|
rc = str2unum(&config->low_speed_time, nextarg);
|
||||||
return PARAM_BAD_NUMERIC;
|
if(rc)
|
||||||
|
return rc;
|
||||||
if(!config->low_speed_limit)
|
if(!config->low_speed_limit)
|
||||||
config->low_speed_limit = 1;
|
config->low_speed_limit = 1;
|
||||||
break;
|
break;
|
||||||
case 'Y':
|
case 'Y':
|
||||||
/* low speed limit */
|
/* low speed limit */
|
||||||
if(str2num(&config->low_speed_limit, nextarg))
|
rc = str2unum(&config->low_speed_limit, nextarg);
|
||||||
return PARAM_BAD_NUMERIC;
|
if(rc)
|
||||||
|
return rc;
|
||||||
if(!config->low_speed_time)
|
if(!config->low_speed_time)
|
||||||
config->low_speed_time = 30;
|
config->low_speed_time = 30;
|
||||||
break;
|
break;
|
||||||
|
@ -32,6 +32,7 @@ typedef enum {
|
|||||||
PARAM_HELP_REQUESTED,
|
PARAM_HELP_REQUESTED,
|
||||||
PARAM_GOT_EXTRA_PARAMETER,
|
PARAM_GOT_EXTRA_PARAMETER,
|
||||||
PARAM_BAD_NUMERIC,
|
PARAM_BAD_NUMERIC,
|
||||||
|
PARAM_NEGATIVE_NUMERIC,
|
||||||
PARAM_LIBCURL_DOESNT_SUPPORT,
|
PARAM_LIBCURL_DOESNT_SUPPORT,
|
||||||
PARAM_NO_MEM,
|
PARAM_NO_MEM,
|
||||||
PARAM_LAST
|
PARAM_LAST
|
||||||
|
@ -54,6 +54,8 @@ const char *param2text(int res)
|
|||||||
return "is badly used here";
|
return "is badly used here";
|
||||||
case PARAM_BAD_NUMERIC:
|
case PARAM_BAD_NUMERIC:
|
||||||
return "expected a proper numerical parameter";
|
return "expected a proper numerical parameter";
|
||||||
|
case PARAM_NEGATIVE_NUMERIC:
|
||||||
|
return "expected a positive numerical parameter";
|
||||||
case PARAM_LIBCURL_DOESNT_SUPPORT:
|
case PARAM_LIBCURL_DOESNT_SUPPORT:
|
||||||
return "the installed libcurl version doesn't support this";
|
return "the installed libcurl version doesn't support this";
|
||||||
case PARAM_NO_MEM:
|
case PARAM_NO_MEM:
|
||||||
|
@ -146,8 +146,8 @@ void cleanarg(char *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse the string and write the integer in the given address. Return
|
* Parse the string and write the long in the given address. Return non-zero
|
||||||
* non-zero on failure, zero on success.
|
* on failure, zero on success.
|
||||||
*
|
*
|
||||||
* Since this function gets called with the 'nextarg' pointer from within the
|
* Since this function gets called with the 'nextarg' pointer from within the
|
||||||
* getparameter a lot, we must check it for NULL before accessing the str
|
* getparameter a lot, we must check it for NULL before accessing the str
|
||||||
@ -161,10 +161,26 @@ int str2num(long *val, const char *str)
|
|||||||
long num = strtol(str, &endptr, 10);
|
long num = strtol(str, &endptr, 10);
|
||||||
if((endptr != str) && (endptr == str + strlen(str))) {
|
if((endptr != str) && (endptr == str + strlen(str))) {
|
||||||
*val = num;
|
*val = num;
|
||||||
return 0; /* Ok */
|
return PARAM_OK; /* Ok */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1; /* badness */
|
return PARAM_BAD_NUMERIC; /* badness */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse the string and write the long in the given address. Return non-zero
|
||||||
|
* on failure, zero on success. ONLY ACCEPTS POSITIVE NUMBERS!
|
||||||
|
*
|
||||||
|
* Since this function gets called with the 'nextarg' pointer from within the
|
||||||
|
* getparameter a lot, we must check it for NULL before accessing the str
|
||||||
|
* data.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int str2unum(long *val, const char *str)
|
||||||
|
{
|
||||||
|
if(str[0]=='-')
|
||||||
|
return PARAM_NEGATIVE_NUMERIC; /* badness */
|
||||||
|
return str2num(val, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -274,8 +290,8 @@ long proto2num(struct Configurable *config, long *val, const char *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the given string looking for an offset (which may be
|
* Parses the given string looking for an offset (which may be a
|
||||||
* a larger-than-integer value).
|
* larger-than-integer value). The offset CANNOT be negative!
|
||||||
*
|
*
|
||||||
* @param val the offset to populate
|
* @param val the offset to populate
|
||||||
* @param str the buffer containing the offset
|
* @param str the buffer containing the offset
|
||||||
@ -283,16 +299,24 @@ long proto2num(struct Configurable *config, long *val, const char *str)
|
|||||||
*/
|
*/
|
||||||
int str2offset(curl_off_t *val, const char *str)
|
int str2offset(curl_off_t *val, const char *str)
|
||||||
{
|
{
|
||||||
|
char *endptr;
|
||||||
|
if(str[0] == '-')
|
||||||
|
/* offsets aren't negative, this indicates weird input */
|
||||||
|
return PARAM_NEGATIVE_NUMERIC;
|
||||||
|
|
||||||
#if(CURL_SIZEOF_CURL_OFF_T > CURL_SIZEOF_LONG)
|
#if(CURL_SIZEOF_CURL_OFF_T > CURL_SIZEOF_LONG)
|
||||||
*val = curlx_strtoofft(str, NULL, 0);
|
*val = curlx_strtoofft(str, &endptr, 0);
|
||||||
if((*val == CURL_OFF_T_MAX || *val == CURL_OFF_T_MIN) && (ERRNO == ERANGE))
|
if((*val == CURL_OFF_T_MAX || *val == CURL_OFF_T_MIN) && (ERRNO == ERANGE))
|
||||||
return 1;
|
return PARAM_BAD_NUMERIC;
|
||||||
#else
|
#else
|
||||||
*val = strtol(str, NULL, 0);
|
*val = strtol(str, &endptr, 0);
|
||||||
if((*val == LONG_MIN || *val == LONG_MAX) && ERRNO == ERANGE)
|
if((*val == LONG_MIN || *val == LONG_MAX) && ERRNO == ERANGE)
|
||||||
return 1;
|
return PARAM_BAD_NUMERIC;
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
if((endptr != str) && (endptr == str + strlen(str)))
|
||||||
|
return 0; /* Ok */
|
||||||
|
|
||||||
|
return PARAM_BAD_NUMERIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
ParameterError checkpasswd(const char *kind, /* for what purpose */
|
ParameterError checkpasswd(const char *kind, /* for what purpose */
|
||||||
|
@ -32,6 +32,7 @@ ParameterError file2memory(char **bufp, size_t *size, FILE *file);
|
|||||||
void cleanarg(char *str);
|
void cleanarg(char *str);
|
||||||
|
|
||||||
int str2num(long *val, const char *str);
|
int str2num(long *val, const char *str);
|
||||||
|
int str2unum(long *val, const char *str); /* for unsigned input numbers */
|
||||||
|
|
||||||
long proto2num(struct Configurable *config, long *val, const char *str);
|
long proto2num(struct Configurable *config, long *val, const char *str);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user