Rumah >Java >javaTutorial >Peraturan diagnostik baharu dalam PVS-Studio 4

Peraturan diagnostik baharu dalam PVS-Studio 4

Linda Hamilton
Linda Hamiltonasal
2024-12-31 06:18:09600semak imbas

Keluaran PVS-Studio 7.34 telah memperkenalkan sekumpulan peraturan diagnostik baharu ke dalam penganalisis: analisis taint untuk Java, peraturan diagnostik khusus Unity untuk C#, menyelam mendalam ke dalam OWASP dan banyak lagi! Artikel ini akan merangkumi kesemuanya.

New diagnostic rules in PVS-Studio 4

C

Dalam keluaran ini, pasukan C menumpukan pada peraturan diagnostik Analisis Am dan sokongan untuk pelbagai piawaian pembangunan perisian.

Tetapi pegang topi anda, ini baru permulaan! Pasukan merancang untuk merangkumi lebih banyak lagi peraturan diagnostik standard MISRA, jadi nantikan berita lanjut :)

Dan buat masa ini, mari kita lihat peraturan utama dalam keluaran 7.34.

V1116

Mencipta objek pengecualian tanpa mesej penjelasan boleh mengakibatkan pengelogan tidak mencukupi.

Peraturan diagnostik ini direka bentuk untuk mengesan pengecualian yang dibuat tanpa mesej penjelasan.

Ketiadaan mesej mungkin menghalang proses pengesanan dan pembetulan ralat, serta kebolehbacaan kod keseluruhan.

Berikut ialah contoh kod yang menjadikan penganalisis PVS-Studio menjana amaran:

void SomeCheck(const char *val)
{
  if (!val) throw std::runtime_error { "" };
  ....
}

void Foo()
{
  const char *val = ....;
  try
  {
    SomeCheck(val);              // <=
  }
  catch(std::runtime_error &err)
  {
    std::cerr << err.what() << std::endl;
  }
}

Jika ralat berlaku, fungsi SomeCheck membuang pengecualian dengan mesej kosong, yang akan dikendalikan dalam fungsi Foo. Semasa pemprosesan, std::cerr dijangka mengandungi maklumat tentang sebab pengecualian, tetapi tidak.

Dengan menulis kod dengan cara ini, pembangun menghantar ucapan "selamat penyahpepijatan" kepada rakan sekerja. Ini menghalang pemahaman apa sebenarnya yang menyebabkan kegagalan.

Peraturan ini berfungsi untuk pengecualian standard. Anda boleh menggunakan mekanisme anotasi tersuai untuk mengeluarkan amaran bagi pengecualian tersuai.

Lihat dokumentasi untuk mendapatkan butiran lanjut tentang peraturan diagnostik ini.

V1117 [Untuk bahasa C]

Jenis fungsi yang diisytiharkan adalah kelayakan cv. Tingkah laku semasa menggunakan jenis ini tidak ditentukan.

Peraturan diagnostik ini hanya digunakan pada bahasa C.

Ia bertujuan untuk mengesan kes definisi jenis fungsi yang menggunakan const atau penentu yang tidak menentu.

Mengikut standard C23 (titik ke-10 perenggan 6.7.4.1), menggunakan jenis ini membawa kepada tingkah laku yang tidak ditentukan.

Contoh kod yang menjadikan penganalisis PVS-Studio menjana amaran:

typedef int fun_t(void);

typedef const fun_t const_qual_fun_t;          // <=

typedef const fun_t * ptr_to_const_qual_fun_t; // <=

void foo()
{
  const fun_t c_fun_t;       // <=
  const fun_t * ptr_c_fun_t; // <=
}

Lihat dokumentasi untuk mendapatkan butiran lanjut tentang peraturan diagnostik ini.

V2022 [Untuk bahasa C]

Penukaran jenis tersirat daripada jenis integer kepada jenis enum.

Satu lagi peraturan diagnostik untuk bahasa C yang boleh membantu semasa pemfaktoran semula dan penyahpepijatan.

Peraturan ini membolehkan penganalisis mengesan hantaran tersirat jenis integer kepada jenis enum.

Contoh kod dengan amaran PVS-Studio:

void SomeCheck(const char *val)
{
  if (!val) throw std::runtime_error { "" };
  ....
}

void Foo()
{
  const char *val = ....;
  try
  {
    SomeCheck(val);              // <=
  }
  catch(std::runtime_error &err)
  {
    std::cerr << err.what() << std::endl;
  }
}

Kod ini menggunakan pengendali bersyarat (?:) untuk memilih antara dua pembolehubah integer posOne dan postTwo, menghasilkan hantaran tersirat.

Lihat dokumentasi untuk mendapatkan butiran lanjut tentang peraturan diagnostik ini.

V5014 [OWASP Standard]

OWASP. Fungsi kriptografi ditamatkan. Penggunaannya boleh membawa kepada isu keselamatan. Pertimbangkan untuk bertukar kepada fungsi baharu yang setara.

Berikut ialah peraturan diagnostik baharu yang memfokuskan pada keselamatan, sejajar dengan prinsip SAST.

Peraturan ini direka bentuk mengikut piawaian pengesahan keselamatan OWASP.

Ia bertujuan untuk mengesan panggilan fungsi kriptografi usang. Penggunaannya boleh menyebabkan masalah keselamatan perisian yang kritikal.

Contoh kod dengan amaran PVS-Studio:

typedef int fun_t(void);

typedef const fun_t const_qual_fun_t;          // <=

typedef const fun_t * ptr_to_const_qual_fun_t; // <=

void foo()
{
  const fun_t c_fun_t;       // <=
  const fun_t * ptr_c_fun_t; // <=
}

Menurut dokumentasi Microsoft, fungsi CryptoImportKey dan CryptoDestroyKey tidak digunakan lagi. Ini harus digantikan dengan rakan sejawat daripada Cryptography Next Generation (BCryptoImportKey dan BCryptoDestroyKey).

Lihat dokumentasi untuk mendapatkan butiran lanjut tentang peraturan diagnostik ini.

Tetapi itu hanya pemanasan badan! Pasukan C dan C merancang untuk merangkumi lebih banyak peraturan diagnostik pada pelbagai piawaian pembangunan perisian. Perhatian khusus akan diberikan kepada standard MISRA. Jadi, tunggu beritanya :)

C

Dalam keluaran PVS-Studio 7.34 baharu, pasukan C# menumpukan pada mencipta peraturan diagnostik khusus Perpaduan tetapi juga tidak melupakan peraturan Analisis Umum.

Mari kita mulakan dengan yang terakhir.

V3207

Corak logik 'bukan A atau B' mungkin tidak berfungsi seperti yang diharapkan. Corak 'bukan' dipadankan hanya dengan ungkapan pertama daripada corak 'atau'.

Peraturan diagnostik baharu ini bertujuan untuk mengesan penggunaan corak bukan A atau B yang salah. Masalahnya berpunca daripada kekeliruan pembangun tentang keutamaan operasi.

Contoh kod dengan amaran PVS-Studio:

Orientation GetOrientation (bool b)
{
  int posOne = 1;
  int posTwo = 2;
  return b ? posOne : posTwo;    // V2022
}

Pada permulaan kaedah, kunci parameter input disemak untuk rentetan kosong atau nol.

Tetapi terdapat ralat dalam logik ungkapan bersyarat. Keutamaan pengendali bukan adalah lebih tinggi daripada pengendali atau. Akibatnya, penolakan tidak digunakan pada sebelah kanan ungkapan. Selain itu, jika kunci ditetapkan kepada null, syarat tersebut akan menjadi benar.

Lihat dokumentasi untuk mendapatkan butiran lanjut tentang peraturan diagnostik ini.

V3208 [Enjin Perpaduan]

Enjin Perpaduan. Menggunakan 'WeakReference' dengan 'UnityEngine.Object' tidak disokong. GC tidak akan menuntut semula memori objek kerana ia dipautkan kepada objek asli.

Ini ialah peraturan diagnostik pertama dalam siri baharu peraturan khusus Perpaduan.

Ia bertujuan untuk mengesan penggunaan UnityEngine.Object (atau objek lain yang diwarisi daripadanya) bersama-sama dengan System.WeakReference.

Disebabkan oleh penggunaan tersirat contoh oleh enjin itu sendiri, gelagat rujukan yang lemah mungkin berbeza daripada yang dijangkakan.

Contoh kod dengan amaran PVS-Studio:

void SomeCheck(const char *val)
{
  if (!val) throw std::runtime_error { "" };
  ....
}

void Foo()
{
  const char *val = ....;
  try
  {
    SomeCheck(val);              // <=
  }
  catch(std::runtime_error &err)
  {
    std::cerr << err.what() << std::endl;
  }
}

Dalam contoh, kita boleh melihat rujukan yang lemah kepada objek kelas GameObject. Walaupun pengarang belum mencipta rujukan yang kukuh kepada objek ini, pemungut sampah tidak akan dapat membersihkannya.

Lihat dokumentasi untuk mendapatkan butiran lanjut tentang peraturan diagnostik ini.

V3209 [Enjin Perpaduan]

Enjin Perpaduan. Menggunakan tunggu pada objek 'Ditunggu' lebih daripada sekali boleh menyebabkan pengecualian atau kebuntuan, kerana objek tersebut dikembalikan ke kolam selepas ditunggu.

Dalam peraturan diagnostik lain untuk Unity, penganalisis mencari tempat dengan berbilang kegunaan objek UnityEngine.Awaitable yang sama dengan operator menunggu.

Objek disimpan dalam kumpulan objek untuk tujuan pengoptimuman.

Pada panggilan tunggu, objek Ditunggu dikembalikan ke kolam. Selepas itu jika tunggu digunakan pada objek yang sama sekali lagi, kita mendapat pengecualian. Dalam sesetengah kes, kebuntuan juga mungkin berlaku.

Contoh kod dengan amaran PVS-Studio:

typedef int fun_t(void);

typedef const fun_t const_qual_fun_t;          // <=

typedef const fun_t * ptr_to_const_qual_fun_t; // <=

void foo()
{
  const fun_t c_fun_t;       // <=
  const fun_t * ptr_c_fun_t; // <=
}

Dalam kod ini, kami mendapat pengecualian atau kebuntuan. Biar saya terangkan sebabnya. Kami mendapat nilai menggunakan panggilan tunggu menunggu. Kemudian kita mulakan pembolehubah hasil dengan nilai ini. Kebuntuan berlaku, kerana penantian sebelum ini telah digunakan untuk menunggu dalam pembinaan bersyarat.

Lihat dokumentasi untuk mendapatkan butiran lanjut tentang peraturan diagnostik ini.

V3210 [Enjin Perpaduan]

Enjin Perpaduan. Unity tidak membenarkan mengalih keluar komponen 'Transform' menggunakan kaedah 'Destroy' atau 'DestroyImmediate'. Panggilan kaedah akan diabaikan.

Peraturan diagnostik ini bertujuan untuk mengesan anomali yang berkaitan dengan panggilan kaedah Destroy atau DestroyImmediate kelas UnityEngine.Object.

Masalah berlaku dalam situasi apabila hujah jenis UnityEngine.Transform digunakan. Ini menyebabkan ralat semasa panggilan kaedah. Mengalih keluar komponen Transform daripada objek permainan tidak dibenarkan dalam Unity.

Contoh kod dengan amaran PVS-Studio:

Orientation GetOrientation (bool b)
{
  int posOne = 1;
  int posTwo = 2;
  return b ? posOne : posTwo;    // V2022
}

Harta transform daripada kelas asas MonoBehaviour mengembalikan tika kelas Transform, yang dihantar sebagai hujah kepada kaedah Destroy.

Apabila memanggil kaedah dengan cara ini, Unity akan memberikan mesej ralat, tetapi komponen itu sendiri tidak akan dimusnahkan.

Lihat dokumentasi untuk mendapatkan butiran lanjut tentang peraturan diagnostik ini.

V4007 [Enjin Perpaduan]

Enjin Perpaduan. Elakkan mencipta dan memusnahkan objek UnityEngine dalam konteks sensitif prestasi. Pertimbangkan untuk mengaktifkan dan menyahaktifkannya.

Peraturan diagnostik ini menyasarkan pelbagai ralat yang berbeza—isu prestasi.

Jika anda berminat dengan cara analisis statik boleh membantu mengoptimumkan projek Unity, saya menjemput anda untuk membaca artikel ini.

Tujuan peraturan ini adalah untuk membantu penganalisis mengesan penciptaan objek Unity dalam kaedah yang kerap dilaksanakan.

Penciptaan/pemusnahan objek permainan secara tetap bukan sahaja memuatkan CPU, tetapi juga membawa kepada peningkatan kekerapan panggilan pemungut sampah. Ini menjejaskan prestasi.

Contoh kod dengan amaran PVS-Studio:

void SomeCheck(const char *val)
{
  if (!val) throw std::runtime_error { "" };
  ....
}

void Foo()
{
  const char *val = ....;
  try
  {
    SomeCheck(val);              // <=
  }
  catch(std::runtime_error &err)
  {
    std::cerr << err.what() << std::endl;
  }
}

Di sini dalam kaedah Kemas kini, objek _instance permainan dibuat dan dimusnahkan. Memandangkan Kemas kini dilaksanakan setiap kali bingkai dikemas kini, adalah disyorkan untuk mengelakkan operasi ini di dalamnya jika boleh.

Lihat dokumentasi untuk mendapatkan butiran lanjut tentang peraturan diagnostik ini.

Dengan cara ini, diagnostik Unity yang lain masih belum datang! Bersedia untuk berita baik daripada pasukan kami :)

Lagi satu...

Kami tidak boleh tidak memberitahu anda tentang satu peningkatan penting dalam penganalisis C#—menjejaki perubahan nilai pulangan kaedah antara panggilan. Apakah yang berubah? Jom pecahkan.

Lihat contoh ini:

typedef int fun_t(void);

typedef const fun_t const_qual_fun_t;          // <=

typedef const fun_t * ptr_to_const_qual_fun_t; // <=

void foo()
{
  const fun_t c_fun_t;       // <=
  const fun_t * ptr_c_fun_t; // <=
}

Kaedah Contoh() menyemak nilai pulangan Foo() untuk null. Kaedah Foo() kemudian dipanggil semula dalam kandungan keadaan dan nilai pulangannya dinyahrujuk.

Terdahulu, penganalisis akan menjana amaran dalam kes ini kerana ia tidak mempertimbangkan konteks seruan, hanya memfokuskan pada kod pengisytiharannya. Penganalisis digunakan untuk membayangkan bahawa null boleh dikembalikan.

Kini penganalisis memahami bahawa Foo() mengembalikan nilai yang sama dalam kedua-dua kes dan tidak akan ada amaran.

Tetapi mari kita lihat contoh dengan kod yang diubah suai sedikit...

Orientation GetOrientation (bool b)
{
  int posOne = 1;
  int posTwo = 2;
  return b ? posOne : posTwo;    // V2022
}

Daripada pengisytiharan kaedah Foo(), kita boleh mendapatkannya apabila _condition == benar, kaedah mengembalikan bukan batal.

Penganalisis akan melihat medan _condition berubah sebelum seruan kedua dan akan membuat andaian: jika medan yang digunakan di dalam Foo() telah berubah, nilai pulangan Foo() mungkin telah berubah juga.

Akibatnya, amaran tentang kemungkinan dereference akan kekal.

Penganalisis C# kini menyokong analisis projek .NET 9! Ketahui lebih lanjut tentang ini dan ciri baharu yang lain dalam PVS-Studio 7.34 di sini.

Jawa

Dengan keluaran PVS-Studio 7.34, penganalisis Java kini mempunyai mekanisme untuk analisis taint!

Mekanisme ini menjadi asas untuk peraturan diagnostik pertama—cari suntikan SQL. Kemas kini masa hadapan bagi penganalisis Java akan memfokuskan pada SAST, senarai 10 Teratas OWASP bagi potensi kerentanan yang paling biasa dan peraturan diagnostik lain yang berkaitan dengan noda.

Sekarang, mari kita mulakan dengan beberapa peraturan Analisis Am baharu, kerana ia juga berbaloi.

V6123

Nilai operan yang diubah suai tidak digunakan selepas operasi kenaikan/penurunan.

Peraturan diagnostik baharu ini menyerlahkan kawasan dalam kod di mana nilai operasi postfix tidak digunakan.

Masalahnya ialah sama ada operasi berlebihan atau, lebih serius, operasi bercampur aduk dan pembangun mahu menggunakan awalan.

Contoh kod dengan amaran PVS-Studio:

void SomeCheck(const char *val)
{
  if (!val) throw std::runtime_error { "" };
  ....
}

void Foo()
{
  const char *val = ....;
  try
  {
    SomeCheck(val);              // <=
  }
  catch(std::runtime_error &err)
  {
    std::cerr << err.what() << std::endl;
  }
}

Pengendali tidak akan menjejaskan nilai yang kaedah hitungSesuatu akan dikembalikan.

Lihat dokumentasi untuk mendapatkan butiran lanjut tentang peraturan diagnostik ini.

V6124

Menukar literal integer kepada jenis dengan julat nilai yang lebih kecil akan mengakibatkan limpahan.

Seperti yang anda boleh lihat daripada nama peraturan diagnostik ini, ia mengesan kemungkinan limpahan.

Contoh kod dengan amaran PVS-Studio:

typedef int fun_t(void);

typedef const fun_t const_qual_fun_t;          // <=

typedef const fun_t * ptr_to_const_qual_fun_t; // <=

void foo()
{
  const fun_t c_fun_t;       // <=
  const fun_t * ptr_c_fun_t; // <=
}

Pembolehubah jenis integer telah diberikan nilai di luar julat yang sah, yang akan menyebabkan limpahan.

Pembolehubah jelas akan menyimpan nilai yang berbeza daripada nilai yang cuba ditetapkan oleh pembangun.

Lihat dokumentasi untuk mendapatkan butiran lanjut tentang peraturan diagnostik ini.

V6125

Memanggil kaedah 'tunggu', 'beritahu' dan 'notifyAll' di luar konteks yang disegerakkan akan membawa kepada 'IllegalMonitorStateException'.

Diagnostik ini membantu mengenal pasti masalah penyegerakan.

Contoh kod dengan amaran PVS-Studio:

Orientation GetOrientation (bool b)
{
  int posOne = 1;
  int posTwo = 2;
  return b ? posOne : posTwo;    // V2022
}

Penganalisis melihat menunggu, memberitahu dan memberitahuSemua kaedah, kerana kaedah itu mungkin dipanggil dalam konteks tidak disegerakkan. Mereka beroperasi dengan monitor objek yang penyegerakan berlaku. Iaitu, seruan mereka adalah betul hanya dalam konteks yang disegerakkan dan hanya pada objek yang penyegerakan berlaku.

Jika tunggu, maklumkan atau maklumkanSemua kaedah dipanggil dalam konteks yang tidak disegerakkan atau pada objek yang salah, kami mendapat pengecualian IllegalMonitorStateException.

Lihat dokumentasi untuk mendapatkan butiran lanjut tentang peraturan diagnostik ini.

V5309 [standard OWASP]

OWASP. Kemungkinan suntikan SQL. Data yang berpotensi tercemar digunakan untuk mencipta arahan SQL.

Peraturan diagnostik berkaitan noda pertama bagi penganalisis Java! Lebih khusus lagi, penganalisis kini boleh mengesan kemungkinan suntikan SQL.

Suntikan SQL ialah kelemahan yang membolehkan penyerang menyuntik kod mereka ke dalam pertanyaan SQL. Jika pertanyaan menggunakan data luaran, tanpa mengesahkannya dengan betul, seseorang itu akan mempertaruhkan integriti dan kerahsiaan maklumat yang disimpan dalam pangkalan data.

void SomeCheck(const char *val)
{
  if (!val) throw std::runtime_error { "" };
  ....
}

void Foo()
{
  const char *val = ....;
  try
  {
    SomeCheck(val);              // <=
  }
  catch(std::runtime_error &err)
  {
    std::cerr << err.what() << std::endl;
  }
}

Sekiranya pengguna ternyata berniat jahat dan nilai param adalah lebih kurang seperti berikut:- "111' atau 1=1; drop table users; pilih ' ",—anda boleh mengucapkan selamat tinggal kepada jadual pengguna. Oleh itu, adalah penting untuk menyemak data luaran.

Lihat dokumentasi untuk mendapatkan butiran lanjut tentang peraturan diagnostik ini.

Terima kasih kerana membaca!

Jika anda mempunyai permintaan untuk artikel atau soalan, jangan teragak-agak untuk menghantarnya melalui borang maklum balas. Akhir sekali, kami ingin mendengar pendapat anda dalam ulasan:)

Atas ialah kandungan terperinci Peraturan diagnostik baharu dalam PVS-Studio 4. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel sebelumnya:Jenis dataArtikel seterusnya:Jenis data