【问题标题】:How should a UTF-8 decoder handle invalid codepoints (surrogates, larger than 0x10ffff) correctly?UTF-8 解码器应该如何正确处理无效的代码点(代理,大于 0x10ffff)?
【发布时间】:2018-09-30 11:20:16
【问题描述】:

我正在编写一个 UTF-8 解码器,但我不知道如何正确处理无效代码点:

  • 代理
  • 大于 0x10ffff 的代码点

假设,我想用 0xfffd 替换无效的代码点。现在,我应该如何更换它们?在我知道代码点无效后立即,还是应该解码/使用第一个字节要求的所有字节?

例如,假设 UTF-8 流包含:0xf4 0x90 0x80 0x80

这些字节解码为0x110000,一个无效的代码点。

但是,在第二个字节处,当0xf4 0x90 被处理时,我知道,无论最后两个字节是什么,它都不是有效的代码点。

那么,这个流应该产生一个错误(和一个替换),还是应该产生3个错误(因为0xf4 0x90无效,然后0x80和另一个0x80也无效)?

是否有强制执行此操作的标准?如果没有,最佳做法是什么?

【问题讨论】:

  • 您忘记了过长的编码。

标签: utf-8


【解决方案1】:

我在 unicode 标准 chapter 03 第 126-129 页找到了答案:

  • unicode 标准要求格式正确的子序列不得作为格式错误的序列的一部分使用(不过,我的示例不包含这种情况)
  • 建议遵循 W3C:应为格式错误的子序列的最大子部分生成一个错误(请参阅链接文档中的定义)
  • 0xf4 0x90 0x80 0x80的第二个字节无效,所以如果按照建议我应该会产生4错误(因为第二个字节无效,开头的最大子部分只是0xf4 )

如果我的示例是 0xf4 0x8f 0x41,那么我应该只生成 1 错误,因为 0xf4 0x8f 是最大子部分,0x41 是格式良好的子序列。

【讨论】:

    【解决方案2】:

    Unicode 联盟似乎只关心准确性(不丢弃好的字节)和安全性(不将两个好的文本放在一起,因为安全扫描器在考虑坏字节时可能会通过文本,但可能会阻止了清理后的文本)。它允许其他人定义任何特定的实践。 (似乎已经提出了最佳实践,但会back away,因为 W3C 已经将它们正式化了。)

    当然,W3C 关注安全性,但也关注您所要求的一致性。根据其非常详细的reference UTF-8 Decoder algorithm,它对每个格式错误的子序列表示错误(例如插入替换字符)。

    【讨论】:

      猜你喜欢
      • 2012-08-05
      • 1970-01-01
      • 2011-01-23
      • 2021-06-10
      • 2017-09-06
      • 1970-01-01
      • 1970-01-01
      • 2010-09-21
      • 2011-11-11
      相关资源
      最近更新 更多