PVS-Studio on nyt Chocolateyssa: tarkista Chocolatey Azure DevOpsista

PVS-Studio on nyt Chocolateyssa: tarkista Chocolatey Azure DevOpsista
Jatkamme PVS-Studion käytön helpottamista. Analysaattorimme on nyt saatavilla Chocolateyssa, Windowsin pakettien hallinnassa. Uskomme, että tämä helpottaa PVS-Studion käyttöönottoa erityisesti pilvipalveluissa. Jotta ei mennä pitkälle, tarkistetaan saman Chocolateyn lähdekoodi. Azure DevOps toimii CI-järjestelmänä.

Tässä on luettelo muista pilvijärjestelmien integrointia käsittelevistä artikkeleistamme:

Suosittelen kiinnittämään huomiota ensimmäiseen artikkeliin integraatiosta Azure DevOpsiin, koska tässä tapauksessa joitain kohtia jätetään pois, jotta niitä ei kopioida.

Joten tämän artikkelin sankarit:

PVS-studio on staattinen koodianalyysityökalu, joka on suunniteltu tunnistamaan C-, C++-, C#- ja Java-kielillä kirjoitettujen ohjelmien virheet ja mahdolliset haavoittuvuudet. Toimii 64-bittisissä Windows-, Linux- ja macOS-järjestelmissä ja voi analysoida 32-bittisille, 64-bittisille ja sulautetuille ARM-alustoille suunniteltua koodia. Jos tämä on ensimmäinen kerta, kun yrität staattista koodianalyysiä tarkistaaksesi projektisi, suosittelemme, että tutustut siihen artikla kuinka nopeasti nähdä kiinnostavimmat PVS-Studion varoitukset ja arvioida tämän työkalun ominaisuuksia.

Azure DevOps — kokonaisuus pilvipalveluista, jotka kattavat yhdessä koko kehitysprosessin. Tämä alusta sisältää työkaluja, kuten Azure Pipelines, Azure Boards, Azure Artifacts, Azure Repos, Azure Test Plans, joiden avulla voit nopeuttaa ohjelmiston luontiprosessia ja parantaa sen laatua.

chocolatey on avoimen lähdekoodin pakettien hallinta Windowsille. Projektin tavoitteena on automatisoida ohjelmiston koko elinkaart asennuksesta päivitykseen ja asennuksen poistamiseen Windows-käyttöjärjestelmissä.

Tietoja Chocolateyn käytöstä

Näet kuinka itse paketinhallinta asennetaan tästä linkki. Täydelliset asiakirjat analysaattorin asennusta varten ovat saatavilla osoitteessa linkki Katso Asennus Chocolatey-paketinhallinnan avulla. Toistan lyhyesti muutamia kohtia sieltä.

Komento asentaa analysaattorin uusin versio:

choco install pvs-studio

Komento asentaa tietty versio PVS-Studio-paketista:

choco install pvs-studio --version=7.05.35617.2075

Oletusarvoisesti vain analysaattorin ydin, Core-komponentti, on asennettu. Kaikki muut liput (Standalone, JavaCore, IDEA, MSVS2010, MSVS2012, MSVS2013, MSVS2015, MSVS2017, MSVS2019) voidaan välittää käyttämällä --package-parameters.

Esimerkki komennosta, joka asentaa analysaattorin Visual Studio 2019:n laajennuksella:

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

Katsotaanpa nyt esimerkkiä Azure DevOpsin analysaattorin kätevästä käytöstä.

säätö

Haluan muistuttaa, että on erillinen osio sellaisista ongelmista kuin tilin rekisteröinti, Build Pipelinen luominen ja tilisi synkronointi GitHub-arkistossa sijaitsevan projektin kanssa. artikkeli. Asennus alkaa välittömästi määritystiedoston kirjoittamisella.

Määritetään ensin käynnistyslaukaisin, joka osoittaa, että käynnistämme vain muutoksia varten mestari haara:

trigger:
- master

Seuraavaksi meidän on valittava virtuaalikone. Toistaiseksi se on Microsoftin isännöimä agentti Windows Server 2019:n ja Visual Studio 2019:n kanssa:

pool:
  vmImage: 'windows-latest'

Siirrytään määritystiedoston runkoon (block vaiheet). Huolimatta siitä, että et voi asentaa mielivaltaisia ​​ohjelmistoja virtuaalikoneeseen, en lisännyt Docker-säilöä. Voimme lisätä Chocolateyn Azure DevOps -laajennukseksi. Tätä varten mennään kohtaan linkki. Klikkaus Saa se ilmaiseksi. Seuraavaksi, jos olet jo valtuutettu, valitse tilisi, ja jos ei, tee sama valtuutuksen jälkeen.

PVS-Studio on nyt Chocolateyssa: tarkista Chocolatey Azure DevOpsista

Täällä sinun on valittava, mihin laajennus lisätään, ja napsauta painiketta install.

PVS-Studio on nyt Chocolateyssa: tarkista Chocolatey Azure DevOpsista

Kun asennus on onnistunut, napsauta Siirry organisaatioon:

PVS-Studio on nyt Chocolateyssa: tarkista Chocolatey Azure DevOpsista

Näet nyt Chocolatey-tehtävän mallin ikkunassa tehtävät kun muokkaat asetustiedostoa azure-pipelines.yml:

PVS-Studio on nyt Chocolateyssa: tarkista Chocolatey Azure DevOpsista

Napsauta Chocolatey ja katso luettelo kentistä:

PVS-Studio on nyt Chocolateyssa: tarkista Chocolatey Azure DevOpsista

Tässä meidän on valittava asentaa kentällä joukkueiden kanssa. SISÄÄN Nuspec-tiedoston nimi ilmoita tarvittavan paketin nimi – pvs-studio. Jos et määritä versiota, asennetaan uusin, joka sopii meille täysin. Painamme nappia lisätä ja näemme luodun tehtävän asetustiedostossa.

steps:
- task: ChocolateyCommand@0
  inputs:
    command: 'install'
    installPackageId: 'pvs-studio'

Siirrytään seuraavaksi tiedostomme pääosaan:

- task: CmdLine@2
  inputs:
    script: 

Nyt meidän on luotava tiedosto analysaattorin lisenssillä. Tässä PVSNAME и PVSKEY – muuttujien nimet, joiden arvot määritämme asetuksissa. Ne tallentavat PVS-Studion kirjautumistunnuksen ja lisenssiavaimen. Voit asettaa niiden arvot avaamalla valikon Muuttujat-> Uusi muuttuja. Luodaan muuttujia PVSNAME kirjautumiseen ja PVSKEY analysaattorin avaimelle. Älä unohda valita valintaruutua Pidä tämä arvo salassa varten PVSKEY. Komentokoodi:

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

Rakennetaan projekti käyttämällä arkistossa olevaa bat-tiedostoa:

сall build.bat

Luodaan kansio, johon tallennetaan tiedostot analysaattorin tuloksista:

сall mkdir PVSTestResults

Aloitetaan projektin analysointi:

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

Muunnamme raportin html-muotoon käyttämällä PlogСonverter-apuohjelmaa:

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

Nyt sinun on luotava tehtävä, jotta voit ladata raportin.

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

Koko asetustiedosto näyttää tältä:

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

Napsautetaan Tallenna->Tallenna->Suorita suorittaaksesi tehtävän. Ladataan raportti siirtymällä Tehtävät-välilehteen.

PVS-Studio on nyt Chocolateyssa: tarkista Chocolatey Azure DevOpsista

Chocolatey-projekti sisältää vain 37615 riviä C#-koodia. Katsotaanpa joitain löydettyjä virheitä.

Testitulokset

Varoitus N1

Analysaattorin varoitus: V3005 'Provider'-muuttuja on määritetty itselleen. CrytpoHashProviderSpecs.cs 38

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

Analysaattori havaitsi muuttujan osoituksen itselleen, mikä ei ole järkevää. Todennäköisimmin yhden näistä muuttujista pitäisi olla jokin muu. No, tai tämä on kirjoitusvirhe, ja ylimääräinen tehtävä voidaan yksinkertaisesti poistaa.

Varoitus N2

Analysaattorin varoitus: V3093 [CWE-480] '&'-operaattori arvioi molemmat operandit. Ehkä sen sijaan tulisi käyttää oikosulkuoperaattoria '&&'. 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;
  }
}

Operaattorin ero & operaattorilta && on se, että jos lausekkeen vasen puoli on väärä, silloin oikea puoli lasketaan edelleen, mikä tarkoittaa tässä tapauksessa tarpeettomia menetelmäkutsuja system.directory_exists.

Tarkastetussa fragmentissa tämä on pieni virhe. Kyllä, tämä ehto voidaan optimoida korvaamalla &-operaattori &&-operaattorilla, mutta käytännön näkökulmasta tämä ei vaikuta mihinkään. Kuitenkin muissa tapauksissa sekavuus &:n ja &&:n välillä voi aiheuttaa vakavia ongelmia, kun lausekkeen oikeaa puolta käsitellään väärillä/virheellisillä arvoilla. Esimerkiksi virhekokoelmassamme tunnistettu käyttämällä V3093-diagnostiikkaa, on tämä tapaus:

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

Vaikka indeksi k on virheellinen, sitä käytetään taulukkoelementin käyttämiseen. Tämän seurauksena tehdään poikkeus IndexOutOfRangeException.

Varoitukset N3, N4

Analysaattorin varoitus: V3022 [CWE-571] Lauseke "shortPrompt" on aina tosi. InteractivePrompt.cs 101
Analysaattorin varoitus: V3022 [CWE-571] Lauseke "shortPrompt" on aina tosi. 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
    ....
  }
  ....
}

Tässä tapauksessa kolmioperaattorin toiminnan takana on outo logiikka. Katsotaanpa tarkemmin: jos ehto, jonka merkitsin numerolla 1, täyttyy, siirrytään ehtoon 2, joka on aina totta, eli suoritetaan rivi 3. Jos ehto 1 osoittautuu epätosi, siirrytään numerolla 4 merkitylle riville, jonka ehto on myös aina totta, mikä tarkoittaa, että suoritetaan rivi 5. Näin ollen kommentilla 0 merkityt ehdot eivät koskaan täyty, mikä ei välttämättä ole täsmälleen ohjelmoijan odottamaa toimintalogiikkaa.

Varoitus N5

Analysaattorin varoitus: V3123 [CWE-783] Ehkä '?:'-operaattori toimii eri tavalla kuin odotettiin. Sen prioriteetti on alhaisempi kuin muiden toimijoiden prioriteetti sen kunnossa. 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);
  }
}

Diagnoosi toimi linjalla:

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

Koska muuttuja j muutaman rivin yläpuolella alustetaan nollaan, kolmiosainen operaattori palauttaa arvon väärä. Tämän ehdon vuoksi silmukan runko suoritetaan vain kerran. Minusta näyttää siltä, ​​että tämä koodinpätkä ei toimi ollenkaan ohjelmoijan tarkoittamalla tavalla.

Varoitus N6

Analysaattorin varoitus: V3022 [CWE-571] Lauseke "installedPackageVersions.Count != 1" on aina tosi. 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);
    }
    ....
  }
  ....
}

Tässä on outo sisäkkäinen ehto: installPackageVersions.Count != 1joka tulee aina olemaan totta. Usein tällainen varoitus osoittaa loogisen virheen koodissa, ja muissa tapauksissa se tarkoittaa yksinkertaisesti ylimääräistä tarkistusta.

Varoitus N7

Analysaattorin varoitus: V3001 Kohteen '||' vasemmalla ja oikealla puolella on identtiset alilausekkeet 'commandArguments.contains("-apikey")'. operaattori. 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");
}

Ohjelmoija, joka kirjoitti tämän koodin osan, kopioi ja liitti kaksi viimeistä riviä ja unohti muokata niitä. Tämän vuoksi Chocolateyn käyttäjät eivät voineet käyttää parametria apikey pari tapaa lisää. Kuten yllä olevat parametrit, voin tarjota seuraavat vaihtoehdot:

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

Kopioi-liitä virheillä on suuri mahdollisuus ilmaantua ennemmin tai myöhemmin missä tahansa projektissa, jossa on paljon lähdekoodia, ja yksi parhaista työkaluista niiden torjumiseen on staattinen analyysi.

PS Ja kuten aina, tämä virhe ilmenee usein monirivisen ehdon lopussa :). Katso julkaisu "Viimeisen rivin vaikutus".

Varoitus N8

Analysaattorin varoitus: V3095 [CWE-476] InstalledPackage-objektia käytettiin ennen kuin se varmistettiin nollaa vastaan. Tarkistusrivit: 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)
  {
    ....
  }
  ....
}

Klassinen virhe: esine ensin asennettu paketti käytetään ja sen jälkeen tarkistetaan nolla. Tämä diagnostiikka kertoo meille yhdestä kahdesta ohjelman ongelmasta: joko asennettu paketti ei koskaan tasa-arvoista nolla, mikä on kyseenalaista, ja sitten tarkistus on tarpeeton, tai saatamme mahdollisesti saada vakavan virheen koodissa - yrityksen päästä käsiksi nollaviitteeseen.

Johtopäätös

Olemme siis ottaneet toisen pienen askeleen - nyt PVS-Studion käyttäminen on tullut entistä helpommaksi ja kätevämmäksi. Haluan myös sanoa, että Chocolatey on hyvä paketinhallinta, jolla on pieni määrä virheitä koodissa, joita voisi olla jopa vähemmän PVS-Studioa käytettäessä.

Kutsumme скачать ja kokeile PVS-Studiota. Staattisen analysaattorin säännöllinen käyttö parantaa tiimisi kehittämän koodin laatua ja luotettavuutta ja auttaa estämään monia nollapäivän haavoittuvuuksia.

PS.

Ennen julkaisua lähetimme artikkelin Chocolateyn kehittäjille, ja he ottivat sen hyvin vastaan. Emme löytäneet mitään kriittistä, mutta he esimerkiksi pitivät löytämämme "api-avain"-avaimeen liittyvästä bugista.

PVS-Studio on nyt Chocolateyssa: tarkista Chocolatey Azure DevOpsista

Jos haluat jakaa tämän artikkelin englanninkielisen yleisön kanssa, käytä käännöslinkkiä: Vladislav Stolyarov. PVS-Studio on nyt Chocolateyssa: Chocolateyn tarkistus Azure DevOpsissa.

Lähde: will.com

Lisää kommentti