NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: lib/58461: strtoi(3) is not portable



The following reply was made to PR lib/58461; it has been noted by GNATS.

From: Robert Elz <kre%munnari.OZ.AU@localhost>
To: Alejandro Colomar <alx%kernel.org@localhost>
Cc: gnats-bugs%netbsd.org@localhost, netbsd-bugs%netbsd.org@localhost,
        Paul Eggert <eggert%cs.ucla.edu@localhost>
Subject: Re: lib/58461: strtoi(3) is not portable
Date: Wed, 24 Jul 2024 16:57:09 +0700

     Date:        Wed, 24 Jul 2024 11:17:30 +0200
     From:        Alejandro Colomar <alx%kernel.org@localhost>
     Message-ID:  <lrsaw6f7bzrygmzcjmtmzi6esbw3gwvkkcfzh7gc5777hvxupm@watpgasqovu6>
 
   | I documented in the Linux man-pages that it is impossible to portably
   | detect an invalid base _after_ a call to strtol(3), as you say.  And
   | thus it only makes sense to validate the base before the call, which
   | makes the POSIX decision to report EINVAL completely bogus,
 
 No, the EINVAL on an invalid base is fine.   The problem is the EINVAL
 when there are no digits.   That's unnecessary, that situation can be
 detected other ways, an errno value for it is not needed.
 
 If EINVAL only ever meant that base was invalid (or perhaps some other
 invalid args - though I don't believe there are any), then there would
 be no issue, all that would be necessary is to check for (errno == EINVAL)
 before doing anything else after a call to strtoimax() (or strtowhatever()).
 
 But it doesn't.   And there's nothing much we can do about that.
 
   | And so ISO C's choice of leaving the behavior undefined
   | on an invalid base was actually better
 
 Not really, nothing would really alter if it were like that.
 
   | (POSIX probably only codified implementations's behavior;
 
 Yes, that happens all the time, unless someone happens to realise
 that some implementations are simply broken, and should not be
 permitted.   That generally needs to happen when an interface is
 first added however, except in the very rare case that implementations
 later converge on sane behaviour, and the allowed difference is no
 longer needed by anyone, and can be deleted.
 
   | I see that FreeBSD, OpenBSD, and Bionic libc (Android) also set nptr on
   | an invalid base.  It seems glibc and musl are the weirdos here.  :(
 
 That difference isn't what matters.   It is the other use of EINVAL
 that breaks things.
 
   | Robert, would you mind opening a bug report for POSIX,
 
 I could, I'll see what might work - there's little point in reporting
 things that would just be rejected.   This gets messier as the exact
 same text is in all of the (fleshed out) function specifications (I
 mean, unlike strtoumax() which just appears in the strtoimax() page).
 
 
   | If you do, please add
   | 	Reported-by: Alejandro Colomar <alx%kernel.org@localhost>
 
 I can do that, if I find some wording that would be reasonable.
 Do remember that POSIX is definitely not intended to be a tutorial,
 its readers are expected to know what it means when something is
 left unspecified or undefined, particularly when the APPLICATION USAGE
 already points out the issue.
 
   | Yeah, that was my original approach, which has the downside that if a
   | system adds support for other bases (e.g., base 1, a.k.a., tally marks)
   | strtoi(3) would need to be patched because it hardcoded the bases.  But
   | it is how it is, it seems.
 
 Yes, that is the problem.   We could fix that (at least for strtoi())
 by simply making the base verification code a function, and calling that
 from everywhere else (and since the test it would do is so simple, it
 could even be an inline function), but other applications (outside callers
 inside libc) couldn't get the benefit of that.
 
 kre
 
 ps: submitting POSIX defect reports isn't all that difficult, though it
 is tedious, as their bug system (MANTIS) is not good - almost as bad as
 gnats!   But you do need an opengroup login to be able to submit things.
 
 


Home | Main Index | Thread Index | Old Index