Partilhar via


Aviso C26861

O campo de um objeto var de data-hora foi modificado sem a devida verificação de ano bissexto: expr

Essa regra foi adicionada no Visual Studio 2022 17.8.

Comentários

No calendário gregoriano, cada ano exatamente divisível por quatro é um ano bissexto - exceto para anos que são exatamente divisíveis por 100. Os anos centuriais também são anos bissextos se forem exatamente divisíveis por 400.

Um bug de ano bissexto ocorre quando o software não dá conta dessa lógica de ano bissexto ou usa lógica falha. Isso pode afetar a confiabilidade, a disponibilidade ou até mesmo a segurança do sistema afetado.

Não é seguro adicionar ou subtrair algum número de ou para o campo de ano, mês ou dia de um objeto de data-hora sem levar em conta os anos bissextos. Esse cálculo geralmente é realizado para determinar a data de expiração de um certificado, por exemplo. Em muitas datas, um cálculo ingênuo pode produzir o resultado desejado. No entanto, quando o resultado é 29 de fevereiro (um dia bissexto) e o ano não é um ano bissexto, o resultado é inválido.

Por exemplo, adicionar um ano a 2020-01-31 produz 2021-01-31. Mas adicionar um ano a 29-02-2020 produz 29-02-2021, que não é uma data válida porque 2021 não é um ano bissexto.

Seja cauteloso ao manipular variáveis que representam valores de data. Lide com anos bissextos e dias bissextos corretamente ou use uma API ou biblioteca que lide com aritmética de data com segurança.

Nome da análise de código: DATETIME_MANIPULATION_WITHOUT_LEAPYEAR_CHECK

Exemplo

O código a seguir avança a hora do sistema em um ano incrementando o campo ano do objeto date-time que representa a hora do sistema. No entanto, ele pode produzir um objeto de data-hora inválido se a data foi 29 de fevereiro antes da modificação, porque o próximo ano não é um ano bissexto:

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

Para evitar a criação de um objeto de data-hora inválido devido a um ano bissexto, verifique se a data resultante ainda é válida e faça os ajustes necessários para torná-la válida, como neste exemplo:

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

Heurística

Atualmente, essa regra só reconhece o Windows SYSTEMTIME struct e C tm struct.

Essa regra emprega uma heurística simplificada para encontrar alterações potencialmente arriscadas e relata avisos, a menos que haja verificação apropriada de ano bissexto ou dia bissexto. Ele não tenta verificar se a verificação de ano bissexto ou dia bissexto é executada corretamente para o objeto de data-hora modificado.

Essa regra é uma regra de aceitação, o que significa que a análise de código deve usar um arquivo de conjunto de regras, e a regra deve ser explicitamente incluída no arquivo de conjunto de regras e habilitada para que seja aplicada. Para obter mais informações sobre como criar um conjunto de regras personalizado para análise de código, consulte: Usar conjuntos de regras para especificar as C++ regras a serem executadas.

Confira também

C6393
C6394
C26862
C26863
C26864