时间转换函数未检查返回值¶
ID: cpp/leap-year/unchecked-return-value-for-time-conversion-function
Kind: problem
Security severity:
Severity: warning
Precision: medium
Tags:
- leap-year
- correctness
Query suites:
- cpp-security-and-quality.qls
公历(已成为国际通用的民用历法)的闰年规则是:凡是可以被 4 整除的年份都是闰年,但可以被 100 整除的年份除外,这些世纪年份只有在可以被 400 整除的情况下才是闰年。
当软件(任何语言)在编写时没有考虑闰年逻辑,或者使用有缺陷的逻辑来计算闰年时,就会出现闰年错误;这通常会导致不正确的结果。
这些错误的影响范围从几乎不可察觉的错误(例如日期错误)到影响受影响系统可靠性、可用性甚至安全性的严重错误。
使用将日期结构进行转换的函数时,如果对 API 的输入参数中的年份进行了修改,则必须检查函数的返回值,以确保其执行成功。
否则,函数可能会失败,并且输出参数可能包含无效数据,从而在受影响的系统上导致任何数量的问题。
以下是此查询涵盖的函数列表
FileTimeToSystemTime
SystemTimeToFileTime
SystemTimeToTzSpecificLocalTime
SystemTimeToTzSpecificLocalTimeEx
TzSpecificLocalTimeToSystemTime
TzSpecificLocalTimeToSystemTimeEx
RtlLocalTimeToSystemTime
RtlTimeToSecondsSince1970
_mkgmtime
建议¶
调用将经过修改的日期变量进行转换的 API 时,始终检查返回值,以验证 API 调用是否成功。
示例¶
在此示例中,我们在当前日期的基础上加了一年。这在大多数情况下可能有效,但在任何一个 2 月 29 日,结果值将无效。
SYSTEMTIME st;
FILETIME ft;
GetSystemTime(&st);
// Flawed logic may result in invalid date
st.wYear++;
// The following code may fail
SystemTimeToFileTime(&st, &ft);
要修复此错误,您必须验证 SystemTimeToFileTime
的返回值,并相应地处理任何潜在的错误。
SYSTEMTIME st;
FILETIME ft;
GetSystemTime(&st);
// Flawed logic may result in invalid date
st.wYear++;
// Check for leap year, and adjust the date accordingly
bool isLeapYear = st.wYear % 4 == 0 && (st.wYear % 100 != 0 || st.wYear % 400 == 0);
st.wDay = st.wMonth == 2 && st.wDay == 29 && !isLeapYear ? 28 : st.wDay;
if (!SystemTimeToFileTime(&st, &ft))
{
// handle error
}
参考¶
美国宇航局/戈达德太空飞行中心 - 日历
维基百科 - 闰年错误
Microsoft Azure 博客 - 您的代码已准备好迎接闰年了吗?