SafeConvert is a noisy class due to signed/unsigned comparisons
intersecting template parameters. We can silence the warnings in the
library with pragmas, or with compiler specific flags like
-Wno-tautological-compare for Clang and -Wno-type-limits for GCC.
The pragmas don't work on many platforms (like OpenBSD with GCC 4.2.1 and
Cent OS 5 with GCC 4.1). The compiler flags don't clear the problem in user
code because users may not be using them.
I made a misguided attempt to silence the warnings, I attempted to provide
template specializations. The problem with this was platforms define size_t
and ssize_t to different things, so we would have gaps at times and get
collisions on occasion.
Below is the latest code to remediate the signed/unsigned warnings from
IntToString and SafeConvert:
Any comments or objections?
$ cat misc.h.diff
diff --git a/misc.h b/misc.h
index 30e080b..99968e3 100644
--- a/misc.h
+++ b/misc.h
@@ -269,6 +269,14 @@ template <class T> inline const T& STDMAX(const T& a,
const T& b)
#define CRYPTOPP_GET_BYTE_AS_BYTE(x, y) byte((x)>>(8*(y)))
+// Signed-ness
+template<bool B, class T, class F>
+struct Conditional { typedef T type; };
+template<class T, class F>
+struct Conditional<false, T, F> { typedef F type; };
+template <typename T>
+struct Signedness { typedef typename Conditional<T(-1)<T(0),int,unsigned
int>::type type; };
+
template <class T>
unsigned int Parity(T value)
{
@@ -358,13 +366,25 @@ inline T Crop(T value, size_t size)
return value;
}
-// Provide specializations of these as required. It avoids the
signed/unsigned mismatch.
template <class T1, class T2>
inline bool SafeConvert(T1 from, T2 &to)
{
+ // Original code: always perform the assignment
to = (T2)from;
- if (from != to || (from > 0) != (to > 0))
+
+ // Check for sign difference
+ if(std::numeric_limits<T1>::is_signed ^
std::numeric_limits<T2>::is_signed)
+ {
+ // Handle T1 is signed
+ if(std::numeric_limits<T1>::is_signed && from < 0)
+ return false;
+
+ // Fall through for T1 is unsigned
+ }
+
+ if(from > static_cast<T1>(std::numeric_limits<T2>::max()))
return false;
+
return true;
}
@@ -569,6 +589,8 @@ inline bool NativeByteOrderIs(ByteOrder order)
template <class T>
std::string IntToString(T a, unsigned int base = 10)
{
+ typename Signedness<T>::type b = static_cast<typename
Signedness<T>::type>(base);
+
if (a == 0)
return "0";
bool negate = false;
@@ -580,9 +602,9 @@ std::string IntToString(T a, unsigned int base = 10)
std::string result;
while (a > 0)
{
- T digit = a % base;
+ T digit = a % b;
result = char((digit < 10 ? '0' : ('a' - 10)) + digit) + result;
- a /= base;
+ a /= b;
}
if (negate)
result = "-" + result;
--
--
You received this message because you are subscribed to the "Crypto++ Users"
Google Group.
To unsubscribe, send an email to [email protected].
More information about Crypto++ and this group is available at
http://www.cryptopp.com.
---
You received this message because you are subscribed to the Google Groups
"Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.