From 11df43be781aa498896d50afd5a09b7e0b5b2d20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dan=20=C4=8Cerm=C3=A1k?= Date: Tue, 21 Aug 2018 23:09:56 +0200 Subject: [PATCH] [types] Apply Safe::abs() in floatToRationalCast & gcd Also check for infinity in floatToRationalCast as depending on the compiler special values of floats are converted to either LONGMAX/LONGMIN or +/-inf --- include/exiv2/types.hpp | 10 ++++++++-- src/types.cpp | 12 +++++++++--- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/include/exiv2/types.hpp b/include/exiv2/types.hpp index 21f58a0e..06767ddc 100644 --- a/include/exiv2/types.hpp +++ b/include/exiv2/types.hpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -555,8 +556,13 @@ namespace Exiv2 { #ifdef _MSC_VER #pragma warning( disable : 4146 ) #endif - if (n < zero) - n = -n; + if (n < zero) { + if (n == std::numeric_limits::min()) { + n = std::numeric_limits::max(); + } else { + n = -n; + } + } if (m < zero) m = -m; #ifdef _MSC_VER diff --git a/src/types.cpp b/src/types.cpp index 729c3ac7..6db7071b 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -29,6 +29,7 @@ #include "types.hpp" #include "i18n.h" // for _exvGettext #include "unused.h" +#include "safe_op.hpp" // + standard includes #ifdef EXV_UNICODE_PATH @@ -46,6 +47,7 @@ #include #include #include +#include // ***************************************************************************** namespace { @@ -657,11 +659,15 @@ namespace Exiv2 { Rational floatToRationalCast(float f) { + if (isinf(f)) { + return Rational(f > 0 ? 1 : -1, 0); + } // Beware: primitive conversion algorithm int32_t den = 1000000; - if (std::labs(static_cast(f)) > 2147) den = 10000; - if (std::labs(static_cast(f)) > 214748) den = 100; - if (std::labs(static_cast(f)) > 21474836) den = 1; + const long f_as_long = static_cast(f); + if (Safe::abs(f_as_long) > 2147) den = 10000; + if (Safe::abs(f_as_long) > 214748) den = 100; + if (Safe::abs(f_as_long) > 21474836) den = 1; const float rnd = f >= 0 ? 0.5f : -0.5f; const int32_t nom = static_cast(f * den + rnd); const int32_t g = gcd(nom, den);