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

PVS-Studio tani në Chocolatey: kontrolli i Chocolatey nga Azure DevOps
Ne vazhdojmë ta bëjmë përdorimin e PVS-Studio më të lehtë. Tani analizuese jonë është e disponueshme në Chocolatey, menaxhuesin e paketave për Windows. Mendojmë se kjo do të lehtësojë vendosjen e PVS-Studio, veçanërisht në shërbimet cloud. Për të mos shkuar shumë larg, le të kontrollojmë kodin burimor të të njëjtit Chocolatey. Si sistem CI do të përdorim Azure DevOps.

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

Këshilloj që të kushtoni vëmendje artikullit të parë rreth integrimit me Azure DevOps, pasi në këtë rast disa momente janë lënë mënjanë për të mos u përsëritur.

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

PVS-Studio — njĂ« mjet analize statike tĂ« kodit, i destinuar pĂ«r identifikimin e gabimeve dhe vulnerabiliteteve potenciale 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Ă« menduar pĂ«r platformat 32-bit, 64-bit dhe ARM tĂ« integruara. NĂ«se po provoni pĂ«r herĂ« tĂ« parĂ« analizĂ«n statike tĂ« kodit pĂ«r tĂ« kontrolluar projektet tuaja, ju rekomandojmĂ« tĂ« jeni tĂ« njohur me artikullin rreth mĂ«nyrĂ«s pĂ«r tĂ« parĂ« shpejt paralajmĂ«rimet mĂ« interesante PVS-Studio dhe pĂ«r tĂ« vlerĂ«suar mundĂ«sitĂ« e kĂ«tij mjeti.

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

Chocolatey – njĂ« menaxhues pakete pĂ«r Windows me burim tĂ« hapur. QĂ«llimi i projektit Ă«shtĂ« tĂ« automatizojĂ« tĂ« 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

Të shihni se si të instaloni vetë menaxhuesin e paketave, mund ta gjeni në këtë linkun. Dokumentacioni i plotë për instalimin e analizuese është i disponueshëm në linkun në seksionin "Instalimi duke përdorur menaxhuesin e paketave Chocolatey". Në mënyrë të përmbledhur, do të përsëris disa pika nga aty.

Komanda për instalimin e versionit më të fundit të analizuese:

choco install pvs-studio

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

choco install pvs-studio --version=7.05.35617.2075

Default installs only the core of the analyzer — the Core component. All other flags (Standalone, JavaCore, IDEA, MSVS2010, MSVS2012, MSVS2013, MSVS2015, MSVS2017, MSVS2019) can be passed with —package-parameters.

Example command to install the analyzer with the plugin for Visual Studio 2019:

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

Now let's look at a convenient example of using the analyzer with Azure DevOps.

Configuration

I remind you that there are separate instructions on such matters as account registration, creating a Build Pipeline, and syncing the account with a project in the GitHub repository. artikulliOur setup will start right away with writing the configuration file.

First, let's set up the trigger for execution, specifying that we only trigger for changes in master the branch:

trigger:
- master

Next, we need to choose a virtual machine. For now, it will be a Microsoft-hosted agent with Windows Server 2019 and Visual Studio 2019:

pool:
  vmImage: 'windows-latest'

Let's move to the body of the configuration file (block steps). Despite the fact that arbitrary software cannot be installed on the virtual machine, I decided not to add a Docker container. We can add Chocolatey as an extension for Azure DevOps. For this, we can go to linkun. Click Get it free. Then, if you are already logged in, just select your account, or if not, do the same after logging in.

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

Here you need to select where we will add the extension and click the button Install.

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

After successful installation, click Proceed to organization:

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

Now you can see the template for the Chocolatey task in the window tasks when editing the configuration file azure-pipelines.yml:

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

Click on Chocolatey and see the list of fields:

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

Here we need to select instalo in the commands field. In Nuspec File Name we will specify the name of the desired package – pvs-studio. If no version is specified, the latest version will be installed, which suits us perfectly. Click on the button add and see the generated task in the configuration file.

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

Next, let's move on to the main part of our file:

- task: CmdLine@2
  inputs:
    script: 

Now we need to create a file with the license for the analyzer. Here PVSNAME dhe PVSKEY – are the names of the variables whose values we specify in the settings. They will store the username and license key for PVS-Studio. To set their values, we will open the menu Variables->New variable. We will create variables PVSNAME for the login and PVSKEY pĂ«r çelĂ«sin e analizuesit. Mos harro tĂ« vendosĂ«sh shenjĂ«n e kontrollit Mbaje kĂ«tĂ« vlerĂ« sekrete pĂ«r PVSKEY. Kodi i komandĂ«s:

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

Do të mbledhim projektin me ndihmën e skedarit bat, që ndodhet në depo:

thirr build.bat

Do të krijojmë një dosje ku do të ruhen skedarët me rezultatet e punës së analizuesit:

thirr mkdir PVSTestResults

Do të fillojmë analizën e projektit:

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

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

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

Tani duhet të krijojmë një detyrë që të mund të nxjerrim raportin.

- detyrë: PublishBuildArtifacts@1
  hyrjet:
    pathToPublish: PVSTestResults
    artifactName: PVSTestResults
    kushti: always()

I gjithë skedari i konfigurimit duket kështu:

trigger:
- master

pool:
  vmImage: 'windows-latest'

steps:
- detyrë: ChocolateyCommand@0
  hyrjet:
    komandë: 'instalo'
    installPackageId: 'pvs-studio'

- detyrë: CmdLine@2
  hyrjet:
    skript: |
      thirr "C:Program Files (x86)PVS-StudioPVS-Studio_Cmd.exe" 
      credentials –u $(PVSNAME) –n $(PVSKEY)
      thirr build.bat
      thirr mkdir PVSTestResults
      thirr "C:Program Files (x86)PVS-StudioPVS-Studio_Cmd.exe" 
      –t .srcchocolatey.sln –o .PVSTestResultsChoco.plog
      thirr "C:Program Files (x86)PVS-StudioPlogConverter.exe" 
      –t html –o .PVSTestResults .PVSTestResultsChoco.plog

- detyrë: PublishBuildArtifacts@1
  hyrjet:
    pathToPublish: PVSTestResults
    artifactName: PVSTestResults
    kushti: always()

Të klikojmë Ruaj->Ruaj->Ekzekuto për të filluar detyrën. Do të nxjerrim raportin duke hyrë në skedën e detyrës.

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

Projekti Chocolatey ka gjithsej 37615 rreshta kodi C#. Le të shqyrtojmë disa nga gabimet e gjetura.

Rezultatet e kontrollit

Kujdesi N1

Kujdesi i analizuesit: V3005 Variabla ‘Provider’ i caktohet vetĂ«. CrytpoHashProviderSpecs.cs 38

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

Analizuesi gjeti përjashtimin e variablës me veten e saj, që nuk ka kuptim. Ndoshta në vend të një prej këtyre variablave duhet të jetë ndonjë tjetër. Ose ndoshta është një gabim shtypi, dhe caktoja të tepërt mund të hiqet thjesht.

Kujdesi N2

Kujdesi i analizuesit: V3093 [CWE-480] OperatorĂ«t ‘&’ vlerĂ«sojnĂ« tĂ« dy operandĂ«t. Ndoshta duhet tĂ« pĂ«rdoret operatori i shkurtĂ«r ‘&&’ nĂ« vend.

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 && ka nĂ« lidhje me faktin qĂ« nĂ«se pjesa e majtĂ« e shprehjes — false, do tĂ« llogaritet gjithsesi pjesa e djathtĂ«, e cila nĂ« kĂ«tĂ« rast pĂ«rfshin thirrje tĂ« tepruara tĂ« metodĂ«s system.directory_exists.

Në fragmentin e shqyrtuar, ky është një gabim i vogël. Po, kjo kusht shumë mirë mund të optizohet duke zëvendësuar operatorin & me operatorin &&, por, nga pikëpamja praktike, kjo nuk ndikon në asgjë. Megjithatë, në raste të tjera, konfuzioni midis & dhe && mund të shkaktojë probleme serioze, kur pjesa e djathtë e shprehjes punon me vlera të pasakta / të pavlefshme. 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 të aksesuar elementin e array-it. Si rezultat, do të gjenerohet një përjashtim IndexOutOfRangeException.

Kujdeset N3, N4

Kujdesi i analizuesit: V3022 [CWE-571] Shprehja ‘shortPrompt’ Ă«shtĂ« gjithmonĂ« e vĂ«rtetĂ«. InteractivePrompt.cs 101
Kujdesi i 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 nga unë me numrin 1 përmbushet, atëherë do të kalojmë te kushti 2, i cili gjithmonë true, që do të thotë se do të ekzekutohet rreshti 3. Nëse kushti 1 del të jetë i pavërtetë, atëherë do të kalojmë tek rreshti i shënuar me numrin 4, kushti në të cilin gjithashtu gjithmonë true, që do të thotë, do të ekzekutohet rreshti 5. Kështu, kushtet e shënuara me komentin 0, kurrë nuk do të përmbushen, që mund të jetë një logjikë që programuesi nuk e priste.

Kujdesi N5

Kujdesi i analizuesit: V3123 [CWE-783] Ndoshta operatori ‘?:’ funksionon ndryshe nga sa pritej. 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 ? "VLERË" : "VLERË" + (index + 1);
  }
}

Diagnostika u aktivizua për rreshtin:

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

Duke pasur parasysh se variabli j është inicializuar me zero disa rreshta më sipër, operatori ternar do të kthejë vlerën false. Për shkak të kësaj kushtet, trupi i ciklit do të ekzekutohet vetëm një herë. Më duket se ky fragment kodi funksionon ndryshe nga sa e kishte menduar programuesi.

Alarmi N6

Kujdesi i 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 ka një kusht të çuditshëm të ndërlidhur: installedPackageVersions.Count != 1, i cili do të jetë gjithmonë true. Shpesh ky lloj paralajmërimi tregon për një gabim logjik në kod, dhe në rastet e tjera thjesht për një kontroll të panevojshëm.

Alarmi N7

Kujdesi i analizuesit: V3001 EkzistojnĂ« shprehje identike sub 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, e kopjoi dy rreshtat e fundit dhe harroi t'i redaktojë ato. Për këtë arsye, përdoruesit e Chocolatey u privuan nga mundësia për të aplikuar parametrin apikey me disa mënyra të tjera. Njësoj si parametrat e sipërm, mund të sugjeroj këto opsione:

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

Gabimet e kopjimit dhe ngjitjes kanë një mundësi të madhe që të shfaqen shpejt në çdo projekt me një sasi të madhe të kodit burim, dhe një prej mjeteve më të mira për t'u luftuar me to është analiza statike.

P.S. Dhe si gjithmonë, kjo gabim ka tendencë të shfaqet në fund të një kushti shumë-rreshtëshe :). Shihni publikimin "Efekti i rreshtit të fundit".

Alarmi N8

Kujdesi i analizuesit: V3095 [CWE-476] Objeksioni ‘installedPackage’ u pĂ«rdor para se tĂ« verifikohej me null. Kontrolloni rreshtat: 910, 917. NugetService.cs 910

publike virtuale 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: objekti pĂ«rdoret nĂ« fillim installedPackage dhe mĂ« pas kontrollohet pĂ«r null. Ky diagnostikim na tregon pĂ«r njĂ« nga dy problemet nĂ« program: ose installedPackage nuk Ă«shtĂ« kurrĂ« e barabartĂ« me null, qĂ« Ă«shtĂ« dyshim, dhe atĂ«herĂ« kontrolli Ă«shtĂ« i tepĂ«rt, ose potencialisht mund tĂ« marrim njĂ« gabim tĂ« rĂ«ndĂ« nĂ« kod – njĂ« pĂ«rpjekje pĂ«r qasje me referencĂ« zero.

Përfundim

Kemi bĂ«rĂ« edhe njĂ« hap tĂ« vogĂ«l – tani pĂ«rdorimi i PVS-Studio Ă«shtĂ« bĂ«rĂ« edhe mĂ« i lehtĂ« dhe mĂ« i pĂ«rshtatshĂ«m. Po ashtu, dua tĂ« them se Chocolatey Ă«shtĂ« njĂ« menaxher i mirĂ« paketash me njĂ« numĂ«r tĂ« vogĂ«l gabimesh nĂ« kod, qĂ« do tĂ« mund tĂ« ishin edhe mĂ« tĂ« pakta me pĂ«rdorimin e PVS-Studio.

Ftojmë shkarkoni dhe të provoni PVS-Studio. Përdorimi i rregullt i analizatorit statik do të rrisë cilësinë dhe besueshmërinë e kodit që ekipi juaj zhvillon dhe do të ndihmojë në parandalimin e shumë shfrytëzimeve të zero ditëve.

P.S.

Para publikimit, e dërguam artikullin zhvilluesve të Chocolatey, dhe ata e pranuan mirë. Asgjë kritike nuk u gjet nga ne, por atyre, për shembull, iu pëlqeu gabimi që e gjetëm lidhur me çelësin "api-key".

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

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

Burimi: habr.com

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