diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2011-12-22 13:00:32 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2011-12-22 13:00:32 +0100 |
commit | ba6587295053f369d6e2e9b788f42b49e1baced5 (patch) | |
tree | 87adf3c5a302a9f91ba4cc6f97a8f2d2f44eb3e0 | |
parent | 6a93212b54327c77383d88efd581475105f3b72a (diff) |
libbb/bb_strtonum: always set end ptr, even on error return
function old new delta
handle_errors 69 61 -8
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-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 |