Баг работает не только в самом браузере Chrome, но и в программах, использующих его движок — это как другие браузеры и сборки Chromium, так и Steam, клиенты мессенджера Slack и так далее. Для падения браузера нужно вставить ссылку в адресную строку, но также сработает наведение указателя мыши на гиперссылку с проблемным кодом. Последний факт уже используют для создания игр, которые наказывают падением браузера.
Комбинация из 16 символов — это
http://a/%%30%30
. При её вставке в адресную строку или при наведении указателя мыши на гиперссылку, ведущую на неё, происходит следующее:- Последовательность в конце ссылки преобразуется в
%00
, а0x30
— это ASCII-код для 0. На конце УРЛ появляется нулевой байт. - УРЛ передаётся в GURLToDatabaseURL(), которая вызывает ReplaceComponents().
- УРЛ снова обрабатывается, обнаруживается нулевой байт. Его там быть не должно, поэтому УРЛ помечается как недействительная.
- Ссылка возвращается GURLToDatabaseURL(), со стороны которой ожидается валидность УРЛ. Происходит вызов spec().
- УРЛ невалидна. Вызов DCHECK() приводит к падению.
При наведении курсора мыши над проблемной гиперссылкой происходит примерно то же самое, хотя в этом случае УРЛ обрабатывается в другой части браузера. Но и здесь ожидается только корректный адрес.
Вероятно, этот баг скоро исправят, но некоторые пытаются привлечь к нему внимание с помощью небольших игр-демонстраций. Пощекотать себе нервы могут пользователи следующих веб-обозревателей: Google Chrome, Opera, «Яндекс.Браузера» и других хромоподобных браузеров на движке Blink. В Microsoft Edge, Internet Explorer и Mozilla Firefox игры не работают. Перед открытием одной из двух следующих страниц рекомендуется сохранить работу и убедиться в том, что не будут потеряны важные данные.
Первая игра носит название %%30%30. Это лабиринт, созданный обычным HTML-кодом. Он выглядит как веб-страница с кликабельными картинками, по которым нужно провести указатель мыши. Нужно располагать курсор строго над эмодзи с мишками, не натыкаясь на деревья, иначе браузер упадёт. Для пользователей браузеров с иммунитетом: процесс выглядит следующим образом (2,26 МиБ).
https://github.com/szhu/3030/tree/master
Первый пример простой, но скучный. Второй куда более интерактивен и жесток. Это веб-сайт, на котором кликабельная точка гоняется за курсором мыши. Если она его настигнет, то попадёт в фокус, и браузер упадёт. Достижения в игре регистрирует счётчик очков. К недостаткам игры можно отнести низкую скорость движения и предсказуемость поведения «хищника».
http://linkofdeath.com
Описание ошибки на баг-трекере Chromium
Комментарии (40)
vlivyur
23.09.2015 13:11+1Vivaldi хорошо падает. Эту вкладку только переоткрывать, иначе ничего в ней не работает.
agent10
23.09.2015 15:22+1клиенты мессенджера Slack
Попробовал в Slack просто сообщением — не получается…
roboq6
23.09.2015 15:44+3Кстати, в обоих играх можно сжульничать с помощью правой кнопки мыши.
1.Жмем правую кнопку мыши, появляется контекстное меню. В случае Link of death точка может догнать курсор пока меню открыто, но это не приведет к проигрышу.
2.Перемещяем курсор куда хотим.
3.Снова кликаем правой кнопкой мыши, после чего продолжаем игру как ни в чем не бывало.
Я этому трюку научился еще в flash-играх, забавно что тут он тоже работает.fshp
24.09.2015 02:04+1Сложно как-то. Можно просто курсор вывести за окно браузера.
ivaschenko
24.09.2015 13:04+1Счёт не идёт без движения хищника.
fshp
24.09.2015 13:07+1Так и при открытом контекстном меню счёт не идёт, даже если двигать мышку.
ivaschenko
24.09.2015 13:10+1Можно подвинуть мышку и нажать в новом месте: хищник полетит за вами в новое место, но вы защищены контекстным меню. Но рано или поздно всё равно хищник будет летать быстрее, чем открывается контекстное меню.
fshp
24.09.2015 13:14+1Не знаю, как в виндах, но в линуксе повторный щелчок правой кнопкой мыши не открывает новое меню, а закрывает старое. Т.е. нужно сделать даблклик для открытия нового, что намного медленее.
roboq6
23.09.2015 16:43-1Внимание, под спойлером картинка которая при открытии в Хроме обрушивает вкладку.
В качестве источника картинки я указал ту самую ссылку-которую-нельзя-называть.
Если бы эта картинка загружалась автоматически, то статью было бы невозможно открыть в Хроме.
Так что дыра не такая безобидная как может показаться на первый взгляд.
p.s. был вынужден удалить картинку, спойлер не помогает, хром все равно вылетает.
Vlad_IT
23.09.2015 20:55+2В инструменте разработчика хрома, если навести на атрибут href элемента, то валится сам инструмент.
Alehandr0
23.09.2015 22:05+1Недавно на моём хроме, версии dew-2.0,
< meta http-equiv=refresh content=100 >
вызывала непрерывное и постоянное обновление страницы.
Alehandr0
23.09.2015 22:11Недавно на моём хроме, версии dew-2.0,
< head >
< meta http-equiv=refresh content=100 >
< /head >
вызывала непрерывное и постоянное обновление страницы.
MrNobody
24.09.2015 08:14+1Google Chrome 45.0.2454.93 (64-bit)
Gentoo
Падает если вставить в адресную строку весь.
Если навести на ссылку падает только вкладка.
vintage
24.09.2015 09:10-1Давайте похлопаем тому человеку, что десятки лет назад придумал null terminated string и всем тем миллионам разработчиков, что до сих пор не выпилили эту гадость из своих проектов.
Elvish
24.09.2015 09:56+1а как Вы предлагаете хранить длину строки? или сделать все строки фиксированного размера? Или вообще все символы связным списком?
Если хранить длину — то в скольких битах? Тут или перерасход или недостаток рано или поздно случится. Если сделать переменное число бит на хранение длины строки — то оверхед будет при считывании этой длины.
Интересует именно универсальный и кросс платформенный подход.
И оценочное сравнение по потреблению лишней памяти для мелких и больших строк. А также сравнение производительности в типичных операциях со строками.Alexey2005
24.09.2015 10:27Похоже, что null-terminated-строки — действительно худший способ хранения строк из всех известных человечеству. Во-первых, он крайне не производителен. Ведь большинство операций со строками требует предварительного определения их длины, а для этого вам придётся пробежать всю строку в поисках нуля. Например, если вы копируете строку — вы должны сначала подсчитать её длину, а потом пробежать по ней повторно, уже для собственно копирования. Разве не оверхед?
Во-вторых, на строки сразу же накладывается ограничение — они не смогут содержать символ null. И тут начинаются проблемы: всякое там экранирование, преобразование и прочие хитрые схемы.
Наконец, длина любой строки всё равно обязана где-то храниться. Ведь мы же выделяем под неё память? И эту память сборщик мусора потом будет должен как-то освободить. Естественно, он должен знать размер освобождаемого блока. А значит, размер блока памяти со строкой всё одно где-то лежит. Просто в неявном виде. Ну и что это за гениальный приём — хранить длину строки, но не использовать, вместо этого занимаясь постоянными поисками нуля?splav_asv
24.09.2015 11:24+1Null-terminated строки живут только в мире без GC, в случае наличия GC их используют только для ffi в C.
Если в языке нет объектов, передавать везде два параметра видимо очень не хотелось. Похоже такой способ хранения обусловлен системой типов языка C.
А в остальном мире — есть native строки в соответствующих языках, ими и следует пользоваться…Bronx
30.09.2015 10:54+1Не обязательно передавать два параметра. BSTR, например, передаётся как обычный указатель на null-terminated строку и отлично совместим с С, но хранит длину строки по отрицательному смещению.
vintage
25.09.2015 19:03+1Так же как и любые другие массивы — длина массива (4-8 байт), после которой идут элементы. Символы обычно хранятся в UCS-2 кодировке (2 байта на символ), реже в UCS-4 (4 байта на символ), так что на этом фоне затраты на хранение длины строки — незначительны.
alhimik45
Для пакмена с одной жизнью неплохо подошло бы