
Vi fortsÊtter med at gÞre brug af PVS-Studio mere bekvemt. Nu er vores analyser tilgÊngelige pÄ Chocolatey, en pakkeadministrator til Windows. Vi mener, at dette vil lette implementeringen af PVS-Studio, isÊr i cloud-tjenester. For ikke at gÄ for langt, lad os tjekke koden fra det samme Chocolatey. Azure DevOps vil fungere som CI-system.
Her er en liste over vores andre artikler om integration med cloud-systemer:
Jeg anbefaler at tage et kig pÄ den fÞrste artikel om integration med Azure DevOps, da nogle punkter er udeladt for ikke at duplikere.
SĂ„ heltene i denne artikel er:
â et vĂŠrktĂžj til statisk kodeanalyse designet til at opdage fejl og potentielle sĂ„rbarheder i programmer skrevet i C, C++, C# og Java. Det fungerer i 64-bit systemer pĂ„ Windows, Linux og macOS og kan analysere kode beregnet til 32-bit, 64-bit og indlejrede ARM-platforme. Hvis du prĂžver statisk kodeanalyse for fĂžrste gang for at teste dine projekter, anbefaler vi at lĂŠse om hvordan man hurtigt kan se de mest interessante advarsler fra PVS-Studio og vurdere mulighederne for dette vĂŠrktĂžj.
â en rĂŠkke cloud-tjenester, der dĂŠkker hele udviklingsprocessen. Platformen omfatter vĂŠrktĂžjer som Azure Pipelines, Azure Boards, Azure Artifacts, Azure Repos, Azure Test Plans, som gĂžr det muligt at fremskynde softwareudviklingsprocessen og forbedre kvaliteten.
â en open source pakkeadministrator til Windows. Projektets mĂ„l er at automatisere hele livscyklussen for software fra installation til opdatering og sletning i Windows-operativsystemer.
Om brugen af Chocolatey
Du kan finde ud af, hvordan du installerer selve pakkeadministratoren, via denne . Den fulde dokumentation til installation af analysatoren er tilgĂŠngelig under afsnittet 'Installation ved hjĂŠlp af Chocolatey pakkeadministrator'. Jeg vil kort gentage nogle punkter derfra.
Kommandoen til at installere den seneste version af analysatoren:
choco install pvs-studioKommandoen til at installere en specifik version af PVS-Studio-pakken:
choco install pvs-studio --version=7.05.35617.2075Som standard installeres kun kernen af analysatoren - komponenten Core. Alle andre flag (Standalone, JavaCore, IDEA, MSVS2010, MSVS2012, MSVS2013, MSVS2015, MSVS2017, MSVS2019) kan overfĂžres ved hjĂŠlp af --package-parameters.
Eksempel pÄ en kommando, der installerer analysatoren med et plugin til Visual Studio 2019:
choco install pvs-studio --package-parameters="'/MSVS2019'"Lad os nu se pÄ et eksempel pÄ, hvordan man praktisk bruger analysatoren under Azure DevOps.
Indstillinger
Jeg minder om, at der er en separat guide til emner som registrering af en konto, oprettelse af Build Pipeline og synkronisering af kontoen med et projekt, der ligger i et repository pÄ GitHub. . Vores opsÊtning vil dog straks begynde med at skrive konfigurationsfilen.
For at starte skal vi konfigurere en starttrigger ved at angive, at vi kun udfĂžrer kĂžrsel for ĂŠndringer i master branch:
trigger:
- masterDernĂŠst skal vi vĂŠlge en virtuel maskine. PĂ„ nuvĂŠrende tidspunkt vil det vĂŠre en Microsoft-hosted agent med Windows Server 2019 og Visual Studio 2019:
pool:
vmImage: 'windows-latest'Lad os gÄ videre til brÞdteksten i konfigurationsfilen (blok steps). Selvom vi ikke kan installere vilkÄrlig software pÄ den virtuelle maskine, tilfÞjede jeg ikke en Docker-container. Vi kan tilfÞje Chocolatey som en udvidelse til Azure DevOps. For at gÞre dette gÄr vi til . Klikker pÄ Get it free. Hvis du allerede er logget ind, vÊlger du blot din konto; hvis ikke, sÄ fÞlger du de samme trin efter login.

Her skal du vÊlge, hvor vi skal tilfÞje udvidelsen, og klikke pÄ knappen Installer.

Efter en vellykket installation klikker vi pÄ Proceed to organization:

Nu kan vi se skabelonen til Chocolatey-opgaven i vinduet tasks ved redigering af konfigurationsfilen azure-pipelines.yml:

Klik pÄ Chocolatey og se listen over felter:

Her skal vi vĂŠlge installation i feltet med kommandoer. I Nuspec File Name angiver vi navnet pĂ„ den Ăžnskede pakke â pvs-studio. Hvis vi ikke angiver en version, installeres den seneste, hvilket er helt fint for os. Klik pĂ„ knappen add og vi vil se den dannede opgave i konfigurationsfilen.
steps:
- task: ChocolateyCommand@0
inputs:
command: 'install'
installPackageId: 'pvs-studio'Lad os derefter gÄ videre til hoveddelen af vores fil:
- task: CmdLine@2
inputs:
script: Nu skal vi oprette en fil med licensen til analysatoren. Her PVSNAME og PVSKEY â er navnene pĂ„ variablerne, hvis vĂŠrdier vi angiver i indstillingerne. De vil gemme login og licensnĂžgle til PVS-Studio. For at angive deres vĂŠrdier Ă„bner vi menuen Variables->New variable. Vi opretter variabler PVSNAME for login og PVSKEY for analyzer key. Donât forget to check the box Hold this value confidential for PVSKEY. Command code:
call "C:Program Files (x86)PVS-StudioPVS-Studio_Cmd.exe" credentials
âu $(PVSNAME) ân $(PVSKEY)We will build the project using the bat file available in the repository:
call build.batLetâs create a folder where the analyzer results will be stored:
call mkdir PVSTestResultsWe will start the project analysis:
call "C:Program Files (x86)PVS-StudioPVS-Studio_Cmd.exe"
ât .srcchocolatey.sln âo .PVSTestResultsChoco.plog We will convert our report to HTML format using the PlogConverter utility:
call "C:Program Files (x86)PVS-StudioPlogConverter.exe"
ât html âo PVSTestResults .PVSTestResultsChoco.plogNow we need to create a task to upload the report.
- task: PublishBuildArtifacts@1
inputs:
pathToPublish: PVSTestResults
artifactName: PVSTestResults
condition: always()The complete configuration file looks like this:
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()Letâs press Save->Save->Run to trigger the task. We will upload the report by going to the task tab.
The Chocolatey project contains a total of 37615 lines of C# code. Letâs take a look at some of the identified errors.
Analysis results
Warning N1
Analyzer warning: The âProviderâ variable is assigned to itself. CryptoHashProviderSpecs.cs 38
public abstract class CrytpoHashProviderSpecsBase : TinySpec
{
....
protected CryptoHashProvider Provider;
....
public override void Context()
{
Provider = Provider = new CryptoHashProvider(FileSystem.Object);
}
}The analyzer detected that a variable is assigned to itself, which makes no sense. Most likely, one of these variables should be something else. Or it's a typo and the redundant assignment can simply be removed.
Warning N2
Analyzer warning: [CWE-480] The â&â operator evaluates both operands. Perhaps a short-circuit â&&â operator should be used instead. 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;
}
}The distinction of the operator & from the operator && handler om, at hvis venstre del af udtrykket â false, vil den hĂžjre del stadig blive beregnet, hvilket i dette tilfĂŠlde indebĂŠrer unĂždvendige metodekald system.directory_exists.
I det behandlede fragment er dette en lille fejl. Ja, denne betingelse kan optimeres ved at erstatte operatoren & med operatoren &&, men fra et praktisk synspunkt har det ingen indflydelse. Imidlertid kan forvirringen mellem & og && i andre tilfÊlde forÄrsage alvorlige problemer, nÄr hÞjre del af udtrykket arbejder med ugyldige/ulovlige vÊrdier. For eksempel, i vores fejlsamling, , er der et sÄdant tilfÊlde:
if ((k < nct) & (s[k] != 0.0))Selv hvis indekset k er ugyldigt, vil det stadig blive brugt til at tilgÄ elementet i arrayet. Resultatet vil vÊre, at der genereres en undtagelse IndexOutOfRangeException.
Advarsler N3, N4
Analyzer warning: [CWE-571] Udtryk âshortPromptâ er altid sandt. InteractivePrompt.cs 101
Analyzer warning: [CWE-571] Udtryk âshortPromptâ er altid sandt. 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
....
}
....
}I dette tilfÊlde er der en underlig logik i den ternÊre operator. Lad os se nÊrmere pÄ det: hvis betingelsen markeret med nummer 1 opfyldes, vil vi gÄ til betingelsen 2, som altid true, hvilket betyder, at linje 3 vil blive udfÞrt. Hvis betingelse 1 viser sig at vÊre falsk, gÄr vi til linjen markeret med nummer 4, hvor betingelsen ogsÄ altid true, hvilket betyder, at linje 5 ogsÄ vil blive udfÞrt. Dermed vil betingelserne markeret med kommentar 0 aldrig blive udfÞrt, hvilket kan vÊre en uventet logik, som programmÞren ikke havde forudset.
Advarsel N5
Analyzer warning: [CWE-783] MĂ„ske fungerer â?:â operatoren pĂ„ en anden mĂ„de, end forventet. Dens prioritet er lavere end prioriteten af andre operatorer i sin betingelse. 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);
}
}Diagnose blev udlÞst pÄ linje:
while (start >= 0 && j != 0 ? description [j++ - 1] == '{' : false)Da variablen j initialiseres til nul flere linjer ovenfor, vil den ternÊre operator returnere vÊrdien false. PÄ grund af denne betingelse vil lÞkkens krop kun blive udfÞrt én gang. Jeg mener, at denne kodefragments funktionalitet ikke fungerer som programmereren mente.
Advarsel N6
Analyzer warning: [CWE-571] Udtrykket âinstalledPackageVersions.Count != 1â er altid sandt. NugetService.cs 1405
private void remove_nuget_cache_for_package(....)
{
if (!config.AllVersions && installedPackageVersions.Count > 1)
{
const string allVersionsChoice = "Alle versioner";
if (installedPackageVersions.Count != 1)
{
choices.Add(allVersionsChoice);
}
....
}
....
}Her er en mÊrkelig indlejret betingelse: installedPackageVersions.Count != 1, som altid vil vÊre true. Ofte indikerer en sÄdan advarsel en logisk fejl i koden, i andre tilfÊlde blot en overflÞdig kontrol.
Advarsel N7
Analyzer warning: Der er identiske deludtryk âcommandArguments.contains("-apikey")â til venstre og til hĂžjre for '||'-operatoren. 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");
}Programmereren, der skrev dette kodefragment, har kopieret de sidste to linjer og glemt at redigere dem. Dette har medfÞrt, at brugere af Chocolatey har mistet muligheden for at anvende parameteren apikey pÄ et par andre mÄder. Tilsvarende til de ovenstÄende parametre kan jeg foreslÄ fÞlgende muligheder:
commandArguments.contains("-apikey=");
commandArguments.contains("-api-key=");Copy-paste fejl har en stor chance for at opstÄ fÞr eller senere i ethvert projekt med meget kildekode, og et af de bedste redskaber til at bekÊmpe dem er statisk analyse.
P.S. Og som altid har denne fejl tendens til at opstÄ i slutningen af en flerlinjede betingelse :). Se indlÊgget "".
Advarsel N8
Analyzer warning: [CWE-476] 'installedPackage'-objektet blev brugt, fĂžr det blev verificeret mod null. Tjek linjer: 910, 917. NugetService.cs 910
offentlig virtuel 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)
{
....
}
....
}Klassisk fejl: objektet bruges fĂžrst installedPackage og kontrolleres derefter for null. Denne diagnose indikerer et af to problemer i programmet: enten installedPackage er aldrig lig med null, hvilket er tvivlsomt, og sĂ„ er kontrolen overflĂždig, eller vi kan potentielt fĂ„ en alvorlig fejl i koden â et forsĂžg pĂ„ at tilgĂ„ en null reference.
Konklusion
Her har vi taget endnu et lille skridt â nu er det endnu nemmere og mere praktisk at bruge PVS-Studio. Jeg vil ogsĂ„ sige, at Chocolatey er en god pakkeadministrator med fĂ„ fejl i koden, som kunne vĂŠre endnu fĂŠrre ved brug af PVS-Studio.
Vi inviterer og til at prÞve PVS-Studio. RegelmÊssig brug af en statisk analysator vil forbedre kvaliteten og pÄlideligheden af den kode, dit team udvikler, og hjÊlpe med at forhindre mange .
P.S.
FĂžr offentliggĂžrelsen sendte vi artiklen til udviklerne af Chocolatey, og de modtog den godt. Der blev ikke fundet noget kritisk af os, men de kunne for eksempel lide den fejl, vi fandt, relateret til âapi-keyâ.
Hvis du Þnsker at dele denne artikel med et engelsktalende publikum, sÄ bedes du bruge linket til oversÊttelsen: Vladislav Stolyarov. .
Kilde: habr.com
