Для получения триального ключа
заполните форму ниже
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 уже успешно анализируются, поэтому ничего нового мы не узнали.

Заключение

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

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

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

Популярные статьи по теме
Как различить C и C++ разработчиков по их коду

Дата: 12 Май 2022

Автор: Гость

Так уж случилось, что я пишу код для разных IoT-железок, связанных с электричеством, типа зарядных станций автомобилей. Поскольку аппаратных ресурсов, как правило, вполне достаточно, то основным фоку…
Отладочный вывод на микроконтроллерах: как Concepts и Ranges отправили мой printf на покой

Дата: 06 Май 2022

Автор: Гость

Здравствуйте! Меня зовут Александр, и я работаю программистом микроконтроллеров.
Нереальный baselining или доработки PVS-Studio для Unreal Engine проектов

Дата: 26 Апр 2022

Автор: Валерий Комаров

Статический анализатор PVS-Studio постоянно развивается: улучшаются различные механизмы, происходит интеграция с игровыми движками, IDE, CI/CD и другими системами и сервисами. Благодаря этому несколь…
Разбор некоторых вредных советов для С++ программиста

Дата: 21 Апр 2022

Автор: Андрей Карпов

Юмор юмором, но осторожность не повредит. Вдруг кому-то не до конца понятно, почему какой-то из советов является вредным. Здесь можно найти соответствующие пояснения.
Четыре причины проверять, что вернула функция malloc

Дата: 20 Апр 2022

Автор: Андрей Карпов

Некоторые разработчики пренебрежительно относятся к проверкам: удалось ли выделить память с помощью функции malloc или нет. Их логика проста – памяти всегда должно хватить. А если не хватит, всё равн…

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

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