Что на самом деле означает «недопустимые последовательности единиц кода» в PHP?Как работают «недопустимые последовательности единиц кода» в htmlspecialchars ()?Нужны примеры этого - PullRequest
0 голосов
/ 27 марта 2019

Итак, мне всегда нужны ответы, специфичные для PHP, а не обобщенные ответы с учетом технологий, отличных от PHP.

Я использую PHP 7.3.3 на моем ноутбуке, который работает под управлением 64-разрядной операционной системы Windows 10 Home Single Language.

Я установил последнюю версию установщика XAMPP на свой ноутбук, на котором установлены Apache / 2.4.38 (Win64) и PHP 7.3.3

Сегодня я натолкнулся на следующий текст из PHP Manual , описывающий возможные значения flags параметров:

флаги

Битовая маска одного или нескольких из следующих флагов, которые указывают как обрабатывать кавычки, недопустимые кодовые последовательности единиц и используемые тип документа. По умолчанию ENT_COMPAT | ENT_HTML401 .

Из вышеприведенного текста я не понял, что на самом деле означает недопустимые последовательности кодовых единиц конкретно в PHP.

Я также нигде не получил определения, объяснения или примера недопустимых последовательностей единиц кода .

Просим вас предоставить несколько хороших примеров неверных последовательностей кодовых единиц .

Кроме того, объясните мне, как это явление недопустимых последовательностей единиц кода работает со встроенной функцией htmlspecialchars()?

Ответ, сопровождаемый подходящим примером рабочего кода, будет заветным.

Спасибо.

1 Ответ

3 голосов
/ 27 марта 2019

Может быть несколько причин, по которым строка может содержать недопустимые кодовые единицы . Чтобы понять, почему это может произойти, вам сначала нужно понять, что такое кодовая единица и чем она отличается от кодовой точки.

Стандарт Unicode определяет список кодовых точек, что в простых терминах означает, что каждый символ, который вам понадобится, должен иметь четко определенный идентификатор. Следовательно, кодовая точка - это уникальный идентификатор для конкретного символа в стандарте Unicode. Он определяет 1,114,112 кодовых точек на 17 плоскостях.

Юникод может быть реализован различными кодировками символов. Стандарт Unicode определяет UTF-8, UTF-16 и UTF-32, а также используется несколько других кодировок. Наиболее часто используемые кодировки - это UTF-8, UTF-16 и UCS-2, предшественник UTF-16. Каждое кодирование будет генерировать различную кодовую единицу для кодирования конкретной кодовой точки.

Максимальное количество, которое вы можете сохранить в байте, равно 255, и вы можете видеть, что количество кодовых точек значительно превышает максимальное количество, которое вы можете сохранить в одном байте. Именно здесь приходят упомянутые выше многобайтовые кодировки. Я рекомендую читать о них больше в свободное время, но для простоты я буду говорить о UTF-8 только с этого момента.

UTF-8 - кодировка переменной длины. Это означает, что для кодирования буквы A, например, вам нужен только 1 байт, в отличие от, например, ?, который использует 4 байта. Чтобы узнать, какой байт в последовательности строк является частью многобайтовой последовательности, вам нужны префиксные коды. Первый байт указывает количество байтов в последовательности. Все байты составляют единицу кода для этого символа. Неправильный символ не будет декодирован, если поток заканчивается в середине последовательности. Отдельный байт из единицы кода сам по себе является недопустимой единицей кода ; он не может быть декодирован, чтобы указывать на правильный код Unicode. Посмотрите, что происходит после 7F . Если вы сравните это с исходным кодом PHP , вы можете ясно увидеть, что если вы встретите байт в диапазоне 0x80 https://en.wikipedia.org/wiki/UTF-8#Description

Благодаря UTF-16 некоторые кодовые точки также могут быть недействительными единицами кода. Они называются суррогатами и сами по себе не представляют символ Unicode.

Строка может быть искажена по разным причинам, но возможно иметь недопустимых байтовых последовательностей, то есть кодовых единиц

Некоторые примеры недопустимых последовательностей кодовых единиц:

  • "\xED\x9F\xC0" - суррогатное
  • "\x80"
  • "\xC2\x79"
  • "\xC3\xC0" и так далее ...
...