Udostępnij za pośrednictwem


Ostrzeżenie C26861

Pole obiektu var daty i godziny zostało zmodyfikowane bez odpowiedniego sprawdzania roku przestępnego: expr

Ta reguła została dodana w programie Visual Studio 2022 17.8.

Uwagi

W kalendarzu gregoriańskim każdy rok dokładnie dzielący przez cztery jest rokiem przestępnym — z wyjątkiem lat, które są dokładnie podzielne przez 100. Lata centurialne są również lat przestępnych, jeśli są dokładnie podzielne przez 400.

Błąd roku przestępnego występuje, gdy oprogramowanie nie uwzględnia tej logiki roku przestępnego lub używa wadliwej logiki. Może to mieć wpływ na niezawodność, dostępność, a nawet bezpieczeństwo systemu, którego dotyczy problem.

Nie można bezpiecznie dodać ani odjąć pewnej liczby do lub z pola roku, miesiąca lub dnia obiektu daty i godziny bez uwzględniania lat przestępnych. To obliczenie jest często wykonywane w celu określenia daty wygaśnięcia certyfikatu, na przykład. W wielu datach naiwne obliczenie może spowodować uzyskanie żądanego wyniku. Jeśli jednak wynik to 29 lutego (dzień przestępny), a rok nie jest rokiem przestępnym, wynik jest nieprawidłowy.

Na przykład dodanie roku do 2020-01-31 powoduje wygenerowanie 2021-01-31. Ale dodanie roku do 2020-02-29 produkuje 2021-02-29, co nie jest prawidłową datą, ponieważ 2021 nie jest rokiem przestępnym.

Podczas manipulowania zmiennymi reprezentującymi wartości daty należy zachować ostrożność. Prawidłowo obsłuż lata przestępne i dni przestępne lub używaj interfejsu API lub biblioteki obsługującej arytmetyczną datę.

Nazwa analizy kodu: DATETIME_MANIPULATION_WITHOUT_LEAPYEAR_CHECK

Przykład

Poniższy kod zwiększa godzinę systemową o rok, zwiększając pole roku obiektu daty i godziny reprezentującej godzinę systemową. Może jednak wygenerować nieprawidłowy obiekt daty i godziny, jeśli data przypadała 29 lutego przed modyfikacją, ponieważ następny rok nie jest rokiem przestępnym:

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

Aby uniknąć tworzenia nieprawidłowego obiektu daty i godziny z powodu roku przestępnego, sprawdź, czy wynikowa data jest nadal prawidłowa i wprowadź niezbędne korekty, aby było prawidłowe, jak w tym przykładzie:

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; 
    } 
}

Algorytmy heurystyczne

Obecnie ta reguła rozpoznaje tylko strukturę systemu Windows SYSTEMTIME i strukturę C tm .

Ta reguła wykorzystuje uproszczoną heurystyczną do znajdowania potencjalnie ryzykownych zmian i raportów ostrzeżeń, chyba że istnieje odpowiedni rok przestępny lub sprawdzanie dnia przestępnego. Nie próbuje sprawdzić, czy sprawdzanie roku przestępnego lub przestępnego jest wykonywane poprawnie dla zmodyfikowanego obiektu daty i godziny.

Ta reguła jest regułą zgody, co oznacza, że analiza kodu powinna używać pliku zestawu reguł, a reguła powinna zostać jawnie dołączona do pliku zestawu reguł i włączona, aby została zastosowana. Aby uzyskać więcej informacji na temat tworzenia niestandardowego zestawu reguł na potrzeby analizy kodu, zobacz: Używanie zestawów reguł do określania C++ reguł do uruchomienia.

Zobacz też

C6393
C6394
C26862
C26863
C26864