PVS-Studio on nüüd Chocolatey: Chocolatey kontrollimine Azure DevOpsist

PVS-Studio on nüüd Chocolatey: Chocolatey kontrollimine Azure DevOpsist
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:

PVS-Studio — 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 artiklit kuidas kiiresti vaadata läbi kõige huvitavamad PVS-Studio hoiatused ja hinnata selle tööriista võimalusi.

Azure DevOps'is — 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.

Chocolatey – 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 lingil. Täielik dokumentatsioon analüsaatori installimise kohta on saadaval lingil peatükis "Installimine Chocolatey paketihalduri abil". Kordan sealt mõned punktid.

Viimane versioon analüsaatori installimise käsk:

choco install pvs-studio

Käsk kindla PVS-Studio versiooni installimiseks:

choco install pvs-studio --version=7.05.35617.2075

Vaikimisi 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 artikkel. Meie seadistamine algab kohe konfiguratsioonifaili kirjutamisest.

Alustame käivitustrigri seadistamisest, märkides, et viime käivitamise ellu ainult muudatuste jaoks master harus:

trigger:
- master

Seejä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 lingil. 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.

PVS-Studio on nüüd Chocolatey: Chocolatey kontrollimine Azure DevOpsist

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

PVS-Studio on nüüd Chocolatey: Chocolatey kontrollimine Azure DevOpsist

Pärast õnnestunud installimist vajutame Proceed to organization:

PVS-Studio on nüüd Chocolatey: Chocolatey kontrollimine Azure DevOpsist

Nüüd saab näha Chocolatey ülesande malli konfiguratsioonifaili tasks redigeerimisel azure-pipelines.yml:

PVS-Studio on nüüd Chocolatey: Chocolatey kontrollimine Azure DevOpsist

Vajutame Chocolateyle ja näeme väljade loendit:

PVS-Studio on nüüd Chocolatey: Chocolatey kontrollimine Azure DevOpsist

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 и 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.bat

Loome kausta, kuhu analüsaatori töö tulemused paigutatakse:

call mkdir PVSTestResults

Kä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.plog

Nüü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.

PVS-Studio on nüüd Chocolatey: Chocolatey kontrollimine Azure DevOpsist

Chocolatey projekt sisaldab kokku 37615 realist C# koodi. Vaadakem mõningaid leitud vigu.

Kontrollimise tulemused

Hoiatus N1

Analüsaatori hoiatamine: V3005 '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: V3093 [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, mis tuvastati V3093 diagnostika abil, 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: V3022 [CWE-571] Avaldis ‘shortPrompt’ on alati tõene. InteractivePrompt.cs 101
Analüsaatori hoiatamine: V3022 [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: V3123 [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: V3022 [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: V3001 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 "Viimase rea efekt".

Hoiatus N8

Analüsaatori hoiatamine: V3095 [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 alla laadida ja proovida PVS-Studio. Regulaarne staatilise analüsaatori kasutamine parandab teie meeskonna arendatava koodi kvaliteeti ja usaldusväärsust ning aitab ennetada paljusid nullpunktilugeja haavatavusi.

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'.

PVS-Studio on nüüd Chocolatey: Chocolatey kontrollimine Azure DevOpsist

Kui soovite seda artiklit ingliskeelse publikuga jagada, siis palun kasutage tõlke linki: Vladislav Stolyarov. PVS-Studio on nüüd Chocolatey: kontrollime Chocolateyd Azure DevOpsis.

Allikas: habr.com

Купить надежный хостинг для сайтов с защитой от DDoS, VPS VDS серверы 🔥 Купить надежный хостинг для сайтов с защитой от DDoS, VPS VDS серверы | ProHoster