为什么在 URL 百分比解码算法中“使用除 utf-8 解码器以外的任何解码器......可能不安全”?

Cha*_*had 5 unicode url url-parsing utf-8

我正在实现一个 URL 解析器,并对 W3C URL 规范有疑问(位于http://www.w3.org/TR/2014/WD-url-1-20141209/)在“2. 百分比编码字节”部分中它有以下算法(强调):

要对字节序列输入进行百分比解码,请运行以下步骤:

当输入包含 0x00 到 0x7F 范围之外的字节时,使用除 utf-8 解码器之外的任何解码器可能不安全,不建议这样做。

  1. 令输出为空字节序列。

  2. 对于输入中的每个字节,运行以下步骤:

    1. 如果字节不是“%”,则将字节附加到输出。

    2. 否则,如果 byte 为 '%' 并且输入中 byte 之后的接下来两个字节不在 0x30 到 0x39、0x41 到 0x46 和 0x61 到 0x66 范围内,则将字节附加到输出。

    3. 否则,运行这些子步骤:

      1. 令 bytePoint 为输入中字节后的两个字节,已解码,然后解释为十六进制数。

      2. 将值为 bytePoint 的字节添加到输出。

      3. 跳过输入中接下来的两个字节。

  3. 返回输出。

在原始规范中,“解码”一词(上面以粗体显示)是指向 UTF-8 解码算法的链接。我假设这是上面第二句(斜体)中提到的“utf-8 解码器”。

据我所知,无效的 UTF-8 字节序列可能会导致安全问题。然而,在使用解码器的步骤中,字节已经被前面的子步骤 2 验证为有效的 ASCII 十六进制数字,因此在这里使用 UTF-8 解码器来确保安全似乎有点矫枉过正。

谁能解释一下,当解码器仅用于 0x30 到 0x39、0x41 到 0x46 和 0x61 到 0x66 范围内的字节值时,在此算法中使用 UTF-8 解码器以外的其他解码器可能会不安全?或者我对规范中的某些内容的解释不正确?

在我看来,0x00 到 0x7f 范围之外的任何字节都将简单地按原样复制到输出(在子步骤 1 中,因为它们不是 %,或者在子子步骤 2 中,因为它们不是 ASCII 十六进制数字),因此它们在此算法中永远不会出现在解码器中