[BUG] strto[iu](3bsd) incorrectly handles EINVAL

Alejandro Colomar alx at kernel.org
Sat Jul 20 13:09:51 UTC 2024


Bon dia Guillem (and Christos),

I've been re-reading libbsd's strto[iu](3) functions, after some rather
extensive discussion about the suitability of strtol(3), strtoi(3), and
other string-to-numeric functions in projects.

After finding some quite obscure bugs in gnulib a couple of days ago[1],
I suspected strtoi(3) might have similar problems.  Indeed, it does (in
some systems).

NetBSD is safe, because strtol(3) only reports EINVAL if the base is
invalid.  However, since libbsd is portable to POSIX systems, and POSIX
allows strtol(3) to report EINVAL for what strtoi(3) reports ECANCELED,
NetBSD's strtoi(3) implementation is not portable, and cannot be used in
libbsd.

Let's analyze what would happen in a system where strtol("foo", &e, 0)
reports EINVAL.

-  For a call strtoi("foo", NULL, 0, 0, 0, &st):

   -  strtoimax() reports EINVAL.

   -  *rstatus = errno; sets EINVAL.

   -  The condition `if (*rstatus == 0 && nptr == *endptr)` is not met.

   -  strtoi(3bsd) falls through to the last line, and returns im.

The user receives a bugos error report of EINVAL, where it would expect
ECANCELED.

I propose using my implementation instead:
<https://git.kernel.org/pub/scm/libs/liba2i/liba2i.git/tree/lib/src/a2i/strtoi/strtoi/strtoi.h>

Maybe NetBSD could also use it, so that you can just paste it from it,
as you do with most code.  However, it might be harder to convince
NetBSD of fixing what is not a bug for them.  In any case, I've CCed
Christos just in case.  (Don't be worried about the license; we can
discuss that.)

I've minimized accesses to objects via function parameters, which should
be a slight micro-optimization that could be interesting for NetBSD too.

Also, I think it's slightly more readable (but this depends on taste).

Have a lovely day!
Alex

[1]:

   <https://lists.gnu.org/archive/html/bug-gnulib/2024-07/msg00156.html>
   <https://lists.gnu.org/archive/html/bug-gnulib/2024-07/msg00161.html>
   <https://lists.gnu.org/archive/html/bug-gnulib/2024-07/msg00174.html>
   <https://git.savannah.gnu.org/cgit/gnulib.git/commit/?id=e9d3a876113e61330f341ddac84f67227ef61872>
   <https://git.savannah.gnu.org/cgit/gnulib.git/commit/?id=64ddc975e72cb55d2b2d755c25603bd70312aa5e>
   <https://git.savannah.gnu.org/cgit/gnulib.git/commit/?id=16b33e6649425fcdce095f262da98b539d2f7448>


-- 
<https://www.alejandro-colomar.es/>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/libbsd/attachments/20240720/6919c6a9/attachment.sig>


More information about the libbsd mailing list