mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 10:51:54 -04:00
Reject negative and out-of-range values in non-negative integer parsing
This commit is contained in:
parent
99a79b7049
commit
6f74455864
6 changed files with 131 additions and 23 deletions
|
|
@ -487,15 +487,9 @@ static int parse_option_size(const char* arg, uint64_t* out_size)
|
|||
char* e;
|
||||
uint64_t mult = 1;
|
||||
|
||||
while (isspace((unsigned char)*arg))
|
||||
++arg;
|
||||
|
||||
if (*arg == '-')
|
||||
return -1;
|
||||
|
||||
/* parse the number part */
|
||||
errno = 0;
|
||||
uint64_t size = strtoull(arg, &e, 10);
|
||||
uint64_t size = strtonll(arg, &e, 10);
|
||||
if (e == arg || errno == ERANGE)
|
||||
return -1;
|
||||
|
||||
|
|
@ -701,7 +695,7 @@ int snapraid_main(int argc, char* argv[])
|
|||
}
|
||||
break;
|
||||
case 'o' :
|
||||
olderthan = strtou(optarg, &e, 10);
|
||||
olderthan = strton(optarg, &e, 10);
|
||||
if (e == optarg || *e || olderthan > 1000) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal(EUSER, "Invalid number of days '%s'\n", optarg);
|
||||
|
|
@ -726,7 +720,7 @@ int snapraid_main(int argc, char* argv[])
|
|||
break;
|
||||
case 'S' :
|
||||
blockstart_set = 1;
|
||||
blockstart = strtoull(optarg, &e, 0);
|
||||
blockstart = strtonll(optarg, &e, 0);
|
||||
if (e == optarg || *e) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal(EUSER, "Invalid start position '%s'\n", optarg);
|
||||
|
|
@ -736,7 +730,7 @@ int snapraid_main(int argc, char* argv[])
|
|||
break;
|
||||
case 'B' :
|
||||
blockcount_set = 1;
|
||||
blockcount = strtoull(optarg, &e, 0);
|
||||
blockcount = strtonll(optarg, &e, 0);
|
||||
if (e == optarg || *e) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal(EUSER, "Invalid count number '%s'\n", optarg);
|
||||
|
|
@ -745,7 +739,7 @@ int snapraid_main(int argc, char* argv[])
|
|||
}
|
||||
break;
|
||||
case 'L' :
|
||||
opt.io_error_limit = strtou(optarg, &e, 0);
|
||||
opt.io_error_limit = strton(optarg, &e, 0);
|
||||
if (e == optarg || *e) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal(EUSER, "Invalid error limit number '%s'\n", optarg);
|
||||
|
|
@ -857,7 +851,7 @@ int snapraid_main(int argc, char* argv[])
|
|||
opt.gui_touch_before = 1;
|
||||
break;
|
||||
case OPT_GUI_THRESHOLD_REMOVES :
|
||||
opt.gui_threshold_removes = strtou(optarg, &e, 0);
|
||||
opt.gui_threshold_removes = strton(optarg, &e, 0);
|
||||
if (e == optarg || *e) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal(EUSER, "Invalid threshold '%s'\n", optarg);
|
||||
|
|
@ -866,7 +860,7 @@ int snapraid_main(int argc, char* argv[])
|
|||
}
|
||||
break;
|
||||
case OPT_GUI_THRESHOLD_UPDATES :
|
||||
opt.gui_threshold_updates = strtou(optarg, &e, 0);
|
||||
opt.gui_threshold_updates = strton(optarg, &e, 0);
|
||||
if (e == optarg || *e) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal(EUSER, "Invalid threshold '%s'\n", optarg);
|
||||
|
|
|
|||
|
|
@ -1444,7 +1444,7 @@ void state_config(struct snapraid_state* state, const char* path, const char* co
|
|||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
int val = strtou(buffer, &e, 0);
|
||||
int val = strton(buffer, &e, 0);
|
||||
|
||||
if (e && !*e) {
|
||||
/* numerical form */
|
||||
|
|
@ -1593,7 +1593,7 @@ void state_config(struct snapraid_state* state, const char* path, const char* co
|
|||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
state->autosave = strtoul(buffer, &e, 0);
|
||||
state->autosave = strtonl(buffer, &e, 0);
|
||||
|
||||
if (!e || *e) {
|
||||
/* LCOV_EXCL_START */
|
||||
|
|
|
|||
105
cmdline/str.c
105
cmdline/str.c
|
|
@ -299,6 +299,111 @@ unsigned strtou(const char* nptr, char** endptr, int base)
|
|||
return (unsigned)val;
|
||||
}
|
||||
|
||||
unsigned strton(const char* nptr, char** endptr, int base)
|
||||
{
|
||||
const char* p = nptr;
|
||||
unsigned val;
|
||||
int save_errno = errno;
|
||||
|
||||
while (isspace((unsigned char)*p)) {
|
||||
++p;
|
||||
}
|
||||
|
||||
if (*p == '-') {
|
||||
if (endptr) {
|
||||
*endptr = (char*)nptr;
|
||||
}
|
||||
errno = ERANGE;
|
||||
return (unsigned)-1;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
val = strtou(nptr, endptr, base);
|
||||
|
||||
if (errno == ERANGE) {
|
||||
if (endptr) {
|
||||
*endptr = (char*)nptr;
|
||||
}
|
||||
return (unsigned)-1;
|
||||
}
|
||||
|
||||
if (errno == 0) {
|
||||
errno = save_errno;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
unsigned long strtonl(const char* nptr, char** endptr, int base)
|
||||
{
|
||||
const char* p = nptr;
|
||||
unsigned long val;
|
||||
int save_errno = errno;
|
||||
|
||||
while (isspace((unsigned char)*p)) {
|
||||
++p;
|
||||
}
|
||||
|
||||
if (*p == '-') {
|
||||
if (endptr) {
|
||||
*endptr = (char*)nptr;
|
||||
}
|
||||
errno = ERANGE;
|
||||
return (unsigned long)-1;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
val = strtoul(nptr, endptr, base);
|
||||
|
||||
if (errno == ERANGE) {
|
||||
if (endptr) {
|
||||
*endptr = (char*)nptr;
|
||||
}
|
||||
return (unsigned long)-1;
|
||||
}
|
||||
|
||||
if (errno == 0) {
|
||||
errno = save_errno;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
unsigned long long strtonll(const char* nptr, char** endptr, int base)
|
||||
{
|
||||
const char* p = nptr;
|
||||
unsigned long long val;
|
||||
int save_errno = errno;
|
||||
|
||||
while (isspace((unsigned char)*p)) {
|
||||
++p;
|
||||
}
|
||||
|
||||
if (*p == '-') {
|
||||
if (endptr) {
|
||||
*endptr = (char*)nptr;
|
||||
}
|
||||
errno = ERANGE;
|
||||
return (unsigned long long)-1;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
val = strtoull(nptr, endptr, base);
|
||||
|
||||
if (errno == ERANGE) {
|
||||
if (endptr) {
|
||||
*endptr = (char*)nptr;
|
||||
}
|
||||
return (unsigned long long)-1;
|
||||
}
|
||||
|
||||
if (errno == 0) {
|
||||
errno = save_errno;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* wnmatch */
|
||||
|
||||
|
|
|
|||
|
|
@ -115,6 +115,15 @@ int strtoi(const char* nptr, char** endptr, int base);
|
|||
*/
|
||||
unsigned strtou(const char* nptr, char** endptr, int base);
|
||||
|
||||
/**
|
||||
* Convert strings to non-negative unsigned integers.
|
||||
* Negative or out-of-range values are rejected by returning (type)-1,
|
||||
* setting errno to ERANGE, and setting endptr to nptr.
|
||||
*/
|
||||
unsigned strton(const char* nptr, char** endptr, int base);
|
||||
unsigned long strtonl(const char* nptr, char** endptr, int base);
|
||||
unsigned long long strtonll(const char* nptr, char** endptr, int base);
|
||||
|
||||
/****************************************************************************/
|
||||
/* match */
|
||||
|
||||
|
|
|
|||
|
|
@ -2356,21 +2356,21 @@ int smartctl_attribute(OS_FILE* f, const char* file, const char* name, struct sm
|
|||
|
||||
smart[id].raw = raw;
|
||||
|
||||
v = strtoul(norm, &e, 10);
|
||||
v = strtonl(norm, &e, 10);
|
||||
if (e != norm || *e == 0) {
|
||||
smart[id].norm = v;
|
||||
} else {
|
||||
smart[id].norm = SMART_UNASSIGNED;
|
||||
}
|
||||
|
||||
v = strtoul(worst, &e, 10);
|
||||
v = strtonl(worst, &e, 10);
|
||||
if (e != worst || *e == 0) {
|
||||
smart[id].worst = v;
|
||||
} else {
|
||||
smart[id].worst = SMART_UNASSIGNED;
|
||||
}
|
||||
|
||||
v = strtoul(thresh, &e, 10);
|
||||
v = strtonl(thresh, &e, 10);
|
||||
if (e != thresh || *e == 0) {
|
||||
smart[id].thresh = v;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -520,7 +520,7 @@ static unsigned parse_cpulist(const char* str, unsigned* cpus, unsigned max_cpus
|
|||
break;
|
||||
|
||||
char* end;
|
||||
unsigned long start = strtoul(p, &end, 10);
|
||||
unsigned long start = strtonl(p, &end, 10);
|
||||
if (end == p)
|
||||
break;
|
||||
|
||||
|
|
@ -528,7 +528,7 @@ static unsigned parse_cpulist(const char* str, unsigned* cpus, unsigned max_cpus
|
|||
p = end;
|
||||
if (*p == '-') {
|
||||
++p;
|
||||
stop = strtoul(p, &end, 10);
|
||||
stop = strtonl(p, &end, 10);
|
||||
if (end == p)
|
||||
break;
|
||||
p = end;
|
||||
|
|
@ -3297,7 +3297,7 @@ static dev_t devread(const char* path)
|
|||
|
||||
buf[len] = 0;
|
||||
|
||||
ma = strtou(buf, &e, 10);
|
||||
ma = strton(buf, &e, 10);
|
||||
if (*e != ':') {
|
||||
/* LCOV_EXCL_START */
|
||||
log_error(EEXTERNAL, "Invalid format in '%s' for '%s'.\n", path, buf);
|
||||
|
|
@ -3305,7 +3305,7 @@ static dev_t devread(const char* path)
|
|||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
mi = strtou(e + 1, &e, 10);
|
||||
mi = strton(e + 1, &e, 10);
|
||||
if (*e != 0 && !isspace((unsigned char)*e)) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_error(EEXTERNAL, "Invalid format in '%s' for '%s'.\n", path, buf);
|
||||
|
|
@ -3495,7 +3495,7 @@ static int devstat(dev_t device, uint64_t* count)
|
|||
break;
|
||||
*i++ = 0; /* put a terminator */
|
||||
|
||||
v = strtoull(n, &e, 10);
|
||||
v = strtonll(n, &e, 10);
|
||||
if (*e != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
break;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue