Fixed potential ODR violation of non-member function StringNarrow

pull/136/head
Jeffrey Walton 2016-01-30 14:01:20 -05:00
parent f8ff9e2c7f
commit 3a3fae8b8b
2 changed files with 71 additions and 13 deletions

View File

@ -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;

20
misc.h
View File

@ -1060,22 +1060,21 @@ inline void SecureWipeArray(T *buf, size_t n)
}
//! \brief Converts a wide character C-string to a multibyte string
//! \param str a C-string consiting of wide characters
//! \param str C-string consiting of wide characters
//! \param throwOnError specifies the function should throw an InvalidArgument exception on error
//! \returns str converted to a multibyte string or an empty string.
//! \details This function converts a wide string to a string using C++ wcstombs under the executing
//! thread's locale. A locale must be set before using this function, and it can be set with setlocale.
//! Upon success, the converted string is returned. Upon failure with throwOnError as false, the
//! function returns an empty string. Upon failure with throwOnError as true, the function throws
//! InvalidArgument exception.
//! \details StringNarrow converts a wide string to a narrow string using C++ std::wcstombs under the executing
//! thread's locale. A locale must be set before using this function, and it can be set with std::setlocale.
//! Upon success, the converted string is returned.
//! \details Upon failure with throwOnError as false, the function returns an empty string. Upon failure with
//! throwOnError as true, the function throws InvalidArgument exception.
//! \note If you try to convert, say, the Chinese character for "bone" from UTF-16 (0x9AA8) to UTF-8
//! (0xE9 0xAA 0xA8), then you should ensure the locales are available. If the locales are not available,
//! then a 0x21 error is returned which eventually results in an InvalidArgument exception
//! (0xE9 0xAA 0xA8), then you must ensure the locale is available. If the locale is not available,
//! then a 0x21 error is returned on Windows which eventually results in an InvalidArgument exception.
#ifndef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
static inline std::string StringNarrow(const wchar_t *str, bool throwOnError = true)
std::string StringNarrow(const wchar_t *str, bool throwOnError = true);
#else
static std::string StringNarrow(const wchar_t *str, bool throwOnError = true)
#endif
{
assert(str);
std::string result;
@ -1130,6 +1129,7 @@ CONVERSION_ERROR:
return result;
}
#endif // StringNarrow and CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY_562
#ifdef CRYPTOPP_DOXYGEN_PROCESSING