我试图将std::wstring
编码为UTF-16并将其传递给一个带有一对向量迭代器的函数。为此,我尝试了以下内容。
std::vector<unsigned char> HashAlgorithm::ComputeHash(std::wstring value)
{
std::wstring_convert<std::codecvt_utf16<wchar_t>> converter;
std::string encodedString = converter.to_bytes(value);
std::vector<unsigned char> encodedBytes(
reinterpret_cast<unsigned char const *>(encodedString.c_str()),
reinterpret_cast<unsigned char const *>(encodedString.c_str() + encodedString.size()));
std::vector<unsigned char> hashedBytes = this->ComputeHash(encodedBytes.begin(), encodedBytes.end());
return hashedBytes;
}
它在大多数情况下工作正常,除了我知道有些错误,因为在调试模式下,我在hashedBytes
的返回时看到以下断言,这有点像某种堆栈损坏。
导致此错误的原因是什么?如何预防?
编辑#1
以下是我正在使用的支持功能的内容。我一直试图将其分解以找出断言的起源和原因,但我还没有能够获得最小的再现。
std::vector<unsigned char> HashAlgorithm::ComputeHash(std::vector<unsigned char>::const_iterator begin, std::vector<unsigned char>::const_iterator end)
{
this->Process(begin, end);
std::vector<unsigned char> hashedBytes = this->Complete();
return hashedBytes;
}
void HashAlgorithm::Process(std::vector<unsigned char>::const_iterator begin, std::vector<unsigned char>::const_iterator end)
{
NTSTATUS status = BCryptHashData(this->hash, const_cast<unsigned char *>(&(*begin)), std::distance(begin, end), 0);
}
std::vector<unsigned char> HashAlgorithm::Complete()
{
std::vector<unsigned char> result(this->outputSize);
NTSTATUS status = BCryptFinishHash(this->hash, result.data(), (ULONG)result.size(), 0);
return result;
}
答案 0 :(得分:1)
std::wstring
不向后兼容。
问题是库代码(VS 2010)中的std::wstring
和客户端代码(VS 2015)的大小差异为4个字节。较新版本的std::wstring
较大,为32字节,而较旧版本为28字节。当通过值传递这些变量时,堆栈损坏发生在较小的std::wstring
的前4个字节中,并触发用于防止基于堆栈的漏洞的堆栈canaries。
答案 1 :(得分:0)
为了确保您不会丢失任何数据,您应该直接散列字节:
std::vector<unsigned char> myClass::ComputeHash(std::wstring value)
{
auto size_of_data = value.size()*sizeof(value[0]);
auto pointer_to_data = reinterpret_cast<unsigned char const *>(value.data());
std::vector<unsigned char> encodedBytes(pointer_to_data,pointer_to_data+size_of_data);
std::vector<unsigned char> hashedBytes = this->ComputeHash(encodedBytes.begin(),encodedBytes.end());
return hashedBytes;
}
尝试添加香蕉(\ U0001F34C),以便在您单步执行时查看数据会发生什么。例如std::wstring my_unicode_string{L"Test string \n"};
或std::wstring wstr = L"z\u00df\u6c34\U0001F34C"; // L"zß水"
。如果你的.cpp文件没有保存为unicode文本,那么第二个例子可能会更好。
to_bytes
可能会引发异常,因为只有基本多语言平面中的代码点才能编码为单个wchar
。如果它确实为你做了转换,它可能已经将不同的更高代码点映射到类似的字节,这将导致不同字符串的相同散列。