Ben*_*oit 3 unicode wchar-t buffer-overflow visual-studio-2010 visual-c++
我们正在计划让我们的应用程序识别Unicode,我们正在分析我们将遇到的问题.
特别是,我们的应用程序将严重依赖于字符串的长度,我们希望将其wchar_t
用作基本字符类.
当处理必须以UTF-16中的2个16位单位存储的字符时出现问题,即U + 10000以上的字符.
简单的例子:
我有UTF-8字符串"蟂"(Unicode字符U + 87C2,UTF-8:E8 9F 82)
所以,我设置以下代码:
const unsigned char my_utf8_string[] = { 0xe8, 0x9f, 0x82, 0x00 };
// compute size of wchar_t buffer.
int nb_chars = ::MultiByteToWideChar(CP_UTF8, // input is UTF8
0, // no flags
reinterpret_cast<char *>(my_utf8_string), // input string (no worries about signedness)
-1, // input is zero-terminated
NULL, // no output this time
0); // need the necessary buffer size
// allocate
wchar_t *my_utf16_string = new wchar_t[nb_chars];
// convert
nb_chars = ::MultiByteToWideChar(CP_UTF8,
0,
reinterpret_cast<char *>(my_utf8_string),
-1,
my_widechar_string, // output buffer
nb_chars); // allocated size
Run Code Online (Sandbox Code Playgroud)
好的,这个工作,它分配两次16位,我的缓冲区wchar_t
包含{0x87c2,0x0000}.如果我将它存储在一个std::wstring
并计算大小,我得到1.
现在,让我们将字符(U + 104A2)作为输入,UTF-8:F0 90 92 A2.
这次,它为三个wchar_t和std :: wstring :: size分配空间返回2,即使我认为我只有一个字符.
这是有问题的.我们假设我们以UTF-8接收数据.我们可以简单地通过不计算等于的字节数来计算Unicode字符10xxxxxx
.我们希望将数据导入到数组中wchar_t
以使用它.如果我们只是分配字符数加1,那么可能是安全的...直到有人使用U + FFFF以上的字符.然后我们的缓冲区将太短,我们的应用程序将崩溃.
那么,使用以不同方式编码的相同字符串,计算字符串中字符的函数将返回不同的值?
如何设计适用于Unicode字符串的应用程序以避免这种烦恼?
谢谢您的回复.
你必须接受的std :: wstring的大小::并没有放弃的字符数.相反,它为您提供了代码单元的数量.如果您有16位代码单元,它将确定您在字符串中有多少代码单元.计算Unicode字符的数量需要在字符串上循环.一旦你接受它就不再烦人了.
至于计算UTF-8中的字符:不要.相反,您发布的代码很好:调用MultiByteToWideChar一次会告诉您需要多少代码单元,然后分配正确的数字 - 无论是BMP字符还是辅助平面.如果您绝对想要编写自己的计数例程,请使用其中两个:一个计算字符数,另一个计算16位代码单位.如果前导字节是11110xxx,则需要计算两个代码单元.
归档时间: |
|
查看次数: |
4769 次 |
最近记录: |