PVS-Studio er nÄ i Chocolatey: sjekk Chocolatey fra Azure DevOps

PVS-Studio er nÄ i Chocolatey: sjekk Chocolatey fra Azure DevOps
Vi fortsetter Ä gjÞre bruken av PVS-Studio mer praktisk. NÄ er analyseverktÞyet vÄrt tilgjengelig i Chocolatey, en pakkehÄndterer for Windows. Vi mener dette vil lette distribusjonen av PVS-Studio, spesielt i sky-tjenester. For Ä ikke gÄ langt, la oss sjekke kildekoden til nettopp Chocolatey. Som CI-system vil Azure DevOps bli brukt.

Her er en liste over andre artikler om integrasjon med sky-systemer:

Jeg anbefaler Ä se nÊrmere pÄ den fÞrste artikkelen om integrasjon med Azure DevOps, da i dette tilfellet er noen punkter utelatt for ikke Ä duplisere informasjon.

SĂ„, heltene i denne artikkelen:

PVS-Studio — et statisk kodeanalyseverktĂžy designet for Ă„ identifisere feil og potensielle sĂ„rbarheter i programmer skrevet i sprĂ„kene C, C++, C# og Java. Det fungerer pĂ„ 64-bits systemer pĂ„ Windows, Linux og macOS, og kan analysere kode beregnet for 32-bits, 64-bits og innebygde ARM-plattformer. Hvis du prĂžver statisk kodeanalyse for fĂžrste gang for Ă„ sjekke prosjektene dine, anbefaler vi Ă„ se nĂŠrmere pĂ„ artikkelen om hvordan du raskt kan se de mest interessante advarslene fra PVS-Studio og vurdere mulighetene til dette verktĂžyet.

Azure DevOps — et sett med sky-tjenester som dekker hele utviklingsprosessen. Plattformen inkluderer verktþy som Azure Pipelines, Azure Boards, Azure Artifacts, Azure Repos, Azure Test Plans, som gjþr at programvareutviklingsprosessen kan akselereres og kvaliteten forbedres.

Chocolatey – en pakkehĂ„ndterer for Windows med Ă„pen kildekode. Prosjektets mĂ„l er Ă„ automatisere hele livssyklusen til programvare fra installasjon til oppdatering og fjerning i Windows-operativsystemer.

Om bruken av Chocolatey

Se hvordan du installerer selve pakkehÄndtereren i denne lenken. Den komplette dokumentasjonen for installasjon av analyseverktÞyet er tilgjengelig pÄ lenken i delen «Installasjon med pakkehÄndtereren Chocolatey». La meg kort gjenta noen punkter derfra.

Kommandoen for Ă„ installere den nyeste versjonen av analyseverktĂžyet:

choco install pvs-studio

Kommandoen for Ă„ installere en spesifikk versjon av PVS-Studio-pakken:

choco install pvs-studio --version=7.05.35617.2075

Som standard installeres kun analyzatorens kjerne — komponenten Core. Alle andre flagg (Standalone, JavaCore, IDEA, MSVS2010, MSVS2012, MSVS2013, MSVS2015, MSVS2017, MSVS2019) kan overfþres ved hjelp av —package-parameters.

Eksempel pÄ en kommando som installerer analyzatoren med et plugin for Visual Studio 2019:

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

La oss nÄ se pÄ et eksempel pÄ bruk av analyzatoren under Azure DevOps.

Konfigurasjon

Jeg minner om at for aspekter som registrering av en konto, oppretting av Build Pipeline og synkronisering av kontoen med prosjektet som ligger i GitHub-repositoriet, finnes det et eget article. VÄr oppsett vil imidlertid begynne med Ä skrive konfigurasjonsfilen.

FĂžrst vil vi konfigurere utlĂžseren, og angi at vi kun aktiverer for endringer i master grenen:

trigger:
- master

Deretter mÄ vi velge en virtuell maskin. Per nÄ vil dette vÊre en Microsoft-hosted agent med Windows Server 2019 og Visual Studio 2019:

pool:
  vmImage: 'windows-latest'

La oss gÄ videre til kroppen av konfigurasjonsfilen (blokk steps). Selv om det ikke er mulig Ä installere vilkÄrlig programvare pÄ den virtuelle maskinen, har jeg valgt Ä ikke legge til Docker-containerne. Vi kan legge til Chocolatey som en utvidelse for Azure DevOps. For dette, gÄ til lenken. Klikk pÄ Get it free. Hvis du allerede er logget inn, velger du bare kontoen din, ellers fÞlger du de samme trinnene etter innlogging.

PVS-Studio er nÄ i Chocolatey: sjekk Chocolatey fra Azure DevOps

Her mÄ vi velge hvor vi vil legge til utvidelsen og trykke pÄ knappen Installer.

PVS-Studio er nÄ i Chocolatey: sjekk Chocolatey fra Azure DevOps

Etter at installeringen er fullfÞrt, klikker vi pÄ Proceed to organization:

PVS-Studio er nÄ i Chocolatey: sjekk Chocolatey fra Azure DevOps

NÄ kan vi se malen for Chocolatey-oppgaven i vinduet tasks nÄr vi redigerer konfigurasjonsfilen azure-pipelines.yml:

PVS-Studio er nÄ i Chocolatey: sjekk Chocolatey fra Azure DevOps

Klikk pÄ Chocolatey og se listen over felt:

PVS-Studio er nÄ i Chocolatey: sjekk Chocolatey fra Azure DevOps

Her mĂ„ vi velge install i feltet med kommandoer. I Nuspec File Name oppgir vi navnet pĂ„ den nĂždvendige pakken – pvs-studio. Hvis vi ikke oppgir versjonen, vil den siste installeres, noe som er helt greit for oss. Klikk pĂ„ knappen add og se oppgaven som er generert i konfigurasjonsfilen.

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

Deretter gÄr vi til hoveddelen av filen vÄr:

- task: CmdLine@2
  inputs:
    script: 

NĂ„ mĂ„ vi opprette en fil med lisensen til analyzatoren. Her PVSNAME og PVSKEY – er navnene pĂ„ variablene, verdiene som vi angir i innstillingen. De vil lagre brukernavnet og lisensnĂžkkelen for PVS-Studio. For Ă„ sette verdiene deres Ă„pner vi menyen Variables->New variable. Vi skal opprette variabler PVSNAME for brukernavnet og PVSKEY for the analyzer key. Don't forget to check the box Hold this value confidential for PVSKEYCommand code:

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

We will compile the project using the bat file located in the repository:

call build.bat

Let's create a folder where the analyzer's result files will be stored:

call mkdir PVSTestResults

Let's start the project analysis:

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

We'll 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 allow the report to be uploaded.

- 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 run the task. We will upload the report after accessing the tasks tab.

PVS-Studio er nÄ i Chocolatey: sjekk Chocolatey fra Azure DevOps

The Chocolatey project contains a total of 37,615 lines of C# code. Let's look at some of the errors found.

Check results

Advarsel N1

Analyzer warning: V3005 The ‘Provider’ variable is assigned to itself. CrytpoHashProviderSpecs.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 was assigned to itself, which makes no sense. Most likely, one of these variables should be some other. Or this is a typo, and the redundant assignment can simply be removed.

Advarsel 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 difference between the operator & and the operator && is that if the left part of the expression — false, so it will still calculate the right part, which in this case implies unnecessary method calls. system.directory_exists.

In the discussed fragment, this is a minor oversight. Yes, this condition can be optimized by replacing the operator & with the operator &&, but from a practical standpoint, it does not affect anything. However, in other cases, the confusion between & and && can lead to serious problems when the right part of the expression operates with incorrect/invalid values. For example, in our collection of errors, identified through diagnostic V3093, there is such a case:

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

Even if the index k is incorrect, it will be used to access the array element. As a result, an exception will be generated IndexOutOfRangeException.

Warnings N3, N4

Analyzer warning: V3022 [CWE-571] Expression ‘shortPrompt’ is always true. InteractivePrompt.cs 101
Analyzer warning: V3022 [CWE-571] Expression ‘shortPrompt’ is always true. 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 this case, there is a strange logic in how the ternary operator works. Let's consider in more detail: if the condition marked by me with the number 1 is executed, we will move to condition 2, which is always true, which means line 3 will be executed. If condition 1 turns out to be false, we will move to the line marked with number 4, which is also always true, which means line 5 will be executed. Thus, the conditions marked with comment 0 will never be executed, which may not be exactly the logic that the programmer was counting on.

Advarsel N5

Analyzer warning: V3123 [CWE-783] Perhaps the ‘?:’ operator works in a different way than it was expected. Its priority is lower than priority of other operators in its condition. 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);
  }
}

The diagnosis triggered on line:

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

Since the variable j Tohu kvenn kem dnatikk er i fÀðr? false. Av denne grunnen vil kroppens lÞkke bare kjÞre én gang. Jeg synes denne kodesnutten fungerer helt annerledes enn programmereren hadde tenkt.

Advarsel N6

Analyzer warning: V3022 [CWE-571] Uttrykket ‘installedPackageVersions.Count != 1’ er alltid sant. NugetService.cs 1405

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

Her er det en merkelig nestet betingelse: installedPackageVersions.Count != 1, som alltid vil vĂŠre true. Slik advarsler indikerer ofte en logisk feil i koden, og i andre tilfeller bare en unĂždvendig sjekk.

Advarsel N7

Analyzer warning: V3001 Det er identiske sub-uttrykk ‘commandArguments.contains("-apikey")’ til venstre og til hþyre 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 som skrev denne koden har kopiert de to siste linjene og glemt Ä redigere dem. Som et resultat har brukerne av Chocolatey mistet muligheten til Ä bruke parameteren apikey pÄ flere mÄter. I likhet med parameterne ovenfor, kan jeg foreslÄ fÞlgende alternativer:

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

Copy-paste feil har stor sjanse for Ă„ dukke opp i ethvert prosjekt med mye kildekode, og et av de beste verktĂžyene for Ă„ bekjempe dem er statisk analyse.

P.S. Og som alltid, har denne feilen en tendens til Ä oppstÄ pÄ slutten av en flerlags betingelse :). Se publikasjonen "Effekten av den siste linjen".

Advarsel N8

Analyzer warning: V3095 [CWE-476] ‘installedPackage’-objektet ble brukt fþr det ble verifisert mot null. Sjekk linjer: 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)
  {
    ....
  }
  ....
}

Klassisk feil: objektet brukes fĂžrst installedPackage og deretter sjekkes for null. Denne diagnosen forteller oss om et av to problemer i programmet: enten installedPackage aldri er lik null, noe som er tvilsomt, og da er sjekken overflĂždig, eller vi kan potensielt fĂ„ en alvorlig feil i koden – et forsĂžk pĂ„ Ă„ fĂ„ tilgang til nullreferansen.

Konklusjon

Her har vi tatt et lite skritt videre – nĂ„ er det enda enklere og mer praktisk Ă„ bruke PVS-Studio. Jeg vil ogsĂ„ si at Chocolatey er en god pakkebehandler med et lite antall feil i koden, som kunne vĂŠrt enda fĂŠrre med bruk av PVS-Studio.

Vi inviterer lastes ned og prÞve PVS-Studio. Jevnlig bruk av statisk analyser vil forbedre kvaliteten og pÄliteligheten til koden utviklet av teamet ditt og hjelpe med Ä forhindre mange null-dag sÄrbarheter.

P.S.

FĂžr publisering sendte vi artikkelen til Chocolatey-utviklerne, og de tok imot den godt. Ingenting kritisk ble funnet av oss, men de likte for eksempel feilen vi fant, knyttet til nĂžkkelen "api-key".

PVS-Studio er nÄ i Chocolatey: sjekk Chocolatey fra Azure DevOps

Hvis du vil dele denne artikkelen med et engelsksprÄklig publikum, vennligst bruk linken til oversettelsen: Vladislav Stolyarov. PVS-Studio er nÄ i Chocolatey: Sjekker Chocolatey under Azure DevOps.

Kilde: habr.com

KjĂžp pĂ„litelig hosting for nettsteder med DDoS-beskyttelse, VPS VDS-servere đŸ”„ KjĂžp pĂ„litelig hosting for nettsteder med DDoS-beskyttelse, VPS VDS-servere | ProHoster