bin: fix number conversion routines on 32bit

On 32bit archetectures, long int = int the current check for detecting
values that overflow int will fail.  Conversion routings should check
errno.

* bin/common_conv.cc, bin/common_range.cc: Here.
This commit is contained in:
Alexandre Duret-Lutz 2023-01-24 15:48:06 +01:00
parent e5150d0314
commit 121d5e5524
2 changed files with 12 additions and 6 deletions

View file

@ -25,12 +25,13 @@ int
to_int(const char* s, const char* where) to_int(const char* s, const char* where)
{ {
char* endptr; char* endptr;
errno = 0;
long int lres = strtol(s, &endptr, 10); long int lres = strtol(s, &endptr, 10);
if (*endptr) if (*endptr)
error(2, 0, "failed to parse '%s' as an integer (in argument of %s).", error(2, 0, "failed to parse '%s' as an integer (in argument of %s).",
s, where); s, where);
int res = lres; int res = lres;
if (res != lres) if (res != lres || errno == ERANGE)
error(2, 0, "value '%s' is too large for an int (in argument of %s).", error(2, 0, "value '%s' is too large for an int (in argument of %s).",
s, where); s, where);
return res; return res;
@ -49,13 +50,14 @@ unsigned
to_unsigned (const char *s, const char* where) to_unsigned (const char *s, const char* where)
{ {
char* endptr; char* endptr;
errno = 0;
unsigned long lres = strtoul(s, &endptr, 10); unsigned long lres = strtoul(s, &endptr, 10);
if (*endptr) if (*endptr)
error(2, 0, error(2, 0,
"failed to parse '%s' as an unsigned integer (in argument of %s).", "failed to parse '%s' as an unsigned integer (in argument of %s).",
s, where); s, where);
unsigned res = lres; unsigned res = lres;
if (res != lres) if (res != lres || errno == ERANGE)
error(2, 0, error(2, 0,
"value '%s' is too large for a unsigned int (in argument of %s).", "value '%s' is too large for a unsigned int (in argument of %s).",
s, where); s, where);
@ -66,8 +68,9 @@ float
to_float(const char* s, const char* where) to_float(const char* s, const char* where)
{ {
char* endptr; char* endptr;
errno = 0;
float res = strtof(s, &endptr); float res = strtof(s, &endptr);
if (*endptr) if (*endptr || errno == ERANGE)
error(2, 0, "failed to parse '%s' as a float (in argument of %s)", error(2, 0, "failed to parse '%s' as a float (in argument of %s)",
s, where); s, where);
return res; return res;
@ -89,8 +92,9 @@ to_longs(const char* arg)
while (*arg) while (*arg)
{ {
char* endptr; char* endptr;
errno = 0;
long value = strtol(arg, &endptr, 10); long value = strtol(arg, &endptr, 10);
if (endptr == arg) if (endptr == arg || errno)
error(2, 0, "failed to parse '%s' as an integer.", arg); error(2, 0, "failed to parse '%s' as an integer.", arg);
res.push_back(value); res.push_back(value);
while (*endptr == ' ' || *endptr == ',') while (*endptr == ' ' || *endptr == ',')

View file

@ -36,9 +36,10 @@ parse_range(const char* str, int missing_left, int missing_right)
{ {
range res; range res;
char* end; char* end;
errno = 0;
long lres = strtol(str, &end, 10); long lres = strtol(str, &end, 10);
res.min = lres; res.min = lres;
if (res.min != lres) if (res.min != lres || errno == ERANGE)
error(2, 0, "start of range '%s' is too large for an int.", str); error(2, 0, "start of range '%s' is too large for an int.", str);
if (end == str) if (end == str)
{ {
@ -69,9 +70,10 @@ parse_range(const char* str, int missing_left, int missing_right)
{ {
// Parse the next integer. // Parse the next integer.
char* end2; char* end2;
errno = 0;
lres = strtol(end, &end2, 10); lres = strtol(end, &end2, 10);
res.max = lres; res.max = lres;
if (res.max != lres) if (res.max != lres || errno == ERANGE)
error(2, 0, "end of range '%s' is too large for an int.", str); error(2, 0, "end of range '%s' is too large for an int.", str);
if (str == end2) if (str == end2)
error(2, 0, "invalid range '%s' " error(2, 0, "invalid range '%s' "