PVS-Studio indi Chocolatey-də: Azure DevOps altından Chocolatey yoxlanılır

PVS-Studio indi Chocolatey-də: Azure DevOps altından Chocolatey yoxlanılır
PVS-Studio-dan istifadəni daha rahat etməyə davam edirik. Analizatorumuz artıq Windows üçün paket meneceri olan Chocolatey-də mövcuddur. İnanırıq ki, bu, PVS-Studio-nun, xüsusən də bulud xidmətlərində tətbiqini asanlaşdıracaq. Uzağa getməmək üçün eyni Chocolatey-nin mənbə kodunu yoxlayaq. Azure DevOps CI sistemi kimi fəaliyyət göstərəcək.

Bulud sistemləri ilə inteqrasiya mövzusundakı digər məqalələrimizin siyahısını təqdim edirik:

Azure DevOps ilə inteqrasiya haqqında birinci məqaləyə diqqət yetirməyi məsləhət görürəm, çünki bu halda təkrarlanmamaq üçün bəzi məqamlar buraxılıb.

Beləliklə, bu məqalənin qəhrəmanları:

PVS Studio C, C++, C# və Java dillərində yazılmış proqramlarda səhvləri və potensial zəiflikləri müəyyən etmək üçün nəzərdə tutulmuş statik kod təhlili vasitəsidir. 64-bit Windows, Linux və macOS sistemlərində işləyir və 32-bit, 64-bit və quraşdırılmış ARM platformaları üçün hazırlanmış kodu təhlil edə bilər. Layihələrinizi yoxlamaq üçün ilk dəfə statik kod analizini sınayırsınızsa, sizə tanış olmağı tövsiyə edirik. məqalə ən maraqlı PVS-Studio xəbərdarlıqlarına necə tez baxmaq və bu alətin imkanlarını qiymətləndirmək haqqında.

Azure DevOps — bütün inkişaf prosesini birlikdə əhatə edən bulud xidmətləri dəsti. Bu platforma Azure Pipelines, Azure Boards, Azure Artifacts, Azure Repos, Azure Test Plans kimi alətlər daxildir ki, bu da proqram təminatının yaradılması prosesini sürətləndirməyə və onun keyfiyyətini yaxşılaşdırmağa imkan verir.

Chocolatey Windows üçün açıq mənbə paket meneceridir. Layihənin məqsədi Windows əməliyyat sistemlərində quraşdırmadan yenilənməsinə və silinməsinə qədər bütün proqram təminatının həyat dövrünü avtomatlaşdırmaqdır.

Şokoladdan istifadə haqqında

Paket menecerinin özünü necə quraşdırmağı burada görə bilərsiniz əlaqə. Analizatorun quraşdırılması üçün tam sənədlər burada mövcuddur əlaqə Chocolatey paket meneceri bölməsindən istifadə edərək quraşdırmaya baxın. Oradan bəzi məqamları qısaca təkrarlayacağam.

Analizatorun ən son versiyasını quraşdırmaq əmri:

choco install pvs-studio

PVS-Studio paketinin xüsusi versiyasını quraşdırmaq əmri:

choco install pvs-studio --version=7.05.35617.2075

Varsayılan olaraq, yalnız analizatorun nüvəsi, Core komponenti quraşdırılmışdır. Bütün digər bayraqlar (Standalone, JavaCore, IDEA, MSVS2010, MSVS2012, MSVS2013, MSVS2015, MSVS2017, MSVS2019) --package-parameters istifadə edərək ötürülə bilər.

Visual Studio 2019 üçün plaginlə analizator quraşdıracaq əmr nümunəsi:

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

İndi Azure DevOps altında analizatordan rahat istifadə nümunəsinə baxaq.

nizamlama

Nəzərinizə çatdırım ki, hesabın qeydiyyatı, Build Pipeline yaradılması və hesabınızın GitHub deposunda yerləşən layihə ilə sinxronlaşdırılması kimi məsələlər haqqında ayrıca bölmə var. məqalə. Quraşdırmamız dərhal konfiqurasiya faylı yazmaqla başlayacaq.

Əvvəlcə, yalnız dəyişikliklər üçün işə saldığımızı bildirən bir işə salma tetiği quraq ustad filial:

trigger:
- master

Sonra virtual maşın seçməliyik. Hələlik o, Windows Server 2019 və Visual Studio 2019 ilə Microsoft-un yerləşdiyi agent olacaq:

pool:
  vmImage: 'windows-latest'

Konfiqurasiya faylının gövdəsinə keçək (blok addımlar). Virtual maşına ixtiyari proqram təminatı quraşdıra bilməməyinizə baxmayaraq, mən Docker konteynerini əlavə etməmişəm. Azure DevOps üçün əlavə olaraq Chocolatey əlavə edə bilərik. Bunu etmək üçün gedək əlaqə. basın Pulsuz ol. Bundan sonra, artıq icazəniz varsa, sadəcə hesabınızı seçin, yoxsa, avtorizasiyadan sonra eyni şeyi edin.

PVS-Studio indi Chocolatey-də: Azure DevOps altından Chocolatey yoxlanılır

Burada genişlənməni harada əlavə edəcəyimizi seçmək və düyməni sıxmaq lazımdır Quraşdırın.

PVS-Studio indi Chocolatey-də: Azure DevOps altından Chocolatey yoxlanılır

Uğurlu quraşdırmadan sonra vurun Təşkilata keçin:

PVS-Studio indi Chocolatey-də: Azure DevOps altından Chocolatey yoxlanılır

İndi pəncərədə Chocolatey tapşırığının şablonunu görə bilərsiniz vəzifələri konfiqurasiya faylını redaktə edərkən azure-pipelines.yml:

PVS-Studio indi Chocolatey-də: Azure DevOps altından Chocolatey yoxlanılır

Chocolatey üzərinə klikləyin və sahələrin siyahısına baxın:

PVS-Studio indi Chocolatey-də: Azure DevOps altından Chocolatey yoxlanılır

Burada seçim etməliyik qurmaq komandalarla sahədə. IN Nuspec Fayl Adı tələb olunan paketin adını göstərin - pvs-studio. Versiyanı qeyd etməsəniz, bizə tam uyğun gələn ən sonuncu quraşdırılacaq. Düyməni basaq əlavə etmək və yaradılan tapşırığı konfiqurasiya faylında görəcəyik.

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

Sonra faylımızın əsas hissəsinə keçək:

- task: CmdLine@2
  inputs:
    script: 

İndi analizator lisenziyası ilə bir fayl yaratmalıyıq. Budur PVSNAME и PVSKEY – parametrlərdə dəyərlərini təyin etdiyimiz dəyişənlərin adları. Onlar PVS-Studio girişini və lisenziya açarını saxlayacaqlar. Onların dəyərlərini təyin etmək üçün menyunu açın Dəyişənlər->Yeni dəyişən. Gəlin dəyişənlər yaradaq PVSNAME giriş üçün və PVSKEY analizator açarı üçün. Qutunu yoxlamağı unutmayın Bu dəyəri gizli saxlayın uğrunda PVSKEY. Komanda kodu:

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

Repozitoriyada yerləşən bat faylından istifadə edərək layihəni quraq:

сall build.bat

Analizatorun nəticələri ilə faylların saxlanacağı bir qovluq yaradaq:

сall mkdir PVSTestResults

Layihəni təhlil etməyə başlayaq:

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

PlogСonverter yardım proqramından istifadə edərək hesabatımızı html formatına çeviririk:

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

İndi bir tapşırıq yaratmalısınız ki, hesabatı yükləyə biləsiniz.

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

Tam konfiqurasiya faylı belə görünür:

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

Gəlin klikləyək Saxla-> Saxla-> Çalıştır tapşırığı yerinə yetirmək üçün. Tapşırıqlar sekmesine keçərək hesabatı yükləyək.

PVS-Studio indi Chocolatey-də: Azure DevOps altından Chocolatey yoxlanılır

Chocolatey layihəsi yalnız 37615 C# kodunu ehtiva edir. Tapılan bəzi səhvlərə nəzər salaq.

Test nəticələri

Xəbərdarlıq N1

Analizator xəbərdarlığı: V3005 'Provayder' dəyişəni özünə təyin edilir. CrytpoHashProviderSpecs.cs 38

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

Analizator dəyişənin özü üçün təyin edilməsini aşkar etdi, bunun mənası yoxdur. Çox güman ki, bu dəyişənlərdən birinin yerinə başqası olmalıdır. Yaxşı, yoxsa bu yazı səhvidir və əlavə tapşırıq sadəcə silinə bilər.

Xəbərdarlıq N2

Analizator xəbərdarlığı: V3093 [CWE-480] '&' operatoru hər iki operandı qiymətləndirir. Bəlkə də əvəzinə qısaqapanma '&&' operatorundan istifadə edilməlidir. 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;
  }
}

Operator fərqi & operatordan && ifadənin sol tərəfi olarsa saxta, sonra sağ tərəf hələ də hesablanacaq, bu halda lazımsız metod çağırışlarını nəzərdə tutur system.directory_exists.

Baxılan fraqmentdə bu, kiçik bir qüsurdur. Bəli, bu şərt & operatorunu && operatoru ilə əvəz etməklə optimallaşdırıla bilər, lakin praktiki baxımdan bu heç nəyə təsir etmir. Bununla belə, digər hallarda, & və && arasında qarışıqlıq ifadənin sağ tərəfi yanlış/etibarsız dəyərlərlə işləndikdə ciddi problemlər yarada bilər. Məsələn, səhv kolleksiyamızda, V3093 diaqnostikasından istifadə edərək müəyyən edilmişdir, bu hal var:

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

İndeks olsa belə k səhvdir, massiv elementinə daxil olmaq üçün istifadə olunacaq. Nəticədə, bir istisna atılacaq IndexOutOfRangeException.

Xəbərdarlıqlar N3, N4

Analizator xəbərdarlığı: V3022 [CWE-571] 'shortPrompt' ifadəsi həmişə doğrudur. InteractivePrompt.cs 101
Analizator xəbərdarlığı: V3022 [CWE-571] 'shortPrompt' ifadəsi həmişə doğrudur. 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
    ....
  }
  ....
}

Bu halda üçlü operatorun işləməsinin arxasında qəribə bir məntiq dayanır. Gəlin daha yaxından nəzər salaq: əgər 1 rəqəmi ilə qeyd etdiyim şərt yerinə yetirilərsə, onda biz həmişə olan 2-ci şərtə keçəcəyik. doğru, bu o deməkdir ki, 3-cü sətir yerinə yetiriləcək.Əgər 1-ci şərt yalan olarsa, o zaman 4 rəqəmi ilə işarələnmiş sətirə keçəcəyik ki, burada da şərt həmişə doğru, yəni 5-ci sətir yerinə yetiriləcək.Beləliklə, 0 şərhi ilə qeyd olunan şərtlər heç vaxt yerinə yetirilməyəcək, bu proqramçının gözlədiyi əməliyyat məntiqi ilə tam uyğun olmaya bilər.

Xəbərdarlıq N5

Analizator xəbərdarlığı: V3123 [CWE-783] Ola bilsin ki, '?:' operatoru gözlənildiyindən fərqli şəkildə işləyir. Onun prioriteti öz vəziyyətində olan digər operatorların prioritetindən aşağıdır. 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);
  }
}

Diaqnostika xətt üçün işlədi:

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

Dəyişəndən bəri j yuxarıdakı bir neçə sətir sıfıra endirilirsə, üçlü operator dəyəri qaytaracaq saxta. Bu şərtə görə, döngənin gövdəsi yalnız bir dəfə yerinə yetiriləcəkdir. Mənə elə gəlir ki, bu kod parçası proqramçının nəzərdə tutduğu kimi ümumiyyətlə işləmir.

Xəbərdarlıq N6

Analizator xəbərdarlığı: V3022 [CWE-571] 'installedPackageVersions.Count != 1' ifadəsi həmişə doğrudur. 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);
    }
    ....
  }
  ....
}

Burada qəribə bir yuva vəziyyəti var: quraşdırılmışPackageVersions.Count != 1olan həmişə olacaq doğru. Tez-tez belə bir xəbərdarlıq koddakı məntiqi səhvi göstərir, digər hallarda isə sadəcə olaraq lazımsız yoxlamanı göstərir.

Xəbərdarlıq N7

Analizator xəbərdarlığı: V3001 '||'-nin solunda və sağında eyni alt ifadələr 'commandArguments.contains("-apikey")' var. 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");
}

Kodun bu hissəsini yazan proqramçı son iki sətri kopyalayıb yapışdırıb və redaktə etməyi unudub. Bu səbəbdən Chocolatey istifadəçiləri parametri tətbiq edə bilməyiblər apikey daha bir neçə yol. Yuxarıdakı parametrlərə oxşar olaraq, aşağıdakı variantları təklif edə bilərəm:

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

Kopyala-yapışdırma xətalarının çoxlu mənbə kodu olan istənilən layihədə gec-tez görünmə şansı yüksəkdir və onlarla mübarizə aparmaq üçün ən yaxşı vasitələrdən biri statik analizdir.

PS Həmişə olduğu kimi, bu xəta çox xəttli vəziyyətin sonunda görünür :). nəşrə baxın "Son xətt effekti".

Xəbərdarlıq N8

Analizator xəbərdarlığı: V3095 [CWE-476] 'installedPackage' obyekti null ilə təsdiqlənməmişdən əvvəl istifadə edilmişdir. Yoxlama xətləri: 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)
  {
    ....
  }
  ....
}

Klassik səhv: əvvəlcə obyekt quraşdırılmış paket istifadə olunur və sonra yoxlanılır null. Bu diaqnostika bizə proqramdakı iki problemdən biri haqqında məlumat verir: ya quraşdırılmış paket heç vaxt bərabər deyil null, bu, şübhəlidir və sonra yoxlama lazımsızdır və ya biz kodda potensial olaraq ciddi bir səhv əldə edə bilərik - null istinada daxil olmaq cəhdi.

Nəticə

Beləliklə, biz daha bir kiçik addım atdıq - indi PVS-Studio-dan istifadə daha asan və daha rahat oldu. Onu da deyim ki, Chocolatey PVS-Studio istifadə edərkən kodda az sayda səhv olan yaxşı paket meneceridir.

Dəvət edirik download və PVS-Studio-nu sınayın. Statik analizatordan müntəzəm istifadə komandanızın hazırladığı kodun keyfiyyətini və etibarlılığını artıracaq və bir çoxunun qarşısını almağa kömək edəcək. sıfır gün zəiflikləri.

PS

Məqaləni dərc etməzdən əvvəl biz Chocolatey tərtibatçılarına göndərdik və onlar yaxşı qəbul etdilər. Biz kritik bir şey tapmadıq, lakin onlar, məsələn, “api-key” açarı ilə bağlı tapdığımız səhvi bəyəndilər.

PVS-Studio indi Chocolatey-də: Azure DevOps altından Chocolatey yoxlanılır

Bu məqaləni ingilisdilli auditoriya ilə bölüşmək istəyirsinizsə, tərcümə linkindən istifadə edin: Vladislav Stolyarov. PVS-Studio İndi Şokoladdadır: Azure DevOps altında Chocolatey yoxlanılır.

Mənbə: www.habr.com

Добавить комментарий