summaryrefslogtreecommitdiff
path: root/misc.h
diff options
context:
space:
mode:
authorejl103 <82910232+ejl103@users.noreply.github.com>2022-02-14 14:02:13 +0000
committerGitHub <noreply@github.com>2022-02-14 09:02:13 -0500
commite06bac5bfcf4962aca14d6a7d67003d13ea70ba5 (patch)
tree0d8dc409097efbfa48cbc777254956c7b4285cb1 /misc.h
parent7762fe2186a9d161312dc83951a6ecaa6076a0e5 (diff)
downloadcryptopp-git-e06bac5bfcf4962aca14d6a7d67003d13ea70ba5.tar.gz
Fix issue with VS runtime checks for data truncation (#1043)
When running VS with the 'c' runtime check on for data truncation (see https://docs.microsoft.com/en-us/cpp/build/reference/rtc-run-time-error-checks?view=msvc-160) This code will throw errors because the 64 bit ptr gets truncated to a 32bit value. Normally I'd disable this using the pragma specifically for this code, but sadly that doesn't work for template functions, so I have come up with a way to get the appropriate masking type for any template combinations and using the recommended way to silence the error without impacting the quality of the generated code. This code could be more concise in modern C++ but it seems the project expects to support C++03 so this should work fine there. All tests passed locally for me on Windows (some asserts but verified they were the same before my changes)
Diffstat (limited to 'misc.h')
-rw-r--r--misc.h46
1 files changed, 44 insertions, 2 deletions
diff --git a/misc.h b/misc.h
index c56fe7cf..1e818829 100644
--- a/misc.h
+++ b/misc.h
@@ -1113,6 +1113,47 @@ inline T1 SaturatingSubtract1(const T1 &a, const T2 &b)
return T1((a > b) ? (a - b) : 1);
}
+/// \brief Get the appropriate mask to do a truncating cast
+template <class T, size_t SIZE = sizeof(T)>
+struct TruncatingMask;
+
+template <class T>
+struct TruncatingMask<T, 1>
+{
+ T operator()()
+ {
+ return 0xFF;
+ }
+};
+
+template <class T>
+struct TruncatingMask<T, 2>
+{
+ T operator()()
+ {
+ return 0xFFFF;
+ }
+};
+
+template <class T>
+struct TruncatingMask<T, 4>
+{
+ T operator()()
+ {
+ return 0xFFFFFFFF;
+ }
+};
+
+template <class T>
+struct TruncatingMask<T, 8>
+{
+ T operator()()
+ {
+ return 0xFFFFFFFFFFFFFFFF;
+ }
+};
+
+
/// \brief Reduces a value to a power of 2
/// \tparam T1 class or type
/// \tparam T2 class or type
@@ -1125,8 +1166,9 @@ template <class T1, class T2>
inline T2 ModPowerOf2(const T1 &a, const T2 &b)
{
CRYPTOPP_ASSERT(IsPowerOf2(b));
- // Coverity finding CID 170383 Overflowed return value (INTEGER_OVERFLOW)
- return T2(a) & SaturatingSubtract(b,1U);
+ // Coverity finding CID 170383 Overflowed return value (INTEGER_OVERFLOW)
+ // Visual studio runtime_checks don't like us truncating here with the cast to T2 TruncatingMask works around it
+ return T2(a & TruncatingMask<T2>()()) & SaturatingSubtract(b,1U);
}
/// \brief Rounds a value down to a multiple of a second value