mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-27 04:52:05 +08:00
ubsan: signed integer overflow in atof_generic
Fix the signed overflows by using unsigned variables and detect overflow at BUG! comment. * atof-generic.c (atof_generic): Avoid signed integer overflow. Return ERROR_EXPONENT_OVERFLOW if exponent overflows a long.
This commit is contained in:
parent
ee6cbff213
commit
b038f394a9
@ -72,11 +72,11 @@ atof_generic (/* return pointer to just AFTER number we read. */
|
||||
const char *string_of_decimal_exponent_marks,
|
||||
FLONUM_TYPE *address_of_generic_floating_point_number)
|
||||
{
|
||||
int return_value; /* 0 means OK. */
|
||||
int return_value = 0; /* 0 means OK. */
|
||||
char *first_digit;
|
||||
unsigned int number_of_digits_before_decimal;
|
||||
unsigned int number_of_digits_after_decimal;
|
||||
long decimal_exponent;
|
||||
unsigned long decimal_exponent;
|
||||
unsigned int number_of_digits_available;
|
||||
char digits_sign_char;
|
||||
|
||||
@ -204,7 +204,7 @@ atof_generic (/* return pointer to just AFTER number we read. */
|
||||
deleting zeros after decimal. In this case the decimal mark and
|
||||
the first zero digits after decimal mark are skipped. */
|
||||
seen_significant_digit = 0;
|
||||
signed long subtract_decimal_exponent = 0;
|
||||
unsigned long subtract_decimal_exponent = 0;
|
||||
|
||||
if (c && IS_DECIMAL_MARK (c))
|
||||
{
|
||||
@ -300,10 +300,11 @@ atof_generic (/* return pointer to just AFTER number we read. */
|
||||
{
|
||||
if (ISDIGIT (c))
|
||||
{
|
||||
if (decimal_exponent > LONG_MAX / 10
|
||||
|| (decimal_exponent == LONG_MAX / 10
|
||||
&& c > '0' + (char) (LONG_MAX - LONG_MAX / 10 * 10)))
|
||||
return_value = ERROR_EXPONENT_OVERFLOW;
|
||||
decimal_exponent = decimal_exponent * 10 + c - '0';
|
||||
/*
|
||||
* BUG! If we overflow here, we lose!
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -327,7 +328,6 @@ atof_generic (/* return pointer to just AFTER number we read. */
|
||||
|
||||
number_of_digits_available =
|
||||
number_of_digits_before_decimal + number_of_digits_after_decimal;
|
||||
return_value = 0;
|
||||
if (number_of_digits_available == 0)
|
||||
{
|
||||
address_of_generic_floating_point_number->exponent = 0; /* Not strictly necessary */
|
||||
@ -505,7 +505,7 @@ atof_generic (/* return pointer to just AFTER number we read. */
|
||||
size_of_power_in_littlenums = precision;
|
||||
/* Precision has a built-in fudge factor so we get a few guard bits. */
|
||||
|
||||
decimal_exponent_is_negative = decimal_exponent < 0;
|
||||
decimal_exponent_is_negative = (long) decimal_exponent < 0;
|
||||
if (decimal_exponent_is_negative)
|
||||
{
|
||||
decimal_exponent = -decimal_exponent;
|
||||
|
Loading…
Reference in New Issue
Block a user