Questionable behavior of strtoi(3bsd) / strtou(3bsd)

Guillem Jover guillem at hadrons.org
Sun Jan 7 04:15:29 UTC 2024


Hi!

On Sun, 2024-01-07 at 03:44:23 +0100, Alejandro Colomar wrote:
> While implementing my own strtoi/u() for shadow, and testing it against
> strtoi/u(3bsd), I found that the behavior differed slightly for one
> specific case: when both ERANGE and ENOTSUP happen at the same time, my
> implementation reports ERANGE, while strtoi/u(3bsd) reports ENOTSUP.
> 
> 	strtou("5z", NULL, 0, 0, 4, &status);
> 
> I don't know what's the behavior of the original NetBSD implementation,
> as I couldn't find the file where it's implemented.  If you can give a
> pointer to where it's implemented in NetBSD, it would help.  Maybe you
> could also CC some NetBSD maintainers or list to get their opinion.

It should be the exact same behavior as on NetBSD, yes. The source
file can be seen from the CVS Id in the source. On my local NetBSD
tree the function is implemented via macros, can be found in:

  common/lib/libc/stdlib/strtoi.c
  common/lib/libc/stdlib/strtou.c
  common/lib/libc/stdlib/_strtoi.h

> I guess you just copied the implementation from NetBSD code, so it
> probably behaves like NetBSD.

Yes.

> I think that design is wrong, and would
> like to justify:
> 
> If a value is out-of-range, that's a more problematic error than just
> having trailing text.  Trailing text is often expected, and is not
> treated as an error, but out-of-range is often a hard error.  Silencing
> that error is problematic, and there's no way to work around it.  If
> instead strtoi(3bsd) reported ERANGE when both ERANGE + ENOTSUP happen,
> it would be trivial for the caller to check it there's trailing text via
> 'endptr'.

I didn't design the functions, so not sure whether that was an
intentional choice or not, from the code PoV I can see the structure
making sense (in first making sure the string parsed is correct, before
evaluating what got parsed from it), and while I see where you are coming
from, I wouldn't say the design is necessarily wrong, it's probably a
convenience function that might not always be suitable as convenient? :)
Because in the same way you can duplicate the endptr check, you could
as well do the same for the range checks. I'm also not sure whether
changing the semantics now could cause other issues though.

If the function changes in NetBSD, I'm happy to import those changes,
but I don't think I'd be comfortable doing that unilaterally in libbsd.
I'd suggest you file a bug report in the NetBSD bug tracker.

Thanks,
Guillem


More information about the libbsd mailing list