fixed: a crash in Big::Add() (buffer overflow)
there was an offset calculated from Int type by using Abs() method and a carry was not checked (if there is a carry we should not make addition -- the argument is too small) this had no impact on calculated values because there was a crash (bus error) immediately following program could crash (64bit): typedef ttmath::Big<1, 8> MyBig; ttmath::Parser<MyBig> parser; parser.Parse("2^(2^63) + 1"); fixed: similar problems were in methods Big::BitAnd() Big::BitOr() and Big::BitXor() (bitwise operations) and they could return incorrect values git-svn-id: svn://ttmath.org/publicrep/ttmath/trunk@1189 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
parent
d93d5ffd74
commit
dcdb1db9ec
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006-2017, Tomasz Sowa
|
||||
* Copyright (c) 2006-2019, Tomasz Sowa
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -930,7 +930,6 @@ public:
|
|||
uint Add(Big<exp, man> ss2, bool round = true, bool adding = true)
|
||||
{
|
||||
bool last_bit_set, rest_zero, do_adding, do_rounding, rounding_up;
|
||||
Int<exp> exp_offset( exponent );
|
||||
uint c = 0;
|
||||
|
||||
if( IsNan() || ss2.IsNan() )
|
||||
|
@ -939,9 +938,6 @@ public:
|
|||
if( !adding )
|
||||
ss2.ChangeSign(); // subtracting
|
||||
|
||||
exp_offset.Sub( ss2.exponent );
|
||||
exp_offset.Abs();
|
||||
|
||||
// (1) abs(this) will be >= abs(ss2)
|
||||
if( SmallerWithoutSignThan(ss2) )
|
||||
Swap(ss2);
|
||||
|
@ -949,6 +945,16 @@ public:
|
|||
if( ss2.IsZero() )
|
||||
return 0;
|
||||
|
||||
Int<exp> exp_offset( exponent );
|
||||
exp_offset.Sub( ss2.exponent );
|
||||
|
||||
if( !exp_offset.Abs() )
|
||||
{
|
||||
// if there is a carry in Abs it means the value in exp_offset has only the lowest bit set
|
||||
// so the value is the smallest possible integer
|
||||
// and its Abs would be greater than mantissa size in bits
|
||||
// so the method AddCheckExponents would do nothing
|
||||
|
||||
last_bit_set = rest_zero = do_adding = do_rounding = false;
|
||||
rounding_up = (IsSign() == ss2.IsSign());
|
||||
|
||||
|
@ -965,6 +971,8 @@ public:
|
|||
|
||||
if( do_adding || do_rounding )
|
||||
c += Standardizing();
|
||||
}
|
||||
|
||||
|
||||
return CheckCarry(c);
|
||||
}
|
||||
|
@ -993,6 +1001,8 @@ public:
|
|||
*/
|
||||
uint BitAnd(Big<exp, man> ss2)
|
||||
{
|
||||
uint c = 0;
|
||||
|
||||
if( IsNan() || ss2.IsNan() )
|
||||
return CheckCarry(1);
|
||||
|
||||
|
@ -1011,20 +1021,20 @@ public:
|
|||
return 0;
|
||||
}
|
||||
|
||||
Int<exp> exp_offset( exponent );
|
||||
Int<exp> mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT );
|
||||
|
||||
uint c = 0;
|
||||
|
||||
exp_offset.Sub( ss2.exponent );
|
||||
exp_offset.Abs();
|
||||
|
||||
// abs(this) will be >= abs(ss2)
|
||||
if( SmallerWithoutSignThan(ss2) )
|
||||
Swap(ss2);
|
||||
|
||||
if( exp_offset >= mantissa_size_in_bits )
|
||||
Int<exp> exp_offset( exponent );
|
||||
Int<exp> mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT );
|
||||
exp_offset.Sub( ss2.exponent );
|
||||
|
||||
if( exp_offset.Abs() || exp_offset >= mantissa_size_in_bits )
|
||||
{
|
||||
// if there is a carry in Abs it means the value in exp_offset has only the lowest bit set
|
||||
// so the value is the smallest possible integer
|
||||
// and its Abs would be greater than mantissa size in bits
|
||||
|
||||
// the second value is too small
|
||||
SetZero();
|
||||
return 0;
|
||||
|
@ -1052,6 +1062,8 @@ public:
|
|||
*/
|
||||
uint BitOr(Big<exp, man> ss2)
|
||||
{
|
||||
uint c = 0;
|
||||
|
||||
if( IsNan() || ss2.IsNan() )
|
||||
return CheckCarry(1);
|
||||
|
||||
|
@ -1070,21 +1082,23 @@ public:
|
|||
if( ss2.IsZero() )
|
||||
return 0;
|
||||
|
||||
Int<exp> exp_offset( exponent );
|
||||
Int<exp> mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT );
|
||||
|
||||
uint c = 0;
|
||||
|
||||
exp_offset.Sub( ss2.exponent );
|
||||
exp_offset.Abs();
|
||||
|
||||
// abs(this) will be >= abs(ss2)
|
||||
if( SmallerWithoutSignThan(ss2) )
|
||||
Swap(ss2);
|
||||
|
||||
if( exp_offset >= mantissa_size_in_bits )
|
||||
Int<exp> exp_offset( exponent );
|
||||
Int<exp> mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT );
|
||||
exp_offset.Sub( ss2.exponent );
|
||||
|
||||
if( exp_offset.Abs() || exp_offset >= mantissa_size_in_bits )
|
||||
{
|
||||
// if there is a carry in Abs it means the value in exp_offset has only the lowest bit set
|
||||
// so the value is the smallest possible integer
|
||||
// and its Abs would be greater than mantissa size in bits
|
||||
|
||||
// the second value is too small
|
||||
return 0;
|
||||
}
|
||||
|
||||
// exp_offset < mantissa_size_in_bits, moving 'exp_offset' times
|
||||
ss2.mantissa.Rcr( exp_offset.ToInt(), 0 );
|
||||
|
@ -1108,6 +1122,8 @@ public:
|
|||
*/
|
||||
uint BitXor(Big<exp, man> ss2)
|
||||
{
|
||||
uint c = 0;
|
||||
|
||||
if( IsNan() || ss2.IsNan() )
|
||||
return CheckCarry(1);
|
||||
|
||||
|
@ -1126,21 +1142,23 @@ public:
|
|||
return 0;
|
||||
}
|
||||
|
||||
Int<exp> exp_offset( exponent );
|
||||
Int<exp> mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT );
|
||||
|
||||
uint c = 0;
|
||||
|
||||
exp_offset.Sub( ss2.exponent );
|
||||
exp_offset.Abs();
|
||||
|
||||
// abs(this) will be >= abs(ss2)
|
||||
if( SmallerWithoutSignThan(ss2) )
|
||||
Swap(ss2);
|
||||
|
||||
if( exp_offset >= mantissa_size_in_bits )
|
||||
Int<exp> exp_offset( exponent );
|
||||
Int<exp> mantissa_size_in_bits( man * TTMATH_BITS_PER_UINT );
|
||||
exp_offset.Sub( ss2.exponent );
|
||||
|
||||
if( exp_offset.Abs() || exp_offset >= mantissa_size_in_bits )
|
||||
{
|
||||
// if there is a carry in Abs it means the value in exp_offset has only the lowest bit set
|
||||
// so the value is the smallest possible integer
|
||||
// and its Abs would be greater than mantissa size in bits
|
||||
|
||||
// the second value is too small
|
||||
return 0;
|
||||
}
|
||||
|
||||
// exp_offset < mantissa_size_in_bits, moving 'exp_offset' times
|
||||
ss2.mantissa.Rcr( exp_offset.ToInt(), 0 );
|
||||
|
|
Loading…
Reference in New Issue