相对于ASCII字符,UTF-8如何安全

时间:2018-12-17 10:42:10

标签: unicode utf-8 character-encoding ascii

我在Wikipedia上阅读,发现以下内容:

"Since ASCII bytes do not occur when encoding non-ASCII code points into UTF-8, 
UTF-8 is safe to use within most programming and document languages that 
interpret certain ASCII characters in a special way, such as "/" in filenames, 
"\" in escape sequences, and "%" in printf."

我不明白这是怎么个问题,即使发生了。如果处理字节的应用程序支持utf-8,那将是一个简单的情况,并且不会有任何问题,因为它将知道在其他前任/后继字节的上下文中对它们进行解释。如果没有,那么首先它就没有业务要处理,而且它可能遇到格式为'\'的位的组合,这一事实并没有像在处理它时那样有害。第一名。

1 个答案:

答案 0 :(得分:4)

以PHP为例。 PHP没有对编码的本机理解(这里有一些星号和脚注,但可以说没有)。它在源代码中寻找某些特定的 bytes ,这对它有一定的意义,并且通常只是通过没有特定含义的任何其他内容。例如:

$foo = "bar $baz 42";

这会触发字符串插值; PHP将尝试将变量$baz插值到该字符串中。它是通过在字符串中查找字节0x24(ASCII“ $”)和下一个“非单词”字节来实现的,这导致它在字符串中找到变量名$baz。字符串中的其他任何内容都照原样通过。

您可以在PHP上执行此操作:

echo "意味分からない";

所有PHP都在这里看到了一些二进制blob,对此它并没有特别的兴趣。它不支持或不理解这些字符,但也不会尝试对它们执行任何操作。它只是按原样传递二进制数据,从而恰好输出所需的日语句子。

现在,如果我们以某种非ASCII安全编码(例如ISO-2022-JP-3)编写该句子,则应该是:

1b24 4230 554c 234a 2c24 2b24 6924 4a24 241b 2842

您会注意到其中的24个字节。如果您可以生成一个有效的PHP文件,其中包含双引号之间的这些字节,则PHP会尝试将这些0x24个字节解释为$并尝试在其中插入变量。

$ cat /tmp/foo.php 
<?php echo "B0UL#J,$+$i$J$$";
$ xxd /tmp/foo.php 
00000000: 3c3f 7068 7020 6563 686f 2022 1b24 4230  <?php echo ".$B0
00000010: 554c 234a 2c24 2b24 6924 4a24 241b 2842  UL#J,$+$i$J$$.(B
00000020: 223b 0a                                  ";.
$ php /tmp/foo.php 
PHP Notice:  Undefined variable: B0UL in /tmp/foo.php on line 1
PHP Notice:  Undefined variable: i in /tmp/foo.php on line 1
PHP Notice:  Undefined variable: J in /tmp/foo.php on line 1

这是一种示例,其中UTF-8与ASCII的兼容性很重要。