Upozornění C26864
Pole Den objektu
var
data a času bylo změněno za předpokladu, že 365 dní v roce bez správné kontroly přestupného roku:expr
Toto pravidlo bylo přidáno v sadě Visual Studio 2022 17.8.
Poznámky
V gregoriánském kalendáři je každý rok přesně dělitelný čtyřmi lety - s výjimkou let, které jsou přesně dělitelné 100. Centurial roky jsou také přestupné roky, pokud jsou přesně dělitelné o 400.
K chybě přestupného roku dochází v případě, že software nebere v úvahu tuto logiku přestupného roku nebo používá chybnou logiku. Může mít vliv na spolehlivost, dostupnost nebo dokonce i na zabezpečení ovlivněného systému.
Při provádění aritmetických operací u proměnné, která představuje datum, musíte vzít v úvahu přestupné roky. Není bezpečné předpokládat, že rok je dlouhý 365 dní. Přestupný rok má 366 dní kvůli "přestupný den" přidaný jako 29. den v únoru.
Chcete-li správně přejít na rok, určete, zda časové rozpětí obsahuje přestupný den, a pak proveďte výpočet pomocí správného počtu dní. Je lepší, pokud je rok přímo upřesňující, s odpovídající kontrolou přestupového dne ve výsledném datu. Případně můžete použít zavedenou rutinu knihovny, která zpracovává přestupné roky správně.
Název analýzy kódu: DATETIME_MANIPULATION_ASSUMING_365_DAYS_WITHOUT_LEAPYEAR_CHECK
Příklad
Následující kód se pokusí získat aktuální systémový čas, posunout den o jeden rok přidáním 365 dnů do pole dne a upravit datum za přestupný rok pravidlo. Výsledek ale nemusí spadat do stejného měsíce a data příštího roku:
#include <Windows.h>
void foo()
{
SYSTEMTIME st;
GetSystemTime(&st);
// Advance a year by adding 365 days
st.wDay += 365; // C26864
}
Pokud chcete tento problém vyřešit, přejděte přímo do pole roku a upravte datum podle pravidla přestupového roku:
#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;
}
}
}
Heuristika
Toto pravidlo rozpoznává pouze strukturu systému Windows SYSTEMTIME
a strukturu jazyka C tm
.
Toto pravidlo se vynucuje, pokud je pole data přímo změněno 365 dny. Nebere v úvahu, jestli je hodnota pole kalendářního data přiřazená jiné proměnné a pak manipulována, a proto může chybět ekvivalentní chyby.
Toto pravidlo je pravidlo výslovného souhlasu, což znamená, že analýza kódu by měla používat soubor sady pravidel a pravidlo by mělo být explicitně zahrnuto do souboru sady pravidel a povoleno, aby se použilo. Další informace o vytvoření vlastní sady pravidel pro analýzu kódu naleznete v tématu Použití sad pravidel k určení C++
pravidel ke spuštění.