我需要调试一个 XML 解析器,我想知道我是否可以构造“恶意”输入,这将导致它无法正确识别开始和结束标签。
此外,一般我在哪里可以找到此类信息?在此之后,我还想确保我正在使用的解析器不会遇到其他特殊字符(如&
、=
、"
等)的问题。
UTF-8 可以很容易地弄清楚代码单元(即字节)的作用是什么:
如果最高位没有设置,即代码单元是0xxxxxxx
,那么这个字节表示一个完整的代码点,其值为xxxxxxx
(即7位信息)。
如果设置了最高位并且代码单元是10xxxxxx
,那么它是多字节序列的连续部分,携带六位信息。
否则,代码单元是多字节序列的起始字节,如下:
110xxxxx
:两个字节(一个连续字节),为 5 + 6 = 11 位。1110xxxx
:三个字节(两个连续字节),为 4 + 6 + 6 = 16 位。11110xxx
:四个字节(三个连续字节),用于 3 + 6 + 6 + 6 = 21 位。如您所见,值 60,即00111100
,是 value 的单字节代码点60
,并且同一字节不能作为任何多字节序列的一部分出现。
该方案实际上可以扩展到七个字节,最多编码 36 位,但由于 Unicode 只需要 21 位,因此四个字节就足够了。该标准要求必须用最少数量的代码单元来表示代码点。
更新:正如@Mark Tolonen 正确指出的那样,您应该仔细检查每个编码的代码点是否实际上是用最少数量的代码单元编码的。如果浏览器无意中接受了此类输入,则用户可能会从您身边偷偷摸摸一些您在逐字节分析中不会发现的东西。作为起点,您可以查找类似 的字节10111100
,但您必须检查它所属的整个多字节序列(因为它当然可以作为不同代码点的一部分合法地出现)。最终,如果您不能信任浏览器,您就无法真正绕过解码所有内容并仅检查生成的代码点序列是否出现 U+3C 等,甚至不必费心查看字节流。
在 UTF-8 中,没有。在其他编码中,是的。
在 UTF-8 中,根据设计,多字节字符的所有字节将始终设置最高位。反之亦然,没有设置最高位的字节始终是 ASCII 字符。
但是,这不适用于其他编码,也适用于 XML。
有关 UTF-8 的更多信息,请查看例如wikipedia
设计不佳的 UTF-8 解码器可以将字节C0 BC
和解释C0 BE
为U+003C
和U+003E
. 正如@KerrekSB 在他的回答中所说:
该标准要求必须用最少数量的代码单元来表示代码点。
但是一个糟糕的算法可能仍然会解码一个格式错误的两字节 UTF-8 序列,该序列不是最小数量的代码单元:
C0 BC = 110 00000 10 111100 = 00000111100 = 3C十六进制= 60 dec = '<'
因此,在您的测试中,请务必包含格式错误的 UTF-8 序列并验证它们是否被拒绝。