Вышел новый релиз PVS-Studio — 7.24. В нём мы улучшили анализ проектов на Unity, добавили новые возможности работы с файлами подавления (*.suppress), реализовали ряд диагностик и сделали многое другое. Подробности в этой заметке.

Улучшения анализа проектов на Unity
Для многих классов игрового движка Unity оператор ‘==’ перегружен особым образом. Наиболее интересной особенностью перегрузки является тот факт, что сравнение с null может вернуть true, даже если сравниваемая ссылка не является нулевой. Пример:
void Start() { GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Sphere); Instantiate(obj); if (obj == null) Debug.Log("obj == null before destroy"); DestroyImmediate(obj); if (obj == null) Debug.Log("obj == null after destroy"); if (ReferenceEquals(obj, null)) Debug.Log("obj is really null"); if (obj is null) Debug.Log("obj is really null 2"); }
Если вы работаете с Unity, то наверняка сможете сказать, что на экран консоли будет выведена единственная надпись: «obj == null after destroy». Всё потому, что оператор ‘==’ при сравнении с null возвращает true, если сравниваемый объект уничтожен.
Новая версия анализатора лучше понимает такие особенности. В первую очередь это позволяет убрать ложные срабатывания о разыменовании нулевых ссылок. Также теперь PVS-Studio отслеживает обращения к методам и свойствам потенциально уничтоженных объектов. Такие обращения могут приводить к выбрасыванию исключений, и для их поиска мы добавили отдельное правило V3188.
Мы планируем и дальше улучшать возможности анализа проектов, использующих Unity, дорабатывая имеющиеся механизмы и реализуя новые диагностики. Обязательно пишите нам если у вас есть идеи по поводу того, какие ошибки анализатору стоит находить в таких проектах.
Продвинутые механизмы работы с файлами подавления в Visual Studio
В плагине для Visual Studio был расширен интерфейс для работы с файлами подавления (*.suppress). Раньше предполагалось, что в проекте может быть только один suppress-файл. Теперь же к каждому проекту может относиться несколько файлов подавления.
Ниже перечислены несколько нововведений.
1) Можно добавлять предупреждения в конкретные suppress-файлы:

2) Можно выбирать suppress-файлы, предупреждения из которых будут отображены в таблице:

3) Подавленные предупреждения можно также перемещать между suppress-файлами:

Эти возможности позволяют реализовывать новые сценарии работы с файлами подавления. К примеру, можно использовать один suppress-файл для предупреждений, оставленных «на потом», и ещё один — для ложных срабатываний.
Подробнее с этими и другими возможностями вы можете ознакомиться в документации.
Новые возможности подавления предупреждений из командной строки
В утилитах PVS-Studio_Cmd.exe и pvs-studio-dotnet появился новый режим — suppression. С помощью него можно производить различные операции с файлами подавления (*.suppress).
К примеру, можно создать для каждого проекта из решения новый suppress-файл:
PVS-Studio_Cmd.exe suppression -m CreateEmptySuppressFiles ^ -t JulietTestSuite.sln ^ -P myPrefix%projName%myPostfix.suppress
В результате выполнения такой команды в каждый проект решения будет добавлен пустой suppress-файл, имя которого генерируется на основе имени соответствующего проекта.
Ещё одной интересной возможностью является подавление предупреждений, соответствующих определённым критериям:
PVS-Studio_Cmd.exe suppression -m Suppress ^ -t JulietTestSuite.sln ^ -P myPrefix%projName%myPostfix.suppress ^ -R JulietTestSuite.plog ^ --groups "GA:3|OWASP"
Указанная команда подавит предупреждения из отчёта JulietTestSuite.plog в suppress-файлы, соответствующие паттерну, переданному через параметр ‘-P’. При этом подавлены будут только предупреждения 3 уровня группы General Analysis и все предупреждения группы OWASP.
Таким же образом можно и «снять подавление» с определённых предупреждений — для этого в качестве значения параметра ‘-m’ необходимо передать ‘UnSuppress’.
Эти и другие возможности нового режима подробно описаны в документации.
Учёт оператора null-forgiving (‘!’) в C#
В C# 9 в язык добавили возможность условного разделения ссылочных типов на допускающие и не допускающие null. Подробности — в официальной документации.
Когда ссылочная переменная может иметь значение null, к имени его типа добавляется ‘?’. Если же в конкретной ситуации такое выражение точно не возвращает нулевую ссылку, разработчики могут использовать оператор null-forgiving (‘!’). Пример:
bool _returnText = false; void Foo() { _returnText = true; string value = GetText()!; _ = value.Length; } // may return null private string? GetText() { return _returnText ? "some text" : null; }
Метод GetText в некоторых обстоятельствах действительно может возвращать null, однако результат его вызова внутри Foo точно является строкой «some text». Пометив вызов с помощью постфиксного ‘!’, разработчик сообщает компилятору, что выражение не равно null.
Мы долго обдумывали необходимость учёта оператора null-forgiving при анализе. С одной стороны, он не даёт гарантий того, что выражение действительно не будет равно null. С другой — он является способом подавления ложных предупреждений компилятора о небезопасном разыменовании. Стоит ли ругаться там, где похожее предупреждение компилятора уже было подавлено?
В итоге анализатор всё же начал учитывать оператор null-forgiving при выдаче предупреждений. Теперь PVS-Studio не будет выдавать предупреждения о разыменовании потенциально нулевой ссылки, если выражение размечено с помощью ‘!’. Однако предупреждение всё же будет показано, если null является единственным возможным значением выражения.
Новые диагностики
C, C++
-
V1095. Usage of potential invalid handle. The value should be non-negative.
-
V1096. Variable with static storage duration is declared inside the inline function with external linkage. This may lead to ODR violation.
-
V1097. Line splice results in a character sequence that matches the syntax of a universal-character-name. Using this sequence lead to undefined behavior.
C#
-
V3187. Parts of an SQL query are not delimited by any separators or whitespaces. Executing this query may lead to an error.
-
V3188. The value of an expression is a potentially destroyed Unity object or null. Member invocation on this value may lead to an exception.
-
V3189. The assignment to a member of the readonly field will have no effect when the field is of a value type. Consider restricting the type parameter to reference types.
Личный кабинет пользователя
Недавно мы добавили на сайт возможность создавать свой аккаунт и заходить в свой личный кабинет. Кнопки регистрации/авторизации можно найти в шапке сайта, наведя курсор на иконку:

Личный кабинет позволяет:
-
просматривать список своих триальных ключей;
-
подписываться на комментарии к статьям;
-
получать оповещения об ответах на ваши комментарии;
-
настраивать подписки на рассылки о новых статьях и релизах.

В общем, приглашаю всех регистрироваться :).
Подробнее о личном кабинете можете прочитать в заметке.
Статьи
Для тех, кто пишет на C++:
Для тех, кто пишет на C#:
-
Зачем при изменении сборки менять её версию или как сломать Visual Studio одной командой
-
Парсинг string в enum ценой в 50 Гб: разбираем уязвимость CVE-2020-36620
-
Нужно ли проверять библиотеки перед их использованием? Разберём на примере MudBlazor
Разное:
**
Загрузить актуальную версию PVS-Studio можно здесь.
Если хотите получать пресс-релизы по почте, подписывайтесь на рассылку.
Если хотите поделиться этой статьей с англоязычной аудиторией, то прошу использовать ссылку на перевод: Nikita Lipilin. PVS-Studio 7.24: Unity, advanced warning suppression and much more.
ссылка на оригинал статьи https://habr.com/ru/articles/728882/
Добавить комментарий