Почему эти тайские символы отображаются на веб-странице с длинным хвостом?

ด ้้้้้็็็็็้้้้้็็็็็้้้้้็็็็็้้้้้็็็็็้้้้้็็็็็้้้้้็็็็็้้้้้็็็็็้้้้้ д ด ็็็็็้้้้้็็็็้้้้้็็็็็้้้้้็็็็็้้้้้็็็็็้้้้้

Я нашел несколько интересных персонажей так же, как я вставил выше, которые занимают всего 3 пробела. Однако фактическая длина строки равна 380.

Я проверил строку в python, и строка encode выглядит следующим образом:

'\ xe0\XB8\x94\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xd0\XB4\xe0\XB8\x94\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\Xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x87\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89\xe0\xb9\x89'

Кажется, что строка представляет собой комбинацию из трех тайских символов:

ด \xe0\xb8\x94  THAI CHARACTER DO DEK

้  \xe0\xb9\x89  THAI CHARACTER MAI THO

็  \xe0\xb9\x87  THAI CHARACTER MAITAIKHU

И мои вопросы:

  • Почему поведение этих персонажей происходит по-другому, это ошибка?
  • Как я могу избежать этого на сайте (возможно, с некоторым html-фильтром)?

UPDATE

Я тестировал символы с большим количеством браузеров, а длинный хвост появился только на хром и firefox на платформе Windows.

Ниже приведен снимок экрана:

выиграть 7 ie8 win 7 ie8


ubuntu firefox ubuntu firefox


выиграть 7 хром win 7 chrome


win 7 firefox win 7 firefox


Поэтому, я думаю, это ошибка, связанная с браузером.

Ответ 1

Есть две проблемы: одна в системе вывода (средство визуализации шрифтов), которая не является тайской, и одна в системе ввода, которая сгенерировала этот текст в первую очередь.

Если вы сделали домашнее задание, вы бы знали, что mai tho и maitaikhu (имена UniCode) - это то, что UniCode называют маркерами Non Spacing (NSM). Это означает, что средство отображения шрифтов не должно перемещаться в следующую ячейку символа при отображении этого символа.

Чтобы избежать беспорядка, который вы видите выше, тайский API-консорциум (TAPIC) сделал стандарт WTT 2.0, который описывает и то, как алгоритм рендеринга шрифта должен обрабатывать тайский порядок букв, когда он получает его как вход, а также как метод ввода должен позволять вводить такие символы, если вы пытаетесь ввести их.

Стандартизация и реализация обзора тайского языка

libthai включает как методы ввода, так и вывода.

thaicheck - небольшая программа, которая может обнаруживать проблемы последовательности букв и исправить их.

Кстати, у вас не может быть последовательности (слова) do dek, mai tho и maitaikhu; входная последовательность - шум.

Имейте в виду, что некоторые редакторы нарушили методы ввода, которые позволяют печатать несколько NSM, которые нельзя комбинировать, но метод вывода будет отображать только правовые последовательности; результатом является недопустимая строка ввода, которая выглядит нормально для пользователя в его системе.

Ответ 2

Коды, которые вы упомянули, все находятся в UTF-8, поэтому каждый символ нуждается в 3 байтах. Кодекс уважения Unicode:

Последние два находятся в категории Mark, Nonspacing и имеют свойство Combine (Canonical_Combining_Class), равное 107, что означает, что кодовые точки объединены с предыдущей точкой кода в рендеринге.

Например, пример начинается с одного символа и добавляет к нему много неровных меток.

Сравните с этим кодом С#:

char DODEK = (char)0x0e14;
char MAITHO = (char)0x0e49;
char MAITAIKHU = (char)0x0e47;

string thai = new string(new char[] { DODEK, MAITHO, MAITAIKHU });
Console.WriteLine("number of code points: " + thai.Length);

var si = new System.Globalization.StringInfo(thai);
Console.WriteLine("number of text elements: " + si.LengthInTextElements);

Вывод:

number of code points: 3
number of text elements: 1

См. также . Класс Net StringInfo.

Ответ 3

Вы никогда не должны сочетать сотни символов Unicode с одним графическим символом, хотя форматы unicode технически позволяют это; вы обычно объединяете не более 2 или 3 символов.

На тайском языке у вас есть гласные и тональные знаки, которые отображаются над символом consonnant (иногда гласные появляются ниже или даже вокруг символов consonant...). Это немного напоминает акценты над гласными на французском языке (& eacute;, eg egveve...) или умлауты на немецком языке. Это не нормально, чтобы иметь более двух таких знаков на тайском (и более одного на французском или немецком). Это означает, что ваш ввод является незаконным тайским текстом (возможно, написан для предоставления некоторых смешных графических эффектов, таких как "ASCII art" ). Я не удивлен, что такой незаконный текст интерпретируется по-разному в зависимости от браузера.

Ответ 4

То, что вы нашли, называется Сочетание символов или как обычный народ, вызываемый Zalgo.

Это работает, потому что Unicode позволяет комбинировать символы, добавляя диакритические знаки после символа.

Любая система, которая использует Unicode, будет работать с этими символами.