CodeQL queries 1.25
Skip to end of metadata
Go to start of metadata

Name: Arithmetic operation assumes 365 days per year

Description: When an arithmetic operation modifies a date by a constant value of 365, it may be a sign that leap years are not taken into account.

ID: cpp/leap-year/adding-365-days-per-year

Kind: problem

Severity: warning

Precision: medium

Query: Adding365DaysPerYear.ql
/**
 * @name Arithmetic operation assumes 365 days per year
 * @description When an arithmetic operation modifies a date by a constant
 *              value of 365, it may be a sign that leap years are not taken
 *              into account.
 * @kind problem
 * @problem.severity warning
 * @id cpp/leap-year/adding-365-days-per-year
 * @precision medium
 * @tags leap-year
 *       correctness
 */

import cpp
import LeapYear
import semmle.code.cpp.dataflow.DataFlow

from Expr source, Expr sink, PossibleYearArithmeticOperationCheckConfiguration config
where config.hasFlow(DataFlow::exprNode(source), DataFlow::exprNode(sink))
select sink,
  "This arithmetic operation $@ uses a constant value of 365 ends up modifying the date/time located at $@, without considering leap year scenarios.",
  source, source.toString(), sink, sink.toString()

The leap year rule for the Gregorian calendar, which has become the internationally accepted civil calendar, is: every year that is exactly divisible by four is a leap year, except for years that are exactly divisible by 100, but these centurial years are leap years if they are exactly divisible by 400.

A leap year bug occurs when software (in any language) is written without consideration of leap year logic, or with flawed logic to calculate leap years; which typically results in incorrect results.

The impact of these bugs may range from almost unnoticeable bugs such as an incorrect date, to severe bugs that affect reliability, availability or even the security of the affected system.

When performing arithmetic operations on a variable that represents a date, leap years must be taken into account. It is not safe to assume that a year is 365 days long.

Recommendation

Determine whether the time span in question contains a leap day, then perform the calculation using the correct number of days. Alternatively, use an established library routine that already contains correct leap year logic.

References