PVS-Studio jest teraz w Chocolatey: sprawdzanie Chocolatey w ramach Azure DevOps

PVS-Studio jest teraz w Chocolatey: sprawdzanie Chocolatey w ramach Azure DevOps
Stale zwiększamy wygodę korzystania z PVS-Studio. Nasz analizator jest teraz dostępny w Chocolatey, menedżerze pakietów dla systemu Windows. Wierzymy, że ułatwi to wdrożenie PVS-Studio w szczególności w usługach chmurowych. Aby nie zajść daleko, sprawdźmy kod źródłowy tej samej Chocolatey. Azure DevOps będzie działać jako system CI.

Oto lista innych naszych artykułów na temat integracji z systemami chmurowymi:

Radzę zwrócić uwagę na pierwszy artykuł o integracji z Azure DevOps, gdyż w tym przypadku pewne punkty zostały pominięte, aby się nie powielać.

A więc bohaterowie tego artykułu:

Studio PVS to narzędzie do statycznej analizy kodu, którego zadaniem jest identyfikacja błędów i potencjalnych podatności w programach napisanych w językach C, C++, C# i Java. Działa na 64-bitowych systemach Windows, Linux i macOS i może analizować kod przeznaczony dla platform 32-bitowych, 64-bitowych i wbudowanych platform ARM. Jeśli po raz pierwszy próbujesz statycznej analizy kodu w celu sprawdzenia swoich projektów, zalecamy zapoznanie się z nią artykuł o tym, jak szybko wyświetlić najciekawsze ostrzeżenia PVS-Studio i ocenić możliwości tego narzędzia.

Azure DevOps — zestaw usług chmurowych, które łącznie obejmują cały proces rozwoju. Platforma ta zawiera narzędzia takie jak Azure Pipelines, Azure Boards, Azure Artifacts, Azure Repos, Azure Test Plans, które pozwalają przyspieszyć proces tworzenia oprogramowania i poprawić jego jakość.

Czekoladowy to menedżer pakietów typu open source dla systemu Windows. Celem projektu jest automatyzacja całego cyklu życia oprogramowania od instalacji po aktualizację i dezinstalację w systemach operacyjnych Windows.

O używaniu Chocolatey

Tutaj możesz zobaczyć, jak zainstalować samego menedżera pakietów powiązanie. Pełna dokumentacja dotycząca montażu analizatora dostępna jest pod adresem powiązanie Zobacz sekcję Instalacja przy użyciu menedżera pakietów Chocolatey. Pokrótce powtórzę niektóre stamtąd punkty.

Polecenie instalacji najnowszej wersji analizatora:

choco install pvs-studio

Polecenie instalacji określonej wersji pakietu PVS-Studio:

choco install pvs-studio --version=7.05.35617.2075

Domyślnie instalowany jest tylko rdzeń analizatora, komponent Core. Wszystkie inne flagi (Standalone, JavaCore, IDEA, MSVS2010, MSVS2012, MSVS2013, MSVS2015, MSVS2017, MSVS2019) można przekazywać za pomocą parametrów --package.

Przykład polecenia, które zainstaluje analizator wraz z wtyczką do Visual Studio 2019:

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

Przyjrzyjmy się teraz przykładowi wygodnego wykorzystania analizatora w ramach Azure DevOps.

regulacja

Przypomnę, że istnieje osobny rozdział poświęcony takim zagadnieniom jak rejestracja konta, utworzenie Build Pipeline i synchronizacja konta z projektem znajdującym się w repozytorium GitHub. artykuł. Nasza konfiguracja natychmiast rozpocznie się od zapisania pliku konfiguracyjnego.

Najpierw skonfigurujmy wyzwalacz uruchamiania, wskazujący, że uruchamiamy tylko w przypadku zmian w mistrz oddział:

trigger:
- master

Następnie musimy wybrać maszynę wirtualną. Na razie będzie to agent hostowany przez firmę Microsoft z systemem Windows Server 2019 i Visual Studio 2019:

pool:
  vmImage: 'windows-latest'

Przejdźmy do treści pliku konfiguracyjnego (block kroki). Pomimo tego, że nie można zainstalować dowolnego oprogramowania na maszynie wirtualnej, nie dodałem kontenera Docker. Możemy dodać Chocolatey jako rozszerzenie dla Azure DevOps. Aby to zrobić, przejdźmy do powiązanie. Kliknij Dostać za darmo. Następnie, jeśli jesteś już autoryzowany, po prostu wybierz swoje konto, a jeśli nie, zrób to samo po autoryzacji.

PVS-Studio jest teraz w Chocolatey: sprawdzanie Chocolatey w ramach Azure DevOps

Tutaj musisz wybrać, gdzie dodamy rozszerzenie i kliknąć przycisk Zainstalować.

PVS-Studio jest teraz w Chocolatey: sprawdzanie Chocolatey w ramach Azure DevOps

Po udanej instalacji kliknij Przejdź do organizacji:

PVS-Studio jest teraz w Chocolatey: sprawdzanie Chocolatey w ramach Azure DevOps

W oknie możesz teraz zobaczyć szablon zadania Chocolatey zadania podczas edycji pliku konfiguracyjnego azure-pipelines.yml:

PVS-Studio jest teraz w Chocolatey: sprawdzanie Chocolatey w ramach Azure DevOps

Kliknij Chocolatey i zobacz listę pól:

PVS-Studio jest teraz w Chocolatey: sprawdzanie Chocolatey w ramach Azure DevOps

Tutaj musimy wybrać zainstalować w terenie z zespołami. W Nazwa pliku Nuspec podaj nazwę wymaganego pakietu – pvs-studio. Jeśli nie określisz wersji, zostanie zainstalowana najnowsza, która nam całkowicie odpowiada. Naciśnijmy przycisk Dodaj i zobaczymy wygenerowane zadanie w pliku konfiguracyjnym.

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

Następnie przejdźmy do głównej części naszego pliku:

- task: CmdLine@2
  inputs:
    script: 

Teraz musimy utworzyć plik z licencją analizatora. Tutaj NAZWA PVS и PVSKEY – nazwy zmiennych, których wartości określamy w ustawieniach. Będą przechowywać login i klucz licencyjny PVS-Studio. Aby ustawić ich wartości, otwórz menu Zmienne->Nowa zmienna. Stwórzmy zmienne NAZWA PVS do logowania i PVSKEY dla klucza analizatora. Nie zapomnij zaznaczyć pola Zachowaj tę wartość w tajemnicy dla PVSKEY. Kod polecenia:

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

Zbudujmy projekt, korzystając z pliku bat znajdującego się w repozytorium:

сall build.bat

Stwórzmy folder, w którym będą przechowywane pliki z wynikami analizatora:

сall mkdir PVSTestResults

Zacznijmy analizę projektu:

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

Konwertujemy nasz raport do formatu HTML za pomocą narzędzia PlogConverter:

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

Teraz musisz utworzyć zadanie, aby móc przesłać raport.

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

Kompletny plik konfiguracyjny wygląda następująco:

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

Kliknijmy Zapisz->Zapisz->Uruchom aby uruchomić zadanie. Pobierzmy raport przechodząc do zakładki zadania.

PVS-Studio jest teraz w Chocolatey: sprawdzanie Chocolatey w ramach Azure DevOps

Projekt Chocolatey zawiera tylko 37615 linii kodu C#. Przyjrzyjmy się niektórym znalezionym błędom.

Wyniki testu

Ostrzeżenie N1

Ostrzeżenie analizatora: V3005 Zmienna „Dostawca” jest przypisana sama do siebie. CrytpoHashProviderSpecs.cs 38

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

Analizator wykrył przypisanie zmiennej do siebie, co nie ma sensu. Najprawdopodobniej zamiast jednej z tych zmiennych powinna znajdować się inna. Cóż, albo to literówka, a dodatkowe zadanie można po prostu usunąć.

Ostrzeżenie N2

Ostrzeżenie analizatora: V3093 [CWE-480] Operator „&” ocenia oba operandy. Być może zamiast tego należy zastosować operator zwarcia „&&”. Platforma.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;
  }
}

Różnica operatora & od operatora && jest tak, jeśli lewa strona wyrażenia to fałszywy, wówczas nadal będzie obliczana prawa strona, co w tym przypadku implikuje niepotrzebne wywołania metod katalog.systemowy_istnieje.

W rozpatrywanym fragmencie jest to drobna wada. Tak, warunek ten można zoptymalizować, zastępując operator & operatorem &&, ale z praktycznego punktu widzenia nie ma to na nic wpływu. Jednak w innych przypadkach pomyłka między & i && może powodować poważne problemy, gdy prawa strona wyrażenia jest traktowana z niepoprawnymi/nieprawidłowymi wartościami. Na przykład w naszej kolekcji błędów zidentyfikowane za pomocą narzędzia diagnostycznego V3093, jest taki przypadek:

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

Nawet jeśli indeks k jest niepoprawny, zostanie użyty do uzyskania dostępu do elementu tablicy. W rezultacie zostanie zgłoszony wyjątek Wyjątek IndexOutOfRange.

Ostrzeżenia N3, N4

Ostrzeżenie analizatora: V3022 [CWE-571] Wyrażenie „shortPrompt” jest zawsze prawdziwe. InteractivePrompt.cs 101
Ostrzeżenie analizatora: V3022 [CWE-571] Wyrażenie „shortPrompt” jest zawsze prawdziwe. 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
    ....
  }
  ....
}

W tym przypadku za działaniem operatora trójskładnikowego kryje się dziwna logika. Przyjrzyjmy się bliżej: jeśli spełniony zostanie warunek, który zaznaczyłem numerem 1, to przejdziemy do warunku 2, który zawsze jest spełniony prawdziwy, co oznacza, że ​​zostanie wykonana linia 3. Jeśli warunek 1 okaże się fałszywy, to przejdziemy do linii oznaczonej cyfrą 4, w której również zawsze występuje warunek prawdziwy, co oznacza, że ​​zostanie wykonana linia 5. Tym samym warunki oznaczone komentarzem 0 nigdy nie zostaną spełnione, co może nie być dokładnie taką logiką działania, jakiej oczekiwał programista.

Ostrzeżenie N5

Ostrzeżenie analizatora: V3123 [CWE-783] Być może operator '?:' działa inaczej niż oczekiwano. Jego priorytet jest niższy niż priorytet innych operatorów w jego stanie. Opcje.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);
  }
}

Diagnostyka zadziałała dla linii:

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

Ponieważ zmienna j kilka linii powyżej jest inicjalizowane na zero, operator trójskładnikowy zwróci wartość fałszywy. Z powodu tego warunku ciało pętli zostanie wykonane tylko raz. Wydaje mi się, że ten fragment kodu wcale nie działa tak, jak zamierzył to programista.

Ostrzeżenie N6

Ostrzeżenie analizatora: V3022 [CWE-571] Wyrażenie „installedPackageVersions.Count != 1” jest zawsze prawdziwe. 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);
    }
    ....
  }
  ....
}

Występuje tu dziwny warunek zagnieżdżony: installPackageVersions.Count != 1co zawsze będzie prawdziwy. Często takie ostrzeżenie wskazuje na błąd logiczny w kodzie, a w innych przypadkach po prostu oznacza nadmiarowe sprawdzenie.

Ostrzeżenie N7

Ostrzeżenie analizatora: V3001 Istnieją identyczne wyrażenia podrzędne „commandArguments.contains(”-apikey”)” po lewej i po prawej stronie „||” 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");
}

Programista, który napisał tę sekcję kodu, skopiował i wkleił dwie ostatnie linie i zapomniał je edytować. Z tego powodu użytkownicy Chocolatey nie mogli zastosować tego parametru Klucz API jeszcze kilka sposobów. Podobnie jak w przypadku powyższych parametrów, mogę zaoferować następujące opcje:

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

Błędy typu „kopiuj-wklej” mają duże prawdopodobieństwo pojawienia się prędzej czy później w każdym projekcie z dużą ilością kodu źródłowego, a jednym z najlepszych narzędzi do ich zwalczania jest analiza statyczna.

PS Jak zwykle błąd ten pojawia się na końcu warunku wielowierszowego :). Zobacz publikację „Efekt ostatniej linii".

Ostrzeżenie N8

Ostrzeżenie analizatora: V3095 [CWE-476] Obiekt „installedPackage” został użyty przed jego zweryfikowaniem pod kątem wartości null. Sprawdź linie: 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)
  {
    ....
  }
  ....
}

Klasyczny błąd: najpierw obiekt zainstalowany pakiet jest używany, a następnie sprawdzany zero. Ta diagnostyka mówi nam o jednym z dwóch problemów w programie: albo zainstalowany pakiet nigdy równe zero, co jest wątpliwe i wtedy sprawdzenie jest zbędne, gdyż w przeciwnym razie możemy potencjalnie otrzymać poważny błąd w kodzie - próbę dostępu do referencji zerowej.

wniosek

Zrobiliśmy więc kolejny mały krok - teraz korzystanie z PVS-Studio stało się jeszcze łatwiejsze i wygodniejsze. Chciałbym również powiedzieć, że Chocolatey to dobry menedżer pakietów z niewielką liczbą błędów w kodzie, których w przypadku PVS-Studio mogłoby być jeszcze mniej.

Zapraszamy Cie pobranie i wypróbuj PVS-Studio. Regularne korzystanie z analizatora statycznego poprawi jakość i niezawodność kodu opracowywanego przez Twój zespół i pomoże zapobiec wielu błędom luki dnia zerowego.

PS

Przed publikacją wysłaliśmy artykuł do twórców Chocolatey, a oni go dobrze przyjęli. Nie znaleźliśmy niczego krytycznego, ale im na przykład spodobał się znaleziony przez nas błąd związany z kluczem „api-key”.

PVS-Studio jest teraz w Chocolatey: sprawdzanie Chocolatey w ramach Azure DevOps

Jeśli chcesz udostępnić ten artykuł anglojęzycznej publiczności, skorzystaj z linku do tłumaczenia: Vladislav Stolyarov. PVS-Studio jest teraz w wersji Chocolatey: sprawdzanie Chocolatey w ramach Azure DevOps.

Źródło: www.habr.com

Dodaj komentarz