
Me jĂ€tkame PVS-Studio kasutamise mugavdamist. NĂŒĂŒd on meie analĂŒsaator saadaval Chocolateyâs, Windowsi paketihalduris. Usume, et see lihtsustab PVS-Studio pĂŒstitamist, eriti pilveteenustes. Et mitte liiga kaugele minna, vaatame ĂŒle sama Chocolatey lĂ€htekoodi. CI sĂŒsteemina kasutame Azure DevOps'i.
Siin on nimekiri teistest meie artiklitest, mis kĂ€sitlevad integreerimist pilvesĂŒsteemidega:
Soovitan tÀhelepanu pöörata esimesele artiklile Azure DevOps'i integreerimise kohta, kuna mÔned punktid on selles juhtumis vahele jÀetud, et mitte korduda.
Nii et selle artikli peategelased on:
â koodi staatilise analĂŒĂŒsi tööriist, mis on mĂ”eldud vigade ja potentsiaalsete haavatavuste tuvastamiseks C, C++, C# ja Java keeltes kirjutatud programmides. Töötab 64-bitiste sĂŒsteemidega Windowsis, Linuxis ja macOS-is ning suudab analĂŒĂŒsida koodi, mis on mĂ”eldud 32-bitiste, 64-bitiste ja sisseehitatud ARM platvormide jaoks. Kui proovite esmakordselt koodi staatilist analĂŒĂŒsi, soovitame tutvuda kuidas kiiresti vaadata lĂ€bi kĂ”ige huvitavamad PVS-Studio hoiatused ja hinnata selle tööriista vĂ”imalusi.
â pilveteenuste komplekt, mis katab kogu arendusprotsessi. Selle platvormi koosseisu kuuluvad tööriistad nagu Azure Pipelines, Azure Boards, Azure Artifacts, Azure Repos, Azure Test Plans, mis kiirendavad tarkvaraarenduse protsessi ja parandavad selle kvaliteeti.
â avatud lĂ€htekoodiga paketihaldur Windowsile. Projekti eesmĂ€rk on automatiseerida kogu tarkvara elutsĂŒkkel alates installimisest kuni uuendamise ja eemaldamiseni Windowsi operatsioonisĂŒsteemides.
Chocolatey kasutamisest
Vaadake, kuidas installida paketihaldur ise, saate seda teha . TĂ€ielik dokumentatsioon analĂŒsaatori installimise kohta on saadaval peatĂŒkis "Installimine Chocolatey paketihalduri abil". Kordan sealt mĂ”ned punktid.
Viimane versioon analĂŒsaatori installimise kĂ€sk:
choco install pvs-studioKĂ€sk kindla PVS-Studio versiooni installimiseks:
choco install pvs-studio --version=7.05.35617.2075Vaikimisi installitakse ainult analĂŒsaatori pÀÀsuosa - komponent Core. KĂ”iki teisi lippe (Standalone, JavaCore, IDEA, MSVS2010, MSVS2012, MSVS2013, MSVS2015, MSVS2017, MSVS2019) saab edastada kĂ€su kaudu âpackage-parameters.
NĂ€ide kĂ€sust, mis installib analĂŒsaatori koos pluginaga Visual Studio 2019 jaoks:
choco install pvs-studio --package-parameters="'/MSVS2019'"NĂŒĂŒd vaatame, kuidas analĂŒsaatorit mugavalt Azure DevOpsis kasutada.
Seadistamine
Tuletan meelde, et selliste asjade nagu konto registreerimine, Build Pipeline'i loomine ja konto sĂŒnkroniseerimine GitHubi repositooriumiga on eraldi . Meie seadistamine algab kohe konfiguratsioonifaili kirjutamisest.
Alustame kÀivitustrigri seadistamisest, mÀrkides, et viime kÀivitamise ellu ainult muudatuste jaoks master harus:
trigger:
- masterSeejÀrel peame valima virtuaalse masina. Praegu on see Microsofti hallatav agent, millel on Windows Server 2019 ja Visual Studio 2019:
pool:
vmImage: 'windows-latest'Liigume konfiguratsioonifaili kehale (plokk steps). Kuigi virtuaalsesse masinasse ei saa installida juhuslikku tarkvara, ei lisanud ma Docker konteinerit. Saame lisada Chocolatey Azure DevOpsi laiendusena. Selleks liikume . Vajutage Get it free. JÀrgnevalt, kui olete juba autentitud, valige lihtsalt oma konto; kui mitte, siis tehke kÔik see sama pÀrast autentimist.

Siin tuleb valida, kuhu me laienduse lisame, ja vajutada nuppu Installi.

PÀrast Ônnestunud installimist vajutame Proceed to organization:

NĂŒĂŒd saab nĂ€ha Chocolatey ĂŒlesande malli konfiguratsioonifaili tasks redigeerimisel azure-pipelines.yml:

Vajutame Chocolateyle ja nÀeme vÀljade loendit:

Siin peame valima install kĂ€skude vĂ€ljal. VĂ€ljas Nuspec File Name mĂ€rkime vajaliku paketi nime - pvs-studio. Kui versioon ei ole mĂ€rgitud, installitakse viimane, mis meile tĂ€ielikult sobib. Vajutage nuppu add ja nĂ€eme, kuidas ĂŒlesanne on konfiguratsioonifailis moodustatud.
steps:
- task: ChocolateyCommand@0
inputs:
command: 'install'
installPackageId: 'pvs-studio'SeejÀrel liigume faili pÔhiosasse:
- task: CmdLine@2
inputs:
script: NĂŒĂŒd peame looma analĂŒsaatori litsentsifaili. Siin PVSNAME ja PVSKEY on muutuja nimed, mille vÀÀrtused mĂ€rkime seadetesse. Need hoiavad PVS-Studio sisselogimise ja litsentsivĂ”tme. Nende vÀÀrtuste seadmiseks avage menĂŒĂŒ Variables->New variable. Loome muutujad PVSNAME sisselogimise jaoks ja PVSKEY analĂŒsaatori vĂ”ti. Ăra unusta linnukest teha Hoia see vÀÀrtus salajas jaoks PVSKEY. KĂ€skude kood:
call "C:Program Files (x86)PVS-StudioPVS-Studio_Cmd.exe" credentials
âu $(PVSNAME) ân $(PVSKEY)Kogume projekti bat-faili abil, mis asub hoidlas:
call build.batLoome kausta, kuhu analĂŒsaatori töö tulemused paigutatakse:
call mkdir PVSTestResultsKĂ€ivitame projekti analĂŒĂŒsi:
call "C:Program Files (x86)PVS-StudioPVS-Studio_Cmd.exe"
ât .srcchocolatey.sln âo .PVSTestResultsChoco.plog Konverteerime meie aruande html-formaati PlogConverter utiliidi abil:
call "C:Program Files (x86)PVS-StudioPlogConverter.exe"
ât html âo PVSTestResults .PVSTestResultsChoco.plogNĂŒĂŒd on vaja luua ĂŒlesanne, et aruannet eksportida.
- task: PublishBuildArtifacts@1
inputs:
pathToPublish: PVSTestResults
artifactName: PVSTestResults
condition: always()TÀielik konfiguratsioonifail nÀeb vÀlja selline:
trigger:
- master
pool:
vmImage: 'windows-latest'
steps:
- task: ChocolateyCommand@0
inputs:
command: 'install'
installPackageId: 'pvs-studio'
- task: CmdLine@2
inputs:
script: |
call "C:Program Files (x86)PVS-StudioPVS-Studio_Cmd.exe"
credentials âu $(PVSNAME) ân $(PVSKEY)
call build.bat
call mkdir PVSTestResults
call "C:Program Files (x86)PVS-StudioPVS-Studio_Cmd.exe"
ât .srcchocolatey.sln âo .PVSTestResultsChoco.plog
call "C:Program Files (x86)PVS-StudioPlogConverter.exe"
ât html âo .PVSTestResults .PVSTestResultsChoco.plog
- task: PublishBuildArtifacts@1
inputs:
pathToPublish: PVSTestResults
artifactName: PVSTestResults
condition: always()KlĂ”psame Salvesta->Salvesta->KĂ€ivita ĂŒlesande kĂ€ivitamiseks. Eksportime aruande, sisenedes ĂŒlesannete vahekaardile.
Chocolatey projekt sisaldab kokku 37615 realist C# koodi. Vaadakem mÔningaid leitud vigu.
Kontrollimise tulemused
Hoiatus N1
AnalĂŒsaatori hoiatamine: 'Provider' muutuja omistatakse iseendale. CrytpoHashProviderSpecs.cs 38
public abstract class CrytpoHashProviderSpecsBase : TinySpec
{
....
protected CryptoHashProvider Provider;
....
public override void Context()
{
Provider = Provider = new CryptoHashProvider(FileSystem.Object);
}
}AnalĂŒsaator leidis, et muutuja on omistatud iseendale, mis pole mĂ”istlik. TĂ”enĂ€oliselt ĂŒks neist muutujaist peaks olema mĂ”ni teine. VĂ”i on see trĂŒkiviga, ja ĂŒlearune omistamine tuleks lihtsalt eemaldada.
Hoiatus N2
AnalĂŒsaatori hoiatamine: [CWE-480] '&&' operaator hindab mĂ”lemat operandi. VĂ”ib-olla tuleks kasutada lĂŒhikest '&&' operaatorit. Platform.cs 64
public static PlatformType get_platform()
{
switch (Environment.OSVersion.Platform)
{
case PlatformID.MacOSX:
{
....
}
case PlatformID.Unix:
if(file_system.directory_exists("/Applications")
& file_system.directory_exists("/System")
& file_system.directory_exists("/Users")
& file_system.directory_exists("/Volumes"))
{
return PlatformType.Mac;
}
else
return PlatformType.Linux;
default:
return PlatformType.Windows;
}
}Operaatori erinevus & operaatorist && on selles, et kui vĂ€ljendi vasak pool â false, aga siiski arvutatakse parempoolne osa, mis sel juhul tĂ€hendab liigseid meetodi kutsungite tegemisi system.directory_exists.
Arutletud fragmendis on tegemist vÀikese puudusega. Jah, seda tingimust saab optimeerida, asendades operaatori & operaatoriga &&, kuid praktiliselt ei oma see mingit mÔju. Siiski vÔivad teistes olukordades segadused & ja && vahel pÔhjustada tÔsiseid probleeme, kui parempoolne osa avaldist kÀitab vale/keelatud vÀÀrtusi. NÀiteks meie vigade kogumis, , on selline juhtum:
if ((k < nct) & (s[k] != 0.0))Isegi kui indeks k on vale, kasutatakse seda massiivi elemendile juurde pÀÀsemiseks. Tulemuseks on erandi genereerimine IndexOutOfRangeException.
Hoiatuse N3, N4
AnalĂŒsaatori hoiatamine: [CWE-571] Avaldis âshortPromptâ on alati tĂ”ene. InteractivePrompt.cs 101
AnalĂŒsaatori hoiatamine: [CWE-571] Avaldis âshortPromptâ on alati tĂ”ene. InteractivePrompt.cs 105
public static string
prompt_for_confirmation(.... bool shortPrompt = false, ....)
{
....
if (shortPrompt)
{
var choicePrompt = choice.is_equal_to(defaultChoice) \/\/1
?
shortPrompt \/\/2
?
"[[{0}]{1}]".format_with(choice.Substring(0, 1).ToUpperInvariant(), \/\/3
choice.Substring(1,choice.Length - 1))
:
"[{0}]".format_with(choice.ToUpperInvariant()) \/\/0
:
shortPrompt \/\/4
?
"[{0}]{1}".format_with(choice.Substring(0,1).ToUpperInvariant(), \/\/5
choice.Substring(1,choice.Length - 1))
:
choice; \/\/0
....
}
....
}Selles olukorras on tegemist kummalise loogika ternaarset operaatorit. Vaatame lÀhemalt: kui tingimus, mille mÀrgistasin numbriga 1, kehtib, siis liigume tingimusele 2, mis on alati true, seega toimub rida 3. Kui tingimus 1 on vale, liigume rida, millel on numbriga 4, tingimusele, mis on samuti alati true, seega toimub rida 5. Seega ei toimu kunagi tingimused, millel on kommentaar 0, mis ei pruugi olla see loogika, millele programmeerija lootis.
Hoiatus N5
AnalĂŒsaatori hoiatamine: [CWE-783] VĂ”ib-olla töötab â?:â operaator erinevalt, kui oodata. Selle prioriteet on madalam kui teiste operaatorite oma tingimuses. 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 = 0 && j != 0 ? description [j++ - 1] == '{' : false);
....
return maxIndex == 1 ? "VALUE" : "VALUE" + (index + 1);
}
}Diagnostika reageeris reale:
while (start >= 0 && j != 0 ? description [j++ - 1] == '{' : false)Kuna muutuja j Ălesande alguses initsialiseeritakse see nulliga, seega tagastab ternaarne operaator vÀÀrtuse. false. Antud tingimuse tĂ”ttu tĂ€idetakse tsĂŒkkel ainult ĂŒhe korra. Minu arvates töötab see koodifragmendi osa hoopis teisiti, kui programmist on soovitud.
Hoiatus N6
AnalĂŒsaatori hoiatamine: [CWE-571] Avaldis 'installedPackageVersions.Count != 1' on alati tĂ”ene. NugetService.cs 1405
private void remove_nuget_cache_for_package(....)
{
if (!config.AllVersions && installedPackageVersions.Count > 1)
{
const string allVersionsChoice = "KÔik versioonid";
if (installedPackageVersions.Count != 1)
{
choices.Add(allVersionsChoice);
}
....
}
....
}Siin on kummaline sise-tingimus: installedPackageVersions.Count != 1, mis on alati tÔene true. Sellised hoiatused viitavad sageli loogilisele veale koodis vÔi nÀitavad muidu liigset kontrollimist.
Hoiatus N7
AnalĂŒsaatori hoiatamine: Avaldil on identseid alammeetodeid 'commandArguments.contains("-apikey")' vasakul ja paremal pool '||' operaatorit. ArgumentsUtility.cs 42
public static bool arguments_contain_sensitive_information(string
commandArguments)
{
return commandArguments.contains("-install-arguments-sensitive")
|| commandArguments.contains("-package-parameters-sensitive")
|| commandArguments.contains("apikey ")
|| commandArguments.contains("config ")
|| commandArguments.contains("push ")
|| commandArguments.contains("-p ")
|| commandArguments.contains("-p=")
|| commandArguments.contains("-password")
|| commandArguments.contains("-cp ")
|| commandArguments.contains("-cp=")
|| commandArguments.contains("-certpassword")
|| commandArguments.contains("-k ")
|| commandArguments.contains("-k=")
|| commandArguments.contains("-key ")
|| commandArguments.contains("-key=")
|| commandArguments.contains("-apikey")
|| commandArguments.contains("-api-key")
|| commandArguments.contains("-apikey")
|| commandArguments.contains("-api-key");
}Programmeerija, kes kirjutas selle koodilĂ”igu, kopeeris kaks viimast rida ja unustas need muuta. Sel pĂ”hjusel kaotasid Chocolatey kasutajad vĂ”imaluse kasutada parameetrit apikey veel mĂ”ningate muude viisidega. Sarnaselt ĂŒlaltoodud parameetritele, vĂ”in soovitada jĂ€rgmisi variante:
commandArguments.contains("-apikey=");
commandArguments.contains("-api-key=");Kopeerimise ja kleepimise vead vĂ”ivad igasugustes suurtes projektides esineda varem vĂ”i hiljem ning ĂŒks parimaid meetodeid nende vastu on staatiline analĂŒĂŒs.
P.S. Ja nagu alati, leiab see viga sageli aset pika tingimuse lÔpus :). Vaata postitust "".
Hoiatus N8
AnalĂŒsaatori hoiatamine: [CWE-476] 'installedPackage' objekti kasutati enne, kui see kontrolliti nulli suhtes. Kontrollige ridu: 910, 917. NugetService.cs 910
public virtual ConcurrentDictionary 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)
{
....
}
....
}Klassikaline viga: alguses kasutatakse objekti installedPackage ja seejĂ€rel kontrollitakse seda null. See diagnostika viitab kahesugusele probleemile programmis: kas installedPackage ei ole kunagi vĂ”rdne null, mis on kaheldav, ning sel juhul on kontroll ĂŒleliigne, vĂ”i meil vĂ”ib potentsiaalselt tekkida tĂ”sine viga koodis â nullpointrike.
KokkuvÔte
NĂŒĂŒd oleme teinud veel ĂŒhe vĂ€ikese sammu â PVS-Studio kasutamine on muutunud veelgi lihtsamaks ja mugavamaks. Tahan ka öelda, et Chocolatey on hea pakihaldur, millel on vĂ€he koodivigu, kuid neid oleks vĂ”inud veelgi vĂ€hem olla, kui oleks kasutatud PVS-Studio.
Tere tulemast ja proovida PVS-Studio. Regulaarne staatilise analĂŒsaatori kasutamine parandab teie meeskonna arendatava koodi kvaliteeti ja usaldusvÀÀrsust ning aitab ennetada paljusid .
P.S.
Enne avaldamist saatsime artikli Chocolatey arendajatele ja nad vÔtsid selle hÀsti vastu. Meie poolt ei leitud midagi kriitilist, kuid neile meeldis nÀiteks leitud viga, mis oli seotud vÔtmega 'api-key'.
Kui soovite seda artiklit ingliskeelse publikuga jagada, siis palun kasutage tÔlke linki: Vladislav Stolyarov. .
Allikas: habr.com
