проверка ввода с помощью std :: ifstream

Я читаю файл, используя что-то вроде:

    std::ifstream is( file_name );
std::string s;

if( !is.good() ) {
std::cout << "error opening file: " << file_name << std::endl;
} else {
while( !is.eof() ) {
s.clear();
is >> s;
if (s.empty())  continue;
if (s.size() < 1 || s.size()>0x7FFFFFFF ) {
std::cout << "implausible data" << std::endl;
continue;
}
char *ss = new char[ s.size() + 1 ]; // COVERITY bails out
// do something with the data
delete[]ss;
}
}

Когда я анализирую приведенный выше код с помощью инструмента статического анализа кода Coverity (бесплатная версия), линия помечена Покрытие выручает выдает ошибку:

 Untrusted value as argument (TAINTED_SCALAR)
tainted_data: Passing tainted variable > s.size() + 1UL to a tainted sink.

Я понимаю, что не должен доверять никаким данным, считанным из файла, но я не вижу, как проверять данные на этом этапе.
Я уже проверяю это s.size() находится в пределах правдоподобного (хотя и довольно большого) диапазона в if-пункт выше ошибочной линии.

Так почему прикрытие бросает на меня предупреждение?

Кроме того, какие другие стратегии для проверки входных данных я должен применить?

1

Решение

В следующем разделе

if (s.empty())
continue;
if (s.size() < 1 || s.size() > 0x7FFFFFFF)
{
std::cout << "implausible data" << std::endl;
continue;
}
char * ss = new char[s.size() + 1];

логика проверки опирается на важный факт, что s.size() будет возвращать одно и то же значение каждый раз, когда оно вызывается. Хотя в этом случае мы (люди) знаем, что это будет правдой, статический анализатор кода может не понять этого.

В качестве обходного пути попробуйте ввести локальную переменную и используйте ее.

const std::size_t length = s.size();
if (!length)
continue;
if (length < 1 || length > 0x7FFFFFFF)
{
std::cout << "implausible data" << std::endl;
continue;
}
char * ss = new char[length + 1];

Здесь анализатору просто сказать, что length не изменит свое значение.

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

Не делайте программу уродливой, просто чтобы успокоить инструменты статического анализа, такие как lint, clang и GCC, с дополнительными опциями предупреждений, такими как -Wconversion а также -Wundef, Эти инструменты могут помочь найти ошибки и неясный код, но они также могут генерировать так много ложных тревог, что это ухудшает читабельность, заставляя их замолчать с ненужными приведениями, обертками и другими сложностями. Например, пожалуйста, не вставляйте приведение к void или призывы к действиям бездействия только для того, чтобы успокоить средство проверки lint.

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

2

Другие решения