Uyarı C26861

Bir tarih-saat nesnesinin var alanı, uygun artık yıl denetimi yapılmadan 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.

Artık yılları hesaba katmadan bir tarih-saat nesnesinin yıl, ay veya gün alanına bir sayı eklemek veya çıkarmak güvenli değildir. Bu hesaplama, örneğin bir sertifikanın son kullanma tarihini belirlemek için yaygın olarak gerçekleştirilir. Birçok tarihte, saf bir hesaplama istenen sonucu verebilir. Ancak, sonuç 29 Şubat (artık gün) olduğunda ve yıl artık yıl değilse, sonuç geçersiz olur.

Örneğin, 2020-01-31'e bir yıl eklemek 2021-01-31'i üretir. Ancak 2020-02-29'a bir yıl eklemek 2021-02-29'a neden olur ve bu geçerli bir tarih değildir çünkü 2021 artık bir yıl değildir.

Tarih değerlerini temsil eden değişkenleri düzenlerken dikkatli olun. Artık yılları ve artık günleri düzgün bir şekilde işleyin veya tarih aritmetiğini güvenli bir şekilde işleyen bir API veya kitaplık kullanın.

Kod analizi adı: DATETIME_MANIPULATION_WITHOUT_LEAPYEAR_CHECK

Örnek

Aşağıdaki kod, sistem saatini temsil eden tarih-saat nesnesinin yıl alanını artırarak sistem saatini bir yıl ilerletir. Ancak, tarih değişiklik öncesinde 29 Şubat ise geçersiz bir tarih-saat nesnesi oluşturabilir, çünkü sonraki yıl artık yıl değildir:

SYSTEMTIME st; 
GetSystemTime(&st); 
st.wYear++;  // warning C26861 

Artık yıl nedeniyle geçersiz bir tarih-saat nesnesi oluşturmaktan kaçınmak için, sonuçta elde edilen tarihin hala geçerli olup olmadığını denetleyin ve bu örnekte olduğu gibi geçerli hale getirmek için gerekli ayarlamaları yapın:

SYSTEMTIME st; 
GetSystemTime(&st); 
st.wYear++; 
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

Şu anda bu kural yalnızca Windows SYSTEMTIME yapısını ve C tm yapısını tanır.

Bu kural, riskli olabilecek değişiklikleri bulmak için basitleştirilmiş bir buluşsal yöntemlere sahiptir ve uygun artık yıl veya artık gün denetimi olmadığı sürece uyarıları bildirir. Artık yıl veya artık gün denetiminin değiştirilen tarih-saat nesnesi için doğru şekilde gerçekleştirilip gerçekleştirilmediğini doğrulamaya çalışmaz.

Bu kural bir kabul etme kuralıdır; bu da kod analizinin bir kural kümesi dosyası kullanması ve kuralın kural kümesi dosyasına açıkça dahil edilmesi ve uygulanması için etkinleştirilmesi gerektiği anlamına gelir. Kod analizi için özel bir 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.

Ayrıca bkz.

C6393
C6394
C26862
C26863
C26864