Разработчики системы для автоматизированного выявления ошибок Coverity опубликовали статью (http://cacm.acm.org/magazines/2010/2/69354-a-few-billion-lin...), в которой обобщили наиболее важные выводы о природе возникновения ошибок в реальных проектах. Приводится пример важности обнаружения трудноуловимых глупых ошибок, вызванных невнимательностью разработчиков, но часто приводящих к серьезным последствиям. Например конструкция "if(getuid() !=0 && geteuid == 0){ErrorF("only root");exit(1);}" вызвала серьезную уязвимость в X-сервере, так как использование "geteuid" вместо "geteuid()" привело к сравнению указателя на функцию, который никогда не равен 0, соответственно условие всегда было ложным.URL: http://cacm.acm.org/magazines/2010/2/69354-a-few-billion-lin...
Новость: http://www.opennet.me/opennews/art.shtml?num=25423
Какой ужас, неужели этоif(getuid() !=0 && geteuid == 0){}
написал человек, что он хотел тут проверить?
интересно, это сама программа нашла эту ошибку или она выдёт подозрительные строчки?
> написал человек, что он хотел тут проверить?А что непонятного?
хотел проверить, не через sudo/suid-бинарник ли мы запустились.
if(pow(2, 2) !=0 && pow(2, 2) == 0){ printf(не послать ли нам гонца за бутылочкой винца"); }
>if(pow(2, 2) !=0 && pow(2, 2) == 0){ printf(не послать ли нам
>гонца за бутылочкой винца"); }getuid не тождественно getEuid
Должно было быть:
if(getuid() !=0 && geteuid() == 0){}
но скобки забыли
Моск огни забыли. Надо код прогонять с -Wall -Werror# gcc test.c -Wall -Werror
cc1: warnings being treated as errors
test.c: В функции ‘main’:
test.c:8: ошибка: the address of ‘geteuid’ will never be NULL
X с -wall'ом не собираются :) (Почти шутка)
только я не увидел e ?
Нет, не только..
Больше стоит винить сам язык, а не кодеров. Неявное преобразование типов и т.д. В том же Pascal'е, как бы его сильно не любили, такую ошибку допустить невозможно дважды (указатель не может иметь значения 0 и если мы хотим работать с адресом функции, а не с её результатом, то так и придется говорить компилятору - @)...bw
> указатель не может иметь значения 0Опа! Указатель не имеет значения, он указывает :)
int main() {
int var = 0;
int *p = 0;
int *pp = 0;p = &var;
pp = p;
p = 0;return 0;
}Чё страшного-то?
Нет, никогда не стоит винить язык вместо самих кодеров.В том же Poscacal-е
1.
> указатель не может иметь значения 0,но может и часто имеет значение nil, как пример:
if GetUIDPtr() <> nil and GetEUIDPtr = nil then begin end;2.
> то там всегда надо говорить компилятору - @а в C нужно вставлять &, не обязательно, правда, но так сделано для удобства.
Дело в том, что в С работают-таки с указателями, в отличии от Паскаля. Единственный Паскаль в котором можно нормально работать с указателями - это Борландовские паскали, в которых от паскаля один лишь С и остался.
Потому причина ошибок не в языке, а в конкретных кодерах.
No silver bullet
> ... GetEUIDPtr = nil then begin end;"=" или "=="
Ах да, в паскале присваивание это ":="
В паскале ваша конструкция компилироваться не будет и язык вам ошибку сделать не даст.Если это функция без аргументов, то скобки там лишние. Это во первых.
Во вторых, как утверждал один из ораторов выше, взятие адреса функции выполняется отдельным оператором.
Поэтому как ни пиши, и сравнивай хоть с нулем хоть с Nil - будет два вызова функции.
Строгая типизация - рулит.
>В паскале ваша конструкция компилироваться не будетВ этом и point: Паскаль - для бумажным программистов. Указателя в жизни не нюхавших.
Потому и работа с указателями с нем - неудобна.и компилироваться не будет, но какой ценой?
> Это во первых.
Pascal compiler detected!! :)
>
>Во вторых, как утверждал один из ораторов выше, взятие адреса функции выполняется
>отдельным оператором.это то же самое "во-первых". :)
>Поэтому как ни пиши, и сравнивай хоть с нулем хоть с Nil
>- будет два вызова функции.для сравнения указателей функция не вызывается ни в каком себя уважающем языке :)
даже в паскале. Вы наверное так и не вышли за ментальные рамки Виртуальной-Паскаль-машины.
>Строгая типизация - рулит.Но только для студентов первого курса.
Учитывая акселерацию, сейчас - для нулевого..
В реальных задачах это больше помеха: компилятор никогда не умнее программиста. Программист компилирует свои знания в исходный код. чем высокоуровнее этот код тем всем лучше. а если не так, то пишите на ассемлере...нет, в машинных кодах.
Скажите люди, кто-нибудь, когда-нибудь эту Coverity юзал.Я кроме их рекламных достижений ничего и не знаю.
Это статический анализатор кода.У нас в компании используется: для С и C++ кода. Весьма полезная штука.
И весьма продвинутая.
Для маломальски крупных проектов нужно иметь что-то подобное.Кстати, простенький вариант статического анализатора: http://cppcheck.sourceforge.net/
>Это статический анализатор кода.Что это таке, я знаю. Но кроме слухов и радостных, слюниипускающих рассказов не слышал :)
>У нас в компании используется: для С и C++ кода. Весьма полезная штука.
>И весьма продвинутая.Дайте поиграться...
>Для маломальски крупных проектов нужно иметь что-то подобное.
>Кстати, простенький вариант статического анализатора: http://cppcheck.sourceforge.net/видали, юзали, ...
Я юзаю связку splint + rats + its4 + flawfinder + pscan + gibberish + boot + mops + bogosec + boon + ckit + magic + valgrid + smatch :)
Но так достало их постоянно настраивать ...
это же Pascal, там нет == ;P