CodeQL 文档

时间转换函数未检查返回值

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

点击查看 CodeQL 仓库中的查询

公历(已成为国际通用的民用历法)的闰年规则是:凡是可以被 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
}

参考

  • ©GitHub, Inc.
  • 条款
  • 隐私