Для получения триального ключа
заполните форму ниже
Team license
Enterprise license
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
RUB
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Бесплатная лицензия PVS-Studio для специалистов Microsoft MVP
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

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

Мне интересно попробовать плагин на:
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте папку
Spam/Junk и нажмите на письме кнопку "Не спам".
Так Вы не пропустите ответы от нашей команды.

>
>
>
Что скрывают в себе комментарии

Что скрывают в себе комментарии

20 Сен 2012

О пользе или вреде комментариев в коде программ много говорится и однозначного мнения так и не сформировалось. Однако мы решили посмотреть на них с другой стороны. Могут ли комментарии навести исследователя на скрытые ошибки в коде?

При изучении различных проектов на предмет ошибок, было замечено, что программисты иногда замечают дефекты, но не могут до конца разобраться в их причинах. Нередко подозрение падает на компилятор. Про этот эффект недавно писал мой коллега в статье "Во всём виноват компилятор". В результате, программист делает в коде подпорку и оставляет различные комментарии. Часто эти комментарии нецензурного характера.

Мы решили, что это интересная сфера для исследований. Просматривать файлы вручную или искать обычным поиском по одному слову это очень долгий и утомительный процесс. Была написана утилита, которая ищет в ".c" и ".cpp" файлах подозрительные комментарии, основываясь на своем словаре "подозрительных слов". Например, в словарь подозрительных слов попали: fuck, bug, stupid, compiler.

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

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

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

Но раз исследование проведено, мы решили поделиться парой примеров с вами.

Например, такой пример кода:

// Search for EOH (CRLFCRLF)
const char* pc = m_pStrBuffer;
int iMaxOff = m_iStrBuffSize - sizeof(DWORD);
for (int i = 0; i <= iMaxOff; i++) {
  if (*(DWORD*)(pc++) == 0x0A0D0A0D) {
    // VC-BUG?: '\r\n\r\n' results in 0x0A0D0A0D too,
    //although it should not!
    bFoundEOH = true;
    break;
  }
}

Как видно из комментария "// Search for EOH (CRLFCRLF)" хотели находить последовательность байт 0D,0A,0D,0A (CR == 0x0D, LF == 0x0A). Поскольку, байты располагаются в обратном порядке, константа для поиска равна 0x0A0D0A0D.

Видимо, это программа не очень успешно работает с иной последовательностью возвратов каретки и переносов строк. Это вызывает непонимание у автора, о чем говорит комментарий: " // VC-BUG?: '\r\n\r\n' results in 0x0A0D0A0D too, although it should not!". Так почему же алгоритм находит не только последовательность {0D,0A,0D,0A}, но и {0A,0D,0A,0D} ?

Всё очень просто. Алгоритм поиска движется в массиве по одному байту. Поэтому, если в программе встречается длинная последовательность вида {0A,0D,0A,0D,0A,0D,0A,...}, то алгоритм пропустит первый символ 0A и найдет дальше не то, что хотелось.

К сожалению при статическом анализе найти подобные дефекты невозможно.

Вот еще один пример странного кода :

TCHAR szCommand[_MAX_PATH * 2];
LPCTSTR lpsz = (LPCTSTR)GlobalLock(hData);
int commandLength = lstrlen(lpsz);
if (commandLength >= _countof(szCommand))
{
  // The command would be truncated.
  //This could be a security problem
  TRACE(_T("Warning: ........\n"));
  return 0;
}
// !!! MFC Bug Fix
_tcsncpy(szCommand, lpsz, _countof(szCommand) - 1);
szCommand[_countof(szCommand) - 1] = '\0';
// !!!

В данном случае "MFC Bug Fix" совершенно не соответсвует действительности, поскольку никакой ошибки в MFC здесь нет. Код не вызывает ошибок в таком виде, но возможно изначально было записано только: '_tcsncpy(szCommand, lpsz, _countof(szCommand) - 1);'. В таком случае ошибка действительно имела место быть. Но записать корректное копирование строк можно несколько короче:

_tcsncpy(szCommand, lpsz, _countof(szCommand));

Функции вида 'strncpy' сами добавляют завершающий нуль в конец строки, если строка источник не длиннее значения указанного в счетчике. А это именно так, так как выше есть соответствующая проверка. Случаи некорректного копирования строк в PVS-Studio уже успешно анализируются, поэтому ничего нового мы не узнали.

Заключение

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

  • написать простой синтаксический анализ для уменьшения нахождения "неинтересных" строк;
  • расширить словарь новыми выражениями.

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

Популярные статьи по теме
Интервью с Джейсоном Тернером, одним из ведущих подкаста "CppCast": история и причины закрытия проекта

Дата: 27 Сен 2022

Автор: Ульяна Гришина

В этой статье мы поговорим с Джейсоном Тернером, одним из основателей CppCast. CppCast – это первый С++ подкаст, основанный С++ разработчиками. Начиная с 2015 года каждую неделю на CppCast выходили п…
Боремся с 16-летним легаси-кодом, или исправляем C и C++ front-end в PVS-Studio

Дата: 22 Сен 2022

Автор: Сергей Ларин

В 2022 году статическому анализатору PVS-Studio для языков C и C++ исполняется 16 лет. Если бы анализатор был человеком, то он бы уже заканчивал школу. Это очень старый проект, и система типов в нем …
Как фидбек помог улучшить наш C++ квиз

Дата: 31 Авг 2022

Автор: Алексей Саркисов

Ранее в нашем блоге мы рассказывали о квизе для C++ разработчиков. С момента запуска мы тщательно собирали обратную связь. Часть из неё касалась ошибок в работе квиза, которые мы естественно решили и…
Концепция умного указателя static_ptr<T> в C++

Дата: 30 Авг 2022

Автор: Гость

В C++ есть несколько "умных указателей" – 'std::unique_ptr', 'std::shared_ptr', 'std::weak_ptr'.
"Так исторически сложилось", или за что разделили V512

Дата: 12 Авг 2022

Автор: Михаил Гельвих

Как говорится, в любом деле самое сложное — это начать. Так и мы, очень долго откладывали разделение диагностики V512, но время пришло. Ну а о причинах и последствиях этого решения можно прочитать в …

Комментарии (0)

Следующие комментарии
Unicorn with delicious cookie
Мы используем куки, чтобы пользоваться сайтом было удобно. Хотите узнать подробнее?
Принять