From 55625cf05f4345dcab5d9d92b83bb8b5606debab Mon Sep 17 00:00:00 2001 From: Florian Kriener Date: Thu, 3 Mar 2016 15:37:22 +0100 Subject: Integrate integer overflow fixes from security branch * Throw exception on float cast overflow in dng_stream.cpp. * Ensure hue is in range before converting to integer. * Replace the limits from stdint.h by the limit from std::numeric_limits<>. Change-Id: I660c730a8551a8613655898c0fff749925dad149 --- source/dng_safe_arithmetic.h | 14 +++++++++----- source/dng_stream.cpp | 8 ++++---- source/dng_utils.h | 7 ++++--- 3 files changed, 17 insertions(+), 12 deletions(-) (limited to 'source') diff --git a/source/dng_safe_arithmetic.h b/source/dng_safe_arithmetic.h index 78d8ae0..2535276 100644 --- a/source/dng_safe_arithmetic.h +++ b/source/dng_safe_arithmetic.h @@ -129,9 +129,12 @@ inline std::int64_t SafeInt64MultByClang(std::int64_t arg1, std::int64_t arg2) { #ifdef DNG_HAS_INT128 inline std::int64_t SafeInt64MultByInt128(std::int64_t arg1, std::int64_t arg2) { + const __int128 kInt64Max = + static_cast<__int128>(std::numeric_limits::max()); + const __int128 kInt64Min = + static_cast<__int128>(std::numeric_limits::min()); __int128 result = static_cast<__int128>(arg1) * static_cast<__int128>(arg2); - if (result > static_cast<__int128>(INT64_MAX) || - result < static_cast<__int128>(INT64_MIN)) { + if (result > kInt64Max || result < kInt64Min) { ThrowProgramError("Arithmetic overflow"); } return static_cast(result); @@ -213,9 +216,10 @@ static void ConvertUnsigned(TSrc src, TDest *dest) { *dest = converted; } -// Returns the result of converting val to an int32_t using truncation if val is -// in range of int32_t values. Otherwise, throws a dng_exception with error code -// dng_error_unknown. +// Returns the result of converting val to the result type using truncation if +// val is in range of the result type values. Otherwise, throws a dng_exception +// with error code dng_error_unknown. std::int32_t ConvertDoubleToInt32(double val); +std::uint32_t ConvertDoubleToUint32(double val); #endif // __dng_safe_arithmetic__ diff --git a/source/dng_stream.cpp b/source/dng_stream.cpp index c1db250..d94a5c7 100644 --- a/source/dng_stream.cpp +++ b/source/dng_stream.cpp @@ -819,7 +819,7 @@ uint32 dng_stream::TagValue_uint32 (uint32 tagType) if (x > (real64) 0xFFFFFFFF) x = (real64) 0xFFFFFFFF; - return (uint32) (x + 0.5); + return ConvertDoubleToUint32(x + 0.5); } @@ -960,7 +960,7 @@ dng_urational dng_stream::TagValue_urational (uint32 tagType) } - result.n = (uint32) (x + 0.5); + result.n = ConvertDoubleToUint32(x + 0.5); } @@ -1012,7 +1012,7 @@ dng_srational dng_stream::TagValue_srational (uint32 tagType) } - result.n = (int32) (x + 0.5); + result.n = ConvertDoubleToInt32(x + 0.5); } @@ -1028,7 +1028,7 @@ dng_srational dng_stream::TagValue_srational (uint32 tagType) } - result.n = (int32) (x - 0.5); + result.n = ConvertDoubleToInt32(x - 0.5); } diff --git a/source/dng_utils.h b/source/dng_utils.h index d87de51..691f0b9 100644 --- a/source/dng_utils.h +++ b/source/dng_utils.h @@ -18,6 +18,7 @@ /*****************************************************************************/ +#include #include #include "dng_classes.h" @@ -708,12 +709,12 @@ inline void DNG_HSVtoRGB (real32 h, if (s > 0.0f) { + if (!std::isfinite(h)) + ThrowProgramError("Unexpected NaN or Inf"); + h = std::fmod(h, 6.0f); if (h < 0.0f) h += 6.0f; - if (h >= 6.0f) - h -= 6.0f; - int32 i = (int32) h; real32 f = h - (real32) i; -- cgit v1.2.3