ProHoster > PVS-Studio зараз у Chocolatey: праверка Chocolatey з-пад Azure DevOps
PVS-Studio зараз у Chocolatey: праверка Chocolatey з-пад Azure DevOps
Мы працягваем рабіць выкарыстанне PVS-Studio зручней. Цяпер наш аналізатар даступны ў Chocolatey, пакетным мэнэджэры для Windows. Мы лічым, што гэта аблегчыць разгортванне PVS-Studio, у прыватнасці, у хмарных сэрвісах. Каб не ісці далёка, праверым зыходны код усё таго ж Chocolatey. У якасці CI сістэмы выступіць Azure DevOps.
Вось спіс іншых нашых артыкулаў на тэму інтэграцыі з хмарнымі сістэмамі:
Раю звярнуць увагу на першы артыкул пра інтэграцыю з Azure DevOps, бо ў дадзеным выпадку некаторыя моманты апушчаны, каб не дубліравацца.
Такім чынам, героі дадзенага артыкула:
PVS-студыя - інструмент статычнага аналізу кода, прызначаны для выяўлення памылак і патэнцыйных уразлівасцяў у праграмах, напісаных на мовах З, C++, C# і Java. Працуе ў 64-бітных сістэмах на Windows, Linux і macOS, і можа аналізаваць код, прызначаны для 32-бітных, 64-бітных і ўбудавальных ARM платформаў. Калі вы ўпершыню будзеце спрабаваць статычны аналіз кода для праверкі сваіх праектаў, то рэкамендуемы азнаёміцца са артыкулам аб тым, як хутка паглядзець самыя цікавыя папярэджанні PVS-Studio і ацаніць магчымасці гэтай прылады.
Azure DevOps - Набор хмарных сэрвісаў, сумесна якія ахопліваюць увесь працэс распрацоўкі. У склад дадзенай платформы ўваходзяць такія прылады, як Azure Pipelines, Azure Boards, Azure Artifacts, Azure Repos, Azure Test Plans, якія дазваляюць паскорыць працэс стварэння праграмнага забеспячэння і павысіць яго якасць.
шакаладным - пакетны мэнэджар для Windows з адчыненым зыходным кодам. Мэта праекта - аўтаматызаваць увесь жыццёвы цыкл праграмнага забеспячэння ад усталёўкі да абнаўлення і выдаленні ў аперацыйных сістэмах Windows.
Аб выкарыстанні Chocolatey
Паглядзець, як усталяваць сам пакетны мэнэджар, вы можаце па гэтай спасылцы. Поўная дакументацыя па ўстаноўцы аналізатара даступна па спасылцы у раздзеле "Усталяванне з выкарыстаннем пакетнага мэнэджара Chocolatey". Сцісла паўтару некаторыя моманты адтуль.
Каманда для ўстаноўкі апошняй версіі аналізатара:
choco install pvs-studio
Каманда ўстаноўкі канкрэтнай версіі пакета PVS-Studio:
Па змаўчанні усталёўваецца толькі ядро аналізатара - кампанент Core. Усе астатнія сцягі (Standalone, JavaCore, IDEA, MSVS2010, MSVS2012, MSVS2013, MSVS2015, MSVS2017, MSVS2019) можна перадаць пры дапамозе -package-parameters.
Прыклад каманды, якая ўсталюе аналізатар з убудовай для Visual Studio 2019:
Цяпер паглядзім на прыклад зручнага выкарыстання аналізатара пад Azure DevOps.
Настройка
Нагадваю, што пра такія моманты, як рэгістрацыя ўліковага запісу, стварэнне Build Pipeline і сінхранізацыя ўліковага запісу з праектам, які ляжыць у рэпазітары на GitHub, ёсць асобная артыкул. Наша ж настройка адразу пачнецца з напісання канфігурацыйнага файла.
Для пачатку наладзім трыгер запуску, паказаўшы, што вырабляем запуск толькі для змен у майстар галінцы:
trigger:
- master
Далей нам трэба абраць віртуальную машыну. На дадзены момант гэта будзе Microsoft-hosted агент з Windows Server 2019 і Visual Studio 2019:
pool:
vmImage: 'windows-latest'
Пяройдзем да цела канфігурацыйнага файла (блок крокі). Нягледзячы на тое, што ў віртуальную машыну нельга ўсталяваць адвольнае ПЗ, я не стаў дадаваць Docker кантэйнер. Мы можам дадаць Chocolatey як пашырэнне для Azure DevOps. Для гэтага пяройдзем па спасылцы. Ціснем Атрымаць бясплатна. Далей, калі вы ўжо аўтарызаваны, проста выбіраем свой уліковы запіс, а калі не, то прарабляем усё тое ж самае пасля аўтарызацыі.
Тут трэба абраць, куды мы дадамо пашырэнне, і націснуць кнопку Усталёўваць.
Пасля шчаснай усталёўкі націснем Proceed to organization:
Цяпер можна ўбачыць шаблон для задачы Chocolatey у акне задачы пры рэдагаванні канфігурацыйнага файла azure-pipelines.yml:
Націснем на Chocolatey і ўбачым спіс палёў:
Тут нам трэба абраць ўсталёўваць у поле з камандамі. У Nuspec File Name пакажам назву патрэбнага пакета - pvs-studio. Калі не пазначыць версію, усталюецца апошняя, што нас цалкам задавальняе. Націснем на кнопку дадаваць і ўбачым якая сфармавалася задачу ў файле канфігурацыі.
Цяпер нам трэба стварыць файл з ліцэнзіяй аналізатара. Тут PVSNAME и PVSKEY – назвы зменных, значэнні якіх мы паказваем у настройках. Яны будуць захоўваць лагін і ліцэнзійны ключ PVS-Studio. Каб усталяваць іх значэння, адкрыем меню Variables->New variable. Створым зменныя PVSNAME для лагіна і PVSKEY для ключа аналізатара. Не забудзьцеся паставіць галачку Keep this value secret для PVSKEY. Код каманды:
Націснем Save->Save->Run для запуску задачы. Выгрузім справаздачу, зайшоўшы ва ўкладку задачы.
Праект Chocolatey змяшчае ўсяго 37615 радкоў C# кода. Разгледзім некаторыя са знойдзеных памылак.
Вынікі праверкі
Папярэджанне N1
Папярэджанне аналізатара: V3005 'Provider' variable з'яўляецца itself. CrytpoHashProviderSpecs.cs 38
public abstract class CrytpoHashProviderSpecsBase : TinySpec
{
....
protected CryptoHashProvider Provider;
....
public override void Context()
{
Provider = Provider = new CryptoHashProvider(FileSystem.Object);
}
}
Аналізатар выявіў прысвойванне зменнай самой сабе, што не мае сэнсу. Хутчэй за ўсё, на месцы адной з гэтых зменных павінна быць нейкая іншая. Ну ці гэта памылка друку, і лішняе прысвойванне можна проста выдаліць.
Папярэджанне N2
Папярэджанне аналізатара: V3093 [CWE-480] The '&' operator evaluates both operands. Perhaps a short-circuit '&&' абаронца павінен быць выкарыстаны. Platform.cs 64
Адрозненне аператара & ад аператара && заключаецца ў тым, што калі левая частка выразы ілжывы, то ўсё роўна будзе вылічана правая частка, што ў дадзеным выпадку мае на ўвазе лішнія выклікі метаду system.directory_exists.
У разгледжаным фрагменце гэта дробны недахоп. Так, дадзеную ўмову можна аптымізаваць, замяніўшы аператар & на аператар &&, але, з практычнага пункта гледжання, гэта ні на што не ўплывае. Аднак, у іншых выпадках блытаніна паміж & і && можа выклікаць сур'ёзныя праблемы, калі правая частка выразы будзе працаваць з некарэктнымі/недапушчальнымі значэння. Напрыклад, у нашай калекцыі памылак, выяўленых з дапамогай дыягностыкі V3093, ёсць вось такі выпадак:
if ((k < nct) & (s[k] != 0.0))
Нават калі індэкс k некарэктны, ён будзе выкарыстоўвацца для доступу да элемента масіва. У выніку будзе згенеравана выключэнне IndexOutOfRangeException.
У дадзеным выпадку мае быць дзіўная логіка працы тэрнарнага аператара. Разгледзім падрабязней: калі выканаецца ўмова, пазначанае мной лічбай 1, то мы пяройдзем да ўмовы 2, якое заўсёды праўда, а значыць выканаецца радок 3. Калі ж умова 1 апынецца ілжывым, то мы пяройдзем на радок, пазначаную лічбай 4, умова ў якой таксама заўсёды праўда, а значыць, выканаецца радок 5. Такім чынам, умовы, пазначаныя каментаром 0, ніколі не будуць выкананы, што можа з'яўляцца не зусім той логікай працы, на якую разлічваў праграміст.
Папярэджанне N5
Папярэджанне аналізатара: V3123 [CWE-783] Вырашыце, што '?:' абаронца працуе ў розных выпадках, калі ён быў выяўлены. Гэтая priorita з'яўляецца нізкай, а priority of other operators in its condition. Options.cs 1019
private static string GetArgumentName (...., string description)
{
string[] nameStart;
if (maxIndex == 1)
{
nameStart = new string[]{"{0:", "{"};
}
else
{
nameStart = new string[]{"{" + index + ":"};
}
for (int i = 0; i < nameStart.Length; ++i)
{
int start, j = 0;
do
{
start = description.IndexOf (nameStart [i], j);
}
while (start >= 0 && j != 0 ? description [j++ - 1] == '{' : false);
....
return maxIndex == 1 ? "VALUE" : "VALUE" + (index + 1);
}
}
Бо зменная j на некалькі радкоў вышэй ініцыялізуецца нулём, тэрнарны аператар верне значэнне ілжывы. З-за дадзенай умовы, цела цыклу выканаецца толькі адзін раз. Мне падаецца, што дадзены фрагмент кода працуе зусім не так, як задумваў праграміст.
private void remove_nuget_cache_for_package(....)
{
if (!config.AllVersions && installedPackageVersions.Count > 1)
{
const string allVersionsChoice = "All versions";
if (installedPackageVersions.Count != 1)
{
choices.Add(allVersionsChoice);
}
....
}
....
}
Тут дзіўная ўкладзеная ўмова: installedPackageVersions.Count != 1, якое заўсёды будзе праўда. Часта такое папярэджанне паказвае на лагічную памылку ў кодзе, а ў астатніх выпадках проста на залішнюю праверку.
Папярэджанне N7
Папярэджанне аналізатара: V3001 Ёсць падобныя sub-expressions 'commandArguments.contains("-apikey")' у левай і правы '||' operator. ArgumentsUtility.cs 42
Праграміст, які напісаў дадзены ўчастак кода, сабраў два апошнія радкі і забыўся іх адрэдагаваць. З-за гэтага карыстачы Chocolatey пазбавіліся магчымасці ўжыць параметр apikey яшчэ парай спосабаў. Аналагічна параметрам вышэй, магу прапанаваць такія варыянты:
Copy-paste памылкі маюць вялікі шанец рана ці позна з'явіцца ў любым праекце з вялікай колькасцю зыходнага кода, і адно з лепшых сродкаў барацьбы з імі - статычны аналіз.
PS І як заўсёды, гэтая памылка імкнецца з'явіцца ў канцы шматрадковай умовы :). Глядзіце публікацыю "Эфект апошняга радка".
Папярэджанне N8
Папярэджанне аналізатара: V3095 [CWE-476] 'installedPackage' аб'ект быў выкарыстаны перад тым, што ён быў зняволены да null. Check lines: 910, 917. NugetService.cs 910
public virtual ConcurrentDictionary<string, PackageResult> get_outdated(....)
{
....
var pinnedPackageResult = outdatedPackages.GetOrAdd(
packageName,
new PackageResult(installedPackage,
_fileSystem.combine_paths(
ApplicationParameters.PackagesLocation,
installedPackage.Id)));
....
if ( installedPackage != null
&& !string.IsNullOrWhiteSpace(installedPackage.Version.SpecialVersion)
&& !config.UpgradeCommand.ExcludePrerelease)
{
....
}
....
}
Класічная памылка: спачатку аб'ект installedPackage выкарыстоўваецца, а потым правяраецца на нуля. Дадзеная дыягностыка кажа нам аб адной з двух праблем у праграме: альбо installedPackage ніколі не роўны нуля, Што сумнеўна, і тады праверка залішняя, альбо мы патэнцыйна можам атрымаць сур'ёзную памылку ў кодзе – спробу доступу па нулявой спасылцы.
Заключэнне
Вось мы і прарабілі яшчэ адзін маленькі крок - зараз карыстацца PVS-Studio стала яшчэ прасцей і зручней. Таксама хачу сказаць, што Chocolatey - добры пакетны мэнэджар з невялікай колькасцю памылак у кодзе, якіх магло б стаць яшчэ менш пры выкарыстанні PVS-Studio.
Запрашаем спампаваць і паспрабаваць PVS-Studio. Рэгулярнае выкарыстанне статычнага аналізатара павысіць якасць і надзейнасць распрацоўванага вашай камандай кода і дапаможа прадухіліць шматлікія уразлівасці нулявога дня.
PS
Перад публікацыяй мы адправілі артыкул распрацоўшчыкам Сhocolatey, і яны добра яе прынялі. Нічога крытычнага намі знойдзена не было, але ім, напрыклад, спадабалася знойдзеная намі памылка, звязаная з ключом "api-key".