是否有任何UTF-8代码单元具有字节60或62(`<`和`>`)而不是它们的二进制表示的第一个字节?

时间:2013-01-27 16:59:15

标签: unicode utf-8

我需要调试一个XML解析器,我想知道是否可以构造“恶意”输入,导致它无法正确识别开关标签。

此外,我在哪里可以找到这类信息?在此之后,我还要确保我正在使用的解析器不会遇到其他特殊字符的问题,例如&="等。

3 个答案:

答案 0 :(得分:3)

UTF-8可以很容易地弄清楚代码单元(即一个字节)的作用是什么:

  • 如果未设置最高位,即代码单位为0xxxxxxx,则此字节表示整个代码点,其值为xxxxxxx(即7位信息)

  • 如果设置了最高位且代码单位为10xxxxxx,则它是多字节序列的延续部分,带有六位信息。

  • 否则,代码单元是多字节序列的初始字节,如下所示:

    • 110xxxxx:两个字节(一个连续字节),用于5 + 6 = 11位。
    • 1110xxxx:3个字节(两个连续字节),4 + 6 + 6 = 16位。
    • 11110xxx:4个字节(3个连续字节),3 + 6 + 6 + 6 = 21位。

如您所见,值为00111100的值为60的单字节代码点,并且相同的字节不能作为任何多字节序列的一部分出现。

该方案实际上可以扩展到七个字节,最多可编码36位,但由于Unicode只需要21位,因此四个字节就足够了。标准要求代码点必须用最少数量的代码单元表示。

更新:正如@Mark Tolonen正确指出的那样,您应该仔细检查每个编码的代码点是否实际使用最少数量的代码单元进行编码。如果浏览器无意中接受了这样的输入,那么用户可能会偷偷摸摸一些你不会在逐字节分析中发现的东西。作为起点,您可以查找像10111100这样的字节,但是您必须检查它所属的整个多字节序列(因为它当然可以作为不同代码点的一部分合法地发生)。最终,如果你不能信任浏览器,你就不会真正解决所有问题,只是检查生成的代码点序列是否出现U + 3C等,甚至不用费心去查看字节流。 / p>

答案 1 :(得分:1)

在UTF-8中,没有。在其他编码中,是的。

在UTF-8中,按照设计,多字节字符的所有字节始终具有最高位设置。反之亦然,没有设置最高位的字节始终是ASCII字符。

但是,对于其他编码也是如此,这些编码对XML也有效。

有关UTF-8的更多信息,请查看wikipedia

答案 2 :(得分:1)

设计不佳的UTF-8解码器可以将字节C0 BCC0 BE解释为U+003CU+003E。正如@KerrekSB在答案中所述:

  

标准规定代码点必须用最少数量的代码单元表示。

但是一个糟糕的算法仍然可能会解码格式错误的双字节UTF-8序列,而不是最小数量的代码单元:

  

C0 BC = 110 00000 10 111100 = 00000111100 = 3C hex = 60 dec ='< “

因此,在您的测试中,请确保包含格式错误的UTF-8序列并验证它们是否被拒绝。