vfprintf typing problem
Carlos O'Donell
carlos@systemhalted.org
Sun Apr 1 04:25:00 GMT 2012
On Sun, Apr 1, 2012 at 12:20 AM, David Miller <davem@davemloft.net> wrote:
> From: "Carlos O'Donell" <carlos@systemhalted.org>
> Date: Sat, 31 Mar 2012 22:10:44 -0400
>
>> Does that make sense?
>
> Yep.
>
>> The check probably has to be:
>>
>> if (retval > INT_MAX/10-digit)
>> return -1;
>> retval *= 10;
>> retal += digit;
>>
>> That way you *know* the next two operations won't overflow, and either
>> you exit or get another chance at looking at the next operation.
>
> Ok, I'll let this patch cook in my build/testsuite runs overnight:
>
> diff --git a/stdio-common/printf-parse.h b/stdio-common/printf-parse.h
> index bcf914b..2038541 100644
> --- a/stdio-common/printf-parse.h
> +++ b/stdio-common/printf-parse.h
> @@ -75,10 +75,12 @@ read_int (const UCHAR_T * *pstr)
>
> while (ISDIGIT (*++(*pstr)))
> {
> - retval *= 10;
> - if (retval > INT_MAX)
> + unsigned int digit = **pstr - L_('0');
> +
> + if (retval > INT_MAX/10 - digit)
> return -1;
> - retval += **pstr - L_('0');
> + retval *= 10;
> + retval += digit;
> }
>
> return (int) retval;
Shucks... if you look closely I *did* do the math wrong.
It should be (retval > (INT_MAX - digit)/10)
That way when you rearrange it becomes:
retval*10+digit > INT_MAX
But because of the rearrangement you're assured you check before any
possible unsigned int or signed int overflow.
Cheers,
Carlos.
More information about the Libc-alpha
mailing list