PVS-Studio tani është në Chocolatey: verifikimi i Chocolatey nga Azure DevOps

PVS-Studio tani është në Chocolatey: verifikimi i Chocolatey nga Azure DevOps
Ne vazhdojmë të bëjmë përdorimin e PVS-Studio më të lehtë. Tani analizuesi ynë është në dispozicion në Chocolatey, menaxherin e paketave për Windows. Mendojmë se kjo do të lehtësojë instalimin e PVS-Studio, veçanërisht në shërbimet cloud. Për të mos u larguar shumë, do të kontrollojmë kodin burimor të Chocolatey. Si sistem CI do të përdorim Azure DevOps.

Ja lista e artikujve tanë të tjerë mbi integrimin me sistemet cloud:

Të rekomandoj të kushtosh vëmendje artikullit të parë mbi integrimin me Azure DevOps, pasi në këtë rast disa pika janë lënë jashtë për të shmangur përsëritjen.

Pra, heronjtë e këtij artikulli janë:

PVS-Studio — njĂ« mjet pĂ«r analizĂ«n statike tĂ« kodit, e cila Ă«shtĂ« e destinuar pĂ«r tĂ« identifikuar gabimet dhe potencialet e dobĂ«ta nĂ« programet e shkruara nĂ« gjuhĂ«t C, C++, C# dhe Java. Funksionon nĂ« sisteme 64-bit nĂ« Windows, Linux dhe macOS, dhe mund tĂ« analizojĂ« kodin qĂ« Ă«shtĂ« i destinuar pĂ«r platformat 32-bit, 64-bit dhe ARM tĂ« integruara. NĂ«se je duke provuar analizĂ«n statike tĂ« kodit pĂ«r herĂ« tĂ« parĂ« pĂ«r tĂ« kontrolluar projektet e tua, rekomandojmĂ« tĂ« njohesh me artikullin pĂ«r mĂ«nyrĂ«n e shpejtĂ« pĂ«r tĂ« parĂ« paralajmĂ«rimet mĂ« interesante tĂ« PVS-Studio dhe pĂ«r tĂ« vlerĂ«suar mundĂ«sitĂ« e kĂ«tij instrumenti.

Azure DevOps — njĂ« grup shĂ«rbimesh cloud qĂ« mbulojnĂ« gjithĂ« procesin e zhvillimit. Ky platformĂ« pĂ«rfshin mjete si Azure Pipelines, Azure Boards, Azure Artifacts, Azure Repos, Azure Test Plans, qĂ« lejojnĂ« pĂ«rshpejtimin e procesit tĂ« zhvillimit tĂ« softuerit dhe pĂ«rmirĂ«simin e cilĂ«sisĂ« sĂ« tij.

Chocolatey – menaxher paketa pĂ«r Windows me kod tĂ« hapur. QĂ«llimi i projektit Ă«shtĂ« tĂ« automatizojĂ« gjithĂ« ciklin e jetĂ«s sĂ« softuerit, nga instalimi deri te pĂ«rditĂ«simi dhe fshirja nĂ« sistemet operative Windows.

Rreth përdorimit të Chocolatey

Për të parë si të instaloni menaxherin e paketave vetë, mund të ndihmoni në këtë lidhjes. Dokumentacioni i plotë për instalimin e analizuesit është në dispozicion në lidhjes në seksionin "Instalimi me përdorimin e menaxherit të paketave Chocolatey". Në përmbledhje, le të përsërisim disa pika nga aty.

Komanda për të instaluar versionin më të fundit të analizuesit:

choco install pvs-studio

Komanda për instalimin e një versioni të caktuar të paketës PVS-Studio:

choco install pvs-studio --version=7.05.35617.2075

NĂ« mĂ«nyrĂ« tĂ« paracaktuar instalohet vetĂ«m bĂ«rthama e analizuesit — komponenti Core. TĂ« gjithĂ« parametrat e tjerĂ« (Standalone, JavaCore, IDEA, MSVS2010, MSVS2012, MSVS2013, MSVS2015, MSVS2017, MSVS2019) mund tĂ« kalohen pĂ«rmes —package-parameters.

Shembuj komande që do të instalojnë analizuesin me pluginin për Visual Studio 2019:

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

Tani le të shohim një shembull të përdorimit të lehtë të analizuesit nën Azure DevOps.

Konfigurimi

Të kujtojmë se për çështje si regjistrimi i llogarisë, krijimi i Build Pipeline dhe sinkronizimi i llogarisë me projektin në repozitorin në GitHub, ka një të veçantë artikull. Konfigurimi ynë do të fillojë me hartimin e skedës së konfigurimit.

Së pari, le të konfigurojmë trigger-in e nisjes, duke treguar se prodhojmë nisje vetëm për ndryshimet në master degën:

trigger:
- master

Më pas, na nevojitet të zgjedhim makinën virtuale. Aktualisht kjo do të jetë një agjent i hostuar nga Microsoft me Windows Server 2019 dhe Visual Studio 2019:

pool:
  vmImage: 'windows-latest'

Të kalojmë në trupin e skedës së konfigurimit (bloku steps). Megjithëse në makinën virtuale nuk është e mundur të instalosh softuer të rastësishëm, nuk e kam shtuar një kontejner Docker. Ne mund të shtojmë Chocolatey si një shtesë për Azure DevOps. Për këtë, do të kalojmë te lidhjes. Klikojmë Get it free. Më pas, nëse jeni tashmë të autorizuar, thjesht zgjidhni llogarinë tuaj, dhe nëse jo, bëni të njëjtën gjë pas autorizimit.

PVS-Studio tani është në Chocolatey: verifikimi i Chocolatey nga Azure DevOps

Këtu duhet të zgjidhni se ku do ta shtojmë shtesën dhe të klikoni butonin Instalo.

PVS-Studio tani është në Chocolatey: verifikimi i Chocolatey nga Azure DevOps

Pasi ta instaloni me sukses, do të klikoni Proceed to organization:

PVS-Studio tani është në Chocolatey: verifikimi i Chocolatey nga Azure DevOps

Tani mund të shihni një model për detyrën e Chocolatey në dritaren detyrat kur po redaktoni skedën e konfigurimit azure-pipelines.yml:

PVS-Studio tani është në Chocolatey: verifikimi i Chocolatey nga Azure DevOps

Klikojmë mbi Chocolatey dhe shohim listën e fushave:

PVS-Studio tani është në Chocolatey: verifikimi i Chocolatey nga Azure DevOps

KĂ«tu na nevojitet tĂ« zgjedhim install nĂ« fushĂ«n me komandat. NĂ« Nuspec File Name do tĂ« vendosim emrin e paketĂ«s sĂ« nevojshme – pvs-studio. NĂ«se nuk e specifikoni versionin, do tĂ« instalohet versioni mĂ« i fundit, qĂ« na pĂ«rshtatet plotĂ«sisht. KlikojmĂ« mbi butonin shto dhe do tĂ« shohim detyrĂ«n e formuar nĂ« skedĂ«n e konfigurimit.

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

Më pas kalojmë në pjesën kryesore të skedës sonë:

- task: CmdLine@2
  inputs:
    script: 

Tani na nevojitet tĂ« krijojmĂ« njĂ« skedĂ« me licencĂ«n e analizuesit. KĂ«tu PVSNAME dhe PVSKEY – emrat e variablave, vlerat e tĂ« cilave do t'i caktosh nĂ« cilĂ«simet. Ato do tĂ« ruajnĂ« emrin dhe çelĂ«sin e licencĂ«s PVS-Studio. PĂ«r tĂ« caktuar vlerat e tyre, do tĂ« hapim menunĂ« Variables->New variable. Do tĂ« krijojmĂ« variablat PVSNAME pĂ«r emrin e pĂ«rdoruesit dhe PVSKEY pĂ«r çelĂ«sin e analizuesit. Mos harro tĂ« vendosĂ«sh shenjĂ«n Keep this value secret pĂ«r PVSKEY. Kodi i komandĂ«s:

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

Do të krijojmë projektin me ndihmën e skedarit bat që ndodhet në repository:

call build.bat

Do të krijojmë një direktori ku do të vendosen skedarët me rezultatet e punës së analizuesit:

call mkdir PVSTestResults

Do të nisim analizën e projektit:

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

Do ta konvertojmë raportin tonë në formatin html me ndihmën e utilitarit PlogConverter:

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

Tani duhet të krijojmë një detyrë për të mundësuar eksportimin e raportit.

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

Skedari i plotë i konfigurimit duket kështu:

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

Klikoni Ruaj->Ruaj->Ekzekuto për të nisur detyrën. Do të eksportojmë raportin duke hyrë në skedën e detyrave.

PVS-Studio tani është në Chocolatey: verifikimi i Chocolatey nga Azure DevOps

Projekti Chocolatey përmban gjithsej 37615 rreshta kodo në C#. Le të shqyrtojmë disa nga gabimet e gjetura.

Rezultatet e kontrollit

Paralajmërimi N1

Kujtesa e analizuesit: V3005 Variabla ‘Provider’ i jepet vetes. CrytpoHashProviderSpecs.cs 38

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

Analizuesi ka zbuluar një për asignim variablin ndaj vetes, që nuk ka kuptim. Me shumë mundësi, në vend të njërit prej këtyre variablave duhet të jetë ndonjë tjetër. Ose është një gabim shkrimi dhe për asignimin e tepërt mund të eliminohet.

Paralajmërimi N2

Kujtesa e analizuesit: V3093 [CWE-480] Operatori ‘&’ vlerĂ«son tĂ« dy operandĂ«t. Ndoshta duhet tĂ« pĂ«rdoret njĂ« operator ‘&&’ pĂ«r shkurtim nĂ« vendin e tij. 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;
  }
}

Dallimi i operatorit & nga operatori && consiston në atë se nëse ana e majtë e shprehjes është false, do të llogaritet po ashtu ana e djathtë, që në këtë rast nënkupton thirrje të panevojshme të metodës system.directory_exists.

Në fragmentin e shqyrtuar, kjo është një gabim i vogël. Po, kjo kusht mund të optimizohet duke e zëvendësuar operatorin & me operatorin &&, por nga pikëpamja praktike, kjo nuk ndikon në asgjë. Megjithatë, në raste të tjera, ngatërrimi mes & dhe && mund të shkaktojë probleme serioze, kur ana e djathtë e shprehjes punon me vlera të papërshtatshme/jo të lejuara. Për shembull, në koleksionin tonë të gabimeve, të identifikuara përmes diagnostikimit V3093, ka një rast të tillë:

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

Edhe nëse indeksi k është i pasaktë, ai do të përdoret për qasje në elementin e array-t. Si pasojë, do të gjenerohet një përjashtim IndexOutOfRangeException.

Paralajmërimet N3, N4

Kujtesa e analizuesit: V3022 [CWE-571] Shprehja ‘shortPrompt’ Ă«shtĂ« gjithmonĂ« e vĂ«rtetĂ«. InteractivePrompt.cs 101
Kujtesa e analizuesit: V3022 [CWE-571] Shprehja ‘shortPrompt’ Ă«shtĂ« gjithmonĂ« e vĂ«rtetĂ«. 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
    ....
  }
  ....
}

Në këtë rast, ka një logjikë të çuditshme të funksionimit të operatorit ternar. Le të shqyrtojmë më në detaje: nëse kushti i shënuar me numrin 1 përmbushet, atëherë do të kalojmë tek kushti 2, i cili gjithmonë e vërtetë, pra do të përmbushet rreshti 3. Nëse kushti 1 është i fals, atëherë do të kalojmë në rreshtin e shënuar me numrin 4, kushti i të cilit gjithashtu është gjithmonë e vërtetë, pra do të përmbushet rreshti 5. Kështu, kushtet e shënuara me komentarin 0 nuk do të përmbushen kurrë, që mund të përbëjë një logjikë jo aq të saktë për të cilën programuesi ka pasur prirje.

Kujdesi N5

Kujtesa e analizuesit: V3123 [CWE-783] Ndoshta operatori ‘?:’ punon nĂ« njĂ« mĂ«nyrĂ« tĂ« ndryshme nga ajo qĂ« ishte pritur. Prioriteti i tij Ă«shtĂ« mĂ« i ulĂ«t se prioriteti i operatorĂ«ve tĂ« tjerĂ« nĂ« kushtin e tij. 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 ka vepruar në rreshtin:

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

Duke qenë se variabli j në disa rreshta më sipër është inicializuar në zero, operatori ternar do të kthejë vlerën false. Për shkak të kësaj gjendjeje, trupi i ciklit do të ekzekutohet vetëm një herë. Më duket se ky fragment kodi nuk funksionon ashtu siç e kishte menduar programuesi.

Kujdesi N6

Kujtesa e analizuesit: V3022 [CWE-571] Shprehja ‘installedPackageVersions.Count != 1’ Ă«shtĂ« gjithmonĂ« e vĂ«rtetĂ«. NugetService.cs 1405

private void remove_nuget_cache_for_package(....)
{
  if (!config.AllVersions && installedPackageVersions.Count > 1)
  {
    const string allVersionsChoice = "TĂ« gjitha versionet";
    if (installedPackageVersions.Count != 1)
    {
      choices.Add(allVersionsChoice);
    }
    ....
  }
  ....
}

Këtu është një kusht i çuditshëm i përgjakur: installedPackageVersions.Count != 1, i cili gjithmonë do të jetë e vërtetë. Shpesh, një paralajmërim i tillë tregon mbi një gabim logjik në kod, dhe në raste të tjera, thjesht për një kontroll të tepërt.

Paralajmërimi N7

Kujtesa e analizuesit: V3001 Ka nĂ«n-shprehje identike ‘commandArguments.contains("-apikey")’ nĂ« tĂ« majtĂ« dhe nĂ« tĂ« djathtĂ« tĂ« operatorit ‘||’. 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");
}

Programuesi që shkroi këtë pjesë kodi ka kopjuar dy rreshtat e fundit dhe harroi t'i rregullojë ato. Si pasojë, përdoruesit e Chocolatey humbën mundësinë për të aplikuar parametrin apikey me disa mënyra të tjera. Po ashtu, për parametrat e mësipërm, mund të sugjeroj këto variante:

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

Gabimet e kopjim-ngritjes kanë një mundësi të madhe për t'u shfaqur në çdo projekt me një numër të madh kodin burimor, dhe një nga mjetet më të mira për t'u luftuar ato është analiza statike.

P.S. Dhe si gjithmonë, ky gabim ka prirje të shfaqet në fund të një kushti shumë-rreshtor :). Shih publikimin "Efekti i rreshtit të fundit".

Paralajmërimi N8

Kujtesa e analizuesit: V3095 [CWE-476] Objektin ‘installedPackage’ u pĂ«rdor para se tĂ« verifikohej kundrejt null. Kontrolloni rreshtat: 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)
  {
    ....
  }
  ....
}

Gabimi klasik: nĂ« fillim objekti installedPackage pĂ«rdoret, dhe mĂ« pas kontrollohet pĂ«r null. Kjo diagnozĂ« na tregon pĂ«r njĂ« nga dy probleme nĂ« program: ose installedPackage nuk Ă«shtĂ« kurrĂ« i barabartĂ« me null, qĂ« Ă«shtĂ« dyshues, dhe atĂ«herĂ« kontrolli Ă«shtĂ« i tepĂ«rt, ose potencialisht mund tĂ« lĂ«shojmĂ« njĂ« gabim tĂ« rĂ«ndĂ« nĂ« kod – njĂ« pĂ«rpjekje pĂ«r qasje pĂ«rmes njĂ« referencĂ« tĂ« null.

Përfundimi

Ja ku e bĂ«mĂ« njĂ« hap tĂ« vogĂ«l tjetĂ«r – tani pĂ«rdorimi i PVS-Studio Ă«shtĂ« bĂ«rĂ« edhe mĂ« i lehtĂ« dhe mĂ« i rehatshĂ«m. Gjithashtu, dua tĂ« them se Chocolatey Ă«shtĂ« njĂ« menaxher i mirĂ« paketash me njĂ« numĂ«r tĂ« vogĂ«l gabimesh nĂ« kodin qĂ« do tĂ« kishte mundur tĂ« ishte edhe mĂ« i vogĂ«l nĂ« pĂ«rdorimin e PVS-Studio.

Ftojme shkarko dhe të provoni PVS-Studio. Përdorimi i rregullt i analistit statik do të rrisë cilësinë dhe besueshmërinë e kodit që zhvillohet nga ekipi juaj dhe do të ndihmojë në parandalimin e shumë kërcënimeve të ditës së zeros.

P.S.

Para publikimit, ne e dërguam artikullin zhvilluesve të Chocolatey, dhe ata e pranuan shumë mirë. Nuk gjetëm asgjë kritike, por atyre, për shembull, iu pëlqye gabimi që gjetëm në lidhje me çelësin "api-key".

PVS-Studio tani është në Chocolatey: verifikimi i Chocolatey nga Azure DevOps

Nëse dëshironi të ndani këtë artikull me një audiencë anglishtfolëse, ju lutem përdorni lidhjen për përkthimin: Vladislav Stolyarov. PVS-Studio Tani është në Chocolatey: Kontrolli i Chocolatey nën Azure DevOps.

Burimi: habr.com

Bleni hostim tĂ« besueshĂ«m pĂ«r faqe me mbrojtje nga DDoS, serverĂ« VPS VDS đŸ”„ Bleni hostim tĂ« besueshĂ«m pĂ«r faqe me mbrojtje nga DDoS, serverĂ« VPS VDS | ProHoster