Partager via


Avertissement C26861

Le champ d’un objet var date/heure a été modifié sans vérification appropriée de l’année bissextile : expr

Cette règle a été ajoutée dans Visual Studio 2022 17.8.

Notes

Dans le calendrier grégorien, chaque année exactement divisible par quatre est une année bissextile, à l’exception des années qui sont exactement divisibles par 100. Les années centuriales sont aussi des années bissextiles si elles sont exactement divisibles par 400.

Un bogue de l’année bissextile se produit lorsque le logiciel ne tient pas compte de cette logique de l’année bissextile ou utilise une logique défectueuse. Cela peut affecter la fiabilité, la disponibilité ou même la sécurité du système concerné.

Il n’est pas sûr d’ajouter ou de soustraire un nombre vers ou depuis l’année, le mois ou le champ jour d’un objet date-heure sans prendre en compte les années bissextiles. Ce calcul est généralement effectué pour déterminer la date d’expiration d’un certificat, par exemple. À de nombreuses dates, un calcul naïf peut produire le résultat souhaité. Toutefois, lorsque le résultat est le 29 février (un jour bissextile) et que l’année n’est pas une année bissextile, le résultat n’est pas valide.

Par exemple, l’ajout d’une année à 2020-01-31 produit 2021-01-31. Mais l’ajout d’une année à 2020-02-29 produit 2021-02-29, ce qui n’est pas une date valide car 2021 n’est pas une année bissextile.

Soyez prudent lors de la manipulation de variables qui représentent des valeurs de date. Gérez correctement les années bissextiles et les jours bissextiles, ou utilisez une API ou une bibliothèque qui gère en toute sécurité la date arithmétique.

Nom de l’analyse du code : DATETIME_MANIPULATION_WITHOUT_LEAPYEAR_CHECK

Exemple

Le code suivant avance l’heure système d’une année en incrémentant le champ année de l’objet date-heure représentant l’heure système. Toutefois, elle peut produire un objet date-heure non valide si la date était le 29 février avant la modification, car l’année suivante n’est pas une année bissextile :

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

Pour éviter de créer un objet date/heure non valide en raison d’une année bissextile, vérifiez si la date résultante est toujours valide et effectuez les ajustements nécessaires pour le rendre valide, comme dans cet exemple :

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

Heuristique

Actuellement, cette règle reconnaît uniquement le struct Windows SYSTEMTIME et le struct C tm .

Cette règle utilise une heuristique simplifiée pour trouver des changements potentiellement risqués et signale des avertissements, sauf s’il existe une vérification appropriée de l’année bissextile ou du jour bissextile. Il n’essaie pas de vérifier si la vérification de l’année bissextile ou du jour bissextile est effectuée correctement pour l’objet date-heure modifié.

Cette règle est une règle d’opt-in, ce qui signifie que l’analyse du code doit utiliser un fichier d’ensemble de règles, et que la règle doit être explicitement incluse dans le fichier d’ensemble de règles et activée pour qu’elle soit appliquée. Pour plus d’informations sur la création d’un ensemble de règles personnalisé pour l’analyse du code, consultez : Utiliser des ensembles de règles pour spécifier les C++ règles à exécuter.

Voir aussi

C6393
C6394
C26862
C26863
C26864