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

Re: Help needed on #95010

On Mon, 25 June 2001, Craig Small wrote:
> On Tue, Jun 19, 2001 at 03:13:31PM +0200, Samuel Tardieu wrote:
> > could one of you have a look at 95010? I cannot find an Alpha machine
> > with Debian and X installed (vic needs X11 headers) to debug that
> > (this is probably a minor problem, or 64 bits machines will be removed
> > from vic Architecture line).
> It is and it isn't, here is a patch.
> The problems
>   configure was not defining HAVE_INET_NTOP and HAVE_INET_PTON
>   time() is in <time.h>
>   if (<some-int> == <some-long>) is dumb as long != int, casting added
>   to provide sanity

Sanity's good. Extra pairs of eyes are sometimes handy too. I've proposed a different modification below, which I believe should be more sane.

> diff -ur vic-2.8ucl1.1.3.orig/common/mbus_parser.c vic-2.8ucl1.1.3/common/mbus_parser.c
> --- vic-2.8ucl1.1.3.orig/common/mbus_parser.c    Thu Feb 17 23:59:36 2000
> +++ vic-2.8ucl1.1.3/common/mbus_parser.c    Tue Jun 26 13:17:03 2001
> @@ -167,7 +167,7 @@
>          }
>      *i = strtol(m->buffer, &p, 10);
> -    if (((*i == LONG_MAX) || (*i == LONG_MIN)) && (errno == ERANGE)) {
> +    if (((*i == (int)LONG_MAX) || (*i == (int)LONG_MIN)) && (errno == ERANGE)) {
>          debug_msg("integer out of range\n");
>          return FALSE;
>      }

If the problem is that you are trying to read a signed integer into *i using the strtol functions, then the range error is the condition 
  long-value-read<INT_MIN || long-value-read>INT_MAX
For example, if the string being read contains the value 999999999999, then it is _not_ out of range for strtol, and errno will not be set. However, *i will be set to 9999999999l%~0u, i.e. a bogus number. The error condition inside strtol is flagged by both errno and the extremal return values, and thus can be checked by only using errno.

I would propose

     long tmpLong;
     /* ... */
     tmpLong = strtol(m->buffer, &p, 10);
     if((tmpLong < (long)INT_MIN) ||
        (tmpLong > (long)INT_MAX) ||
        (errno == ERANGE)) {
         debug_msg("integer out of range\n");
         *i = /* whatever makes sense if anything */
         return FALSE;
     } else {
         *i = (int)tmpLong;

This is based not on knowledge of the clients of the above code, but merely 'linting by eye' using nothing but static heuristics.
When sizeof(int)==sizeof(long), the above code isn't quite equivalent to the original, as the boundary conditions are never satisfiable, and may cause compiler heuristics. In which case
     if(tmpLong == (long)(int)tmpLong)
could be used as the 'does it fit in an int' condition. Either way, keeping the value as a long until you've checked it is the safer thing to do.


Mathematics should not have to involve martyrdom;
Support Eric Weisstein, see http://mathworld.wolfram.com
Find the best deals on the web at AltaVista Shopping!

Reply to: