scanf Cppcheck предупреждение - PullRequest
       11

scanf Cppcheck предупреждение

7 голосов
/ 11 августа 2011

Cppcheck показывает следующее предупреждение для scanf:

Message: scanf without field width limits can crash with huge input data. To fix this error message add a field width specifier:
    %s => %20s
    %i => %3i

Sample program that can crash:

#include 
int main()
{
    int a;
    scanf("%i", &a);
    return 0;
}

To make it crash:
perl -e 'print "5"x2100000' | ./a.out

Я не могу завершить работу этой программы, набрав "огромные входные данные".Что именно я должен напечатать, чтобы получить этот сбой?Я также не понимаю значение последней строки в этом предупреждении:

perl -e ...

Ответы [ 3 ]

6 голосов
/ 11 августа 2011

Последняя строка - это пример команды для запуска, чтобы продемонстрировать сбой с примером программы. По сути, Perl печатает 2.100.000 раз «5», а затем передает это в стандартный поток программы «a.out» (которая должна быть скомпилированной программой примера).

Прежде всего, scanf() следует использовать только для тестирования, а не в реальных программах из-за нескольких проблем, которые он не будет корректно обрабатывать (например, запрашивать «% i», но пользователь вводит «12345abc» («abc»). "останется в stdin и может привести к тому, что следующие входные данные будут заполнены без возможности изменения пользователем).

Относительно этой проблемы: scanf() будет знать, что должно прочитать целочисленное значение, однако не будет знать, как долго это может продолжаться. Указатель может указывать на 16-битное целое, 32-битное целое или 64-битное целое или что-то еще большее (что он не знает). Функции с переменным числом аргументов (определены с помощью ...) не знают точный тип данных переданных элементов, поэтому он должен полагаться на строку формата (причина в том, что теги формата не являются необязательными, как в C #, где вы просто нумеруйте их, например "{0} {1} {2}"). А без заданной длины она должна принимать некоторую длину, которая также может зависеть от платформы (что делает функцию еще более небезопасной для использования).

В общем, посчитайте, что это возможно вредно и является отправной точкой для атак переполнения буфера. Если вы хотите обезопасить и оптимизировать свою программу, начните с замены ее альтернативами.

0 голосов
/ 11 августа 2011

Использование функции 'scanf' (или fscanf и sscanf) в реальных приложениях обычно вообще не рекомендуется, потому что это небезопасно, и это обычно дыра для переполнения буфера, если будут предоставлены некоторые неверные входные данные.Есть много более безопасных способов ввода чисел во многих широко используемых библиотеках для C ++ (QT, библиотеки времени выполнения для Microsoft Visual C ++ и т. Д.).Возможно, вы также можете найти безопасные альтернативы для «чистого» языка Си.

0 голосов
/ 11 августа 2011

Я попытался запустить выражение perl для программы на C, и оно потерпело крах здесь в Linux (ошибка сегментации).

...