PVS-Studio اکنون در Chocolatey است: بررسی Chocolatey از زیر Azure DevOps

PVS-Studio اکنون در Chocolatey است: بررسی Chocolatey از زیر Azure DevOps
ما همچنان استفاده از PVS-Studio را راحت‌تر می‌کنیم. آنالایزر ما اکنون در Chocolatey، یک مدیریت بسته برای ویندوز در دسترس است. ما معتقدیم که این امر استقرار PVS-Studio را به ویژه در خدمات ابری تسهیل می کند. برای اینکه راه دور نریم سورس کد همون شکلاتی رو چک کنیم. Azure DevOps به عنوان یک سیستم CI عمل خواهد کرد.

در اینجا لیستی از مقالات دیگر ما در مورد موضوع یکپارچه سازی با سیستم های ابری آمده است:

به شما توصیه می کنم به مقاله اول در مورد ادغام با Azure DevOps توجه کنید، زیرا در این مورد برخی از نکات حذف می شوند تا تکراری نشوند.

بنابراین، قهرمانان این مقاله:

PVS Studio یک ابزار تجزیه و تحلیل کد استاتیک است که برای شناسایی خطاها و آسیب پذیری های احتمالی در برنامه های نوشته شده در C، C++، C# و جاوا طراحی شده است. روی سیستم های ویندوز، لینوکس و macOS 64 بیتی اجرا می شود و می تواند کدهای طراحی شده برای پلتفرم های 32 بیتی، 64 بیتی و تعبیه شده ARM را تجزیه و تحلیل کند. اگر این اولین باری است که برای بررسی پروژه های خود از تجزیه و تحلیل کد استاتیک استفاده می کنید، توصیه می کنیم با آن آشنا شوید مقاله در مورد نحوه مشاهده سریع جالب ترین هشدارهای PVS-Studio و ارزیابی قابلیت های این ابزار.

Azure DevOps - مجموعه ای از خدمات ابری که به طور مشترک کل فرآیند توسعه را پوشش می دهند. این پلتفرم شامل ابزارهایی مانند Azure Pipelines، Azure Boards، Azure Artifacts، Azure Repos، Azure Test Plans است که به شما امکان می دهد روند ایجاد نرم افزار را سرعت بخشیده و کیفیت آن را ارتقا دهید.

شکلات یک مدیریت بسته منبع باز برای ویندوز است. هدف این پروژه خودکارسازی کل چرخه عمر نرم افزار از نصب تا به روز رسانی و حذف نصب در سیستم عامل های ویندوز است.

درباره استفاده از شکلات

در اینجا می توانید نحوه نصب خود پکیج منیجر را مشاهده کنید پیوند. مستندات کامل برای نصب آنالایزر در اینجا موجود است پیوند نصب با استفاده از بخش Chocolatey package manager را ببینید. از آنجا به اختصار چند نکته را تکرار می کنم.

دستور نصب آخرین نسخه آنالایزر:

choco install pvs-studio

دستور نصب یک نسخه خاص از بسته PVS-Studio:

choco install pvs-studio --version=7.05.35617.2075

به طور پیش فرض، تنها هسته آنالایزر، کامپوننت Core، نصب شده است. همه پرچم‌های دیگر (Standalone، JavaCore، IDEA، MSVS2010، MSVS2012، MSVS2013، MSVS2015، MSVS2017، MSVS2019) را می‌توان با استفاده از پارامترهای -package ارسال کرد.

نمونه ای از دستوری که یک آنالایزر را با یک پلاگین برای Visual Studio 2019 نصب می کند:

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

حال بیایید به مثالی از استفاده راحت از تحلیلگر تحت Azure DevOps نگاه کنیم.

تنظیم

اجازه دهید به شما یادآوری کنم که یک بخش جداگانه در مورد مسائلی مانند ثبت حساب، ایجاد یک خط لوله و همگام سازی حساب شما با یک پروژه واقع در مخزن GitHub وجود دارد. مقاله. راه اندازی ما بلافاصله با نوشتن یک فایل پیکربندی آغاز می شود.

ابتدا، بیایید یک راه‌انداز راه‌اندازی تنظیم کنیم که نشان می‌دهد فقط برای تغییرات در آن راه‌اندازی می‌کنیم استاد شاخه:

trigger:
- master

بعد باید یک ماشین مجازی را انتخاب کنیم. در حال حاضر این یک عامل میزبان مایکروسافت با Windows Server 2019 و Visual Studio 2019 خواهد بود:

pool:
  vmImage: 'windows-latest'

بیایید به بدنه فایل پیکربندی (block مراحل). با وجود این واقعیت که شما نمی توانید نرم افزار دلخواه را در ماشین مجازی نصب کنید، من ظرف 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)

بیایید پروژه را با استفاده از فایل bat واقع در مخزن بسازیم:

сall build.bat

بیایید یک پوشه ایجاد کنیم که در آن فایل های حاوی نتایج تجزیه و تحلیل ذخیره می شوند:

сall mkdir PVSTestResults

بیایید شروع به تجزیه و تحلیل پروژه کنیم:

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

ما گزارش خود را با استفاده از ابزار PlogСonverter به فرمت html تبدیل می کنیم:

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

بیایید کلیک کنیم Save->Save->Run برای اجرای کار بیایید با رفتن به برگه وظایف، گزارش را دانلود کنیم.

PVS-Studio اکنون در Chocolatey است: بررسی Chocolatey از زیر Azure DevOps

پروژه Chocolatey فقط شامل 37615 خط کد سی شارپ است. بیایید به برخی از خطاهای یافت شده نگاه کنیم.

نتایج آزمون

هشدار N1

هشدار آنالایزر: V3005 متغیر 'Provider' به خودش اختصاص داده شده است. 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] عملگر '&' هر دو عملوند را ارزیابی می کند. شاید باید به جای آن از اپراتور «&&» اتصال کوتاه استفاده شود. 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;
  }
}

تفاوت اپراتور & از اپراتور && این است که اگر سمت چپ عبارت باشد غلط، سپس سمت راست همچنان محاسبه می شود که در این مورد به فراخوانی روش های غیر ضروری اشاره می کند system.directory_exists.

در قطعه در نظر گرفته شده، این یک نقص جزئی است. بله، این شرایط را می توان با جایگزینی عملگر & با عملگر && بهینه کرد، اما از نظر عملی، این روی چیزی تاثیری ندارد. با این حال، در موارد دیگر، زمانی که سمت راست عبارت با مقادیر نادرست/نامعتبر برخورد شود، سردرگمی بین & و && می‌تواند مشکلات جدی ایجاد کند. به عنوان مثال، در مجموعه خطاهای ما، با استفاده از تشخیص 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=");

خطاهای کپی پیست، دیر یا زود در هر پروژه ای با مقدار زیادی کد منبع، احتمال زیادی دارند که ظاهر شوند و یکی از بهترین ابزارها برای مبارزه با آنها، تحلیل استاتیک است.

PS و مثل همیشه، این خطا تمایل دارد در انتهای یک شرط چند خطی ظاهر شود :). مشاهده نشریه "اثر خط آخر".

هشدار N8

هشدار آنالایزر: V3095 [CWE-476] شیء 'installedPackage' قبل از اینکه در برابر null تأیید شود استفاده شد. بررسی خطوط: 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

اگر می خواهید این مقاله را با مخاطبان انگلیسی زبان به اشتراک بگذارید، لطفاً از پیوند ترجمه استفاده کنید: Vladislav Stolyarov. PVS-Studio اکنون در Chocolatey است: بررسی Chocolatey تحت Azure DevOps.

منبع: www.habr.com

اضافه کردن نظر