PVS-Studio bevindt zich nu in Chocolatey: Chocolatey controleren onder Azure DevOps

PVS-Studio bevindt zich nu in Chocolatey: Chocolatey controleren onder Azure DevOps
We blijven het gebruik van PVS-Studio gemakkelijker maken. Onze analyser is nu beschikbaar in Chocolatey, een pakketbeheerder voor Windows. Wij zijn van mening dat dit de inzet van PVS-Studio, met name in clouddiensten, zal vergemakkelijken. Laten we, om niet ver te gaan, de broncode van dezelfde Chocolatey controleren. Azure DevOps zal fungeren als een CI-systeem.

Hier vindt u een lijst met onze andere artikelen over het onderwerp integratie met cloudsystemen:

Ik raad u aan om aandacht te besteden aan het eerste artikel over de integratie met Azure DevOps, aangezien in dit geval enkele punten worden weggelaten om niet te worden gedupliceerd.

Dus de helden van dit artikel:

PVS Studio is een statische code-analysetool ontworpen om fouten en potentiële kwetsbaarheden te identificeren in programma's geschreven in C, C++, C# en Java. Draait op 64-bits Windows-, Linux- en macOS-systemen en kan code analyseren die is ontworpen voor 32-bits, 64-bits en embedded ARM-platforms. Als dit de eerste keer is dat u statische code-analyse probeert om uw projecten te controleren, raden we u aan er vertrouwd mee te raken artikel over hoe u snel de meest interessante PVS-Studio-waarschuwingen kunt bekijken en de mogelijkheden van deze tool kunt evalueren.

Azure DevOps — een set clouddiensten die gezamenlijk het hele ontwikkelingsproces dekken. Dit platform bevat tools zoals Azure Pipelines, Azure Boards, Azure Artefacts, Azure Repos en Azure Test Plans, waarmee u het proces van het maken van software kunt versnellen en de kwaliteit ervan kunt verbeteren.

chocolatey is een open source pakketbeheerder voor Windows. Het doel van het project is om de gehele levenscyclus van software te automatiseren, van installatie tot updaten en verwijderen op Windows-besturingssystemen.

Over het gebruik van Chocolatey

Hier kunt u zien hoe u de pakketbeheerder zelf installeert link. Volledige documentatie voor het installeren van de analyser is beschikbaar op link Zie de sectie Installatie met behulp van de Chocolatey-pakketbeheerder. Ik zal vanaf daar enkele punten kort herhalen.

Commando om de nieuwste versie van de analysator te installeren:

choco install pvs-studio

Commando om een ​​specifieke versie van het PVS-Studio-pakket te installeren:

choco install pvs-studio --version=7.05.35617.2075

Standaard wordt alleen de kern van de analysator, de Core-component, geïnstalleerd. Alle andere vlaggen (Standalone, JavaCore, IDEA, MSVS2010, MSVS2012, MSVS2013, MSVS2015, MSVS2017, MSVS2019) kunnen worden doorgegeven met behulp van --package-parameters.

Een voorbeeld van een opdracht die een analyser installeert met een plug-in voor Visual Studio 2019:

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

Laten we nu eens kijken naar een voorbeeld van handig gebruik van de analyser onder Azure DevOps.

afstelling

Ik wil u eraan herinneren dat er een aparte sectie is over zaken als het registreren van een account, het maken van een Build Pipeline en het synchroniseren van uw account met een project in de GitHub-repository. artikel. Onze installatie begint onmiddellijk met het schrijven van een configuratiebestand.

Laten we eerst een starttrigger instellen, die aangeeft dat we alleen starten voor wijzigingen in meester tak:

trigger:
- master

Vervolgens moeten we een virtuele machine selecteren. Voorlopig zal het een door Microsoft gehoste agent zijn met Windows Server 2019 en Visual Studio 2019:

pool:
  vmImage: 'windows-latest'

Laten we verder gaan met de hoofdtekst van het configuratiebestand (block stappen). Ondanks dat je geen willekeurige software op een virtuele machine kunt installeren, heb ik geen Docker-container toegevoegd. We kunnen Chocolatey toevoegen als extensie voor Azure DevOps. Om dit te doen, gaan we naar link. Klik Krijg het gratis. Als u vervolgens al geautoriseerd bent, selecteert u eenvoudig uw account en als dat niet het geval is, doet u hetzelfde na autorisatie.

PVS-Studio bevindt zich nu in Chocolatey: Chocolatey controleren onder Azure DevOps

Hier moet u selecteren waar we de extensie zullen toevoegen en op de knop klikken Install.

PVS-Studio bevindt zich nu in Chocolatey: Chocolatey controleren onder Azure DevOps

Na een succesvolle installatie klikt u op Ga verder naar organisatie:

PVS-Studio bevindt zich nu in Chocolatey: Chocolatey controleren onder Azure DevOps

U kunt nu de sjabloon voor de Chocolatey-taak in het venster zien taken bij het bewerken van een configuratiebestand azure-pipelines.yml:

PVS-Studio bevindt zich nu in Chocolatey: Chocolatey controleren onder Azure DevOps

Klik op Chocolatey en bekijk een lijst met velden:

PVS-Studio bevindt zich nu in Chocolatey: Chocolatey controleren onder Azure DevOps

Hier moeten we selecteren installeren met de teams op het veld. IN Nuspec-bestandsnaam geef de naam van het gewenste pakket aan – pvs-studio. Als u de versie niet opgeeft, wordt de nieuwste versie geïnstalleerd, wat helemaal bij ons past. Laten we op de knop drukken toevoegen en we zullen de gegenereerde taak in het configuratiebestand zien.

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

Laten we vervolgens verder gaan met het hoofdgedeelte van ons bestand:

- task: CmdLine@2
  inputs:
    script: 

Nu moeten we een bestand maken met de analyserlicentie. Hier PVSNAAM и PVSKEY – namen van variabelen waarvan we de waarden specificeren in de instellingen. Zij slaan de login en licentiesleutel van PVS-Studio op. Om hun waarden in te stellen, opent u het menu Variabelen->Nieuwe variabele. Laten we variabelen maken PVSNAAM voor inloggen en PVSKEY voor de analysatorsleutel. Vergeet niet het vakje aan te vinken Houd deze waarde geheim voor PVSKEY. Commandocode:

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

Laten we het project bouwen met behulp van het bat-bestand in de repository:

сall build.bat

Laten we een map maken waarin bestanden met de resultaten van de analyser worden opgeslagen:

сall mkdir PVSTestResults

Laten we beginnen met het analyseren van het project:

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

We converteren ons rapport naar HTML-formaat met behulp van het hulpprogramma PlogСonverter:

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

Nu moet u een taak aanmaken zodat u het rapport kunt uploaden.

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

Het volledige configuratiebestand ziet er als volgt uit:

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

Laten we klikken Opslaan->Opslaan->Uitvoeren om de taak uit te voeren. Laten we het rapport downloaden door naar het tabblad Taken te gaan.

PVS-Studio bevindt zich nu in Chocolatey: Chocolatey controleren onder Azure DevOps

Het Chocolatey-project bevat slechts 37615 regels C#-code. Laten we eens kijken naar enkele van de gevonden fouten.

Test resultaten

Waarschuwing N1

Analysatorwaarschuwing: V3005 De variabele 'Provider' wordt aan zichzelf toegewezen. CrytpoHashProviderSpecs.cs 38

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

De analysator heeft een toewijzing van de variabele aan zichzelf gedetecteerd, wat niet logisch is. Hoogstwaarschijnlijk zou er in plaats van een van deze variabelen een andere moeten zijn. Nou ja, of dit is een typefout en de extra opdracht kan eenvoudig worden verwijderd.

Waarschuwing N2

Analysatorwaarschuwing: V3093 [CWE-480] De operator '&' evalueert beide operanden. Misschien moet in plaats daarvan een '&&'-operator voor kortsluiting worden gebruikt. 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;
  }
}

Operatorverschil & van de exploitant && is dat als de linkerkant van de uitdrukking is vals, dan wordt nog steeds de rechterkant berekend, wat in dit geval onnodige methodeaanroepen impliceert systeem.directory_bestaat.

In het beschouwde fragment is dit een klein minpunt. Ja, deze voorwaarde kan worden geoptimaliseerd door de &-operator te vervangen door de &&-operator, maar vanuit praktisch oogpunt heeft dit nergens invloed op. In andere gevallen kan verwarring tussen & en && echter ernstige problemen veroorzaken wanneer de rechterkant van de expressie wordt behandeld met onjuiste/ongeldige waarden. In onze foutenverzameling bijvoorbeeld geïdentificeerd met behulp van de V3093-diagnose, er is dit geval:

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

Zelfs als de index k onjuist is, wordt het gebruikt om toegang te krijgen tot een array-element. Als gevolg hiervan wordt er een uitzondering gegenereerd IndexOutOfRangeException.

Waarschuwingen N3, N4

Analysatorwaarschuwing: V3022 [CWE-571] Expressie 'shortPrompt' is altijd waar. InteractivePrompt.cs 101
Analysatorwaarschuwing: V3022 [CWE-571] Expressie 'shortPrompt' is altijd waar. 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
    ....
  }
  ....
}

In dit geval schuilt er een vreemde logica achter de werking van de ternaire operator. Laten we het eens nader bekijken: als aan de voorwaarde is voldaan die ik met nummer 1 heb gemarkeerd, gaan we verder met voorwaarde 2, die altijd waar, wat betekent dat regel 3 wordt uitgevoerd. Als voorwaarde 1 onwaar blijkt te zijn, gaan we naar de regel gemarkeerd met nummer 4, de voorwaarde waarin ook altijd is waar, wat betekent dat regel 5 wordt uitgevoerd. De voorwaarden gemarkeerd met commentaar 0 zullen dus nooit worden vervuld, wat misschien niet precies de werkingslogica is die de programmeur had verwacht.

Waarschuwing N5

Analysatorwaarschuwing: V3123 [CWE-783] Misschien werkt de '?:'-operator op een andere manier dan verwacht. De prioriteit ervan is lager dan de prioriteit van andere operators in deze toestand. Opties.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);
  }
}

De diagnose werkte voor de lijn:

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

Sinds de variabele j een paar regels erboven is geïnitialiseerd op nul, de ternaire operator retourneert de waarde vals. Vanwege deze voorwaarde wordt de hoofdtekst van de lus slechts één keer uitgevoerd. Het lijkt mij dat dit stukje code helemaal niet werkt zoals de programmeur het bedoeld heeft.

Waarschuwing N6

Analysatorwaarschuwing: V3022 [CWE-571] Expressie 'installedPackageVersions.Count != 1' is altijd waar. 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);
    }
    ....
  }
  ....
}

Er is hier sprake van een vreemde geneste toestand: geïnstalleerdPackageVersions.Count != 1wat altijd zo zal zijn waar. Vaak duidt een dergelijke waarschuwing op een logische fout in de code, en in andere gevallen duidt het eenvoudigweg op een overbodige controle.

Waarschuwing N7

Analysatorwaarschuwing: V3001 Er zijn identieke subexpressies 'commandArguments.contains("-apikey")' links en rechts van de '||' exploitant. 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");
}

De programmeur die dit codegedeelte heeft geschreven, heeft de laatste twee regels gekopieerd en geplakt en vergat ze te bewerken. Hierdoor konden Chocolatey-gebruikers de parameter niet toepassen API sleutel nog een paar manieren. Net als de bovenstaande parameters kan ik de volgende opties aanbieden:

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

Kopieer- en plakfouten hebben een grote kans vroeg of laat op te duiken in projecten met een grote hoeveelheid broncode, en een van de beste hulpmiddelen om deze te bestrijden is statische analyse.

PS En zoals altijd verschijnt deze fout vaak aan het einde van een voorwaarde met meerdere regels :). Zie publicatie"Laatste regeleffect".

Waarschuwing N8

Analysatorwaarschuwing: V3095 [CWE-476] Het object 'installedPackage' is gebruikt voordat het werd geverifieerd op nul. Controleer lijnen: 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)
  {
    ....
  }
  ....
}

Klassieke fout: eerst bezwaar maken geïnstalleerdPakket wordt gebruikt en vervolgens gecontroleerd nul. Deze diagnose vertelt ons over een van de twee problemen in het programma: ofwel geïnstalleerdPakket nooit gelijk nul, wat twijfelachtig is, en dan is de controle overbodig, anders kunnen we mogelijk een ernstige fout in de code krijgen: een poging om toegang te krijgen tot een nulreferentie.

Conclusie

We hebben dus weer een kleine stap gezet: het gebruik van PVS-Studio is nu nog eenvoudiger en handiger geworden. Ik zou ook willen zeggen dat Chocolatey een goede pakketbeheerder is met een klein aantal fouten in de code, wat zelfs nog minder zou kunnen zijn bij gebruik van PVS-Studio.

We nodigen je uit скачать en probeer PVS-Studio. Regelmatig gebruik van een statische analysator zal de kwaliteit en betrouwbaarheid van de code die uw team ontwikkelt verbeteren en veel ervan helpen voorkomen zero day-kwetsbaarheden.

PS

Vóór publicatie hebben we het artikel naar de Chocolatey-ontwikkelaars gestuurd en zij hebben het goed ontvangen. We hebben niets kritisch gevonden, maar ze waren bijvoorbeeld blij met de bug die we vonden met betrekking tot de ‘api-key’-sleutel.

PVS-Studio bevindt zich nu in Chocolatey: Chocolatey controleren onder Azure DevOps

Als u dit artikel met een Engelssprekend publiek wilt delen, gebruik dan de vertaallink: Vladislav Stolyarov. PVS-Studio is nu in Chocolatey: Chocolatey controleren onder Azure DevOps.

Bron: www.habr.com

Voeg een reactie