Re: [pcre-dev] PCRE2 SVN 463 strtoul() return value comparis…

Startseite
Nachricht löschen
Autor: Ralf Junker
Datum:  
To: pcre-dev
Betreff: Re: [pcre-dev] PCRE2 SVN 463 strtoul() return value comparisons
On 14.12.2015 18:30, ph10@??? wrote:

>> Nonetheless, the implementation seems more complex than necessary. As I read
>> >the docs, simple >= or <= comparisons would be sufficient even without #if.
>> >They work well on my system and I suppose also on yours:
>>
>>    for strtol():   li  >=  LONG_MAX || li <= LONG_MIN
>>    for strtoul():  uli >= ULONG_MAX

>
> I'm afraid I don't understand. uli >= ULONG_MAX would not work on a
> system (such as mine) where the check needs to be uli > UINT32_MAX
> because ULONG_MAX is 18446744073709551615UL but UINT32_MAX is
> 4294967295U.


Apologies for the confusion. I realize that I did not quite understand
the exact purpose of the overflow checks. I was confused because in SVN
463 you compare the result of strtoul() against both UINT32_MAX as well
as ULONG_MAX. Somehow I am still wondering if you want to check the
string input overflow or if you want establish an upper limit to target
against unwanted input?

In case both objectives have the same limit, this seems to be min or max
32-bit, which is INT32_MIN, INT32_MAX, or UINT32_MAX.

Now according to

http://man7.org/linux/man-pages/man3/strtol.3.html
http://man7.org/linux/man-pages/man3/strtoul.3.html

the overflow result of strtol() and strtoul() is LONG_MIN and LONG_MAX
or ULONG_MAX, respectively.

These constants can hold different values, depending on compiler and OS:

https://en.wikibooks.org/wiki/C_Programming/C_Reference/limits.h

In MS Visual Studio in particular, they are always 32 bit only:

https://msdn.microsoft.com/en-us/library/296az74e.aspx

Regardless of the differences, the following seems to be always true:

LONG_MIN <= INT32_MIN
LONG_MAX >= INT32_MAX
ULONG_MAX >= UINT32_MAX

So for INT32 overflow checking, it should be possible for all OS and
compilers to simply test the following:

   for strtol():      li  >= INT32_MAX || li <= INT32_MIN
   for strtoul():     uli >= UINT32_MAX
                  (or uli >= INT32_MAX, for consistency).


I hope this makes more sense. If not, let's simply forget about it. Your
code works well as is.

Ralf