PVS-Studio nun estas en Chocolatey: kontrolanta Chocolatey de sub Azure DevOps

PVS-Studio nun estas en Chocolatey: kontrolanta Chocolatey de sub Azure DevOps
Ni daŭre plibonigas la uzeblecon de PVS-Studio. Nia analizilo nun haveblas en Chocolatey, pakaĵadministrilo por WindowsNi kredas, ke ĉi tio faciligos la deplojon de PVS-Studio, precipe en nubaj servoj. Por komenci, ni ekzamenu la fontkodon de Chocolatey. Azure DevOps servos kiel la CI-sistemo.

Jen listo de niaj aliaj artikoloj pri nuba integriĝo:

Mi rekomendas atenti la unuan artikolon pri integriĝo kun Azure DevOps, ĉar en ĉi tiu kazo iuj punktoj estas preterlasitaj por eviti duobligon.

Do, la herooj de ĉi tiu artikolo:

PVS Studio — statika kodanalizilo desegnita por detekti erarojn kaj eblajn vundeblecojn en programoj skribitaj en C, C++, C# kaj Java. Funkcias sur 64-bitaj sistemoj. Windows, Linux и macOS, kaj povas analizi kodon celantan 32-bitajn, 64-bitajn kaj enigitajn ARM-platformojn. Se vi provas statikan kodanalizon por viaj projektoj por la unua fojo, ni rekomendas alkutimiĝi al artikolo pri kiel rapide vidi la plej interesajn avertojn de PVS-Studio kaj taksi la kapablojn de ĉi tiu ilo.

Azure DevOps — aro da nubaj servoj, kiuj kolektive kovras la tutan disvolviĝan procezon. Ĉi tiu platformo inkluzivas ilojn kiel Azure Pipelines, Azure Boards, Azure Artifacts, Azure Repos, Azure Test Plans, kiuj permesas al vi rapidigi la programaran disvolviĝan procezon kaj plibonigi ĝian kvaliton.

Ĉokolado – pakaĵadministrilo por Windows malfermitkoda. La celo de la projekto estas aŭtomatigi la tutan vivciklon de programaro, de instalado ĝis ĝisdatigoj kaj forigo, en operaciumoj. Windows.

Pri Uzado de Ĉokolada

Vi povas vidi kiel instali la pakaĵadministrilon mem ĉi tie ligiloPlena dokumentado pri instalado de la analizilo haveblas ĉe ligilo en la sekcio "Instalado per la pakaĵadministrilo Chocolatey". Mi nelonge ripetos kelkajn punktojn de tie.

Komando por instali la plej novan version de la analizilo:

choco install pvs-studio

Komando por instali specifan version de la pakaĵo PVS-Studio:

choco install pvs-studio --version=7.05.35617.2075

Defaŭlte, nur la analizilo-kerno estas instalita — la Core-komponanto. Ĉiuj aliaj flagoj (Standalone, JavaCore, IDEA, MSVS2010, MSVS2012, MSVS2013, MSVS2015, MSVS2017, MSVS2019) povas esti pasitaj per --package-parameters.

Ekzempla komando kiu instalos la analizilon per kromprogramo por Visual Studio 2019:

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

Nun ni rigardu ekzemplon de oportuna uzo de la analizilo sub Azure DevOps.

alĝustigo

Permesu al mi memorigi vin, ke ekzistas aparta artikolo pri tiaj aferoj kiel registrado de konto, kreado de Build Pipeline, kaj sinkronigado de la konto kun la projekto situanta en la deponejo ĉe GitHub. artikoloNia agordo tuj komenciĝos per skribado de agordodosiero.

Unue, ni agordu lanĉan ellasilon, specifante ke ni lanĉu nur por ŝanĝoj en majstro branĉo:

trigger:
- master

Poste, ni bezonas elekti virtualan maŝinon. Tiam, ĝi estos Microsoft-gastigita agento kun Windows Server 2019 kaj Visual Studio 2019:

pool:
  vmImage: 'windows-latest'

Ni transiru al la korpo de la agordodosiero (bloko paŝoj). Kvankam vi ne povas instali arbitran programaron en virtuala maŝino, mi ne aldonis Docker-ujon. Ni povas aldoni Chocolatey kiel etendaĵon por Azure DevOps. Por fari tion, iru al ligiloAlklaku Akiru ĝin senpagePoste, se vi jam estas rajtigita, simple elektu vian konton, kaj se ne, tiam faru la samon post rajtigo.

PVS-Studio nun estas en Chocolatey: kontrolanta Chocolatey de sub Azure DevOps

Ĉi tie vi devas elekti kie ni aldonos la kromprogramon kaj alklaki la butonon instali.

PVS-Studio nun estas en Chocolatey: kontrolanta Chocolatey de sub Azure DevOps

Post sukcesa instalado, alklaku Daŭrigu al organizo:

PVS-Studio nun estas en Chocolatey: kontrolanta Chocolatey de sub Azure DevOps

Nun vi povas vidi la ŝablonon por la tasko Chocolatey en la fenestro. taskoj dum redaktado de la agordodosiero azure-pipelines.yml:

PVS-Studio nun estas en Chocolatey: kontrolanta Chocolatey de sub Azure DevOps

Ni alklaku Ĉokolada kaj vidu liston de kampoj:

PVS-Studio nun estas en Chocolatey: kontrolanta Chocolatey de sub Azure DevOps

Ĉi tie ni devas elekti instali en la kampo kun komandoj. En Dosiernomo de Nuspec ni specifos la nomon de la bezonata pakaĵo – pvs-studio. Se vi ne specifos la version, la plej nova estos instalita, kiu tute taŭgas al ni. Alklaku la butonon aldoni kaj ni vidos la generitan taskon en la agordodosiero.

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

Sekve, ni transiru al la ĉefa parto de nia dosiero:

- task: CmdLine@2
  inputs:
    script: 

Nun ni bezonas krei dosieron kun la permesilo de la analizilo. Jen PVSNAME и PVSKEY – nomoj de variabloj, kies valorojn ni specifas en la agordoj. Ili konservos la ensalutan kaj licencan ŝlosilon de PVS-Studio. Por agordi iliajn valorojn, malfermu la menuon Variabloj->Nova variabloNi kreu variablojn PVSNAME por ensaluto kaj PVSKEY por la analizilo-ŝlosilo. Ne forgesu marki la keston Tenu ĉi tiun valoron sekreta por PVSKEYKomanda kodo:

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

Ni konstruu la projekton uzante la bat-dosieron situantan en la deponejo:

сall build.bat

Ni kreu dosierujon, kie la dosieroj kun la rezultoj de la analizilo estos konservitaj:

сall mkdir PVSTestResults

Ni efektivigu la projektan analizon:

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

Ni konvertas nian raporton en html-formaton uzante la ilon PlogСonverter:

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

Nun vi bezonas krei taskon por ke vi povu alŝuti la raporton.

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

La kompleta agordodosiero aspektas jene:

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

Ni klaku Konservi->Konservi->Ekzekuti por plenumi la taskon. Ni elŝutu la raporton irante al la langeto tasko.

PVS-Studio nun estas en Chocolatey: kontrolanta Chocolatey de sub Azure DevOps

La projekto Chocolatey enhavas nur 37615 XNUMX liniojn de C#-kodo. Ni rigardu kelkajn el la trovitaj eraroj.

Testrezultoj

Averto N1

Averto pri analizilo: V3005 La variablo 'Provider' estas asignita al si mem. CrytpoHashProviderSpecs.cs 38

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

La analizilo detektis asignon de variablo al si mem, kio ne havas sencon. Plej verŝajne, devus esti alia variablo anstataŭ unu el ĉi tiuj variabloj. Aŭ temas pri preseraro, kaj la superflua asigno povas simple esti forigita.

Averto N2

Averto pri analizilo: V3093 [CWE-480] La operatoro '&' taksas ambaŭ operandojn. Eble oni devus uzi anstataŭe kurtcirkvitan operatoron '&&'. 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;
  }
}

Operatora Diferenco & de la funkciigisto && estas ke se la maldekstra flanko de la esprimo estas falsa, tiam la dekstra flanko ankoraŭ estos kalkulita, kio en ĉi tiu kazo implicas ekstrajn metodajn vokojn sistemo.dosierujo_ekzistas.

En la konsiderata fragmento, ĉi tio estas eta difekto. Jes, ĉi tiu kondiĉo povas esti optimumigita per anstataŭigo de la operatoro & per la operatoro &&, sed el praktika vidpunkto, ĉi tio nenion influas. Tamen, en aliaj kazoj, konfuzo inter & kaj && povas kaŭzi gravajn problemojn kiam la dekstra flanko de la esprimo funkcios kun malĝustaj/malvalidaj valoroj. Ekzemple, en nia kolekto de eraroj, identigita uzante diagnozan V3093, ekzistas tia kazo:

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

Eĉ se la indekso k estas malvalida, ĝi estos uzata por aliri elementon de tabelo. Tio rezultigos escepton ĵetitan. IndeksoElIntervaloEscepto.

Avertoj N3, N4

Averto pri analizilo: V3022 [CWE-571] Esprimo 'shortPrompt' ĉiam estas vera. InteractivePrompt.cs 101
Averto pri analizilo: V3022 [CWE-571] Esprimo 'shortPrompt' ĉiam estas vera. 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
    ....
  }
  ....
}

En ĉi tiu kazo, ekzistas stranga logiko de la ternara operatoro. Ni rigardu pli detale: se la kondiĉo, kiun mi markis per la numero 1, estas plenumita, tiam ni transiros al kondiĉo 2, kiu ĉiam estas veraj, kio signifas, ke linio 3 estos plenumita. Se kondiĉo 1 montriĝas falsa, tiam ni moviĝos al la linio markita per la numero 4, la kondiĉo en kiu ankaŭ ĉiam estas veraj, kio signifas, ke linio 5 estos plenumita. Tiel, la kondiĉoj markitaj per komento 0 neniam estos plenumitaj, kio eble ne tute konformas al la logiko de la laboro, kiun la programisto atendis.

Averto N5

Averto pri analizilo: V3123 [CWE-783] Eble la operatoro '?:' funkcias alimaniere ol atendite. Ĝia prioritato estas pli malalta ol la prioritato de aliaj operatoroj en ĝia kondiĉo. 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);
  }
}

La diagnozoj funkciis sur la linio:

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

Ĉar la variablo j kelkaj linioj supre estas inicialigita al nulo, la ternara operatoro redonos la valoron falsaPro ĉi tiu kondiĉo, la buklokorpo estos plenumata nur unufoje. Ŝajnas al mi, ke ĉi tiu peco de kodo ne funkcias kiel la programisto celis.

Averto N6

Averto pri analizilo: V3022 [CWE-571] Esprimo 'installedPackageVersions.Count != 1' ĉiam estas vera. 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);
    }
    ....
  }
  ....
}

Estas stranga nestita kondiĉo ĉi tie: instalitajPakajVersioj.Kalkulo != 1, kiu ĉiam estos verajOfte tia averto indikas logikan eraron en la kodo, kaj en aliaj kazoj simple troan kontrolon.

Averto N7

Averto pri analizilo: V3001 Ekzistas identaj subesprimoj 'commandArguments.contains("-apikey")' maldekstre kaj dekstre de la operatoro '||'. 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");
}

La programisto, kiu verkis ĉi tiun sekcion de kodo, kopiis kaj algluis la lastajn du liniojn kaj forgesis redakti ilin. Pro tio, uzantoj de Chocolatey ne povis apliki la parametron apikey kelkaj pliaj manieroj. Simile al la supre menciitaj parametroj, mi povas proponi la jenajn eblojn:

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

Kopi-alglui erarojn havas altan ŝancon aperi pli frue aŭ pli malfrue en iu ajn projekto kun granda kvanto da fontkodo, kaj unu el la plej bonaj rimedoj por kontraŭbatali ilin estas statika analizo.

P.S. Kaj kiel ĉiam, ĉi tiu eraro emas aperi ĉe la fino de plurlinia kondiĉo :). Vidu la publikaĵon "Lasta linia efiko".

Averto N8

Averto pri analizilo: V3095 [CWE-476] La objekto 'installedPackage' estis uzata antaŭ ol ĝi estis kontrolita kontraŭ nulo. Kontrolu liniojn: 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)
  {
    ....
  }
  ....
}

Klasika eraro: objekto unue instalita Pakaĵo estas uzata kaj poste kontrolata por nullĈi tiu diagnozo informas nin pri unu el du problemoj en la programo: aŭ instalita Pakaĵo neniam egala null, kio estas dubinda, kaj tiam la kontrolo estas redunda, aŭ ni povas eble ricevi gravan eraron en la kodo - provon aliri per nula referenco.

konkludo

Do, ni faris plian malgrandan paŝon - nun uzi PVS-Studio fariĝis eĉ pli facila kaj pli oportuna. Mi ankaŭ volas diri, ke Chocolatey estas bona pakaĵadministrilo kun malgranda nombro da eraroj en la kodo, kiuj povus esti eĉ malpli se oni uzus PVS-Studio.

Ni invitas vin скачать kaj provu PVS-Studio. Regula uzado de statika analizilo plibonigos la kvaliton kaj fidindecon de la kodo, kiun via teamo disvolvas, kaj helpos malhelpi multajn nul-tagaj vundeblecoj.

PS

Antaŭ la publikigo, ni sendis la artikolon al la programistoj de Chocolatey, kaj ili bone akceptis ĝin. Ni ne trovis ion ajn kritikan, sed ili ŝatis, ekzemple, la eraron, kiun ni trovis rilate al la ŝlosilo "api-key".

PVS-Studio nun estas en Chocolatey: kontrolanta Chocolatey de sub Azure DevOps

Se vi volas dividi ĉi tiun artikolon kun anglalingva publiko, bonvolu uzi la tradukan ligilon: Vladislav Stolyarov. PVS-Studio Nun Estas en Chocolatey: Kontrolante Chocolatey sub Azure DevOps.

fonto: www.habr.com

Aĉetu fidindan gastigadon por retejoj kun DDoS-protekto, VPS-VDS-serviloj 🔥 Aĉetu fidindan retejan gastigadon kun DDoS-protekto, VPS VDS-servilojn | ProHoster