- PVSM.RU - https://www.pvsm.ru -
Текстовые редакторы, основная задача которых — отображение моноширинного шрифта (например, кода), должны, как и следует из названия, показывать символы одной ширины.
В Unicode есть символы, видеть которые не положено.
Текстовый редактор может просто отрендерить текст с таким символом, а может предпринять какие-то действия, чтобы сделать его заметным.
Кто же они?
Код | Пример | Название |
---|---|---|
U+2060 | foobar | WORD JOINER |
U+2061 | foobar | FUNCTION APPLICATION |
U+2062 | foobar | INVISIBLE TIMES |
U+2063 | foobar | INVISIBLE SEPARATOR |
U+180E | foobar | MONGOLIAN VOWEL SEPARATOR |
U+200B | foobar | ZERO WIDTH SPACE |
U+200C | foobar | ZERO WIDTH NON-JOINER |
U+200D | foobar | ZERO WIDTH JOINER |
U+FEFF | foobar | ZERO WIDTH NO-BREAK SPACE |
Пришёл на смену zero-width no-break space (U+FEFF), потому что U+FEFF стал использоваться для кодирования BOM (byte-order mask, несколько байт в начале файла, обозначающие его кодировку и порядок байт). Этот символ запрещает перенос строки там, где он встречается.
Устаревший символ, заменён на word joiner, использовался в тех же целях.
Используется в индийских и арабских шрифтах для объединения символов, которые без него не были бы соединены.
В начертаниях с лигатурами можно вставить его между буквами, чтобы лигатуры не было:
Он втречаетя даже на клавиатурах:
Используется, когда нужно обозначить границу слов, не вставляя пробел. Этот текст будет переноситься по словам:
WordWordWordWordWordWordWordWordWordWordWordWordWordWordWordWordWordWordWordWordWordWord
А этот нет:
WordWordWordWordWordWordWordWordWordWordWordWordWordWordWordWordWordWordWordWordWordWord
"Невидимые операторы", добавленные в Unicode 3.2. Нужны для обозначения математических операций в выражениях.
Например, эта запись: Aij
Может означать или индекс (i, j) в двумерном массиве, или индекс i*j в одномерном. Для устранения неоднозначности можно использовать или Invisible times, или Invisible separator, чтобы было понятно, что имелось в виду.
Аналогчино, f (x + y), это или умножение, или функция.
Визуально они не должны отличаться, но некоторые парсеры смогут понять, что имелось в виду.
Из названия понятно, для чего он. Этот символ уже не раз вызывал проблемы [15]. Очень хорошо описан в этом ответе [16].
Конечно же, отображение зависит не только от редактора, но ещё и от шрифта, посмотрим на рендеринг текста, не меняя настроек редакторов.
Atom, Sublime, VSCode, Xamarin Studio, XCode, Notepad++:
Cat не показывает их:
Vim тоже не сообщает о некоторых символах, даже с включённой настройкой set list, а вот less справляется лучше:
GitHub, вот так показываются эти символы в pull request-ах и diff-ах:
Один из популярных редакторов кода, CodeMirror:
В том же CodeMirror, используемом jsbin, в IE часть символов видна:
ACE догадывается, что там бяка, и говорит, что что-то тут нечисто, но вот что именно — показывает не всегда:
Редакторы на платформе IntelliJ:
Разные инструменты сравнения кода под macOS (P4Merge, FileMerge, KDiff3):
KDiff3, попытка засчитана, но этого не достаточно.
SourceTree: не обрабатывает текст вообще никак, плохо:
Tortoise, тоже почти ничего:
git diff
: молодец, показал всё, ещё и выделил. Просто прекрасно, для diff tools это образец для подражания:
Кто-то сделал язык программирования Anguish [17], использующий только невидимые символы.
Он основан на brainfuck, но использует не знаки пунктуации [18], а символы, о которых мы говорили выше.
Есть даже интерпретатор [19] на Perl и примеры [20] использования.
Плохой код, фу таким быть, сделать закладку можно совсем просто:
function f() {
// ну вы поняли, на что заменить
return 'access_denined';
}
let code = f();
if (code === 'access_denied') {
return 401;
}
Пиши чистый код, %username%. Следуй best practices, их придумали не просто так, а для того чтобы держать меньше вещей в голове, в том числе своевременно замечая такие штуки. Увидел магическую строчку, странный или непроверяемый default case, ещё что-то: есть время — не поленись, перепиши как надо. Проводи код-ревью, смотри что коммитят в твою репу, поддерживай хорошее покрытие. Помни, что строке может быть не только то, что видно на экране, проверь в hex-редакторе, если возникло подозрение.
Вообще, вероятность реализации бэкдора через невидимый символ, конечно, есть, но скорее нет, чем да: найти его достаточно просто, а вставить закладку в говнокод можно и другими методами.
Автор: Antelle
Источник [21]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/unicode/197074
Ссылки в тексте:
[1] Word joiner: https://en.wikipedia.org/wiki/Word_joiner
[2] U+2060: http://unicode-table.com/en/2060/
[3] U+FEFF: http://unicode-table.com/en/FEFF/
[4] Zero-width joiner: https://en.wikipedia.org/wiki/Zero-width_joiner
[5] U+200D: http://unicode-table.com/en/200D/
[6] Zero-width non-joiner: https://en.wikipedia.org/wiki/Zero-width_non-joiner
[7] U+200C: http://unicode-table.com/en/200C/
[8] Zero-width space: https://en.wikipedia.org/wiki/Zero-width_space
[9] U+200B: http://unicode-table.com/en/200B/
[10] Invisible Operators: http://unicode.org/reports/tr25/tr25-3.html#_Toc214
[11] U+2061: http://unicode-table.com/en/2061/
[12] U+2062: http://unicode-table.com/en/2062/
[13] U+2063: http://unicode-table.com/en/2063/
[14] U+180E: http://unicode-table.com/en/180E/
[15] вызывал проблемы: https://codeblog.jonskeet.uk/2014/12/01/when-is-an-identifier-not-an-identifier-attack-of-the-mongolian-vowel-separator/
[16] этом ответе: http://linguistics.stackexchange.com/questions/12712/what-is-the-mongolian-vowel-separator-for
[17] Anguish: http://blogs.perl.org/users/zoffix_znet/2016/05/anguish-invisible-programming-language-and-invisible-data-theft.html
[18] не знаки пунктуации: https://github.com/zoffixznet/perl6-Acme-Anguish/#description
[19] интерпретатор: https://github.com/zoffixznet/perl6-Acme-Anguish/
[20] примеры: https://github.com/zoffixznet/perl6-Acme-Anguish/tree/master/examples
[21] Источник: https://habrahabr.ru/post/311518/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best
Нажмите здесь для печати.