Uyarı C26864
Bir tarih-saat nesnesinin
var
gün alanı, düzgün artık yıl denetimi yapılmadan yılda 365 gün olduğu varsayılarak değiştirildi:expr
Bu kural Visual Studio 2022 17.8'e eklendi.
Açıklamalar
Gregoryen takvimde, tam olarak dört ile bölünebilen her yıl, tam olarak 100 ile bölünebilen yıllar dışında artık yıldır. 400 ile tam olarak bölünebiliyorlarsa centurial yıllar da artık yıllardır.
Yazılım bu artık yıl mantığını hesaba eklemediğinde veya hatalı mantık kullandığında artık yıl hatası oluşur. , güvenilirlik, kullanılabilirlik ve hatta etkilenen sistemin güvenliğini etkileyebilir.
Tarihi temsil eden bir değişken üzerinde aritmetik işlemler gerçekleştirirken artık yılları dikkate almanız gerekir. Bir yılın 365 gün olduğunu varsaymak güvenli değildir. Artık yıl, Şubat ayında 29. gün olarak eklenen 'artık gün' nedeniyle 366 güne sahiptir.
Bir yılı doğru şekilde ilerletmek için, zaman aralığının artık gün içerip içermediğini belirleyin, ardından hesaplamayı doğru gün sayısını kullanarak gerçekleştirin. Yılın doğrudan gelişmiş olması ve sonuçta elde edilen tarih üzerinde uygun bir artık gün denetimi olması daha iyidir. Alternatif olarak, artık yılları doğru işleyen yerleşik bir kitaplık yordamı kullanın.
Kod analizi adı: DATETIME_MANIPULATION_ASSUMING_365_DAYS_WITHOUT_LEAPYEAR_CHECK
Örnek
Aşağıdaki kod geçerli sistem saatini almaya, gün alanına 365 gün ekleyerek ve artık yıl başına tarihi ayarlayarak günü bir yıl ilerletmeye çalışır. Ancak, sonuç sonraki yılın aynı ayına/tarihine düşmeyebilir:
#include <Windows.h>
void foo()
{
SYSTEMTIME st;
GetSystemTime(&st);
// Advance a year by adding 365 days
st.wDay += 365; // C26864
}
Bu sorunu çözmek için yıl alanını doğrudan ilerletip artık yıl kuralına göre tarihi ayarlayın:
#include <Windows.h>
void foo()
{
SYSTEMTIME st;
GetSystemTime(&st);
st.wYear++; // Advance a year
// Adjust the date
if (st.wMonth == 2 && st.wDay == 29)
{
// Move back a day when landing on Feb 29 in a non-leap year
bool isLeapYear = st.wYear % 4 == 0 && (st.wYear % 100 != 0 || st.wYear % 400 == 0);
if (!isLeapYear)
{
st.wDay = 28;
}
}
}
Buluşsal yöntemler
Bu kural yalnızca Windows SYSTEMTIME
yapısını ve C tm
yapısını tanır.
Tarih alanı doğrudan 365 gün değiştirilirse bu kural uygulanır. Tarih alanının değerinin başka bir değişkene atanıp atanmadığını ve daha sonra işlenip işlenmediğini dikkate almaz ve bu nedenle eşdeğer hataları kaçırabilir.
Bu kural bir kabul kuralıdır, yani kod analizi bir kural kümesi dosyası kullanmalıdır ve kuralın kural kümesi dosyasına açıkça eklenmesi ve uygulanması için etkinleştirilmesi gerekir. Kod analizi için özel kural kümesi oluşturma hakkında daha fazla bilgi için bkz. Çalıştırılacak Kuralları Belirtmek C++
için Kural Kümelerini Kullanma.