This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: vfprintf typing problem


On 03/31/2012 10:29 PM, David Miller wrote:
> It's definitely cheaper to do something like:
> 
> 	int overflow = 0;
> 
> 	while (...) {
> 	...
> 		retval *= 10;
> 		overflow |= ((int) retval < 0);

No, because behavior is undefined after signed overflow,
so a compiler is entitled to optimize the
last line away, so that 'overflow' never becomes nonzero.
GCC actually does that sort of thing sometimes.

Instead, I suggest something like this:

  static int
  read_int (const UCHAR_T * *pstr)
  {
    int retval = **pstr - L_('0');

    while (ISDIGIT (*++(*pstr)))
      if (0 <= retval)
	{
	  if (INT_MAX / 10 < retval)
	    retval = -1;
	  else
	    {
	      int digit = **pstr - L_('0');
	      retval *= 10;
	      if (INT_MAX - digit < retval)
		retval = -1;
	      else
		retval += digit;
	    }
	}

    return retval;
  }

Notice that read_int still parses the entire integer,
even when it overflows; this is simpler to explain and
I expect it may work better with other callers.

Also, please adjust the other seven calls to read_int
(in printf-parsemb.c and in vfprintf.c) to adjust
to read_int's new behavior.  This will catch bad formats
with outlandishly large values before '$', which is yet another
bug in this area.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]