如何审核我的Windows应用程序以获得正确的Unicode处理
How can I audit my Windows application for correct Unicode handling?
我不能使用预打包的Unicode字符串库,如ICU,因为它们将二进制文件的大小放大到了疯狂的程度(这是一个200k的程序;ICU是16MB+!)。
我已经对所有内容使用了内置的wchar_t
字符串类型,但我想确保在对字符串进行迭代或类似的事情方面不会做任何愚蠢的事情。
有没有像Fuzzers这样的工具是为了安全而不是为了Unicode?也就是说,在我的代码中抛出基本多语言平面之外的字符,并确保事情像UTF-16一样得到正确处理?
(哦,很明显,跨平台的解决方案是可行的,尽管大多数跨平台的东西都必须同时支持UTF-8和UTF-16)
EDIT:还要注意一些比UTF-16代理项对不那么明显的东西,比如重音符号!
错误答案
使用WM_UNICHAR
,它可以处理UTF-32,并可以处理Unicode补充平面字符。
虽然这几乎是真的,但完全的真相看起来是这样的:
WM_UNICHAR
是为ANSI Windows设计的接收Unicode字符的黑客。创建一个Unicode窗口,您将永远不会收到它- 创建一个ANSI窗口,您会惊讶地发现它仍然没有按预期工作。问题是,当创建窗口时,您会收到一个带有
0xffff
的WM_UNICHAR
,对此必须返回1(默认窗口过程将返回0)。如果不这样做,你就再也看不到WM_UNICHAR
了。干得好,官方文件没有告诉你 - 由于神秘的原因,在不支持
WM_UNICHAR
的系统上运行程序(比如我的Windows 7 64系统),即使你做得正确,它仍然无法工作
理论上的正确答案
没有什么需要审计或注意的。
使用定义的UNICODE
编译,或者使用";CCD_ 9";函数,并使用WM_CHAR
,就好像这是最自然的事情一样。就是这样。这确实是最自然。
WM_CHAR
使用UTF-16(除非它不使用,例如在Windows 2000下)。当然,单个UTF-16字符不能表示BMP之外的代码点,但这不是问题,因为您只需获得两个包含代理对的WM_CHAR
消息。它对你的应用程序是完全透明的,你不需要做任何特别的事情。任何接受宽字符串的Windows API函数也会很高兴地接受这些代理
唯一需要注意的是,现在字符串的字符长度(显然)不再只是16位单词的数量。但无论如何,一开始这是一个错误的假设。
可悲的事实
事实上,在许多(大多数?所有?)系统上,您只会得到一条WM_CHAR
消息,其中wParam
包含密钥代码的低16位。这对BMP中的任何东西都很好,但在其他方面都很糟糕。
我已经通过使用Alt键盘代码和创建自定义键盘布局来验证这一点,该布局在BMP之外生成代码点。在任何一种情况下,都只接收单个WM_CHAR
,其中包含字符的低16位。上面的16位被简单地丢弃。
为了使您的程序能够100%正确地使用Unicode,您显然必须使用输入法管理器(ImmGetCompositionStringW
),这是一个麻烦且文档记录不好的问题。就我个人而言,这仅仅意味着:;好吧,拧螺丝";。但是,如果你有兴趣做到100%正确,可以查看任何使用Scintilla(链接到行)的编辑器的源代码,它可以做到这一点,并且非常完美。
需要检查的一些事项:
-
确保不是处理
WM_CHAR
而是处理WM_UNICHAR
:WM_UNICHAR
消息与WM_CHAR
相同,只是它使用了UTF-32。它被设计为向ANSI窗口发送或发布Unicode字符,并且它可以处理Unicode补充平面字符。 -
不要假设第i个字符位于索引
i
。显然不是,如果你碰巧用这个事实来把绳子掰成两半,那么你可能会把它搞砸。 -
不要仅仅因为字符数组的长度为N就告诉用户(在状态栏或其他地方)用户有N个字符。
- 警告处理为错误这里有什么问题
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 处理多个异常集合的C++方法
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- ascii 和 unicode 在处理级别有什么区别吗?
- 用wchar_t处理 unicode 字符好吗?它不会引起任何问题吗?
- 在2018年使用C++处理Unicode的正确方法是什么?
- C++ 将 setmode 与 _O_U8TEXT 一起使用来处理 unicode 时崩溃
- 使用C 17处理Unicode的有效,符合标准的机制是什么
- 如何处理C 中Unicode支持涉及的代码重复
- 如何处理JSON字符串中的unicode值
- C++中的Unicode字符串处理
- 显式使用Unicode/ANSI Windows API和让它们由别名处理之间的区别
- 如何使用Unicode处理PCRE
- 如何在Visual Studio中处理Unicode和非Unicode项目的混合
- c++和g++如何处理unicode
- 在C++中处理 Unicode 字符
- visual如何在C++中处理Unicode字符
- 使用Windows API处理Unicode字符串
- 如何审核我的Windows应用程序以获得正确的Unicode处理