tech-userlevel archive

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

Re: strtonum(3) from OpenBSD?



At Tue, 30 Jun 2009 03:00:17 +0000, David Holland 
<dholland-tech%netbsd.org@localhost> wrote:
Subject: Re: strtonum(3) from OpenBSD?
> 
> On Sat, Jun 27, 2009 at 10:26:49PM -0400, Greg A. Woods wrote:
>  > > That's the POINT. Calls that succeed may set errno anyway. You have to
>  > > check that an error occurred before inspecting errno.
>  > 
>  > Well, with strtol(3) _both_ conditions must hold exactly -- it doesn't
>  > really matter which test is done first!  :-)
> 
> In all cases, not just strtol, both conditions must hold, but it does
> matter which test is done first if errno might contain a trap
> representation.

I meant in the strict ordering of terms in the test expression(s).
I.e. all of the following statements are equivalent.  I.e. it does not
matter which test is done first.  It can be either errno first:

        if (errno == ERANGE && rval == LONG_MAX)
                err();

        if (errno == ERANGE)
                if (rval == LONG_MAX)
                        err();

etc., or the return value first:

        if (rval == LONG_MAX && errno == ERANGE)
                err();

        if (rval == LONG_MAX)
                if (errno == ERANGE)
                        err();


> The problem is that if strtol were allowed to leave trash in errno,
> and the number you were converting was exactly LONG_MAX, you might
> incorrectly conclude that an overflow occurred.

Hmmm... yes, but _only_ if that "trash" value were ERANGE (or the
undocumented EINVAL return).  If I understand you correctly, you are
suggesting that ERANGE may be inadvertently set by some arithmetic
operation during the conversion of a string that represents _exactly_
LONG_MAX.

In any case that's a separate problem and it will only affect whether
you ignore the return value and focus on errno alone, assuming that the
strtol() implementation does guarantee it to be zero if there was no
overflow.

Do you know of any C implementations where signed integer arithmetic
overflows will trigger some form of trap or exception handling, _and_
where the exception handler will set errno to ERANGE?  OpenVMS can raise
SIGFPE on integer overflow, division by zero, etc. it seems but as far
as I can tell this will abort the program just as on any POSIX system,
and I'm not sure it will happen for ordinary int or even long either.
(GCC-4 has the "-ftrapv" option, but it just calls abort() after doing a
post-condition check assuming execution on a two's complement system.
Apparently someone implemented overflow checking on LCC for those target
platforms which do hardware overflow checking for small integer
operations, but I don't know what it's effect is.)

In any case, IIUC, then such a platform cannot be fully conforming to
the standard unless their strtol() implementation internally does clear
errno in the case where no overflow has occurred (for a completely
successful conversion).  If it does not clear errno as it would be
required to do then it would indeed limit the conversion range to being
one less than LONG_MAX and one more than LONG_MIN and violate standard
requirements.

(of course strtoul() and friends, i.e. the unsigned variants _could_ be
made to be conforming even on a platform which did generate arithmetic
exceptions for signed integer operations since of course conforming
implementations are required to do unsigned integer operations in
exactly the one specified way required by the standard)

> However, as has been noted elsewhere by now, it's not allowed to leave
> trash, which in turn means that there's no particular reason to test
> for LONG_MAX or LONG_MIN; provided you clear errno beforehand it's
> sufficient to test errno afterwards.

Well, at the moment I think that hold true for NetBSD's implementation,
at least for the default compile options.  :-)

Speaking of the NetBSD implementation, I see it returns an undocumented
errno in some cases too, and the documentation is far more convoluted
and complex than necessary too, especially in light of knowing that
errno must be set to zero on return if there was no overflow during an
otherwise error-free conversion.

-- 
                                                Greg A. Woods
                                                Planix, Inc.

<woods%planix.com@localhost>       +1 416 218-0099        http://www.planix.com/

Attachment: pgpf4EMzELRQA.pgp
Description: PGP signature



Home | Main Index | Thread Index | Old Index