Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо
to the top
>
>
>
Как PVS-Studio защищает от поспешных пр…

Как PVS-Studio защищает от поспешных правок кода, пример N3

16 Фев 2022

Продолжаем серию маленьких заметок про то, как анализатор PVS-Studio может быстро находить новые ошибки в коде. При условии, конечно, что он регулярно используется :). Итак, перед нами очередной баг в проекте Blender.

0922_Blender_prevents_rash_code_changes_N3_ru/image1.png

Ради развлечения я мониторю проект Blender. Каждый день мне приходит отчёт PVS-Studio с предупреждениями, относящимися к новому коду. Иногда какая-то ошибка мне нравится, и я пишу про неё. Именно этим я занимаюсь и сейчас :).

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

В этот раз моё внимание привлекло два предупреждения PVS-Studio, указывающих на одну строчку кода:

  • [CWE-480] V616: The 'OB_MODE_OBJECT' named constant with the value of 0 is used in the bitwise operation. transform_snap_object.c 480
  • [CWE-571] V560: A part of conditional expression is always true: !(base->object->mode & OB_MODE_OBJECT). transform_snap_object.c 480

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

if (is_object_active && !(base->object->mode & OB_MODE_OBJECT)) {

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

Чтобы понять, что код неверен, нужно посмотреть, как объявлена именованная константа в перечислении eObjectMode:

typedef enum eObjectMode {
  OB_MODE_OBJECT = 0,
  OB_MODE_EDIT = 1 << 0,
  OB_MODE_SCULPT = 1 << 1,
  OB_MODE_VERTEX_PAINT = 1 << 2,
  OB_MODE_WEIGHT_PAINT = 1 << 3,
  OB_MODE_TEXTURE_PAINT = 1 << 4,
  OB_MODE_PARTICLE_EDIT = 1 << 5,
  OB_MODE_POSE = 1 << 6,
  OB_MODE_EDIT_GPENCIL = 1 << 7,
  OB_MODE_PAINT_GPENCIL = 1 << 8,
  OB_MODE_SCULPT_GPENCIL = 1 << 9,
  OB_MODE_WEIGHT_GPENCIL = 1 << 10,
  OB_MODE_VERTEX_GPENCIL = 1 << 11,
} eObjectMode;

Итак, константа OB_MODE_OBJECT равна нулю! Ещё раз взглянем на условие:

if (is_object_active && !(base->object->mode & OB_MODE_OBJECT)) {

Получается, что результат операции "побитовый И" (&) всегда равен 0. Про это первое сообщение анализатора.

Применим к 0 оператор "!", и получается, что перед нами выражение:

if (is_object_active && true) {

Про то, что часть выражения всегда истинна, нам говорит уже второе предупреждение PVS-Studio.

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

if (is_object_active && base->object->mode != OB_MODE_OBJECT) {

Впрочем, я не уверен, так как не разбираюсь в исходном коде Blender. Задача анализатора – указать на ошибку, а что с ней делать, должен решать уже разработчик проекта.

Спасибо за внимание и подписывайтесь на мой Twitter: @Code_Analysis.

Дополнительные ссылки:

Популярные статьи по теме


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

Следующие комментарии next comments
close comment form
close form

Заполните форму в два простых шага ниже:

Ваши контактные данные:

Шаг 1
Поздравляем! У вас есть промокод!

Тип желаемой лицензии:

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

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

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

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

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

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


Если вы так и не получили ответ, пожалуйста, проверьте, отфильтровано ли письмо в одну из следующих стандартных папок:

  • Промоакции
  • Оповещения
  • Спам