Warning C6393
A lookup table of size 365 isn't sufficient to handle leap years
This rule was added in Visual Studio 2022 17.8.
Remarks
In the Gregorian calendar, every year exactly divisible by four is a leap year--except for years that are exactly divisible by 100. The centurial years are also leap years if they're exactly divisible by 400.
A leap year bug occurs when software doesn't account for this leap year logic, or uses flawed logic. The can affect reliability, availability, or even the security of the affected system.
Lookup tables of size 365 are often used to quickly find the month a given day corresponds to. However, it isn't correct because a leap year has 366 days.
Code analysis name: LEAP_YEAR_INVALID_DATE_KEYED_LOOKUP
Example
The following code creates a lookup table for the day of the year, assuming 365 days per year. However, this doesn't work if the year is a leap year:
#include <vector>
void foo(int year)
{
const std::vector<int> items(365); // C6393
// Initialize items and use it...
}
To fix the problem, adjust the size of the lookup table as the table is created according to the result of appropriate leap year check:
#include <vector>
void foo(int year)
{
bool isLeapYear = year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
const std::vector<int> items(isLeapYear ? 366 : 365);
// Initialize items and use it...
}
Heuristics
This rule is enforced by checking if a constant lookup table is sized for 365 elements. Violation of this rule causes a high confidence warning to be reported.