diff options
author | Jes Klinke <jbk@google.com> | 2019-05-08 10:31:57 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2019-05-14 20:13:39 -0700 |
commit | ac8a13329b0b321daeb87f6afb79c163beb21372 (patch) | |
tree | 386987b4a5b057501dc72463333b32a23f8f38aa /common/util.c | |
parent | a823e6d96f28928d5808149c51cd8f4963b4880e (diff) | |
download | chrome-ec-ac8a13329b0b321daeb87f6afb79c163beb21372.tar.gz |
Align behavior of strtoi() and strtoul() to match Linux manpage description of strtol().
Behavior changes:
1) Initial '+' character is tolerated.
2) Hexadecimal strings prefixed with "0x" are rejected, if given base
parameter is anything other than 16 or 0, rather than parsed as hex,
diregarding the given base.
3) If given base is 0, strings starting with leading zero will be parsed
as octal, rather than decimal.
4) Initial '-' character allowed before "0x" on hexadecimal numbers.
(Note: This is my first time using git or gerrit, please let me know if there is
some policy or customs that I am not properly adhering to.)
BRANCH=none
TEST=make run-utils_str V=1
Bug: 940329
Change-Id: I71654471b77f0df071a58ff6bed7028f00cd46b5
Signed-off-by: Jes Bodi Klinke <jbk@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1577750
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Tested-by: Jes Klinke <jbk@chromium.org>
Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
Diffstat (limited to 'common/util.c')
-rw-r--r-- | common/util.c | 59 |
1 files changed, 31 insertions, 28 deletions
diff --git a/common/util.c b/common/util.c index 8005e0bfdb..f3d3fc3993 100644 --- a/common/util.c +++ b/common/util.c @@ -115,6 +115,18 @@ int atoi(const char *nptr) return neg ? -result : result; } +static int find_base(int base, int *c, const char **nptr) { + if ((base == 0 || base == 16) && *c == '0' + && (**nptr == 'x' || **nptr == 'X')) { + *c = (*nptr)[1]; + (*nptr) += 2; + base = 16; + } else if (base == 0) { + base = *c == '0' ? 8 : 10; + } + return base; +} + /* Like strtol(), but for integers */ int strtoi(const char *nptr, char **endptr, int base) @@ -123,24 +135,18 @@ int strtoi(const char *nptr, char **endptr, int base) int neg = 0; int c = '\0'; - if (endptr) - *endptr = (char *)nptr; - while ((c = *nptr++) && isspace(c)) ; - if (c == '0' && *nptr == 'x') { - base = 16; - c = nptr[1]; - nptr += 2; - } else if (base == 0) { - base = 10; - if (c == '-') { - neg = 1; - c = *nptr++; - } + if (c == '+') { + c = *nptr++; + } else if (c == '-') { + neg = 1; + c = *nptr++; } + base = find_base(base, &c, &nptr); + while (c) { if (c >= '0' && c < '0' + MIN(base, 10)) result = result * base + (c - '0'); @@ -151,11 +157,11 @@ int strtoi(const char *nptr, char **endptr, int base) else break; - if (endptr) - *endptr = (char *)nptr; c = *nptr++; } + if (endptr) + *endptr = (char *)nptr - 1; return neg ? -result : result; } @@ -164,21 +170,18 @@ uint64_t strtoul(const char *nptr, char **endptr, int base) uint64_t result = 0; int c = '\0'; - if (endptr) - *endptr = (char *)nptr; - while ((c = *nptr++) && isspace(c)) ; - if (c == '0' && *nptr == 'x') { - base = 16; - c = nptr[1]; - nptr += 2; - } else if (base == 0) { - base = 10; - if (c == '-') - return result; + if (c == '+') { + c = *nptr++; + } else if (c == '-') { + if (endptr) + *endptr = (char *)nptr - 1; + return result; } + + base = find_base(base, &c, &nptr); while (c) { if (c >= '0' && c < '0' + MIN(base, 10)) @@ -190,11 +193,11 @@ uint64_t strtoul(const char *nptr, char **endptr, int base) else break; - if (endptr) - *endptr = (char *)nptr; c = *nptr++; } + if (endptr) + *endptr = (char *)nptr - 1; return result; } |