Насколько безопасен UTF-8 по сравнению с символами ASCII

Я читал в Википедии и наткнулся на следующее:

"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, тогда это простая ситуация, и не будет никаких проблем, поскольку оно будет знать, как интерпретировать их в контексте других байтов-предшественников / преемников. А если этого не произойдет, то он не имеет с этим никаких дел, и тот факт, что он может натолкнуться на комбинацию битов, являющихся символом формата, подобным '\', не более вреден, чем уже обрабатывает его в первое место.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
160
1

Ответы 1

Возьмем, к примеру, PHP. PHP не имеет собственного понимания кодировок (здесь есть некоторые звездочки и сноски, но, скажем так, это не так). Он ищет определенный конкретный байты в исходном коде, который что-то для него значит, и в основном просто пропускает через все остальное, что не имеет для него особого значения. Например.:

$foo = "bar $baz 42";

Это вызывает интерполяцию строк; PHP попытается вставить в эту строку переменную $baz. Это делается путем поиска байта 0x24 (ASCII «$») и следующего «не-словного» байта в строке, что приводит к нахождению имени переменной $baz внутри строки. Все остальное в строке проходит как есть.

Вы можете сделать это на PHP:

echo "意味分からない";

Все, что PHP видит здесь, - это какой-то двоичный объект, который не представляет для него особого интереса. Он не поддерживает и не понимает этих персонажей, но и не пытается что-либо с ними сделать. Он просто передает двоичные данные как есть и, таким образом, выводит желаемое японское предложение.

Теперь, если бы мы написали это предложение в какой-нибудь кодировке, не безопасной для 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.

Это очень интересно. Возможно, уместно отметить, что по определению все байты в последовательности UTF-8, кодирующей символ Unicode за пределами диапазона ASCII (0-127), полностью состоят из байтов, больших или равных 128, поэтому невозможно, чтобы случайные 24 появится где-нибудь еще в файле с кодировкой UTF-8.

Tim Pietzcker 17.12.2018 12:06

Именно это делает UTF-8 «совместимым с ASCII».

deceze 17.12.2018 12:07

... Перечитывая вопрос, вижу, что об этом там уже упоминалось :)

Tim Pietzcker 17.12.2018 12:09

Я понимаю, как utf-8 безопасен для ascii, но я не могу представить себе контекст, в котором это может быть не так, то есть кодировка, которая понимает Unicode, включая Ascii, но не безопасна для Ascii. Скажем, utf-8 создает байты, подобные ascii, при кодировании других кодовых точек, отличных от ascii, тогда вполне естественно, что алгоритм декодирования обработки будет знать, как интерпретировать их в перспективе, а не путать их как отдельные ASCII. Если он генерирует октеты ASCII, должна быть какая-то логика, чтобы различать их и правильно интерпретировать ...

Learnerer 17.12.2018 12:21

@Learnerer Как я пытался продемонстрировать, существуют наивные системы, которые ничего не декодировать. ищут определенные последовательности байтов и игнорируют все остальное. Им известны только ASCII или ASCII-совместимые кодировки, которые совсем не нужно «интерпретировать в перспективе». Это просто байты, и эти байты были определены богами много лет назад, и вам просто нужно искать байты, которые что-то значат для вас, и вы можете игнорировать все остальное. По крайней мере, так гласила мантра для этих систем.

deceze 17.12.2018 12:24

@deceze Thx. Но, как я сказал в своем вопросе выше, если система не работает с не-ascii, тогда нам не нужно беспокоиться о том, что она неверно интерпретирует части кодировки как asciis, поскольку обработка такого текста в первую очередь является error, т.е. зачем заботиться об ошибке, возникающей поверх ошибки. Мое мнение: этот аргумент, который я прочитал, кажется мне, как будто он пытается продвинуть положительное качество в utf-8, когда это действительно естественная особенность, которую следует принимать как должное в кодировке, которая может обрабатывать ascii - отсюда и мое замешательство ... !

Learnerer 17.12.2018 12:30

@Learnerer UTF-8, совместимый с ASCII, позволяет таким наивным системам «поддерживать Unicode», фактически не поддерживая Unicode. То есть вам не нужно переделывать всю систему, чтобы сделать ее полностью осведомленной о кодировании, ей просто нужно ничего не делать с байтами, которые ее не касаются. Да, в идеальном мире все должно происходить иначе, но без этой совместимости у нас, вероятно, не было бы такой широкой поддержки Unicode, как у нас.

deceze 17.12.2018 12:35

Спасибо. ... и последнее: те объекты в кодировке utf-8, на которые вы ссылались, по-прежнему будут содержать подлинные (преднамеренные) символы ascii как часть юникода, поэтому тот факт, что utf-8 не создает эти байты ascii как часть других chars, не предотвращает появление этих символов в кодировке, и ситуация, которую вы продемонстрировали выше, все равно может возникнуть ..?

Learnerer 17.12.2018 14:29

Я не уверен, что понимаю… !? Если у вас есть байт в UTF-8, который интерпретируется как «$», это потому, что вы хотели ввести там «$». Если вы сравните это с приведенным выше примером ISO-2022, там много «$», которые являются случайными. Вы не имели в виду, чтобы там были эти «$», но программа, которая ожидала ASCII, увидела эти случайные байты как «$». UTF-8 этого избегает. Программа, ожидающая ASCII, увидит «$» в UTF-8 только тогда, когда вы означало поместите туда «$».

deceze 17.12.2018 14:41

Да, это то, что я имел в виду, преднамеренные символы ascii ... Однако теперь я думаю, что я стал яснее ... Спасибо.

Learnerer 18.12.2018 08:00

Другие вопросы по теме