Бид PVS-Studio-г ашиглахад илүү тохиромжтой болгосоор байна. Манай анализаторыг Windows-д зориулсан багц менежер Chocolatey дээр ашиглах боломжтой боллоо. Энэ нь PVS-Studio-г, ялангуяа үүлэн үйлчилгээнд нэвтрүүлэхэд тусална гэж бид үзэж байна. Хол явахгүйн тулд нөгөө л Шоколадейн эх кодыг шалгая. Azure DevOps нь CI системийн үүрэг гүйцэтгэнэ.
Үүлэн системтэй нэгтгэх сэдвээр манай бусад нийтлэлүүдийн жагсаалтыг энд оруулав.
PVS-Studio үүл рүү явдаг: Azure DevOps PVS-Studio үүл рүү явдаг: Travis CI PVS-Studio үүл рүү явдаг: CircleCI PVS-Studio үүл рүү явдаг: GitLab CI/CD
Azure DevOps-тэй нэгтгэх тухай эхний нийтлэлд анхаарлаа хандуулахыг би танд зөвлөж байна, учир нь энэ тохиолдолд давтагдахгүйн тулд зарим зүйлийг орхигдуулсан болно.
Тиймээс, энэ нийтлэлийн баатрууд:
Шоколад хэрэглэх тухай
Та багц менежерийг өөрөө хэрхэн суулгахыг эндээс харж болно
Анализаторын хамгийн сүүлийн хувилбарыг суулгах тушаал:
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-parameters ашиглан дамжуулж болно.
Visual Studio 2019-д зориулсан залгаас бүхий анализаторыг суулгах командын жишээ:
choco install pvs-studio --package-parameters="'/MSVS2019'"
Одоо Azure DevOps дор анализаторыг ашиглахад тохиромжтой жишээг харцгаая.
тохируулга
Бүртгэлийг бүртгэх, Build Pipeline үүсгэх, GitHub репозиторт байрлах төсөлтэй бүртгэлээ синхрончлох зэрэг асуудлуудын талаар тусдаа хэсэг байгааг сануулъя.
Эхлээд эхлүүлэх гохыг тохируулцгаая, энэ нь бид зөвхөн өөрчлөлтөд зориулж ажиллуулдаг гэдгийг харуулж байна мастер салбар:
trigger:
- master
Дараа нь бид виртуал машин сонгох хэрэгтэй. Одоогоор энэ нь Windows Server 2019 болон Visual Studio 2019-тэй Microsoft-ын зохион байгуулсан агент байх болно:
pool:
vmImage: 'windows-latest'
Тохируулгын файлын үндсэн хэсэг рүү шилжье (block алхам). Хэдийгээр та дурын программ хангамжийг виртуал машинд суулгах боломжгүй ч би Docker контейнер нэмээгүй. Бид Chocolatey-г Azure DevOps-ийн өргөтгөл болгон нэмж болно. Үүнийг хийхийн тулд бид рүү явцгаая
Энд та өргөтгөлийг хаана нэмэхээ сонгоод товчлуур дээр дарах хэрэгтэй Суулгах.
Амжилттай суулгасны дараа товшино уу Зохион байгуулалт руугаа ор:
Та одоо цонхон дээрээс Chocolatey даалгаврын загварыг харж болно үүрэг тохиргооны файлыг засварлах үед azure-pipelines.yml:
Chocolatey дээр товшоод талбаруудын жагсаалтыг харна уу:
Энд бид сонгох хэрэгтэй Суулгах багуудтай талбайд. IN Nuspec файлын нэр шаардлагатай багцын нэрийг зааж өгнө үү - pvs-studio. Хэрэв та хувилбараа заагаагүй бол хамгийн сүүлийн хувилбарыг суулгах бөгөөд энэ нь бидэнд бүрэн нийцдэг. Товчлуур дээр дарцгаая нэмнэ мөн бид үүсгэсэн даалгаврыг тохиргооны файлаас харах болно.
steps:
- task: ChocolateyCommand@0
inputs:
command: 'install'
installPackageId: 'pvs-studio'
Дараа нь файлынхаа үндсэн хэсэг рүү шилжье:
- task: CmdLine@2
inputs:
script:
Одоо бид анализаторын лицензтэй файл үүсгэх хэрэгтэй. Энд PVSNAME и ПВСКЕЙ – тохиргоонд утгыг нь тодорхойлсон хувьсагчдын нэрс. Тэд PVS-Studio нэвтрэх болон лицензийн түлхүүрийг хадгалах болно. Тэдгээрийн утгыг тохируулахын тулд цэсийг нээнэ үү Variables->Шинэ хувьсагч. Хувьсагчдыг үүсгэцгээе PVSNAME нэвтрэх болон ПВСКЕЙ анализаторын түлхүүрийн хувьд. Хайрцагыг шалгахаа бүү мартаарай Энэ үнэ цэнийг нууцалж байгаарай нь ПВСКЕЙ. Командын код:
с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()
Дарцгаая Хадгалах->Хадгалах->Ажиллуулах даалгаврыг гүйцэтгэх. Даалгаврын таб руу орж тайланг татаж авцгаая.
Chocolatey төсөл нь зөвхөн 37615 мөр C# кодыг агуулдаг. Олдсон зарим алдааг харцгаая.
Туршилтын үр дүн
Анхааруулга N1
Анализаторын анхааруулга:
public abstract class CrytpoHashProviderSpecsBase : TinySpec
{
....
protected CryptoHashProvider Provider;
....
public override void Context()
{
Provider = Provider = new CryptoHashProvider(FileSystem.Object);
}
}
Анализатор өөрөө хувьсагчийн оноолтыг илрүүлсэн бөгөөд энэ нь утгагүй юм. Эдгээр хувьсагчийн аль нэгний оронд өөр нэг хувьсагч байх магадлалтай. За, эсвэл энэ бол үсгийн алдаа бөгөөд нэмэлт даалгаврыг зүгээр л арилгаж болно.
Анхааруулга N2
Анализаторын анхааруулга:
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;
}
}
Операторын ялгаа & оператороос && Хэрэв илэрхийллийн зүүн тал нь байвал хуурамч, дараа нь баруун тал нь тооцоолсон хэвээр байх бөгөөд энэ тохиолдолд шаардлагагүй аргын дуудлагыг илтгэнэ систем.директор_байна.
Харгалзан үзсэн хэсэгт энэ нь бага зэргийн дутагдал юм. Тиймээ, энэ нөхцөлийг & операторыг && оператороор солих замаар оновчтой болгож болох боловч практик талаас нь авч үзвэл энэ нь юунд ч нөлөөлөхгүй. Гэсэн хэдий ч бусад тохиолдолд илэрхийллийн баруун талыг буруу/хүчингүй утгуудтай харьцах үед & ба && хоёрын хоорондох төөрөгдөл нь ноцтой асуудал үүсгэдэг. Жишээлбэл, бидний алдааны цуглуулгад,
if ((k < nct) & (s[k] != 0.0))
Индекс байсан ч гэсэн k буруу байвал массивын элементэд хандахад ашиглана. Үүний үр дүнд үл хамаарах зүйл шидэгдэх болно IndexOutOfRangeException.
Анхааруулга N3, N4
Анализаторын анхааруулга:
Анализаторын анхааруулга:
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
Анализаторын анхааруулга:
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
Анализаторын анхааруулга:
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);
}
....
}
....
}
Энд нэг хачирхалтай нөхцөл байдал бий: installPackageVersions.Count != 1үргэлж байх болно үнэн. Ихэнхдээ ийм анхааруулга нь кодын логик алдааг илтгэдэг бөгөөд бусад тохиолдолд энэ нь зүгээр л нэмэлт шалгалтыг илтгэдэг.
Анхааруулга N7
Анализаторын анхааруулга:
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 хэрэглэгчид энэ параметрийг ашиглах боломжгүй байсан apikey дахиад хэдэн арга. Дээрх параметрүүдтэй адил би дараах сонголтуудыг санал болгож чадна.
commandArguments.contains("-apikey=");
commandArguments.contains("-api-key=");
Хуулбар буулгах алдаа нь их хэмжээний эх код бүхий аливаа төсөлд эрт орой хэзээ нэгэн цагт гарч ирэх магадлал өндөр байдаг бөгөөд тэдгээртэй тэмцэх хамгийн сайн хэрэгсэл бол статик шинжилгээ юм.
Жич Мөн энэ алдаа үргэлж олон мөрийн нөхцлийн төгсгөлд гарч ирэх хандлагатай байдаг :). Нийтлэлийг үзнэ үү "
Анхааруулга N8
Анализаторын анхааруулга:
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)
{
....
}
....
}
Сонгодог алдаа: эхлээд объект суулгасан багц хэрэглэж, дараа нь шалгадаг тэг. Энэхүү оношлогоо нь програмын хоёр асуудлын аль нэгийг хэлж өгдөг: аль нэг суулгасан багц хэзээ ч тэнцүү биш тэг, энэ нь эргэлзээтэй, дараа нь шалгах шаардлагагүй, эсвэл бид кодонд ноцтой алдаа гаргаж болзошгүй - null лавлагаанд хандах оролдлого.
дүгнэлт
Тиймээс бид өөр нэг жижиг алхам хийлээ - одоо PVS-Studio-г ашиглах нь илүү хялбар, илүү тохиромжтой болсон. Мөн Chocolatey бол PVS-Studio-г ашиглах үед кодонд цөөн тооны алдаатай сайн багц менежер гэдгийг хэлмээр байна.
Бид урьж байна
PS
Нийтлэхээс өмнө бид нийтлэлийг Chocolatey хөгжүүлэгчдэд илгээсэн бөгөөд тэд үүнийг сайн хүлээж авсан. Бид ямар нэг чухал зүйл олж чадаагүй ч, жишээ нь, "api-key" түлхүүртэй холбоотой бидний олсон алдаа тэдэнд таалагдсан.
Хэрэв та энэ нийтлэлийг англи хэлээр ярьдаг үзэгчидтэй хуваалцахыг хүсвэл орчуулгын холбоосыг ашиглана уу: Владислав Столяров.
Эх сурвалж: www.habr.com