- PVSM.RU - https://www.pvsm.ru -
def maps():
print "maps maps maps"
def spam():
print "Erasing everything..."
print "done."
Вы знаете, что если очень долго смотреть на следующую строку, то там останутся только три слова «spam»?
s = "spam" ,spam ,"spam"
s[1]()
Действительно, первая строка очень необычная. В целом, в результате этого кода будет выполнена зловредная функция spam.
Посмотреть на ideone [1]. (Для тех кто не знает: там внизу есть вывод выполнившейся программы)
В основе нашей проблемы с двунаправленным письмом лежит идея о том, что в памяти текст всегда хранится в порядке записи его человеком. В том числе при письме справа-налево, при котором текст будет отрисовываться в обратном привычному направлении.
Направление отрисовки определяется автоматически по принадлежности символов конкретному алфавиту (ивриту, например) или, если это знак пунктуации или цифра, то по более хитрым правилам, в зависимости от контекста.
RLO — символ форматирования, расшифровывается как right-to-left override [2]. Меняет направление письма на правостороннее для символов с дефолтно-левосторонним письмом. (В стандарте написано, что это может использоваться для записи таких вот идентификаторов [3], когда те состоят из смешанного иврита и английского и, видимо, английские включения естественно читаются справа-налево).
Ну так вот. Благодаря ему мы можем получить нашу прелесть:
s = "spam<RLO>" ,spam ,"<PDF>spam"
s = "spam" ,spam ,"spam"
PDF расшифровывается как pop directional formatting, сбрасывает эффект последнего RLO или его друзей [4].
Нетрудно догадаться, что интерпретатор окажется равнодушен к непонятным символам в строковых литералах. А вот некоторые редакторы, вроде emacs*, Xcode, Kate, развернут промежуточный текст именно так, как это делает браузер.
* в случае emacs, возможно, поведение зависит от терминала. Но в vim и nano проблемы в том же терминале нет: оба показывают только код символа RLO в соответствующей позиции.
Символ RLO не является вайтспейсовым, кроме того, python ругается [5] на него в составе идентификаторов, что немного ограничивает возможности применения.
Его приходится класть в строковые литералы, либо в комментарии. При этом к концу каждой строки файла, как параграфа, действие RLO заканчивается.
vim
sublime text
xcode
emacs
… и еще раз ссылка на ideone [1].
upd: есть еще вот такой [6] вариант с Embedding и Mark
«rm -rf echo», которая на самом деле только печатает «rm -rf»
echo -e 'xe2x80x8fxe2x80xaaecho xe2x80xacxe2x80x8fxe2x80xaarm -rf xe2x80xacxe2x80x8f'
bash почему-то игнорирует символы форматирования в начале команды, открывая большой простор для злодействия.
Автор: TheRipper
Источник [7]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/python/85512
Ссылки в тексте:
[1] Посмотреть на ideone: http://ideone.com/GuSU4F
[2] right-to-left override: http://www.fileformat.info/info/unicode/char/202e/index.htm
[3] таких вот идентификаторов: http://en.wikipedia.org/wiki/Part_number
[4] его друзей: http://unicode.org/reports/tr9/#Directional_Formatting_Characters
[5] ругается: http://ideone.com/1xPM1H
[6] вот такой: http://ideone.com/ZvEEab
[7] Источник: http://habrahabr.ru/post/252813/
Нажмите здесь для печати.