PVS-Studio pergi ke awan: Azure DevOps

Gambar 9

Ini adalah artikel kedua tentang menggunakan analisa statis PVS-Studio dalam sistem cloud CI, dan kali ini kita akan mempertimbangkan platform Azure DevOps - solusi cloud CI \ CD dari Microsoft. Sebagai proyek yang dianalisis kali ini, pertimbangkan ShareX.

Kami membutuhkan tiga komponen. Yang pertama adalah analisa statis PVS-Studio. Yang kedua adalah Azure DevOps, yang dengannya kami akan mengintegrasikan alat analisa. Yang ketiga adalah proyek yang akan kami periksa untuk menunjukkan kemampuan PVS-Studio saat bekerja di cloud. Jadi mari kita mulai.

PVS-Studio adalah penganalisa kode statis untuk mencari kesalahan dan cacat keamanan. Melakukan analisis kode dalam C, C ++, C # dan Java.

Azure DevOps . Platform Azure DevOps mencakup alat-alat seperti Azure Pipeline, Azure Board, Azure Artifacts, dan lainnya untuk mempercepat proses pembuatan perangkat lunak dan meningkatkan kualitasnya.

ShareX adalah aplikasi gratis yang memungkinkan Anda menangkap dan merekam bagian mana pun dari layar. Proyek ini ditulis dalam C # dan bagus untuk menunjukkan bagaimana menjalankan analisa statis. Kode sumber untuk proyek tersedia di GitHub .

Output dari perintah cloc untuk proyek ShareX:
Bahasa
file
kosong
komentar
Kode
C #
696
20658
24423
102565
Skrip MSBuild
11
1
77
5859
Dengan kata lain, proyek ini kecil, tetapi cukup memadai untuk menunjukkan karya PVS-Studio dalam hubungannya dengan platform cloud.

Mari mengatur


Untuk memulai di Azure DevOps, klik tautan dan klik tombol "Mulai gratis dengan GitHub".

Gambar 2

Memberikan akses aplikasi Microsoft ke data akun GitHub.

Gambar 1

Untuk menyelesaikan pendaftaran harus membuat akun Microsoft.

Gambar 12

Setelah mendaftar, buat proyek:

Gambar 5

Selanjutnya, kita perlu pergi ke bagian "Pipeline" - "Builds" dan membuat pipeline Build baru

Gambar 8

Untuk pertanyaan di mana kode kami berada, kami akan menjawab - GitHub.

Gambar 13

Kami mengotorisasi aplikasi Azure Pipelines dan memilih repositori dengan proyek yang akan kami konfigurasikan peluncuran analisis statis.

Gambar 7

Di jendela pemilihan template, pilih "Pipeline pemula".

Gambar 17

Kami dapat menjalankan analisis statis kode proyek dalam dua cara: menggunakan agen yang dihosting oleh Microsoft atau di-hosting sendiri

Dalam versi pertama, kami akan menggunakan agen yang dihosting oleh Microsoft. Agen tersebut adalah mesin virtual biasa yang dimulai ketika kami memulai saluran pipa kami dan dihapus setelah tugas selesai. Menggunakan agen semacam itu memungkinkan Anda untuk tidak membuang waktu mendukung dan memperbarui mereka, tetapi memberlakukan beberapa pembatasan, misalnya, ketidakmungkinan menginstal perangkat lunak tambahan yang digunakan untuk membangun proyek.

Ganti konfigurasi default kami dengan yang berikut untuk menggunakan agen yang dihosting oleh Microsoft:

#    #      master- trigger: - master #         # ,   Docker-, #      Windows Server 1803 pool: vmImage: 'win1803' container: microsoft/dotnet-framework:4.7.2-sdk-windowsservercore-1803 steps: #    - task: PowerShell@2 inputs: targetType: 'inline' script: 'Invoke-WebRequest -Uri https://files.viva64.com/PVS-Studio_setup.exe -OutFile PVS-Studio_setup.exe' - task: CmdLine@2 inputs: workingDirectory: $(System.DefaultWorkingDirectory) script: | #      nuget restore .\ShareX.sln #  ,        md .\PVSTestResults #   PVS-Studio_setup.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /COMPONENTS=Core #        "C:\Program Files (x86)\PVS-Studio\PVS-Studio_Cmd.exe" credentials -u $(PVS_USERNAME) -n $(PVS_KEY) #        html. "C:\Program Files (x86)\PVS-Studio\PVS-Studio_Cmd.exe" -t .\ShareX.sln -o .\PVSTestResults\ShareX.plog "C:\Program Files (x86)\PVS-Studio\PlogConverter.exe" -t html -o .\PVSTestResults\ .\PVSTestResults\ShareX.plog #    - task: PublishBuildArtifacts@1 inputs: pathToPublish: PVSTestResults artifactName: PVSTestResults 

Catatan: menurut dokumentasi , wadah yang digunakan harus di-cache dalam gambar mesin virtual, tetapi pada saat penulisan artikel ini tidak berfungsi dan wadah diunduh setiap kali tugas dimulai, yang secara negatif mempengaruhi waktu eksekusi.

Simpan pipeline dan buat variabel yang akan digunakan untuk membuat file lisensi. Untuk melakukan ini, buka jendela pengeditan pipa dan di sudut kanan atas klik tombol "Variabel".

Gambar 14

Tambahkan dua variabel - PVS_USERNAME dan PVS_KEY , masing-masing berisi nama pengguna dan kunci lisensi. Saat membuat variabel PVS_KEY , jangan lupa untuk memeriksa item โ€œRahasiakan nilai iniโ€ untuk mengenkripsi nilai variabel dengan kunci RSA 2048-bit, serta menekan output dari nilai variabel ke log eksekusi tugas.

Gambar 15

Kami menyimpan variabel dan mulai pipa dengan tombol "Run".

Opsi kedua untuk menjalankan analisis adalah menggunakan agen yang di-host-sendiri. Agen yang diinangi sendiri adalah agen yang kami konfigurasikan dan kelola sendiri. Agen tersebut memberikan lebih banyak peluang untuk menginstal perangkat lunak, yang diperlukan untuk perakitan dan pengujian produk perangkat lunak kami.

Sebelum menggunakan agen tersebut, mereka harus dikonfigurasi sesuai dengan instruksi , dan penganalisa statis harus diinstal dan dikonfigurasi .

Untuk memulai tugas pada agen yang di-host-sendiri, kami mengganti konfigurasi default yang diusulkan dengan yang berikut:

 #    #    master- trigger: - master #    self-hosted    'MyPool' pool: 'MyPool' steps: - task: CmdLine@2 inputs: workingDirectory: $(System.DefaultWorkingDirectory) script: | #      nuget restore .\ShareX.sln #  ,        md .\PVSTestResults #        html. "C:\Program Files (x86)\PVS-Studio\PVS-Studio_Cmd.exe" -t .\ShareX.sln -o .\PVSTestResults\ShareX.plog "C:\Program Files (x86)\PVS-Studio\PlogConverter.exe" -t html -o .\PVSTestResults\ .\PVSTestResults\ShareX.plog #    - task: PublishBuildArtifacts@1 inputs: pathToPublish: PVSTestResults artifactName: PVSTestResults 

Setelah menyelesaikan tugas, arsip dengan laporan analisis dapat diunduh pada tab Ringkasan, atau kita dapat menggunakan ekstensi Kirim Surat , yang memungkinkan Anda mengonfigurasi pengiriman email, atau mencari alat yang lebih nyaman bagi kami di Marketplace .

Gambar 21

Tentang hasil analisis


Sekarang mari kita lihat beberapa kesalahan yang ditemukan dalam proyek yang diperiksa - ShareX.

Cek berlebihan

Untuk melakukan pemanasan, mari kita mulai dengan kelemahan sederhana dalam kode, yaitu dengan pemeriksaan berlebihan:

 private void PbThumbnail_MouseMove(object sender, MouseEventArgs e) { .... IDataObject dataObject = new DataObject(DataFormats.FileDrop, new string[] { Task.Info.FilePath }); if (dataObject != null) { Program.MainForm.AllowDrop = false; dragBoxFromMouseDown = Rectangle.Empty; pbThumbnail.DoDragDrop(dataObject, DragDropEffects.Copy | DragDropEffects.Move); Program.MainForm.AllowDrop = true; } .... } 

Peringatan PVS-Studio : V3022 [CWE-571] Ekspresi 'dataObject! = Null' selalu benar. TaskThumbnailPanel.cs 415

Perhatikan memeriksa variabel dataObject untuk null . Untuk apa dia di sini? dataObject tidak bisa nol dalam hal ini, karena ini diinisialisasi dengan referensi ke objek yang dibuat. Akibatnya, kami memiliki verifikasi yang berlebihan. Apakah ini penting? Tidak. Tampak ringkas? Tidak. Pemeriksaan ini jelas lebih baik dihapus agar tidak mengacaukan kode.

Mari kita lihat bagian lain dari kode, di mana Anda dapat membuat komentar serupa:

 private static Image GetDIBImage(MemoryStream ms) { .... try { .... return new Bitmap(bmp); .... } finally { if (gcHandle != IntPtr.Zero) { GCHandle.FromIntPtr(gcHandle).Free(); } } .... } private static Image GetImageAlternative() { .... using (MemoryStream ms = dataObject.GetData(format) as MemoryStream) { if (ms != null) { try { Image img = GetDIBImage(ms); if (img != null) { return img; } } catch (Exception e) { DebugHelper.WriteException(e); } } } .... } 

Peringatan PVS-Studio : V3022 [CWE-571] Ekspresi 'img! = Null' selalu benar. ClipboardHelpers.cs 289

Metode GetImageAlternative lagi memeriksa bahwa variabel img tidak nol segera setelah membuat instance baru dari kelas Bitmap . Perbedaan dari contoh sebelumnya di sini adalah bahwa untuk menginisialisasi variabel img , kita tidak menggunakan konstruktor, tetapi metode GetDIBImage . Pembuat kode mengasumsikan bahwa pengecualian dapat terjadi dalam metode ini, tetapi menyatakan hanya mencoba dan akhirnya memblokir, menghilangkan tangkapan . Oleh karena itu, jika pengecualian terjadi, metode pemanggilan - GetImageAlternative - tidak akan menerima referensi ke objek bertipe Bitmap, tetapi akan dipaksa untuk menangani pengecualian dalam blok tangkapnya sendiri. Dalam kasus ini, variabel img tidak akan diinisialisasi, dan utas eksekusi bahkan tidak akan mencapai centang img! = Null , tetapi akan segera jatuh ke dalam blok tangkap . Oleh karena itu, penganalisa memang menunjukkan validasi berlebihan.

Pertimbangkan contoh peringatan berikut dengan kode V3022 :

 private void btnCopyLink_Click(object sender, EventArgs e) { .... if (lvClipboardFormats.SelectedItems.Count == 0) { url = lvClipboardFormats.Items[0].SubItems[1].Text; } else if (lvClipboardFormats.SelectedItems.Count > 0) { url = lvClipboardFormats.SelectedItems[0].SubItems[1].Text; } .... } 

Peringatan PVS-Studio : V3022 [CWE-571] Ekspresi 'lvClipboardFormats.SelectedItems.Count> 0' selalu benar. AfterUploadForm.cs 155

Mari kita lihat ekspresi kondisional kedua. Di sana kami memeriksa nilai properti Hitung baca-saja. Properti ini menunjukkan jumlah elemen dalam instance koleksi SelectedItems . Kondisi terpenuhi hanya jika properti Hitung lebih besar dari nol. Semuanya akan baik-baik saja, tetapi itu hanya di luar jika pernyataan bahwa Hitungan sudah diperiksa. Turunan dari koleksi SelectedItems tidak dapat memiliki jumlah elemen kurang dari nol, oleh karena itu, Count mengambil nilai yang sama dengan nol atau lebih besar dari nol. Karena kami telah melakukan pemeriksaan pada pernyataan pertama jika pernyataan bahwa Count adalah nol, dan ternyata salah, tidak masuk akal untuk menulis cek lain pada cabang lain bahwa Count lebih besar dari nol.

Contoh terakhir dari nomor kesalahan V3022 adalah fragmen kode berikut:

 private void DrawCursorGraphics(Graphics g) { .... int cursorOffsetX = 10, cursorOffsetY = 10, itemGap = 10, itemCount = 0; Size totalSize = Size.Empty; int magnifierPosition = 0; Bitmap magnifier = null; if (Options.ShowMagnifier) { if (itemCount > 0) totalSize.Height += itemGap; .... } .... } 

Peringatan PVS-Studio : Ekspresi V3022 'itemCount> 0' selalu salah. RegionCaptureForm.cs 1100.

Penganalisis memperhatikan bahwa itemCount kondisi > 0 akan selalu salah, karena sedikit deklarasi yang lebih tinggi dilakukan dan variabel itemCount diatur ke nol pada saat yang sama. Hingga kondisi tersebut, variabel ini tidak digunakan di mana pun dan tidak berubah, oleh karena itu, penganalisa membuat kesimpulan yang benar tentang ekspresi kondisional, yang nilainya selalu salah.

Baiklah, sekarang mari kita lihat sesuatu yang sangat menarik.

Cara terbaik untuk memahami bug adalah dengan memvisualisasikan bug.

Sepertinya kami menemukan kesalahan yang agak menarik di tempat ini:

 public static void Pixelate(Bitmap bmp, int pixelSize) { .... float r = 0, g = 0, b = 0, a = 0; float weightedCount = 0; for (int y2 = y; y2 < yLimit; y2++) { for (int x2 = x; x2 < xLimit; x2++) { ColorBgra color = unsafeBitmap.GetPixel(x2, y2); float pixelWeight = color.Alpha / 255; r += color.Red * pixelWeight; g += color.Green * pixelWeight; b += color.Blue * pixelWeight; a += color.Alpha * pixelWeight; weightedCount += pixelWeight; } } .... ColorBgra averageColor = new ColorBgra((byte)(b / weightedCount), (byte)(g / weightedCount), (byte)(r / weightedCount), (byte)(a / pixelCount)); .... } 

Saya tidak ingin segera mengungkapkan semua kartu dan menunjukkan apa yang ditemukan oleh analis kami di sini, jadi mari kita tunda sejenak untuk saat ini.

Dengan nama metode, mudah untuk menebak apa yang dilakukannya - Anda mengirimkan gambar atau potongan gambar sebagai input, dan melakukan pixelasinya. Kode metode ini cukup panjang, jadi kami tidak akan memberikannya di sini secara keseluruhan, tetapi cukup mencoba menjelaskan algoritmanya dan menjelaskan bug apa yang ditemukan oleh PVS-Studio di sini.

Metode ini menerima dua parameter sebagai input: objek bertipe Bitmap dan nilai bertipe int , yang menunjukkan ukuran piksel. Algoritma operasi cukup sederhana:

1) Kami memecah fragmen gambar yang diterima pada input ke dalam kotak dengan sisi yang sama dengan ukuran pixelation. Sebagai contoh, jika kita memiliki ukuran pixelisasi 15, maka kita mendapatkan persegi yang berisi 15x15 = 225 piksel.

2) Selanjutnya, kita berkeliling setiap piksel dalam kuadrat ini dan mengakumulasikan nilai-nilai bidang Merah , Hijau , Biru dan Alpha menjadi variabel perantara, dan sebelumnya mengalikan nilai warna yang sesuai dan nilai kanal alfa dengan variabel pixelWeight , diperoleh dengan membagi nilai Alpha dengan 255 (variabel Alpha memiliki ketik byte ). Juga, ketika melintasi piksel, kami menjumlahkan nilai yang direkam dalam pixelWeight ke dalam variabel yang disebut weightedCount .

Cuplikan kode yang melakukan langkah-langkah di atas adalah sebagai berikut:

 ColorBgra color = unsafeBitmap.GetPixel(x2, y2); float pixelWeight = color.Alpha / 255; r += color.Red * pixelWeight; g += color.Green * pixelWeight; b += color.Blue * pixelWeight; a += color.Alpha * pixelWeight; weightedCount += pixelWeight; 

Omong-omong, perhatikan bahwa jika nilai variabel Alpha adalah nol, maka pixelWeight tidak akan menambahkan nilai apa pun ke variabel WeightedCount untuk piksel ini. Kami akan membutuhkan ini di masa depan.

3) Setelah kami melewati semua piksel dalam kuadrat saat ini, kami dapat membuat warna "rata-rata" umum untuk kuadrat ini. Kode yang melakukan tindakan ini adalah sebagai berikut:

 ColorBgra averageColor = new ColorBgra((byte)(b / weightedCount), (byte)(g / weightedCount), (byte)(r / weightedCount), (byte)(a / pixelCount)); 

4) Sekarang kita memiliki warna akhir dan menuliskannya ke variabel averageColor , kita dapat kembali berkeliling setiap pixel di dalam kotak dan memberikan nilai dari averageColor .

5) Kami kembali ke langkah 2 selama masih ada kotak mentah.

Sekali lagi, kami mencatat bahwa variabel weightedCount tidak sama dengan jumlah semua piksel yang dikuadratkan. Misalnya, jika piksel yang benar-benar transparan muncul di gambar (nilainya nol pada saluran alfa), maka variabel pixelWeight akan menjadi nol untuk piksel ini ( 0/255 = 0), oleh karena itu, piksel ini tidak akan memberikan kontribusi apa pun pada pembentukan nilai variabel weightedCount . Ini logis - tidak masuk akal untuk memperhitungkan warna-warna piksel yang benar-benar transparan.

Segalanya tampak cukup masuk akal - pixelation harus bekerja dengan benar. Dan itu bekerja dengan baik. Itu tidak untuk gambar png yang memiliki piksel dengan nilai di saluran alpha kurang dari 255 dan tidak sama dengan nol. Perhatikan gambar pixelated di bawah ini:

Gambar 3


Apakah Anda melihat pikselasi? Dan kita tidak. Nah, sekarang mari kita ungkapkan intrik kecil ini dan jelaskan di mana sebenarnya bug itu tersembunyi dalam metode ini. Kesalahan merayap ke baris untuk menghitung nilai variabel pixelWeight :

 float pixelWeight = color.Alpha / 255; 

Faktanya adalah bahwa pembuat kode, menyatakan variabel pixelWeight sebagai float , menyiratkan bahwa ketika membagi bidang Alpha dengan 255, selain nol dan satu, angka fraksional harus diperoleh. Di sinilah masalahnya, karena variabel Alpha adalah tipe byte , dan ketika kita membaginya dengan 255, kita mendapatkan nilai integer, dan hanya kemudian akan secara implisit dilemparkan ke float , oleh karena itu, bagian fraksional hilang.

Ketidakmampuan untuk pixelize gambar PNG yang memiliki tingkat transparansi mudah untuk dijelaskan. Karena nilai kanal alfa untuk piksel ini terletak pada rentang 0 <Alpha <255, saat membagi variabel Alpha dengan 255, kami akan selalu mendapatkan 0. Oleh karena itu, nilai pikselBerat , r , g , b , a , variabel Variabel berbobot juga selalu akan menjadi nol. Hasilnya, rata-rata warna rata-rata kami akan dengan nilai nol di semua saluran: merah - 0, biru - 0, hijau - 0, alfa - 0. Mengisi kotak dengan warna ini, kami tidak mengubah warna asli piksel, karena rata-rata Warna benar-benar transparan . Untuk memperbaiki kesalahan ini, Anda hanya perlu secara eksplisit melemparkan bidang Alpha ke tipe float . Baris kode yang diperbaiki mungkin terlihat seperti ini:

 float pixelWeight = (float)color.Alpha / 255; 

Dan inilah saatnya mengutip pesan yang diberikan PVS-Studio ke kode yang salah:

Peringatan PVS-Studio : V3041 [CWE-682] Ekspresi ini secara implisit dilemparkan dari tipe 'int' ke tipe 'float'. Pertimbangkan untuk menggunakan pemeran tipe eksplisit untuk menghindari hilangnya bagian fraksional. Contoh: double A = (double) (X) / Y; ImageHelpers.cs 1119.

Dan sebagai perbandingan, kami memberikan tangkapan layar gambar yang benar-benar pixelated yang diperoleh pada versi tetap aplikasi:

Gambar 6

Potensi NullReferenceException

 public static bool AddMetadata(Image img, int id, string text) { .... pi.Value = bytesText; if (pi != null) { img.SetPropertyItem(pi); return true; } .... } 

Peringatan PVS-Studio: V3095 [CWE-476] Objek 'pi' digunakan sebelum diverifikasi terhadap null. Periksa baris: 801, 803. ImageHelpers.cs 801

Fragmen kode ini menunjukkan bahwa pembuatnya mengharapkan variabel pi menjadi nol , itulah sebabnya pemeriksaan pi! = Null dilakukan sebelum memanggil metode SetPropertyItem . Sungguh aneh bahwa sebelum pemeriksaan ini, array byte ditugaskan ke properti pi.Value , karena jika pi nol , pengecualian tipe NullReferenceException akan dibuang.

Situasi serupa terlihat di tempat lain:

 private static void Task_TaskCompleted(WorkerTask task) { .... task.KeepImage = false; if (task != null) { if (task.RequestSettingUpdate) { Program.MainForm.UpdateCheckStates(); } .... } .... } 

Peringatan PVS-Studio: V3095 [CWE-476] Objek 'tugas' digunakan sebelum diverifikasi terhadap nol. Periksa baris: 268, 270. TaskManager.cs 268

PVS-Studio menemukan kesalahan serupa lainnya. Artinya masih sama, jadi tidak ada kebutuhan besar untuk memberikan fragmen kode, kami membatasi diri pada pesan penganalisa.

Peringatan PVS-Studio: V3095 [CWE-476] Objek 'Config.PhotobucketAccountInfo' digunakan sebelum diverifikasi dengan null. Periksa baris: 216, 219. UploadersConfigForm.cs 216

Nilai pengembalian yang sama

Sepotong kode yang mencurigakan ditemukan dalam metode EvalWindows dari kelas WindowsList , yang mengembalikan true dalam keadaan apa pun:

 public class WindowsList { public List<IntPtr> IgnoreWindows { get; set; } .... public WindowsList() { IgnoreWindows = new List<IntPtr>(); } public WindowsList(IntPtr ignoreWindow) : this() { IgnoreWindows.Add(ignoreWindow); } .... private bool EvalWindows(IntPtr hWnd, IntPtr lParam) { if (IgnoreWindows.Any(window => hWnd == window)) { return true; // <= } windows.Add(new WindowInfo(hWnd)); return true; // <= } } 

Peringatan PVS-Studio: V3009 Aneh bahwa metode ini selalu mengembalikan nilai yang sama dan 'benar'. WindowsList.cs 82

Tampaknya logis bahwa jika sebuah pointer dengan nilai yang sama dengan hWnd ditemukan dalam daftar dengan nama IgnoreWindows , maka metode tersebut harus mengembalikan false .

Daftar IgnoreWindows dapat diisi baik dengan memanggil konstruktor WindowsList (IntPtr ignWindow) , atau langsung melalui akses ke properti, karena bersifat publik. Salah satu cara atau yang lain, menurut Visual Studio, pada saat ini dalam kode daftar ini tidak diisi dengan cara apa pun. Ini adalah tempat aneh lain dari metode ini.

Panggilan tidak aman ke penangan acara

 protected void OnNewsLoaded() { if (NewsLoaded != null) { NewsLoaded(this, EventArgs.Empty); } } 

Peringatan PVS-Studio: V3083 [CWE-367] Doa yang tidak aman dari acara 'NewsLoaded', NullReferenceException dimungkinkan. Pertimbangkan menugaskan acara ke variabel lokal sebelum menjalankannya. NewsListControl.cs 111

Dalam kasus ini, situasi tidak menyenangkan berikut ini dapat terjadi: setelah memeriksa variabel NewsLoaded untuk ketidaksetaraan nol , metode yang memproses acara tersebut dapat dibatalkan berlangganan, misalnya, di utas lain, dan ketika kita masuk ke tubuh pernyataan conditional if , variabel NewsLoaded sudah akan menjadi sama dengan nol . Mencoba memanggil pelanggan pada acara NewsLoaded yang nol akan melempar NullReferenceException . Jauh lebih aman menggunakan operator kondisional nol dan menulis ulang kode di atas sebagai berikut:

 protected void OnNewsLoaded() { NewsLoaded?.Invoke(this, EventArgs.Empty); } 

Alat analisis menunjukkan 68 tempat lebih mirip. Kami tidak akan menjelaskannya di sini - pola panggilan acara di dalamnya serupa.

Kembalikan null dari ToString

Belum lama ini, dari artikel rekan yang menarik, saya menemukan bahwa Microsoft tidak merekomendasikan pengembalian nol dari metode ToString yang ditimpa. PVS-Studio sangat menyadari hal ini:

 public override string ToString() { lock (loggerLock) { if (sbMessages != null && sbMessages.Length > 0) { return sbMessages.ToString(); } return null; } } 

Peringatan PVS-Studio: V3108 Tidak disarankan untuk mengembalikan 'null' dari metode 'ToSting ()'. Logger.cs 167

Mengapa pantas jika tidak menggunakan?

 public SeafileCheckAccInfoResponse GetAccountInfo() { string url = URLHelpers.FixPrefix(APIURL); url = URLHelpers.CombineURL(APIURL, "account/info/?format=json"); .... } 

PVS-Studio Warning: V3008 Variabel 'url' diberi nilai dua kali berturut-turut. Mungkin ini sebuah kesalahan. Periksa baris: 197, 196. Seafile.cs 197

Seperti yang Anda lihat dari contoh, ketika mendeklarasikan variabel url , ia diberi nilai yang dikembalikan dari metode FixPrefix . Di baris berikutnya, kami "menggiling" nilai yang dihasilkan, bahkan tanpa menggunakannya di mana pun. Kami mendapatkan sesuatu yang mirip dengan "kode mati" - itu berfungsi, tidak mempengaruhi hasil akhir. Kesalahan ini kemungkinan besar merupakan hasil dari copy-paste, karena fragmen kode seperti itu ditemukan di 9 metode lainnya.
Sebagai contoh, kami memberikan dua metode dengan baris pertama yang serupa:

 public bool CheckAuthToken() { string url = URLHelpers.FixPrefix(APIURL); url = URLHelpers.CombineURL(APIURL, "auth/ping/?format=json"); .... } .... public bool CheckAPIURL() { string url = URLHelpers.FixPrefix(APIURL); url = URLHelpers.CombineURL(APIURL, "ping/?format=json"); .... } 

Total


Seperti yang dapat kita lihat, kerumitan pengaturan verifikasi otomatis oleh alat analisis tidak bergantung pada sistem CI yang dipilih - hanya dalam 15 menit dan beberapa klik mouse, kami mengatur verifikasi kode proyek kami dengan alat analisis statis.

Sebagai kesimpulan, kami sarankan Anda mengunduh dan mencoba penganalisa pada proyek Anda.



Jika Anda ingin berbagi artikel ini dengan audiens yang berbahasa Inggris, silakan gunakan tautan ke terjemahan: Oleg Andreev, Ilya Gainulin. PVS-Studio di Awan: Azure DevOps .

Source: https://habr.com/ru/post/id467359/


All Articles