PVS-Studio er nu pÄ Chocolatey: kontrollerer Chocolatey fra Azure DevOps

PVS-Studio er nu pÄ Chocolatey: kontrollerer Chocolatey fra Azure DevOps
Vi fortsÊtter med at gÞre brug af PVS-Studio mere bekvemt. Nu er vores analyser tilgÊngelige pÄ Chocolatey, en pakkeadministrator til Windows. Vi mener, at dette vil lette implementeringen af PVS-Studio, isÊr i cloud-tjenester. For ikke at gÄ for langt, lad os tjekke koden fra det samme Chocolatey. Azure DevOps vil fungere som CI-system.

Her er en liste over vores andre artikler om integration med cloud-systemer:

Jeg anbefaler at tage et kig pÄ den fÞrste artikel om integration med Azure DevOps, da nogle punkter er udeladt for ikke at duplikere.

SĂ„ heltene i denne artikel er:

PVS-Studio — et vĂŠrktĂžj til statisk kodeanalyse designet til at opdage fejl og potentielle sĂ„rbarheder i programmer skrevet i C, C++, C# og Java. Det fungerer i 64-bit systemer pĂ„ Windows, Linux og macOS og kan analysere kode beregnet til 32-bit, 64-bit og indlejrede ARM-platforme. Hvis du prĂžver statisk kodeanalyse for fĂžrste gang for at teste dine projekter, anbefaler vi at lĂŠse artiklen om hvordan man hurtigt kan se de mest interessante advarsler fra PVS-Studio og vurdere mulighederne for dette vĂŠrktĂžj.

Azure DevOps — en rékke cloud-tjenester, der dékker hele udviklingsprocessen. Platformen omfatter vérktþjer som Azure Pipelines, Azure Boards, Azure Artifacts, Azure Repos, Azure Test Plans, som gþr det muligt at fremskynde softwareudviklingsprocessen og forbedre kvaliteten.

Chocolatey – en open source pakkeadministrator til Windows. Projektets mĂ„l er at automatisere hele livscyklussen for software fra installation til opdatering og sletning i Windows-operativsystemer.

Om brugen af Chocolatey

Du kan finde ud af, hvordan du installerer selve pakkeadministratoren, via denne linket. Den fulde dokumentation til installation af analysatoren er tilgĂŠngelig under linket afsnittet 'Installation ved hjĂŠlp af Chocolatey pakkeadministrator'. Jeg vil kort gentage nogle punkter derfra.

Kommandoen til at installere den seneste version af analysatoren:

choco install pvs-studio

Kommandoen til at installere en specifik version af PVS-Studio-pakken:

choco install pvs-studio --version=7.05.35617.2075

Som standard installeres kun kernen af analysatoren - komponenten Core. Alle andre flag (Standalone, JavaCore, IDEA, MSVS2010, MSVS2012, MSVS2013, MSVS2015, MSVS2017, MSVS2019) kan overfĂžres ved hjĂŠlp af --package-parameters.

Eksempel pÄ en kommando, der installerer analysatoren med et plugin til Visual Studio 2019:

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

Lad os nu se pÄ et eksempel pÄ, hvordan man praktisk bruger analysatoren under Azure DevOps.

Indstillinger

Jeg minder om, at der er en separat guide til emner som registrering af en konto, oprettelse af Build Pipeline og synkronisering af kontoen med et projekt, der ligger i et repository pÄ GitHub. artikel. Vores opsÊtning vil dog straks begynde med at skrive konfigurationsfilen.

For at starte skal vi konfigurere en starttrigger ved at angive, at vi kun udfĂžrer kĂžrsel for ĂŠndringer i master branch:

trigger:
- master

DernĂŠst skal vi vĂŠlge en virtuel maskine. PĂ„ nuvĂŠrende tidspunkt vil det vĂŠre en Microsoft-hosted agent med Windows Server 2019 og Visual Studio 2019:

pool:
  vmImage: 'windows-latest'

Lad os gÄ videre til brÞdteksten i konfigurationsfilen (blok steps). Selvom vi ikke kan installere vilkÄrlig software pÄ den virtuelle maskine, tilfÞjede jeg ikke en Docker-container. Vi kan tilfÞje Chocolatey som en udvidelse til Azure DevOps. For at gÞre dette gÄr vi til linket. Klikker pÄ Get it free. Hvis du allerede er logget ind, vÊlger du blot din konto; hvis ikke, sÄ fÞlger du de samme trin efter login.

PVS-Studio er nu pÄ Chocolatey: kontrollerer Chocolatey fra Azure DevOps

Her skal du vÊlge, hvor vi skal tilfÞje udvidelsen, og klikke pÄ knappen Installer.

PVS-Studio er nu pÄ Chocolatey: kontrollerer Chocolatey fra Azure DevOps

Efter en vellykket installation klikker vi pÄ Proceed to organization:

PVS-Studio er nu pÄ Chocolatey: kontrollerer Chocolatey fra Azure DevOps

Nu kan vi se skabelonen til Chocolatey-opgaven i vinduet tasks ved redigering af konfigurationsfilen azure-pipelines.yml:

PVS-Studio er nu pÄ Chocolatey: kontrollerer Chocolatey fra Azure DevOps

Klik pÄ Chocolatey og se listen over felter:

PVS-Studio er nu pÄ Chocolatey: kontrollerer Chocolatey fra Azure DevOps

Her skal vi vĂŠlge installation i feltet med kommandoer. I Nuspec File Name angiver vi navnet pĂ„ den Ăžnskede pakke – pvs-studio. Hvis vi ikke angiver en version, installeres den seneste, hvilket er helt fint for os. Klik pĂ„ knappen add og vi vil se den dannede opgave i konfigurationsfilen.

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

Lad os derefter gÄ videre til hoveddelen af vores fil:

- task: CmdLine@2
  inputs:
    script: 

Nu skal vi oprette en fil med licensen til analysatoren. Her PVSNAME og PVSKEY – er navnene pĂ„ variablerne, hvis vĂŠrdier vi angiver i indstillingerne. De vil gemme login og licensnĂžgle til PVS-Studio. For at angive deres vĂŠrdier Ă„bner vi menuen Variables->New variable. Vi opretter variabler PVSNAME for login og PVSKEY for analyzer key. Don’t forget to check the box Hold this value confidential for PVSKEY. Command code:

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

We will build the project using the bat file available in the repository:

call build.bat

Let’s create a folder where the analyzer results will be stored:

call mkdir PVSTestResults

We will start the project analysis:

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

We will convert our report to HTML format using the PlogConverter utility:

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

Now we need to create a task to upload the report.

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

The complete configuration file looks like this:

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

Let’s press Save->Save->Run to trigger the task. We will upload the report by going to the task tab.

PVS-Studio er nu pÄ Chocolatey: kontrollerer Chocolatey fra Azure DevOps

The Chocolatey project contains a total of 37615 lines of C# code. Let’s take a look at some of the identified errors.

Analysis results

Warning N1

Analyzer warning: V3005 The ‘Provider’ variable is assigned to itself. CryptoHashProviderSpecs.cs 38

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

The analyzer detected that a variable is assigned to itself, which makes no sense. Most likely, one of these variables should be something else. Or it's a typo and the redundant assignment can simply be removed.

Warning N2

Analyzer warning: V3093 [CWE-480] The ‘&’ operator evaluates both operands. Perhaps a short-circuit ‘&&’ operator should be used instead. 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;
  }
}

The distinction of the operator & from the operator && handler om, at hvis venstre del af udtrykket — false, vil den hþjre del stadig blive beregnet, hvilket i dette tilfélde indebérer unþdvendige metodekald system.directory_exists.

I det behandlede fragment er dette en lille fejl. Ja, denne betingelse kan optimeres ved at erstatte operatoren & med operatoren &&, men fra et praktisk synspunkt har det ingen indflydelse. Imidlertid kan forvirringen mellem & og && i andre tilfÊlde forÄrsage alvorlige problemer, nÄr hÞjre del af udtrykket arbejder med ugyldige/ulovlige vÊrdier. For eksempel, i vores fejlsamling, identificeret ved diagnosticering V3093, er der et sÄdant tilfÊlde:

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

Selv hvis indekset k er ugyldigt, vil det stadig blive brugt til at tilgÄ elementet i arrayet. Resultatet vil vÊre, at der genereres en undtagelse IndexOutOfRangeException.

Advarsler N3, N4

Analyzer warning: V3022 [CWE-571] Udtryk ‘shortPrompt’ er altid sandt. InteractivePrompt.cs 101
Analyzer warning: V3022 [CWE-571] Udtryk ‘shortPrompt’ er altid sandt. 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
    ....
  }
  ....
}

I dette tilfÊlde er der en underlig logik i den ternÊre operator. Lad os se nÊrmere pÄ det: hvis betingelsen markeret med nummer 1 opfyldes, vil vi gÄ til betingelsen 2, som altid true, hvilket betyder, at linje 3 vil blive udfÞrt. Hvis betingelse 1 viser sig at vÊre falsk, gÄr vi til linjen markeret med nummer 4, hvor betingelsen ogsÄ altid true, hvilket betyder, at linje 5 ogsÄ vil blive udfÞrt. Dermed vil betingelserne markeret med kommentar 0 aldrig blive udfÞrt, hvilket kan vÊre en uventet logik, som programmÞren ikke havde forudset.

Advarsel N5

Analyzer warning: V3123 [CWE-783] MĂ„ske fungerer ‘?:’ operatoren pĂ„ en anden mĂ„de, end forventet. Dens prioritet er lavere end prioriteten af andre operatorer i sin betingelse. 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 = 0 && j != 0 ? description [j++ - 1] == '{' : false);
    ....
    return maxIndex == 1 ? "VALUE" : "VALUE" + (index + 1);
  }
}

Diagnose blev udlÞst pÄ linje:

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

Da variablen j initialiseres til nul flere linjer ovenfor, vil den ternÊre operator returnere vÊrdien false. PÄ grund af denne betingelse vil lÞkkens krop kun blive udfÞrt én gang. Jeg mener, at denne kodefragments funktionalitet ikke fungerer som programmereren mente.

Advarsel N6

Analyzer warning: V3022 [CWE-571] Udtrykket ‘installedPackageVersions.Count != 1’ er altid sandt. NugetService.cs 1405

private void remove_nuget_cache_for_package(....)
{
  if (!config.AllVersions && installedPackageVersions.Count > 1)
  {
    const string allVersionsChoice = "Alle versioner";
    if (installedPackageVersions.Count != 1)
    {
      choices.Add(allVersionsChoice);
    }
    ....
  }
  ....
}

Her er en mÊrkelig indlejret betingelse: installedPackageVersions.Count != 1, som altid vil vÊre true. Ofte indikerer en sÄdan advarsel en logisk fejl i koden, i andre tilfÊlde blot en overflÞdig kontrol.

Advarsel N7

Analyzer warning: V3001 Der er identiske deludtryk ‘commandArguments.contains("-apikey")’ til venstre og til hþjre for '||'-operatoren. 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");
}

Programmereren, der skrev dette kodefragment, har kopieret de sidste to linjer og glemt at redigere dem. Dette har medfÞrt, at brugere af Chocolatey har mistet muligheden for at anvende parameteren apikey pÄ et par andre mÄder. Tilsvarende til de ovenstÄende parametre kan jeg foreslÄ fÞlgende muligheder:

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

Copy-paste fejl har en stor chance for at opstÄ fÞr eller senere i ethvert projekt med meget kildekode, og et af de bedste redskaber til at bekÊmpe dem er statisk analyse.

P.S. Og som altid har denne fejl tendens til at opstÄ i slutningen af en flerlinjede betingelse :). Se indlÊgget "Effekten af den sidste linje".

Advarsel N8

Analyzer warning: V3095 [CWE-476] 'installedPackage'-objektet blev brugt, fĂžr det blev verificeret mod null. Tjek linjer: 910, 917. NugetService.cs 910

offentlig virtuel 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)
  {
    ....
  }
  ....
}

Klassisk fejl: objektet bruges fĂžrst installedPackage og kontrolleres derefter for null. Denne diagnose indikerer et af to problemer i programmet: enten installedPackage er aldrig lig med null, hvilket er tvivlsomt, og sĂ„ er kontrolen overflĂždig, eller vi kan potentielt fĂ„ en alvorlig fejl i koden – et forsĂžg pĂ„ at tilgĂ„ en null reference.

Konklusion

Her har vi taget endnu et lille skridt – nu er det endnu nemmere og mere praktisk at bruge PVS-Studio. Jeg vil ogsĂ„ sige, at Chocolatey er en god pakkeadministrator med fĂ„ fejl i koden, som kunne vĂŠre endnu fĂŠrre ved brug af PVS-Studio.

Vi inviterer downloade og til at prÞve PVS-Studio. RegelmÊssig brug af en statisk analysator vil forbedre kvaliteten og pÄlideligheden af den kode, dit team udvikler, og hjÊlpe med at forhindre mange zero-day sÄrbarheder.

P.S.

Fþr offentliggþrelsen sendte vi artiklen til udviklerne af Chocolatey, og de modtog den godt. Der blev ikke fundet noget kritisk af os, men de kunne for eksempel lide den fejl, vi fandt, relateret til ‘api-key’.

PVS-Studio er nu pÄ Chocolatey: kontrollerer Chocolatey fra Azure DevOps

Hvis du Þnsker at dele denne artikel med et engelsktalende publikum, sÄ bedes du bruge linket til oversÊttelsen: Vladislav Stolyarov. PVS-Studio er nu i Chocolatey: Tjekker Chocolatey under Azure DevOps.

Kilde: habr.com

KĂžb pĂ„lidelig webhosting med DDoS-beskyttelse, VPS VDS-servere đŸ”„ KĂžb pĂ„lidelig webhosting med DDoS-beskyttelse, VPS VDS-servere | ProHoster