Один День Из Жизни Разработчика Pvs-Studio, Или Как Я Отлаживал Диагностику, Которая Оказалась Внимательнее Трех Программистов

Основная цель статических анализаторов — найти ошибки, которые остались незамеченными разработчиком.

А недавно команда PVS-Studio снова столкнулась с интересным примером мощи этой техники.



Один день из жизни разработчика PVS-Studio, или как я отлаживал диагностику, которая оказалась внимательнее трех программистов

Работа с инструментами статического анализа кода требует осторожности.

Зачастую код, на который указывает анализатор, оказывается корректным.

В таких случаях следует считать предупреждение ложным срабатыванием.

На днях мы сами попали в такую ловушку.

Вот как это произошло.

Недавно мы улучшено ядро анализатора , и коллега, просматривавший новые положительные результаты, обнаружил среди них ложный.

Он выписал триггер для тимлида, который быстро просмотрел код и создал задачу.

Я взялся за задание.

Таким простым способом образовалась цепочка из трех программистов.

Предупреждение анализатора: В645 Вызов функции strncat может привести к переполнению буфера a.consoleText. Границы не должны содержать размер буфера, а количество символов, которые он может содержать.

Фрагмент кода:

  
  
  
  
   

struct A { char consoleText[512]; }; void foo(A a) { char inputBuffer[1024]; .

strncat(a.consoleText, inputBuffer, sizeof(a.consoleText) – strlen(a.consoleText) - 5); .

}

Прежде чем изучать пример, давайте вспомним, что делает функция стрнкат :

char *strncat( char *strDest, const char *strSource, size_t count );

Где:
  • 'destination' — строка назначения;
  • 'source' — исходная строка;
  • «count» — максимальное количество символов, которое можно добавить.

На первый взгляд с кодом вроде бы все в порядке.

Он вычисляет количество пустого места в буфере.

При этом вроде бы даже есть запас в 4 байта.

И именно из-за этого ощущения, что с кодом всё в порядке, его и написали в качестве примера, где анализатор выдаёт ложное предупреждение.

Давайте разберемся, как обстоят дела на самом деле.

В выражении:

sizeof(a.consoleText) – strlen(a.consoleText) – 5

максимальное значение может быть достигнуто при минимальном значении второго операнда:

strlen(a.consoleText) = 0

Тогда результатом будет 507 и переполнения не произойдет. О чем же тогда говорит PVS-Studio? Давайте углубимся во внутренние механизмы анализатора и попробуем разобраться.

В статическом анализаторе за вычисление таких выражений отвечает механизм анализа потока данных.

В большинстве случаев, когда выражение состоит из констант времени компиляции, поток данных вернет строгое значение выражения.

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

В этом случае значение операнда стрлен (a.consoleText) неизвестный нам на этапе компиляции.

Давайте посмотрим ассортимент. После нескольких минут отладки получаем из data-flow целых 2 диапазона:

[0, 507] U [0xFFFFFFFFFFFFFFFC, 0xFFFFFFFFFFFFFFFF]

На первый взгляд кажется, что второй диапазон лишний.

Однако это не так.

Мы просто забыли, что результатом выражения может быть отрицательное число.

Например, это может произойти, когда стрлен(a.consoleText) = 508 .

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

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

Причина неожиданного предупреждения в том, что ложного срабатывания здесь нет! Так мы в очередной раз получили подтверждение, что ключевое преимущество статического анализа перед человеком — его внимательность.

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

Если вы хотите поделиться этой статьей с англоязычной аудиторией, воспользуйтесь ссылкой для перевода: Владислав Столяров.

Один день из жизни разработчика PVS-Studio, или Как я отладил диагностику, превзошедшую трех программистов .

Теги: #c++ #C++ #статический анализ кода #статический анализ #статический анализ #ложное срабатывание #статический анализатор #статический анализатор #strncat

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.