diff options
-rw-r--r-- | libbb/bb_strtonum.c | 59 |
1 files changed, 40 insertions, 19 deletions
diff --git a/libbb/bb_strtonum.c b/libbb/bb_strtonum.c index c66c774f4..949f26bee 100644 --- a/libbb/bb_strtonum.c +++ b/libbb/bb_strtonum.c @@ -36,14 +36,14 @@ static unsigned long long ret_ERANGE(void) return ULLONG_MAX; } -static unsigned long long handle_errors(unsigned long long v, char **endp, char *endptr) +static unsigned long long handle_errors(unsigned long long v, char **endp) { - if (endp) *endp = endptr; + char next_ch = **endp; /* errno is already set to ERANGE by strtoXXX if value overflowed */ - if (endptr[0]) { + if (next_ch) { /* "1234abcg" or out-of-range? */ - if (isalnum(endptr[0]) || errno) + if (isalnum(next_ch) || errno) return ret_ERANGE(); /* good number, just suspicious terminator */ errno = EINVAL; @@ -57,30 +57,37 @@ unsigned long long FAST_FUNC bb_strtoull(const char *arg, char **endp, int base) unsigned long long v; char *endptr; + if (!endp) endp = &endptr; + *endp = (char*) arg; + /* strtoul(" -4200000000") returns 94967296, errno 0 (!) */ /* I don't think that this is right. Preventing this... */ if (!isalnum(arg[0])) return ret_ERANGE(); /* not 100% correct for lib func, but convenient for the caller */ errno = 0; - v = strtoull(arg, &endptr, base); - return handle_errors(v, endp, endptr); + v = strtoull(arg, endp, base); + return handle_errors(v, endp); } long long FAST_FUNC bb_strtoll(const char *arg, char **endp, int base) { unsigned long long v; char *endptr; + char first; + + if (!endp) endp = &endptr; + *endp = (char*) arg; /* Check for the weird "feature": * a "-" string is apparently a valid "number" for strto[u]l[l]! * It returns zero and errno is 0! :( */ - char first = (arg[0] != '-' ? arg[0] : arg[1]); + first = (arg[0] != '-' ? arg[0] : arg[1]); if (!isalnum(first)) return ret_ERANGE(); errno = 0; - v = strtoll(arg, &endptr, base); - return handle_errors(v, endp, endptr); + v = strtoll(arg, endp, base); + return handle_errors(v, endp); } #if ULONG_MAX != ULLONG_MAX @@ -89,23 +96,30 @@ unsigned long FAST_FUNC bb_strtoul(const char *arg, char **endp, int base) unsigned long v; char *endptr; + if (!endp) endp = &endptr; + *endp = (char*) arg; + if (!isalnum(arg[0])) return ret_ERANGE(); errno = 0; - v = strtoul(arg, &endptr, base); - return handle_errors(v, endp, endptr); + v = strtoul(arg, endp, base); + return handle_errors(v, endp); } long FAST_FUNC bb_strtol(const char *arg, char **endp, int base) { long v; char *endptr; + char first; - char first = (arg[0] != '-' ? arg[0] : arg[1]); + if (!endp) endp = &endptr; + *endp = (char*) arg; + + first = (arg[0] != '-' ? arg[0] : arg[1]); if (!isalnum(first)) return ret_ERANGE(); errno = 0; - v = strtol(arg, &endptr, base); - return handle_errors(v, endp, endptr); + v = strtol(arg, endp, base); + return handle_errors(v, endp); } #endif @@ -115,25 +129,32 @@ unsigned FAST_FUNC bb_strtou(const char *arg, char **endp, int base) unsigned long v; char *endptr; + if (!endp) endp = &endptr; + *endp = (char*) arg; + if (!isalnum(arg[0])) return ret_ERANGE(); errno = 0; - v = strtoul(arg, &endptr, base); + v = strtoul(arg, endp, base); if (v > UINT_MAX) return ret_ERANGE(); - return handle_errors(v, endp, endptr); + return handle_errors(v, endp); } int FAST_FUNC bb_strtoi(const char *arg, char **endp, int base) { long v; char *endptr; + char first; + + if (!endp) endp = &endptr; + *endp = (char*) arg; - char first = (arg[0] != '-' ? arg[0] : arg[1]); + first = (arg[0] != '-' ? arg[0] : arg[1]); if (!isalnum(first)) return ret_ERANGE(); errno = 0; - v = strtol(arg, &endptr, base); + v = strtol(arg, endp, base); if (v > INT_MAX) return ret_ERANGE(); if (v < INT_MIN) return ret_ERANGE(); - return handle_errors(v, endp, endptr); + return handle_errors(v, endp); } #endif |