PVS-Studio er nu i Chocolatey: tjekker Chocolatey fra under Azure DevOps

PVS-Studio er nu i Chocolatey: tjekker Chocolatey fra under Azure DevOps
Vi fortsætter med at gøre brugen af ​​PVS-Studio mere bekvem. Vores analysator er nu tilgængelig i Chocolatey, en pakkehåndtering til Windows. Vi mener, at dette vil lette udrulningen af ​​PVS-Studio, især i cloud-tjenester. For ikke at gå langt, lad os tjekke kildekoden til den samme Chocolatey. Azure DevOps fungerer som et CI-system.

Her er en liste over vores andre artikler om emnet integration med cloud-systemer:

Jeg råder dig til at være opmærksom på den første artikel om integration med Azure DevOps, da nogle punkter i dette tilfælde er udeladt for ikke at blive duplikeret.

Så heltene i denne artikel:

PVS Studio er et statisk kodeanalyseværktøj designet til at identificere fejl og potentielle sårbarheder i programmer skrevet i C, C++, C# og Java. Kører på 64-bit Windows-, Linux- og macOS-systemer og kan analysere kode designet til 32-bit, 64-bit og indlejrede ARM-platforme. Hvis det er første gang, du prøver statisk kodeanalyse for at kontrollere dine projekter, anbefaler vi, at du gør dig bekendt med artikel om, hvordan du hurtigt får vist de mest interessante PVS-Studio-advarsler og evaluerer dette værktøjs muligheder.

Azure DevOps — et sæt cloudtjenester, der tilsammen dækker hele udviklingsprocessen. Denne platform inkluderer værktøjer såsom Azure Pipelines, Azure Boards, Azure Artifacts, Azure Repos, Azure Test Plans, som giver dig mulighed for at fremskynde processen med at skabe software og forbedre dens kvalitet.

chocolatey er en open source-pakkehåndtering til Windows. Målet med projektet er at automatisere hele softwarens livscyklus fra installation til opdatering og afinstallation på Windows-operativsystemer.

Om at bruge Chocolatey

Du kan se, hvordan du installerer selve pakkehåndteringen her link. Fuldstændig dokumentation for installation af analysatoren er tilgængelig på link Se afsnittet Installation ved hjælp af Chocolatey Package Manager. Jeg vil kort gentage nogle punkter derfra.

Kommando for at installere den seneste version af analysatoren:

choco install pvs-studio

Kommando til at installere en specifik version af PVS-Studio-pakken:

choco install pvs-studio --version=7.05.35617.2075

Som standard er det kun kernen i analysatoren, Core-komponenten, der er installeret. Alle andre flag (Standalone, JavaCore, IDEA, MSVS2010, MSVS2012, MSVS2013, MSVS2015, MSVS2017, MSVS2019) kan videregives ved hjælp af --package-parametre.

Et eksempel på en kommando, der installerer en analysator med et plugin til Visual Studio 2019:

choco install pvs-studio --package-parameters="'/MSVS2019'"

Lad os nu se på et eksempel på praktisk brug af analysatoren under Azure DevOps.

justering

Lad mig minde dig om, at der er en separat sektion om sådanne problemer som at registrere en konto, oprette en Build Pipeline og synkronisere din konto med et projekt placeret i GitHub-lageret. artiklen. Vores opsætning begynder straks med at skrive en konfigurationsfil.

Lad os først konfigurere en startudløser, der indikerer, at vi kun starter for ændringer i Master afdeling:

trigger:
- master

Dernæst skal vi vælge en virtuel maskine. Indtil videre vil det være en Microsoft-hostet agent med Windows Server 2019 og Visual Studio 2019:

pool:
  vmImage: 'windows-latest'

Lad os gå videre til brødteksten i konfigurationsfilen (blok trin). På trods af at du ikke kan installere vilkårlig software på en virtuel maskine, tilføjede jeg ikke en Docker-container. Vi kan tilføje Chocolatey som en udvidelse til Azure DevOps. For at gøre dette, lad os gå til link. Klik Få det gratis. Dernæst, hvis du allerede er autoriseret, skal du blot vælge din konto, og hvis ikke, så gør det samme efter autorisation.

PVS-Studio er nu i Chocolatey: tjekker Chocolatey fra under Azure DevOps

Her skal du vælge, hvor vi vil tilføje udvidelsen og klikke på knappen Installer.

PVS-Studio er nu i Chocolatey: tjekker Chocolatey fra under Azure DevOps

Efter vellykket installation, klik Fortsæt til organisation:

PVS-Studio er nu i Chocolatey: tjekker Chocolatey fra under Azure DevOps

Du kan nu se skabelonen til Chokoladeopgaven i vinduet opgaver når du redigerer en konfigurationsfil azure-pipelines.yml:

PVS-Studio er nu i Chocolatey: tjekker Chocolatey fra under Azure DevOps

Klik på Chokolade og se en liste over felter:

PVS-Studio er nu i Chocolatey: tjekker Chocolatey fra under Azure DevOps

Her skal vi vælge installere i marken med holdene. I Nuspec filnavn angiv navnet på den nødvendige pakke – pvs-studio. Hvis du ikke angiver versionen, vil den nyeste blive installeret, hvilket passer os fuldstændig. Lad os trykke på knappen tilføje og vi vil se den genererede 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 analysatorlicensen. Her PVSNAME и PVSKEY – navne på variabler, hvis værdier vi angiver i indstillingerne. De vil gemme PVS-Studio login og licensnøgle. Åbn menuen for at indstille deres værdier Variabler->Ny variabel. Lad os skabe variabler PVSNAME til login og PVSKEY for analysatornøglen. Glem ikke at markere boksen Hold denne værdi hemmelig for PVSKEY. Kommandokode:

сall "C:Program Files (x86)PVS-StudioPVS-Studio_Cmd.exe" credentials 
–u $(PVSNAME) –n $(PVSKEY)

Lad os bygge projektet ved hjælp af bat-filen, der er placeret i depotet:

сall build.bat

Lad os oprette en mappe, hvor filer med resultaterne af analysatoren vil blive gemt:

сall mkdir PVSTestResults

Lad os begynde at analysere projektet:

сall "C:Program Files (x86)PVS-StudioPVS-Studio_Cmd.exe" 
–t .srcchocolatey.sln –o .PVSTestResultsChoco.plog 

Vi konverterer vores rapport til html-format ved hjælp af PlogСonverter-værktøjet:

сall "C:Program Files (x86)PVS-StudioPlogConverter.exe" 
–t html –o PVSTestResults .PVSTestResultsChoco.plog

Nu skal du oprette en opgave, så du kan uploade rapporten.

- task: PublishBuildArtifacts@1
  inputs:
    pathToPublish: PVSTestResults
    artifactName: PVSTestResults
    condition: always()

Den komplette konfigurationsfil ser således ud:

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()

Lad os klikke Gem->Gem->Kør at køre opgaven. Lad os downloade rapporten ved at gå til fanen opgaver.

PVS-Studio er nu i Chocolatey: tjekker Chocolatey fra under Azure DevOps

Chocolatey-projektet indeholder kun 37615 linjer med C#-kode. Lad os se på nogle af de fundne fejl.

Test resultater

Advarsel N1

Analysator advarsel: V3005 Variablen 'Provider' er tildelt sig selv. CrytpoHashProviderSpecs.cs 38

public abstract class CrytpoHashProviderSpecsBase : TinySpec
{
  ....
  protected CryptoHashProvider Provider;
  ....
  public override void Context()
  {
    Provider = Provider = new CryptoHashProvider(FileSystem.Object);
  }
}

Analysatoren registrerede en tildeling af variablen til sig selv, hvilket ikke giver mening. Mest sandsynligt burde der være en anden i stedet for en af ​​disse variable. Nå, eller det er en tastefejl, og den ekstra opgave kan simpelthen fjernes.

Advarsel N2

Analysator advarsel: V3093 [CWE-480] '&'-operatoren evaluerer begge operander. Måske skal der bruges en kortslutnings-&&-operator i stedet for. 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;
  }
}

Operatørforskel & fra operatøren && er, at hvis venstre side af udtrykket er falsk, så vil højre side stadig blive beregnet, hvilket i dette tilfælde indebærer unødvendige metodekald system.directory_exists.

I det betragtede fragment er dette en mindre fejl. Ja, denne tilstand kan optimeres ved at erstatte &-operatøren med &&-operatøren, men fra et praktisk synspunkt påvirker dette ikke noget. Men i andre tilfælde kan forveksling mellem & og && give alvorlige problemer, når højre side af udtrykket behandles med forkerte/ugyldige værdier. I vores fejlsamling f.eks. identificeret ved hjælp af V3093-diagnostik, der er denne sag:

if ((k < nct) & (s[k] != 0.0))

Også selvom indekset k er forkert, vil det blive brugt til at få adgang til et array-element. Som følge heraf vil en undtagelse blive kastet IndeksOutOfRangeException.

Advarsler N3, N4

Analysator advarsel: V3022 [CWE-571] Udtrykket 'shortPrompt' er altid sandt. InteractivePrompt.cs 101
Analysator advarsel: V3022 [CWE-571] Udtrykket '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 mærkelig logik bag driften af ​​den ternære operatør. Lad os se nærmere: Hvis betingelsen, jeg har markeret med nummer 1, er opfyldt, så går vi videre til betingelse 2, som altid er sand, hvilket betyder at linje 3 vil blive udført. Hvis betingelse 1 viser sig at være falsk, så går vi til linjen markeret med nummer 4, hvor tilstanden også altid er sand, hvilket betyder, at linje 5 vil blive eksekveret. Betingelserne markeret med kommentar 0 vil således aldrig blive opfyldt, hvilket måske ikke er præcis den operationslogik, som programmøren forventede.

Advarsel N5

Analysator advarsel: V3123 [CWE-783] Måske fungerer '?:'-operatøren på en anden måde, end det var forventet. Dens prioritet er lavere end andre operatørers prioritet i dens tilstand. 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);
  }
}

Diagnostikken virkede for linjen:

while (start >= 0 && j != 0 ? description [j++ - 1] == '{' : false)

Siden variablen j et par linjer ovenfor initialiseres til nul, vil den ternære operator returnere værdien falsk. På grund af denne betingelse vil løkkens krop kun blive udført én gang. Det forekommer mig, at dette stykke kode slet ikke virker, som programmøren havde til hensigt.

Advarsel N6

Analysator advarsel: V3022 [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 = "All versions";
    if (installedPackageVersions.Count != 1)
    {
      choices.Add(allVersionsChoice);
    }
    ....
  }
  ....
}

Der er en mærkelig indlejret tilstand her: installedPackageVersions.Count != 1som altid vil være sand. Ofte indikerer en sådan advarsel en logisk fejl i koden, og i andre tilfælde indikerer den blot overflødig kontrol.

Advarsel N7

Analysator advarsel: V3001 Der er identiske underudtryk 'commandArguments.contains("-apikey")' til venstre og til højre for '||' operatør. 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");
}

Programmøren, der skrev denne sektion af kode, kopierede og indsatte de sidste to linjer og glemte at redigere dem. På grund af dette var Chocolatey-brugere ikke i stand til at anvende parameteren apikey et par måder mere. I lighed med parametrene ovenfor kan jeg tilbyde følgende muligheder:

commandArguments.contains("-apikey=");
commandArguments.contains("-api-key=");

Copy-paste fejl har en stor chance for at dukke op før eller siden i ethvert projekt med en stor mængde kildekode, og et af de bedste værktøjer til at bekæmpe dem er statisk analyse.

PS Og som altid har denne fejl en tendens til at dukke op i slutningen af ​​en tilstand med flere linjer :). Se publikation "Last line effekt".

Advarsel N8

Analysator advarsel: V3095 [CWE-476] 'installedPackage'-objektet blev brugt, før det blev verificeret mod null. Tjek linjer: 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)
  {
    ....
  }
  ....
}

Klassisk fejl: objekt først installeret pakke bruges og derefter kontrolleres for null. Denne diagnostik fortæller os om et af to problemer i programmet: enten installeret pakke aldrig lige null, hvilket er tvivlsomt, og så er kontrollen overflødig, eller vi kan potentielt få en alvorlig fejl i koden - et forsøg på at få adgang til en nul-reference.

Konklusion

Så vi har taget endnu et lille skridt - nu er det blevet endnu nemmere og mere bekvemt at bruge PVS-Studio. Jeg vil også gerne sige, at Chocolatey er en god pakkehåndtering med et lille antal fejl i koden, som kunne være endnu færre ved brug af PVS-Studio.

Vi inviterer dig скачать og prøv 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 nul dages sårbarheder.

PS

Inden udgivelsen sendte vi artiklen til Chocolatey-udviklerne, og de tog godt imod den. Vi fandt ikke noget kritisk, men de kunne for eksempel godt lide den fejl, vi fandt relateret til "api-key"-nøglen.

PVS-Studio er nu i Chocolatey: tjekker Chocolatey fra under Azure DevOps

Hvis du vil dele denne artikel med et engelsktalende publikum, så brug venligst oversættelseslinket: Vladislav Stolyarov. PVS-Studio er nu i Chocolatey: Checker Chocolatey under Azure DevOps.

Kilde: www.habr.com

Tilføj en kommentar