Mercurial > libjeffpc
changeset 672:0dd0932ec440
int: fail all str2uXX calls with -ERANGE on negative looking input
We have to manually check for negative looking input since (1) negative
numbers cannot be represented with uintXX_t types, and (2) strtoull doesn't
fail (instead it does 2's complement negation of the unsigned bits).
We don't bother differentiating between input consisting of a negative but
otherwise valid number and a non-numeric string starting with a dash.
Ideally, we'd return -ERANGE for the former and -EINVAL for the latter, but
it isn't worth the additional clock cycles to differentiate between the two.
Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author | Josef 'Jeff' Sipek <jeffpc@josefsipek.net> |
---|---|
date | Thu, 21 Feb 2019 19:13:41 -0500 |
parents | f3c75c3d7a04 |
children | 927cbe0ea334 |
files | include/jeffpc/int.h tests/test_str2uint.c |
diffstat | 2 files changed, 65 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/include/jeffpc/int.h Thu Feb 21 18:44:13 2019 -0500 +++ b/include/jeffpc/int.h Thu Feb 21 19:13:41 2019 -0500 @@ -46,6 +46,14 @@ \ *i = 0; \ \ + /* \ + * negative numbers aren't representable by uintXX_t; this may \ + * mask a -EINVAL if the input is of the form: \ + * "-<some non-number>" \ + */ \ + if (*s == '-') \ + return -ERANGE; \ + \ errno = 0; \ tmp = strtoull(s, &endptr, base); \ \
--- a/tests/test_str2uint.c Thu Feb 21 18:44:13 2019 -0500 +++ b/tests/test_str2uint.c Thu Feb 21 19:13:41 2019 -0500 @@ -143,9 +143,65 @@ .out[B16] = ENT(0xa, 0xa, 0xa, 0, 0, 0), }, /* + * Check negative numbers + */ + { + .in = "-0", + .out[B8] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE), + .out[B10] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE), + .out[B16] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE), + }, + { + .in = "-1", + .out[B8] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE), + .out[B10] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE), + .out[B16] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE), + }, + { + .in = "-8", + .out[B8] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE), + .out[B10] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE), + .out[B16] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE), + }, + { + .in = "-A", + .out[B8] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE), + .out[B10] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE), + .out[B16] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE), + }, + { + .in = "-a", + .out[B8] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE), + .out[B10] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE), + .out[B16] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE), + }, + { + .in = "-0XA", + .out[B8] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE), + .out[B10] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE), + .out[B16] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE), + }, + { + .in = "-0Xa", + .out[B8] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE), + .out[B10] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE), + .out[B16] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE), + }, + { + .in = "-0xA", + .out[B8] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE), + .out[B10] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE), + .out[B16] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE), + }, + { + .in = "-0xa", + .out[B8] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE), + .out[B10] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE), + .out[B16] = ENT(0, 0, 0, -ERANGE, -ERANGE, -ERANGE), + }, + /* * FIXME: more test cases * - check values > max for type - * - check inputs starting with '-' ? * - check inputs with leading garbage * - check inputs with trailing garbage */