summaryrefslogtreecommitdiff
path: root/misc.cpp
diff options
context:
space:
mode:
authorJeffrey Walton <noloader@gmail.com>2016-01-30 14:01:20 -0500
committerJeffrey Walton <noloader@gmail.com>2016-01-30 14:01:20 -0500
commit3a3fae8b8b2139dbcd6ac359bb76f553ba8bf01f (patch)
treed7288030db37b576c6aaefc58f0e9d18138792d8 /misc.cpp
parentf8ff9e2c7f074d6271248e6aa477adfd413a326c (diff)
downloadcryptopp-git-3a3fae8b8b2139dbcd6ac359bb76f553ba8bf01f.tar.gz
Fixed potential ODR violation of non-member function StringNarrow
Diffstat (limited to 'misc.cpp')
-rw-r--r--misc.cpp58
1 files changed, 58 insertions, 0 deletions
diff --git a/misc.cpp b/misc.cpp
index b5a2ea41..f48f5dd9 100644
--- a/misc.cpp
+++ b/misc.cpp
@@ -133,6 +133,64 @@ bool VerifyBufsEqual(const byte *buf, const byte *mask, size_t count)
return acc8 == 0;
}
+#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
+std::string StringNarrow(const wchar_t *str, bool throwOnError)
+{
+ assert(str);
+ std::string result;
+
+ // Safer functions on Windows for C&A, https://github.com/weidai11/cryptopp/issues/55
+#if (CRYPTOPP_MSC_VERSION >= 1400)
+ size_t len=0, size=0;
+ errno_t err = 0;
+
+ //const wchar_t* ptr = str;
+ //while (*ptr++) len++;
+ len = wcslen(str)+1;
+
+ err = wcstombs_s(&size, NULL, 0, str, len*sizeof(wchar_t));
+ assert(err == 0);
+ if (err != 0) {goto CONVERSION_ERROR;}
+
+ result.resize(size);
+ err = wcstombs_s(&size, &result[0], size, str, len*sizeof(wchar_t));
+ assert(err == 0);
+
+ if (err != 0)
+ {
+CONVERSION_ERROR:
+ if (throwOnError)
+ throw InvalidArgument("StringNarrow: wcstombs_s() call failed with error " + IntToString(err));
+ else
+ return std::string();
+ }
+
+ // The safe routine's size includes the NULL.
+ if (!result.empty() && result[size - 1] == '\0')
+ result.erase(size - 1);
+#else
+ size_t size = wcstombs(NULL, str, 0);
+ assert(size != (size_t)-1);
+ if (size == (size_t)-1) {goto CONVERSION_ERROR;}
+
+ result.resize(size);
+ size = wcstombs(&result[0], str, size);
+ assert(size != (size_t)-1);
+
+ if (size == (size_t)-1)
+ {
+CONVERSION_ERROR:
+ if (throwOnError)
+ throw InvalidArgument("StringNarrow: wcstombs() call failed");
+ else
+ return std::string();
+ }
+#endif
+
+ return result;
+}
+#endif // StringNarrow and CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
+
#if !(defined(_MSC_VER) && (_MSC_VER < 1300))
using std::new_handler;
using std::set_new_handler;