Kaydet (Commit) cdd211d0 authored tarafından Noel Grandin's avatar Noel Grandin

check for NaN in Fraction

which can result from division by zero in earlier code, rather assert
explicitly than suffer from weird very large sal_Int64 values (which is
what NaN converts to, if we let it do the implicit conversion)

Change-Id: Id059b84906bbc90a4fa51489ca96dc0267bb9342
Reviewed-on: https://gerrit.libreoffice.org/42798Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarNoel Grandin <noel.grandin@collabora.co.uk>
üst 46772441
......@@ -22,6 +22,7 @@
#include <sal/types.h>
#include <tools/toolsdllapi.h>
#include <memory>
#include <type_traits>
class SvStream;
......@@ -37,8 +38,14 @@ public:
Fraction();
Fraction( const Fraction & rFrac );
Fraction( Fraction && rFrac );
Fraction( sal_Int64 nNum, sal_Int64 nDen );
explicit Fraction( double dVal );
Fraction( double nNum, double nDen );
Fraction( sal_Int64 nNum, sal_Int64 nDen );
// just to prevent ambiguity between the sal_Int64 and double constructors
template<typename T1, typename T2> Fraction(
T1 nNum, T2 nDen,
typename std::enable_if<std::is_integral<T1>::value && std::is_integral<T2>::value, int>::type = 0)
: Fraction( sal_Int64(nNum), sal_Int64(nDen) ) {}
~Fraction();
bool IsValid() const;
......
......@@ -86,6 +86,27 @@ Fraction::Fraction( sal_Int64 nNum, sal_Int64 nDen ) : mpImpl(new Impl)
mpImpl->valid = true;
}
/**
* only here to prevent passing of NaN
*/
Fraction::Fraction( double nNum, double nDen ) : mpImpl(new Impl)
{
assert( !std::isnan(nNum) );
assert( !std::isnan(nDen) );
assert( nNum >= std::numeric_limits<sal_Int32>::min() );
assert( nNum <= std::numeric_limits<sal_Int32>::max( ));
assert( nDen >= std::numeric_limits<sal_Int32>::min() );
assert( nDen <= std::numeric_limits<sal_Int32>::max( ));
if ( nDen == 0 )
{
mpImpl->valid = false;
SAL_WARN( "tools.fraction", "'Fraction(" << nNum << ",0)' invalid fraction created" );
return;
}
mpImpl->value.assign( sal_Int64(nNum), sal_Int64(nDen));
mpImpl->valid = true;
}
Fraction::Fraction( double dVal ) : mpImpl(new Impl)
{
try
......@@ -439,7 +460,8 @@ SvStream& WriteFraction( SvStream& rOStream, const Fraction& rFract )
static boost::rational<sal_Int32> rational_FromDouble(double dVal)
{
if ( dVal > std::numeric_limits<sal_Int32>::max() ||
dVal < std::numeric_limits<sal_Int32>::min() )
dVal < std::numeric_limits<sal_Int32>::min() ||
std::isnan(dVal) )
throw boost::bad_rational();
const sal_Int32 nMAX = std::numeric_limits<sal_Int32>::max() / 10;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment