PVS-Studio сега е во Chocolatey: проверува Chocolatey од под Azure DevOps

PVS-Studio сега е во Chocolatey: проверува Chocolatey од под Azure DevOps
Продолжуваме да го правиме користењето на PVS-Studio поудобно. Нашиот анализатор сега е достапен во Chocolatey, менаџер на пакети за Windows. Веруваме дека ова ќе го олесни распоредувањето на PVS-Studio, особено во облак услугите. За да не одиме далеку, да го провериме изворниот код на истото Chocolatey. Azure DevOps ќе дејствува како CI систем.

Еве список на други наши статии на тема интеграција со облак системи:

Ве советувам да обрнете внимание на првата статија за интеграција со Azure DevOps, бидејќи во овој случај некои точки се испуштени за да не се дуплираат.

Значи, хероите на оваа статија:

ПВС-Студио е алатка за анализа на статички код дизајнирана да ги идентификува грешките и потенцијалните пропусти во програмите напишани во C, C++, C# и Java. Работи на 64-битни Windows, Linux и macOS системи и може да анализира код дизајниран за 32-битни, 64-битни и вградени платформи ARM. Ако ова е вашиот прв пат да се обидете со статичка анализа на кодови за да ги проверите вашите проекти, ви препорачуваме да се запознаете со статија за тоа како брзо да ги видите најинтересните предупредувања на PVS-Studio и да ги оцените можностите на оваа алатка.

Azure DevOps — збир на облак услуги кои заеднички го покриваат целиот процес на развој. Оваа платформа вклучува алатки како што се Azure Pipelines, Azure Boards, Azure Artifacts, Azure Repos, Azure Test Plans, кои ви овозможуваат да го забрзате процесот на креирање софтвер и да го подобрите неговиот квалитет.

Чоколади е менаџер на пакети со отворен код за Windows. Целта на проектот е да се автоматизира целиот животен циклус на софтверот од инсталација до ажурирање и деинсталирање на оперативните системи Виндоус.

За користење на чоколадо

Можете да видите како да го инсталирате самиот менаџер на пакети на ова линк. Комплетна документација за инсталирање на анализаторот е достапна на линк Погледнете го делот Инсталација користејќи го делот Chocolatey пакет менаџер. Накратко ќе повторам неколку точки од таму.

Команда за инсталирање на најновата верзија на анализаторот:

choco install pvs-studio

Команда за инсталирање на одредена верзија на пакетот PVS-Studio:

choco install pvs-studio --version=7.05.35617.2075

Стандардно, инсталирано е само јадрото на анализаторот, основната компонента. Сите други знаменца (Standalone, JavaCore, IDEA, MSVS2010, MSVS2012, MSVS2013, MSVS2015, MSVS2017, MSVS2019) може да се пренесат со користење на --package-parameters.

Пример за команда што ќе инсталира анализатор со приклучок за Visual Studio 2019:

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

Сега да погледнеме пример за практично користење на анализаторот под Azure DevOps.

прилагодување

Дозволете ми да ве потсетам дека постои посебен дел за прашања како што се регистрирање сметка, создавање на Build Pipeline и синхронизирање на вашата сметка со проект лоциран во складиштето GitHub. Член. Нашето поставување веднаш ќе започне со пишување конфигурациска датотека.

Прво, да поставиме активирач за лансирање, што покажува дека стартуваме само за промени во господар гранка:

trigger:
- master

Следно, треба да избереме виртуелна машина. Засега ќе биде агент кој ќе биде домаќин на Microsoft со Windows Server 2019 и Visual Studio 2019:

pool:
  vmImage: 'windows-latest'

Ајде да преминеме на телото на конфигурациската датотека (блок чекори). И покрај фактот дека не можете да инсталирате произволен софтвер во виртуелна машина, јас не додадов Docker контејнер. Можеме да додадеме Chocolatey како наставка за Azure DevOps. За да го направите ова, ајде да одиме на линк. Кликнете Ослободете се. Следно, ако веќе сте овластени, едноставно изберете ја вашата сметка, а ако не, тогаш направете го истото по овластувањето.

PVS-Studio сега е во Chocolatey: проверува Chocolatey од под Azure DevOps

Овде треба да изберете каде ќе ја додадеме екстензијата и да кликнете на копчето Инсталирајте.

PVS-Studio сега е во Chocolatey: проверува Chocolatey од под Azure DevOps

По успешната инсталација, кликнете Продолжете до организацијата:

PVS-Studio сега е во Chocolatey: проверува Chocolatey од под Azure DevOps

Сега можете да го видите образецот за задачата Chocolatey во прозорецот задачи кога уредувате конфигурациска датотека azure-pipelines.yml:

PVS-Studio сега е во Chocolatey: проверува Chocolatey од под Azure DevOps

Кликнете на Chocolatey и видете список со полиња:

PVS-Studio сега е во Chocolatey: проверува Chocolatey од под Azure DevOps

Тука треба да избереме инсталира на терен со екипите. ВО Име на датотека Nuspec наведете го името на потребниот пакет – pvs-studio. Ако не ја наведете верзијата, ќе се инсталира најновата, која целосно ни одговара. Ајде да го притиснеме копчето додадете и ќе ја видиме генерираната задача во конфигурациската датотека.

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

Следно, да преминеме на главниот дел од нашата датотека:

- task: CmdLine@2
  inputs:
    script: 

Сега треба да создадеме датотека со лиценцата за анализатор. Еве PVSNAME и PVSKEY - имиња на променливи чии вредности ги одредуваме во поставките. Тие ќе ги складираат клучот за најава и лиценца на PVS-Studio. За да ги поставите нивните вредности, отворете го менито Променливи->Нова променлива. Ајде да создадеме променливи PVSNAME за најава и PVSKEY за клучот на анализаторот. Не заборавајте да го проверите полето Чувајте ја оваа вредност во тајност за PVSKEY. Команден код:

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

Ајде да го изградиме проектот користејќи ја датотеката лилјак лоцирана во складиштето:

сall build.bat

Ајде да создадеме папка каде што ќе се складираат датотеките со резултатите од анализаторот:

сall mkdir PVSTestResults

Да почнеме да го анализираме проектот:

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

Ние го претвораме нашиот извештај во формат html користејќи ја алатката PlogСonverter:

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

Сега треба да креирате задача за да можете да го поставите извештајот.

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

Целосната конфигурациска датотека изгледа вака:

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

Ајде да кликнеме Зачувај-> Зачувај-> Стартувај да ја извршите задачата. Ајде да го преземеме извештајот со одење во картичката задачи.

PVS-Studio сега е во Chocolatey: проверува Chocolatey од под Azure DevOps

Проектот Chocolatey содржи само 37615 линии C# код. Ајде да погледнеме некои од пронајдените грешки.

Резултати од тестот

Предупредување N1

Предупредување од анализаторот: V3005 Променливата „Провајдер“ е доделена на самата себе. CrytpoHashProviderSpecs.cs 38

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

Анализаторот откри доделување на променливата на себе, што нема смисла. Најверојатно, на местото на една од овие променливи треба да има некоја друга. Па, или ова е печатна грешка, а дополнителната задача едноставно може да се отстрани.

Предупредување N2

Предупредување од анализаторот: V3093 [CWE-480] Операторот „&“ ги оценува двата операнди. Можеби наместо тоа треба да се користи оператор „&&“ со краток спој. Платформа.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;
  }
}

Операторска разлика & од операторот && е дека ако левата страна на изразот е лажни, тогаш сепак ќе се пресметува десната страна, што во овој случај подразбира непотребни повици на методот систем.директориум_постои.

Во разгледаниот фрагмент, ова е мала грешка. Да, оваа состојба може да се оптимизира со замена на операторот & со операторот &&, но од практична гледна точка, тоа не влијае на ништо. Меѓутоа, во други случаи, конфузијата помеѓу & и && може да предизвика сериозни проблеми кога десната страна на изразот се третира со неточни/невалидни вредности. На пример, во нашата колекција на грешки, идентификувани со помош на дијагностиката V3093, постои овој случај:

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

Дури и ако индексот k е неточна, ќе се користи за пристап до елемент на низа. Како резултат на тоа, ќе се фрли исклучок IndexOutOfRangeException.

Предупредувања N3, N4

Предупредување од анализаторот: V3022 [CWE-571] Изразот 'shortPrompt' е секогаш точен. InteractivePrompt.cs 101
Предупредување од анализаторот: V3022 [CWE-571] Изразот 'shortPrompt' е секогаш точен. 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
    ....
  }
  ....
}

Во овој случај, постои чудна логика зад работата на тројниот оператор. Да погледнеме подетално: ако условот што го означив со број 1 е исполнет, тогаш ќе преминеме на условот 2, кој е секогаш вистина, што значи дека ќе се изврши линијата 3. Ако условот 1 се покаже дека е неточен, тогаш ќе одиме на линијата означена со број 4, состојбата во која исто така е секогаш вистина, што значи дека ќе се изврши линијата 5. Така, условите означени со коментар 0 никогаш нема да се исполнат, што можеби не е точно логиката на работа што ја очекуваше програмерот.

Предупредување N5

Предупредување од анализаторот: V3123 [CWE-783] Можеби операторот '?:' работи на поинаков начин отколку што се очекуваше. Нејзиниот приоритет е помал од приоритетот на другите оператори во неговата состојба. 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);
  }
}

Дијагностиката работеше за линијата:

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

Бидејќи променливата j неколку линии погоре е иницијализиран на нула, тројниот оператор ќе ја врати вредноста лажни. Поради оваа состојба, телото на јамката ќе се изврши само еднаш. Ми се чини дека овој дел од кодот воопшто не работи како што планирал програмерот.

Предупредување N6

Предупредување од анализаторот: V3022 [CWE-571] Изразот „installedPackageVersions.Count != 1“ е секогаш точен. 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);
    }
    ....
  }
  ....
}

Овде има чудна вгнездена состојба: installedPackageVersions.Count != 1што секогаш ќе биде вистина. Честопати таквото предупредување укажува на логичка грешка во кодот, а во други случаи едноставно укажува на непотребна проверка.

Предупредување N7

Предупредување од анализаторот: V3001 Има идентични подизрази 'commandArguments.contains("-apikey")' лево и десно од '||' оператор. 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");
}

Програмерот кој го напиша овој дел од кодот ги ископира и залепи последните два реда и заборави да ги уреди. Поради ова, корисниците на Chocolatey не можеа да го применат параметарот апики уште неколку начини. Слично на параметрите погоре, можам да ги понудам следниве опции:

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

Грешките со Copy-paste имаат големи шанси да се појават порано или подоцна во кој било проект со голема количина на изворен код, а една од најдобрите алатки за борба против нив е статичката анализа.

П.С И како и секогаш, оваа грешка има тенденција да се појавува на крајот од условот со повеќе линии :). Видете ја публикацијата "Ефект на последната линија".

Предупредување N8

Предупредување од анализаторот: V3095 [CWE-476] Објектот „installedPackage“ се користеше пред да биде потврден против нула. Проверете ги линиите: 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)
  {
    ....
  }
  ....
}

Класична грешка: прво предмет инсталиран пакет се користи и потоа се проверува за нула. Оваа дијагностика ни кажува за еден од двата проблеми во програмата: или инсталиран пакет никогаш еднакви нула, што е сомнително, а потоа проверката е излишна, или потенцијално би можеле да добиеме сериозна грешка во кодот - обид за пристап до нула референца.

Заклучок

Така, направивме уште еден мал чекор - сега користењето на PVS-Studio стана уште полесно и поудобно. Исто така, би сакал да кажам дека Chocolatey е добар менаџер на пакети со мал број на грешки во кодот, кои би можеле да бидат уште помалку при користење на PVS-Studio.

Ве покануваме преземете и пробајте го PVS-Studio. Редовната употреба на статички анализатор ќе го подобри квалитетот и доверливоста на кодот што вашиот тим го развива и ќе помогне да се спречат многу ранливости на нула ден.

PS

Пред објавувањето, ја испративме статијата до програмерите на Chocolatey и тие добро ја примија. Не најдовме ништо критично, но ним, на пример, им се допадна грешката што ја најдовме поврзана со копчето „api-key“.

PVS-Studio сега е во Chocolatey: проверува Chocolatey од под Azure DevOps

Ако сакате да ја споделите оваа статија со публика што зборува англиски, ве молиме користете ја врската за превод: Владислав Столјаров. PVS-Studio сега е во Chocolatey: проверувам чоколадо под Azure DevOps.

Извор: www.habr.com

Додадете коментар