Ang PVS-Studio ay nasa Chocolatey na ngayon: sinusuri ang Chocolatey mula sa ilalim ng Azure DevOps

Ang PVS-Studio ay nasa Chocolatey na ngayon: sinusuri ang Chocolatey mula sa ilalim ng Azure DevOps
Patuloy naming ginagawang mas maginhawa ang paggamit ng PVS-Studio. Available na ngayon ang aming analyzer sa Chocolatey, isang package manager para sa Windows. Naniniwala kami na mapapadali nito ang pag-deploy ng PVS-Studio, sa partikular, sa mga serbisyo sa cloud. Upang hindi malayo, tingnan natin ang source code ng parehong Chocolatey. Ang Azure DevOps ay kikilos bilang isang CI system.

Narito ang isang listahan ng aming iba pang mga artikulo sa paksa ng pagsasama sa mga cloud system:

Ipinapayo ko sa iyo na bigyang pansin ang unang artikulo tungkol sa pagsasama sa Azure DevOps, dahil sa kasong ito ang ilang mga punto ay tinanggal upang hindi madoble.

Kaya, ang mga bayani ng artikulong ito:

PVS-Studio ay isang static na code analysis tool na idinisenyo upang matukoy ang mga error at potensyal na kahinaan sa mga program na nakasulat sa C, C++, C# at Java. Gumagana sa 64-bit na Windows, Linux, at macOS system, at maaaring suriin ang code na idinisenyo para sa 32-bit, 64-bit, at naka-embed na ARM platform. Kung ito ang iyong unang pagkakataon na subukan ang static code analysis upang suriin ang iyong mga proyekto, inirerekomenda namin na maging pamilyar ka sa iyong sarili artikulo tungkol sa kung paano mabilis na tingnan ang pinakakawili-wiling mga babala ng PVS-Studio at suriin ang mga kakayahan ng tool na ito.

Mga Azure DevOps — isang hanay ng mga serbisyo sa ulap na magkakasamang sumasaklaw sa buong proseso ng pag-unlad. Kasama sa platform na ito ang mga tool gaya ng Azure Pipelines, Azure Boards, Azure Artifacts, Azure Repos, Azure Test Plans, na nagbibigay-daan sa iyong pabilisin ang proseso ng paglikha ng software at pagbutihin ang kalidad nito.

Chocolatey ay isang open source package manager para sa Windows. Ang layunin ng proyekto ay i-automate ang buong lifecycle ng software mula sa pag-install hanggang sa pag-update at pag-uninstall sa mga operating system ng Windows.

Tungkol sa paggamit ng Chocolatey

Makikita mo kung paano i-install ang package manager mismo dito link. Ang kumpletong dokumentasyon para sa pag-install ng analyzer ay makukuha sa link Tingnan ang Pag-install gamit ang seksyon ng Chocolatey package manager. Uulitin ko sandali ang ilang mga punto mula doon.

Command na i-install ang pinakabagong bersyon ng analyzer:

choco install pvs-studio

Utos na mag-install ng partikular na bersyon ng PVS-Studio package:

choco install pvs-studio --version=7.05.35617.2075

Bilang default, tanging ang core ng analyzer, ang Core component, ang naka-install. Ang lahat ng iba pang flag (Standalone, JavaCore, IDEA, MSVS2010, MSVS2012, MSVS2013, MSVS2015, MSVS2017, MSVS2019) ay maaaring ipasa gamit ang --package-parameters.

Isang halimbawa ng command na mag-i-install ng analyzer na may plugin para sa Visual Studio 2019:

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

Ngayon tingnan natin ang isang halimbawa ng maginhawang paggamit ng analyzer sa ilalim ng Azure DevOps.

pag-aayos

Hayaan mong ipaalala ko sa iyo na mayroong isang hiwalay na seksyon tungkol sa mga isyu tulad ng pagrehistro ng isang account, paggawa ng isang Build Pipeline at pag-synchronize ng iyong account sa isang proyekto na matatagpuan sa GitHub repository. artikulo. Ang aming setup ay magsisimula kaagad sa pagsusulat ng configuration file.

Una, mag-set up tayo ng launch trigger, na nagsasaad na ilulunsad lang natin ang mga pagbabago sa panginoon sangay:

trigger:
- master

Susunod na kailangan nating pumili ng isang virtual machine. Sa ngayon ito ay magiging isang ahente na hino-host ng Microsoft na may Windows Server 2019 at Visual Studio 2019:

pool:
  vmImage: 'windows-latest'

Lumipat tayo sa katawan ng file ng pagsasaayos (block hakbang). Sa kabila ng katotohanan na hindi ka maaaring mag-install ng arbitrary na software sa isang virtual machine, hindi ako nagdagdag ng lalagyan ng Docker. Maaari naming idagdag ang Chocolatey bilang extension para sa Azure DevOps. Upang gawin ito, pumunta tayo sa link. I-click Kumuha ng libre. Susunod, kung awtorisado ka na, piliin lang ang iyong account, at kung hindi, gawin ang parehong pagkatapos ng awtorisasyon.

Ang PVS-Studio ay nasa Chocolatey na ngayon: sinusuri ang Chocolatey mula sa ilalim ng Azure DevOps

Dito kailangan mong piliin kung saan namin idaragdag ang extension at i-click ang pindutan I-install.

Ang PVS-Studio ay nasa Chocolatey na ngayon: sinusuri ang Chocolatey mula sa ilalim ng Azure DevOps

Pagkatapos ng matagumpay na pag-install, i-click Magpatuloy sa organisasyon:

Ang PVS-Studio ay nasa Chocolatey na ngayon: sinusuri ang Chocolatey mula sa ilalim ng Azure DevOps

Maaari mo na ngayong makita ang template para sa gawaing Chocolatey sa window gawain kapag nag-e-edit ng configuration file azure-pipelines.yml:

Ang PVS-Studio ay nasa Chocolatey na ngayon: sinusuri ang Chocolatey mula sa ilalim ng Azure DevOps

Mag-click sa Chocolatey at tingnan ang isang listahan ng mga field:

Ang PVS-Studio ay nasa Chocolatey na ngayon: sinusuri ang Chocolatey mula sa ilalim ng Azure DevOps

Dito kailangan nating pumili install sa field kasama ang mga koponan. SA Pangalan ng File ng Nuspec ipahiwatig ang pangalan ng kinakailangang pakete - pvs-studio. Kung hindi mo tinukoy ang bersyon, ang pinakabago ay mai-install, na ganap na nababagay sa amin. Pindutin natin ang pindutan idagdag at makikita natin ang nabuong gawain sa configuration file.

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

Susunod, lumipat tayo sa pangunahing bahagi ng aming file:

- task: CmdLine@2
  inputs:
    script: 

Ngayon kailangan naming lumikha ng isang file na may lisensya ng analyzer. Dito PVSNAME и PVSKEY – mga pangalan ng mga variable na ang mga halaga ay tinukoy namin sa mga setting. Iimbak nila ang PVS-Studio login at license key. Upang itakda ang kanilang mga halaga, buksan ang menu Mga Variable->Bagong variable. Gumawa tayo ng mga variable PVSNAME para sa pag-login at PVSKEY para sa key ng analyzer. Huwag kalimutang lagyan ng tsek ang kahon Panatilihing lihim ang halagang ito para sa PVSKEY. Command code:

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

Buuin natin ang proyekto gamit ang bat file na matatagpuan sa repositoryo:

сall build.bat

Gumawa tayo ng isang folder kung saan maiimbak ang mga file na may mga resulta ng analyzer:

сall mkdir PVSTestResults

Simulan natin ang pagsusuri sa proyekto:

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

Kino-convert namin ang aming ulat sa html na format gamit ang PlogConverter utility:

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

Ngayon ay kailangan mong lumikha ng isang gawain upang ma-upload mo ang ulat.

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

Ang kumpletong file ng pagsasaayos ay ganito ang hitsura:

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

Pindutin natin Save->Save->Run upang patakbuhin ang gawain. I-download natin ang ulat sa pamamagitan ng pagpunta sa tab na mga gawain.

Ang PVS-Studio ay nasa Chocolatey na ngayon: sinusuri ang Chocolatey mula sa ilalim ng Azure DevOps

Ang proyektong Chocolatey ay naglalaman lamang ng 37615 na linya ng C# code. Tingnan natin ang ilan sa mga error na natagpuan.

Mga resulta ng pagsubok

Babala N1

Babala ng Analyzer: V3005 Ang variable na 'Provider' ay itinalaga sa sarili nito. CrytpoHashProviderSpecs.cs 38

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

Nakita ng analyzer ang isang pagtatalaga ng variable sa sarili nito, na hindi makatwiran. Malamang, sa lugar ng isa sa mga variable na ito ay dapat mayroong isa pa. Well, o ito ay isang typo, at ang labis na pagtatalaga ay maaaring alisin lamang.

Babala N2

Babala ng Analyzer: V3093 [CWE-480] Sinusuri ng operator na '&' ang parehong mga operand. Marahil ay isang short-circuit '&&' operator ang dapat gamitin sa halip. 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;
  }
}

Pagkakaiba ng operator & mula sa operator && ay iyon kung ang kaliwang bahagi ng expression ay hindi totoo, pagkatapos ay kakalkulahin pa rin ang kanang bahagi, na sa kasong ito ay nagpapahiwatig ng hindi kinakailangang mga tawag sa pamamaraan system.directory_exists.

Sa fragment na isinasaalang-alang, ito ay isang maliit na depekto. Oo, maaaring i-optimize ang kundisyong ito sa pamamagitan ng pagpapalit ng & operator ng && operator, ngunit mula sa praktikal na pananaw, hindi ito nakakaapekto sa anuman. Gayunpaman, sa ibang mga kaso, ang pagkalito sa pagitan ng & at && ay maaaring magdulot ng mga seryosong problema kapag ang kanang bahagi ng expression ay ginagamot sa mga hindi tama/invalid na halaga. Halimbawa, sa aming koleksyon ng error, natukoy gamit ang V3093 diagnostic, may ganitong kaso:

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

Kahit na ang index k ay hindi tama, ito ay gagamitin upang ma-access ang isang elemento ng array. Bilang resulta, ang isang pagbubukod ay itatapon IndexOutOfRangeException.

Mga Babala N3, N4

Babala ng Analyzer: V3022 [CWE-571] Ang ekspresyong 'shortPrompt' ay palaging totoo. InteractivePrompt.cs 101
Babala ng Analyzer: V3022 [CWE-571] Ang ekspresyong 'shortPrompt' ay palaging totoo. 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
    ....
  }
  ....
}

Sa kasong ito, mayroong kakaibang lohika sa likod ng pagpapatakbo ng ternary operator. Tingnan natin nang maigi: kung ang kundisyon na minarkahan ko ng numero 1 ay natugunan, pagkatapos ay magpapatuloy tayo sa kundisyon 2, na palaging totoo, na nangangahulugang isasagawa ang linya 3. Kung mali ang kundisyon 1, lilipat tayo sa linyang minarkahan ng numero 4, ang kundisyon kung saan ay palaging totoo, na nangangahulugan na ang linya 5 ay isasagawa. Kaya, ang mga kundisyon na minarkahan ng komento 0 ay hindi kailanman matutupad, na maaaring hindi eksakto ang lohika ng operasyon na inaasahan ng programmer.

Babala N5

Babala ng Analyzer: V3123 [CWE-783] Marahil ang operator na '?:' ay gumagana sa ibang paraan kaysa sa inaasahan. Ang priyoridad nito ay mas mababa kaysa priyoridad ng ibang mga operator sa kondisyon nito. 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);
  }
}

Ang diagnostic ay nagtrabaho para sa linya:

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

Dahil ang variable j ilang linya sa itaas ay sinisimulan sa zero, ibabalik ng ternary operator ang halaga hindi totoo. Dahil sa kundisyong ito, isang beses lang isasagawa ang katawan ng loop. Tila sa akin na ang piraso ng code na ito ay hindi gumagana sa lahat ng nilayon ng programmer.

Babala N6

Babala ng Analyzer: V3022 [CWE-571] Ang ekspresyong 'installedPackageVersions.Count != 1' ay palaging totoo. 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);
    }
    ....
  }
  ....
}

Mayroong kakaibang nested na kondisyon dito: installPackageVersions.Count != 1na palaging magiging totoo. Kadalasan ang gayong babala ay nagpapahiwatig ng isang lohikal na error sa code, at sa ibang mga kaso ito ay nagpapahiwatig lamang ng kalabisan na pagsusuri.

Babala N7

Babala ng Analyzer: V3001 Mayroong magkaparehong mga sub-expression na 'commandArguments.contains("-apikey")' sa kaliwa at sa kanan ng '||' operator. 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");
}

Ang programmer na sumulat ng seksyong ito ng code ay kinopya at i-paste ang huling dalawang linya at nakalimutang i-edit ang mga ito. Dahil dito, hindi nailapat ng mga gumagamit ng Chocolatey ang parameter apikey ilang paraan pa. Katulad ng mga parameter sa itaas, maaari akong mag-alok ng mga sumusunod na opsyon:

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

Ang mga error sa pagkopya-paste ay may mataas na pagkakataon na lumitaw nang maaga o huli sa anumang proyekto na may malaking halaga ng source code, at isa sa mga pinakamahusay na tool upang labanan ang mga ito ay ang static na pagsusuri.

PS At gaya ng dati, ang error na ito ay may posibilidad na lumitaw sa dulo ng isang multi-line na kondisyon :). Tingnan ang publikasyon "Huling epekto ng linya".

Babala N8

Babala ng Analyzer: V3095 [CWE-476] Ang bagay na 'installedPackage' ay ginamit bago ito na-verify laban sa null. Suriin ang mga linya: 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)
  {
    ....
  }
  ....
}

Klasikong pagkakamali: tumutol muna naka-install naPackage ay ginagamit at pagkatapos ay sinuri para sa walang halaga. Sinasabi sa amin ng diagnostic na ito ang tungkol sa isa sa dalawang problema sa programa: alinman naka-install naPackage hindi kailanman pantay walang halaga, na kung saan ay nagdududa, at pagkatapos ay ang tseke ay kalabisan, o maaari tayong makakuha ng isang seryosong error sa code - isang pagtatangka na ma-access ang isang null reference.

Konklusyon

Kaya gumawa kami ng isa pang maliit na hakbang - ngayon ang paggamit ng PVS-Studio ay naging mas madali at mas maginhawa. Gusto ko ring sabihin na si Chocolatey ay isang mahusay na manager ng package na may maliit na bilang ng mga error sa code, na maaaring mas kaunti kapag gumagamit ng PVS-Studio.

Inaanyayahan namin i-download at subukan ang PVS-Studio. Ang regular na paggamit ng isang static na analyzer ay magpapahusay sa kalidad at pagiging maaasahan ng code na binuo ng iyong koponan at makakatulong na maiwasan ang marami zero day na kahinaan.

PS

Bago ilathala, ipinadala namin ang artikulo sa mga developer ng Chocolatey, at natanggap nila ito nang maayos. Wala kaming nakitang kritikal, ngunit nagustuhan nila, halimbawa, ang bug na nakita naming nauugnay sa "api-key" na key.

Ang PVS-Studio ay nasa Chocolatey na ngayon: sinusuri ang Chocolatey mula sa ilalim ng Azure DevOps

Kung nais mong ibahagi ang artikulong ito sa isang madla na nagsasalita ng Ingles, mangyaring gamitin ang link ng pagsasalin: Vladislav Stolyarov. Nasa Chocolatey Na Ngayon ang PVS-Studio: Sinusuri ang Chocolatey sa ilalim ng Azure DevOps.

Pinagmulan: www.habr.com

Magdagdag ng komento