PVS-Studio és ara a Chocolatey: comprovant Chocolatey des d'Azure DevOps

PVS-Studio és ara a Chocolatey: comprovant Chocolatey des d'Azure DevOps
Continuem fent que l'ús de PVS-Studio sigui més còmode. El nostre analitzador ja està disponible a Chocolatey, un gestor de paquets per a Windows. Creiem que això facilitarà el desplegament de PVS-Studio, en particular, als serveis al núvol. Per no anar lluny, comprovem el codi font del mateix Chocolatey. Azure DevOps actuarà com un sistema CI.

Aquí teniu una llista dels nostres altres articles sobre el tema de la integració amb sistemes de núvol:

Us recomano que feu cas al primer article sobre la integració amb Azure DevOps, ja que en aquest cas s'ometen alguns punts per no duplicar-se.

Per tant, els herois d'aquest article:

Estudi PVS és una eina d'anàlisi de codi estàtic dissenyada per identificar errors i vulnerabilitats potencials en programes escrits en C, C++, C# i Java. S'executa en sistemes Windows, Linux i macOS de 64 bits i pot analitzar codi dissenyat per a plataformes ARM de 32, 64 bits i incrustades. Si és la primera vegada que proveu l'anàlisi de codi estàtic per comprovar els vostres projectes, us recomanem que us familiaritzeu article sobre com veure ràpidament els avisos de PVS-Studio més interessants i avaluar les capacitats d'aquesta eina.

AzO DevOps — un conjunt de serveis al núvol que cobreixen conjuntament tot el procés de desenvolupament. Aquesta plataforma inclou eines com Azure Pipelines, Azure Boards, Azure Artifacts, Azure Repos, Azure Test Plans, que permeten accelerar el procés de creació de programari i millorar-ne la qualitat.

Chocolatey és un gestor de paquets de codi obert per a Windows. L'objectiu del projecte és automatitzar tot el cicle de vida del programari, des de la instal·lació fins a l'actualització i desinstal·lació en sistemes operatius Windows.

Sobre l'ús de Chocolatey

Podeu veure com instal·lar el propi gestor de paquets aquí enllaç. La documentació completa per instal·lar l'analitzador està disponible a enllaç Consulteu la instal·lació mitjançant la secció del gestor de paquets Chocolatey. A partir d'aquí, repetiré breument alguns punts.

Ordre per instal·lar la darrera versió de l'analitzador:

choco install pvs-studio

Ordre per instal·lar una versió específica del paquet PVS-Studio:

choco install pvs-studio --version=7.05.35617.2075

Per defecte, només s'instal·la el nucli de l'analitzador, el component Core. Tots els altres indicadors (autònom, JavaCore, IDEA, MSVS2010, MSVS2012, MSVS2013, MSVS2015, MSVS2017, MSVS2019) es poden passar mitjançant --package-parameters.

Un exemple d'ordre que instal·larà un analitzador amb un connector per a Visual Studio 2019:

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

Vegem ara un exemple d'ús convenient de l'analitzador a Azure DevOps.

ajust

Us recordo que hi ha una secció separada sobre qüestions com ara registrar un compte, crear un Build Pipeline i sincronitzar el vostre compte amb un projecte situat al dipòsit de GitHub. article. La nostra configuració començarà immediatament amb l'escriptura d'un fitxer de configuració.

Primer, configurem un activador de llançament, que indica que l'iniciem només per a canvis mestre branca:

trigger:
- master

A continuació, hem de seleccionar una màquina virtual. De moment, serà un agent allotjat per Microsoft amb Windows Server 2019 i Visual Studio 2019:

pool:
  vmImage: 'windows-latest'

Passem al cos del fitxer de configuració (block passos). Malgrat que no podeu instal·lar programari arbitrari en una màquina virtual, no he afegit un contenidor Docker. Podem afegir Chocolatey com a extensió per a Azure DevOps. Per fer-ho, anem a enllaç. Feu clic Obteniu-lo gratis. A continuació, si ja esteu autoritzat, simplement seleccioneu el vostre compte i, si no, feu el mateix després de l'autorització.

PVS-Studio és ara a Chocolatey: comprovant Chocolatey des d'Azure DevOps

Aquí heu de seleccionar on afegirem l'extensió i fer clic al botó install.

PVS-Studio és ara a Chocolatey: comprovant Chocolatey des d'Azure DevOps

Després de la instal·lació correcta, feu clic Passar a l'organització:

PVS-Studio és ara a Chocolatey: comprovant Chocolatey des d'Azure DevOps

Ara podeu veure la plantilla per a la tasca Chocolatey a la finestra tasques en editar un fitxer de configuració azure-pipelines.yml:

PVS-Studio és ara a Chocolatey: comprovant Chocolatey des d'Azure DevOps

Feu clic a Chocolatey i vegeu una llista de camps:

PVS-Studio és ara a Chocolatey: comprovant Chocolatey des d'Azure DevOps

Aquí hem de seleccionar instal · lar al camp amb els equips. EN Nom del fitxer Nuspec indiqueu el nom del paquet necessari: pvs-studio. Si no especifiqueu la versió, s'instal·larà la darrera, que ens convé completament. Premem el botó afegir i veurem la tasca generada al fitxer de configuració.

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

A continuació, passem a la part principal del nostre fitxer:

- task: CmdLine@2
  inputs:
    script: 

Ara hem de crear un fitxer amb la llicència de l'analitzador. Aquí PVSNAME и PVSKEY – noms de variables els valors de les quals especifiquem a la configuració. Emmagatzemaran l'inici de sessió i la clau de llicència de PVS-Studio. Per establir els seus valors, obriu el menú Variables->Nova variable. Creem variables PVSNAME per iniciar sessió i PVSKEY per a la clau de l'analitzador. No us oblideu de marcar la casella Mantingueu aquest valor en secret per PVSKEY. Codi de comandament:

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

Construïm el projecte utilitzant el fitxer bat situat al repositori:

сall build.bat

Creem una carpeta on s'emmagatzemaran els fitxers amb els resultats de l'analitzador:

сall mkdir PVSTestResults

Comencem a analitzar el projecte:

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

Convertim el nostre informe a format html mitjançant la utilitat PlogСonverter:

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

Ara heu de crear una tasca perquè pugueu carregar l'informe.

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

El fitxer de configuració complet té aquest aspecte:

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

Fem clic Desa->Desa->Executar per executar la tasca. Descarregueu l'informe anant a la pestanya de tasques.

PVS-Studio és ara a Chocolatey: comprovant Chocolatey des d'Azure DevOps

El projecte Chocolatey només conté 37615 línies de codi C#. Vegem alguns dels errors trobats.

Resultats de la prova

Avís N1

Advertència de l'analitzador: V3005 La variable "Proveïdor" s'assigna a ella mateixa. CrytpoHashProviderSpecs.cs 38

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

L'analitzador va detectar una assignació de la variable a si mateix, que no té sentit. Molt probablement, en lloc d'una d'aquestes variables n'hi hauria d'haver una altra. Bé, o això és una errada d'ortografia i simplement es pot eliminar l'assignació addicional.

Avís N2

Advertència de l'analitzador: V3093 [CWE-480] L'operador '&' avalua els dos operands. Potser s'hauria d'utilitzar un operador de curtcircuit "&&" en el seu lloc. 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;
  }
}

Diferència d'operador & de l'operador && és que si el costat esquerre de l'expressió és false, llavors encara es calcularà el costat dret, que en aquest cas implica trucades de mètodes innecessàries system.directory_exists.

En el fragment considerat, es tracta d'un defecte menor. Sí, aquesta condició es pot optimitzar substituint l'operador & per l'operador &&, però des d'un punt de vista pràctic, això no afecta res. Tanmateix, en altres casos, la confusió entre & i && pot causar problemes greus quan el costat dret de l'expressió es tracta amb valors incorrectes/no vàlids. Per exemple, a la nostra col·lecció d'errors, identificat mitjançant el diagnòstic V3093, hi ha aquest cas:

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

Encara que l'índex k és incorrecte, s'utilitzarà per accedir a un element de matriu. Com a resultat, es llançarà una excepció IndexOutOfRangeException.

Advertències N3, N4

Advertència de l'analitzador: V3022 [CWE-571] L'expressió 'shortPrompt' sempre és certa. InteractivePrompt.cs 101
Advertència de l'analitzador: V3022 [CWE-571] L'expressió 'shortPrompt' sempre és certa. 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 aquest cas, hi ha una estranya lògica darrere del funcionament de l'operador ternari. Fem una ullada més de prop: si es compleix la condició que vaig marcar amb el número 1, passarem a la condició 2, que sempre és veritable, que significa que s'executarà la línia 3. Si la condició 1 resulta ser falsa, anirem a la línia marcada amb el número 4, la condició en la qual també es troba sempre veritable, que vol dir que s'executarà la línia 5. Així, mai es compliran les condicions marcades amb el comentari 0, que pot ser que no sigui exactament la lògica de funcionament que esperava el programador.

Avís N5

Advertència de l'analitzador: V3123 [CWE-783] Potser l'operador '?:' funciona d'una manera diferent de la que s'esperava. La seva prioritat és inferior a la d'altres operadors en el seu estat. 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);
  }
}

El diagnòstic va funcionar per a la línia:

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

Des de la variable j unes línies més amunt s'inicialitzen a zero, l'operador ternari retornarà el valor false. A causa d'aquesta condició, el cos del bucle només s'executarà una vegada. Em sembla que aquest fragment de codi no funciona gens com pretenia el programador.

Avís N6

Advertència de l'analitzador: V3022 [CWE-571] L'expressió 'installedPackageVersions.Count != 1' sempre és certa. 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);
    }
    ....
  }
  ....
}

Aquí hi ha una estranya condició imbricada: installPackageVersions.Count != 1que sempre serà veritable. Sovint, aquest avís indica un error lògic al codi i, en altres casos, simplement indica una comprovació redundant.

Avís N7

Advertència de l'analitzador: V3001 Hi ha subexpressions idèntiques 'commandArguments.contains("-apikey")' a l'esquerra i a la dreta del '||' operador. 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");
}

El programador que va escriure aquesta secció de codi va copiar i enganxar les dues últimes línies i es va oblidar d'editar-les. Per això, els usuaris de Chocolatey no van poder aplicar el paràmetre apikey un parell de maneres més. De manera similar als paràmetres anteriors, puc oferir les opcions següents:

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

Els errors de copiar i enganxar tenen una gran probabilitat d'aparèixer tard o d'hora en qualsevol projecte amb una gran quantitat de codi font, i una de les millors eines per combatre'ls és l'anàlisi estàtica.

PD I com sempre, aquest error acostuma a aparèixer al final d'una condició de diverses línies :). Veure publicació "Efecte darrera línia".

Avís N8

Advertència de l'analitzador: V3095 [CWE-476] L'objecte 'installedPackage' es va utilitzar abans de verificar-lo contra null. Consulteu les línies: 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)
  {
    ....
  }
  ....
}

Error clàssic: primer l'objecte Paquet instal·lat s'utilitza i després es comprova nul. Aquest diagnòstic ens informa d'un dels dos problemes del programa: qualsevol Paquet instal·lat mai iguals nul, que és dubtós, i aleshores la comprovació és redundant, o podríem obtenir un error greu al codi: un intent d'accedir a una referència nul·la.

Conclusió

Així que hem fet un altre petit pas: ara utilitzar PVS-Studio s'ha tornat encara més fàcil i còmode. També m'agradaria dir que Chocolatey és un bon gestor de paquets amb un petit nombre d'errors al codi, que podrien ser encara menys quan utilitzeu PVS-Studio.

Us convidem descarregar i prova PVS-Studio. L'ús regular d'un analitzador estàtic millorarà la qualitat i la fiabilitat del codi que desenvolupa el vostre equip i ajudarà a prevenir-ne molts vulnerabilitats de dia zero.

PS

Abans de la publicació, vam enviar l'article als desenvolupadors de Chocolatey, i el van rebre bé. No vam trobar res crític, però a ells, per exemple, els va agradar l'error que vam trobar relacionat amb la clau "api-key".

PVS-Studio és ara a Chocolatey: comprovant Chocolatey des d'Azure DevOps

Si voleu compartir aquest article amb un públic de parla anglesa, utilitzeu l'enllaç de traducció: Vladislav Stolyarov. PVS-Studio està ara a Chocolatey: comprovant Chocolatey a Azure DevOps.

Font: www.habr.com

Afegeix comentari