PVS-Studio je zdaj v Chocolatey: preverjanje Chocolatey iz Azure DevOps

PVS-Studio je zdaj v Chocolatey: preverjanje Chocolatey iz Azure DevOps
Še naprej delamo uporabo PVS-Studio bolj priročno. Naš analizator je zdaj na voljo v Chocolateyju, upravitelju paketov za Windows. Verjamemo, da bo to olajšalo uvedbo PVS-Studio, zlasti v storitvah v oblaku. Da ne bi šli daleč, preverimo izvorno kodo iste Chocolatey. Azure DevOps bo deloval kot sistem CI.

Tukaj je seznam naših drugih člankov na temo integracije s sistemi v oblaku:

Svetujem vam, da ste pozorni na prvi članek o integraciji z Azure DevOps, saj so v tem primeru nekatere točke izpuščene, da se ne podvajajo.

Torej, junaki tega članka:

PVS-Studio je orodje za analizo statične kode, zasnovano za prepoznavanje napak in potencialnih ranljivosti v programih, napisanih v C, C++, C# in Javi. Deluje v 64-bitnih sistemih Windows, Linux in macOS ter lahko analizira kodo, zasnovano za 32-bitne, 64-bitne in vdelane platforme ARM. Če prvič poskušate analizirati statično kodo za preverjanje svojih projektov, vam priporočamo, da se seznanite s tem Članek o tem, kako si hitro ogledati najbolj zanimiva opozorila PVS-Studio in oceniti zmogljivosti tega orodja.

Azure DevOps — nabor storitev v oblaku, ki skupaj pokrivajo celoten razvojni proces. Ta platforma vključuje orodja, kot so Azure Pipelines, Azure Boards, Azure Artifacts, Azure Repos, Azure Test Plans, ki vam omogočajo, da pospešite proces ustvarjanja programske opreme in izboljšate njeno kakovost.

Čokolada je odprtokodni upravitelj paketov za Windows. Cilj projekta je avtomatizirati celoten življenjski cikel programske opreme od namestitve do posodobitve in odstranitve v operacijskih sistemih Windows.

O uporabi Chocolatey

Tukaj si lahko ogledate, kako namestiti samega upravitelja paketov povezava. Celotna dokumentacija za namestitev analizatorja je na voljo na povezava Oglejte si razdelek Namestitev z upraviteljem paketov Chocolatey. Na kratko bom ponovil nekaj točk od tam.

Ukaz za namestitev najnovejše različice analizatorja:

choco install pvs-studio

Ukaz za namestitev določene različice paketa PVS-Studio:

choco install pvs-studio --version=7.05.35617.2075

Privzeto je nameščeno samo jedro analizatorja, komponenta Core. Vse druge zastavice (Standalone, JavaCore, IDEA, MSVS2010, MSVS2012, MSVS2013, MSVS2015, MSVS2017, MSVS2019) je mogoče posredovati z --package-parameters.

Primer ukaza, ki bo namestil analizator z vtičnikom za Visual Studio 2019:

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

Zdaj pa si poglejmo primer priročne uporabe analizatorja pod Azure DevOps.

prilagoditev

Naj vas spomnim, da obstaja ločen razdelek o težavah, kot so registracija računa, ustvarjanje Build Pipeline in sinhronizacija vašega računa s projektom, ki se nahaja v repozitoriju GitHub. članek. Naša namestitev se bo takoj začela s pisanjem konfiguracijske datoteke.

Najprej nastavimo sprožilec za zagon, ki nakazuje, da zaženemo samo za spremembe v mojster podružnica:

trigger:
- master

Nato moramo izbrati virtualni stroj. Zaenkrat bo to posrednik, ki ga gosti Microsoft z Windows Server 2019 in Visual Studio 2019:

pool:
  vmImage: 'windows-latest'

Preidimo na telo konfiguracijske datoteke (block koraki). Kljub temu, da v virtualni stroj ne morete namestiti poljubne programske opreme, nisem dodal vsebnika Docker. Chocolatey lahko dodamo kot razširitev za Azure DevOps. Če želite to narediti, pojdimo na povezava. Kliknite Osvobodite ga. Nato, če ste že pooblaščeni, preprosto izberite svoj račun, in če niste, naredite isto po avtorizaciji.

PVS-Studio je zdaj v Chocolatey: preverjanje Chocolatey iz Azure DevOps

Tukaj morate izbrati, kam bomo dodali razširitev in klikniti gumb namestitev.

PVS-Studio je zdaj v Chocolatey: preverjanje Chocolatey iz Azure DevOps

Po uspešni namestitvi kliknite Nadaljujte z organizacijo:

PVS-Studio je zdaj v Chocolatey: preverjanje Chocolatey iz Azure DevOps

Zdaj lahko v oknu vidite predlogo za nalogo Chocolatey Naloge pri urejanju konfiguracijske datoteke azure-pipelines.yml:

PVS-Studio je zdaj v Chocolatey: preverjanje Chocolatey iz Azure DevOps

Kliknite Chocolatey in poglejte seznam polj:

PVS-Studio je zdaj v Chocolatey: preverjanje Chocolatey iz Azure DevOps

Tukaj moramo izbrati namestitev na terenu z ekipami. IN Ime datoteke Nuspec navedite ime zahtevanega paketa – pvs-studio. Če ne navedete različice, se bo namestila zadnja, kar nam popolnoma ustreza. Pritisnimo gumb dodajte in videli bomo ustvarjeno nalogo v konfiguracijski datoteki.

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

Nato preidimo na glavni del naše datoteke:

- task: CmdLine@2
  inputs:
    script: 

Zdaj moramo ustvariti datoteko z licenco analizatorja. Tukaj PVSNAME и PVSKEY – imena spremenljivk, katerih vrednosti določimo v nastavitvah. Shranili bodo prijavo in licenčni ključ PVS-Studio. Če želite nastaviti njihove vrednosti, odprite meni Spremenljivke->Nova spremenljivka. Ustvarimo spremenljivke PVSNAME za prijavo in PVSKEY za ključ analizatorja. Ne pozabite potrditi polja Naj bo ta vrednost skrivnost za PVSKEY. Koda ukaza:

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

Zgradimo projekt z uporabo datoteke bat, ki se nahaja v repozitoriju:

сall build.bat

Ustvarimo mapo, v kateri bodo shranjene datoteke z rezultati analizatorja:

сall mkdir PVSTestResults

Začnimo analizirati projekt:

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

Naše poročilo pretvorimo v html format s pomočjo pripomočka PlogСonverter:

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

Zdaj morate ustvariti nalogo, da boste lahko naložili poročilo.

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

Celotna konfiguracijska datoteka je videti takole:

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

Kliknimo Shrani->Shrani->Zaženi za izvedbo naloge. Prenesimo poročilo tako, da gremo na zavihek opravil.

PVS-Studio je zdaj v Chocolatey: preverjanje Chocolatey iz Azure DevOps

Projekt Chocolatey vsebuje le 37615 vrstic kode C#. Poglejmo nekaj najdenih napak.

Rezultati testov

Opozorilo N1

Opozorilo analizatorja: V3005 Spremenljivka 'Ponudnik' je dodeljena sama sebi. CrytpoHashProviderSpecs.cs 38

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

Analizator je zaznal dodelitev spremenljivke samemu sebi, kar ni smiselno. Najverjetneje bi namesto ene od teh spremenljivk morala biti kakšna druga. No, ali pa je to tipkarska napaka in dodatno dodelitev lahko preprosto odstranite.

Opozorilo N2

Opozorilo analizatorja: V3093 [CWE-480] Operator '&' ovrednoti oba operanda. Morda bi namesto tega morali uporabiti kratkostični operator '&&'. Platforma.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;
  }
}

Razlika med operaterji & od operaterja && je, da če je leva stran izraza false, potem bo desna stran še vedno izračunana, kar v tem primeru pomeni nepotrebne klice metod system.directory_exists.

V obravnavanem fragmentu je to manjša pomanjkljivost. Da, ta pogoj je mogoče optimizirati z zamenjavo operatorja & z operatorjem &&, vendar s praktičnega vidika to ne vpliva na nič. Vendar pa lahko v drugih primerih zmeda med & in && povzroči resne težave, ko se desna stran izraza obravnava z nepravilnimi/neveljavnimi vrednostmi. Na primer, v naši zbirki napak identificiran z diagnostiko V3093, obstaja ta primer:

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

Tudi če indeks k ni pravilna, bo uporabljena za dostop do elementa matrike. Posledično bo vržena izjema IndexOutOfRangeException.

Opozorila N3, N4

Opozorilo analizatorja: V3022 [CWE-571] Izraz 'shortPrompt' je vedno resničen. InteractivePrompt.cs 101
Opozorilo analizatorja: V3022 [CWE-571] Izraz 'shortPrompt' je vedno resničen. 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
    ....
  }
  ....
}

V tem primeru je za delovanjem ternarnega operaterja čudna logika. Poglejmo podrobneje: če je pogoj, ki sem ga označil s številko 1, izpolnjen, potem preidemo na pogoj 2, ki je vedno Res, kar pomeni, da se bo izvršila vrstica 3. Če se izkaže, da je pogoj 1 napačen, se premaknemo v vrstico, označeno s številko 4, kjer je pogoj tudi vedno Res, kar pomeni, da se bo izvršila vrstica 5. Tako pogoji, označeni s komentarjem 0, ne bodo nikoli izpolnjeni, kar morda ni ravno logika delovanja, ki jo je programer pričakoval.

Opozorilo N5

Opozorilo analizatorja: V3123 [CWE-783] Morda operater '?:' deluje na drugačen način, kot je bilo pričakovano. Njegova prioriteta je nižja od prioritete drugih operaterjev v njegovem stanju. 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);
  }
}

Diagnostika je delovala za vrstico:

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

Ker je spremenljivka j nekaj vrstic zgoraj inicializira na nič, bo ternarni operater vrnil vrednost false. Zaradi tega pogoja bo telo zanke izvedeno samo enkrat. Zdi se mi, da ta del kode sploh ne deluje tako, kot si je zamislil programer.

Opozorilo N6

Opozorilo analizatorja: V3022 [CWE-571] Izraz 'installedPackageVersions.Count != 1' je vedno resničen. 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);
    }
    ....
  }
  ....
}

Tukaj je čudno ugnezdeno stanje: InstallPackageVersions.Count != 1ki bo vedno Res. Pogosto takšno opozorilo kaže na logično napako v kodi, v drugih primerih pa preprosto nakazuje odvečno preverjanje.

Opozorilo N7

Opozorilo analizatorja: V3001 Obstajata enaka podizraza 'commandArguments.contains("-apikey")' levo in desno od '||' operater. 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");
}

Programer, ki je napisal ta del kode, je kopiral in prilepil zadnji dve vrstici in ju pozabil urediti. Zaradi tega uporabniki Chocolateyja niso mogli uporabiti parametra apikey še nekaj načinov. Podobno kot pri zgornjih parametrih lahko ponudim naslednje možnosti:

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

Napake kopiraj-prilepi imajo veliko možnosti, da se prej ali slej pojavijo v katerem koli projektu z veliko izvorne kode, in eno najboljših orodij za boj proti njim je statična analiza.

PS Kot vedno se ta napaka pojavi na koncu večvrstičnega pogoja :). Glej publikacijo "Učinek zadnje vrstice".

Opozorilo N8

Opozorilo analizatorja: V3095 [CWE-476] Objekt 'installedPackage' je bil uporabljen, preden je bil preverjen glede na nič. Preverite vrstice: 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)
  {
    ....
  }
  ....
}

Klasična napaka: najprej ugovor InstallPackage je uporabljen in nato preverjen null. Ta diagnostika nam pove o eni od dveh težav v programu: bodisi InstallPackage nikoli enaka null, kar je vprašljivo, in potem je preverjanje odveč ali pa bi lahko dobili resno napako v kodi - poskus dostopa do ničelne reference.

Zaključek

Tako smo naredili še en majhen korak - zdaj je uporaba PVS-Studio postala še lažja in priročnejša. Prav tako bi rad povedal, da je Chocolatey dober upravitelj paketov z majhnim številom napak v kodi, ki bi jih lahko bilo še manj pri uporabi PVS-Studio.

Vabimo prenos in preizkusite PVS-Studio. Redna uporaba statičnega analizatorja bo izboljšala kakovost in zanesljivost kode, ki jo razvija vaša ekipa, in pomagala preprečiti številne zero day ranljivosti.

PS

Pred objavo smo članek poslali razvijalcem Chocolatey, ki so ga dobro sprejeli. Nismo našli nič kritičnega, vendar jim je bila na primer všeč napaka, ki smo jo našli v zvezi s ključem "api-key".

PVS-Studio je zdaj v Chocolatey: preverjanje Chocolatey iz Azure DevOps

Če želite ta članek deliti z angleško govorečim občinstvom, uporabite povezavo za prevod: Vladislav Stolyarov. PVS-Studio je zdaj v različici Chocolatey: preverjanje Chocolatey pod Azure DevOps.

Vir: www.habr.com

Dodaj komentar