【问题标题】:Does the WinApi ever validate UTF-16?WinApi 是否曾经验证过 UTF-16?
【发布时间】:2018-09-01 20:20:23
【问题描述】:

Windows 文档反复提及 UNICODE 和 UTF-16。我知道这是file system 的谎言(即它接受wchar_t 的任何序列)和other documentation 表明无效的UTF-16 只是“未定义”。所以我很困惑。我可以假设非文件系统API 会返回有效的 UTF-16?或者我应该假设它不会?

编辑:由于它会引起一些混乱,我将解释一些术语


UTF-16

UTF-16 在Unicode specification (pdf) 中定义。 FAQ 明确了什么是格式正确的 UTF-16,什么不是格式正确的 UTF-16:

是否存在无效的 16 位值?

未配对的代理在 UTF 中无效。这些包括 D80016 到 DBFF16 范围内的任何值,后跟 DC0016 到 DFFF16,或 DC0016 到 DFFF16 范围内的任何值,前面没有 D80016 到 DBFF16.

非字符呢?它们无效吗?

一点也不。非字符在 UTF 中有效,必须正确转换。有关非字符的定义和使用以及它们在每个 UTF 中的正确表示的更多详细信息,请参阅Noncharacters FAQ

所以唯一的限制是前导代理必须后跟一个尾随代理(也称为代理对)。所有其他 wchar_t(16 位)值都应按原样接受。


UCS-2

正如 Ben Voigt 的回答中提到的那样。这是一个现在已经过时的编码,它允许任何 wchar_t 值。由于它没有与 UTF-16 相同的限制,UCS-2 字符串的子集是无效的 UTF-16。

【问题讨论】:

  • “非文件系统 API”,你的意思是 地球上的所有其他 API 吗?我在想这个问题可能有点太宽泛了。
  • @LasseVågsætherKarlsen 每个其他 Windows W API。是的。
  • 另外,我们在这里谈论什么样的验证?每个代码点都是有效且已知的代码点?这不会向前兼容,因为新的代码点会定期添加,看看最近几年添加的表情符号,比如 ????这是 2015 年添加的。
  • 有效的 UTF-16 包含尚未定义的代码点。所以有效的 UTF-16 是任何 16 位整数的序列,除了尾随代理必须跟在前导代理之后,反之亦然。
  • @las:WideCharToMultiByte 将不可避免地需要进行 UTF-16 验证。这个问题讨论了文件系统 API,因为底层文件系统(主要是 NTFS)并不关心 UTF-16。它会很乐意使用任何非零的 16 位数字序列来命名文件。

标签: winapi utf-16


【解决方案1】:

Windows 宽字符是任意 16 位数字(以前称为“UCS-2”,在 Unicode 标准联盟清除该符号之前)。所以你不能假设它将是一个有效的 UTF-16 序列。 (MultiByteToWideChar 是一个值得注意的异常,它只返回 UTF-16)

仅当生成字符串的程序使用 UTF-16 约定时,解码为 UTF-16 才有意义,但不能保证这一点,就像不能保证 8 位字符包含 UTF-8 一样。

【讨论】:

  • 谢谢!你有资源吗? Windows 文档强烈暗示 W 函数(文件系统路径之外)都使用 utf-16。例如LPCWSTRUnicode character
  • @ChrisD:Windows Unicode 支持早在 UTF 出现之前就已经存在。引入数据必须是有效 UTF-16 的条件的唯一方法是破坏向后兼容性,这还没有完成。 XP 和以后引入的 API 不会有这个问题,但是它们必须与现有的 API 互操作,所以你去吧。为获得最佳结果,请应用 Postel 定律。
  • 控制台 API 也是旧版 UCS-2。它使用当前字体的默认字形(例如空矩形)呈现任何代理代码,无论它是否是有效的 UTF-16 代理对。从控制台的输入缓冲区和屏幕缓冲区读取的字符串可能不是有效的 UTF-16,在这种情况下,例如,通过 WideCharToMultiByte 编码为 UTF-8 可能会失败或替换 U+FFFD,具体取决于使用WC_ERR_INVALID_CHARS 标志。
  • @IInspectable 区别在于 Windows 函数可能会返回一系列 16 位整数,这些整数不是有效的 UTF-16。哪个回答了我的问题,不是吗?
  • @IInspectable:没有无效的 UCS-2 代码单元,只是一些代码值没有关联的含义,而另一些则具有特殊含义(表示字形除外)。 UTF-16 确实使某些代码值无效,但更重要的是它限制了代理项可能出现的顺序。这么多在 UCS-2 中合法(尽管它们可能缺乏语义意义)的序列在 UTF-16 中是非法的。
猜你喜欢
  • 2015-11-12
  • 2020-12-08
  • 2013-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-01
相关资源
最近更新 更多