Skip to content

<chrono>: UB in year_month_day_last::day() when !ok() #1647

@statementreply

Description

@statementreply

Describe the bug

year_month_day_last::day() accesses an array without bounds check.

STL/stl/inc/chrono

Lines 1511 to 1513 in 7f08bb3

_NODISCARD constexpr day day() const noexcept {
return _Last_day(year(), month());
}

STL/stl/inc/chrono

Lines 1334 to 1343 in 7f08bb3

inline constexpr day _Last_day_table[] = {
day{31}, day{28}, day{31}, day{30}, day{31}, day{30}, day{31}, day{31}, day{30}, day{31}, day{30}, day{31}};
_NODISCARD constexpr day _Last_day(const year& _Year, const month& _Month) {
if (_Month == month{2} && _Year.is_leap()) {
return day{29};
}
return _Last_day_table[static_cast<unsigned int>(_Month) - 1];
}

Other call sites of _Last_day have checked _Month.ok() before calling, except year_month_day_last::day().

[time.cal.ymdlast.members]/15

Returns: If ok() is true, [...]. Otherwise, the returned value is unspecified.

year_month_day_last::day() shouldn't invoke UB even if !ok().

Command-line test case

#include <chrono>
#include <iostream>

using namespace std;
using namespace std::chrono;

int main() {
    cout << static_cast<unsigned int>((2020y / 0 / last).day()) << "\n";
    return 0;
}
C:\Users\He\source\test>cl /EHsc /W4 /std:c++latest ymd_last.cpp
用于 x64 的 Microsoft (R) C/C++ 优化编译器 19.28.29828 版
版权所有(C) Microsoft Corporation。保留所有权利。

/std:c++latest 作为最新的 C++
working 草稿中的语言功能预览提供。我们希望你提供有关 bug 和改进建议的反馈。
但是,请注意,这些功能按原样提供,没有支持,并且会随着工作草稿的变化
而更改或移除。有关详细信息,请参阅
https://go.microsoft.com/fwlink/?linkid=2045807。

ymd_last.cpp
Microsoft (R) Incremental Linker Version 14.28.29828.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:ymd_last.exe
ymd_last.obj

C:\Users\He\source\test>.\ymd_last.exe

C:\Users\He\source\test>echo %ERRORLEVEL%
-1073741819

Expected behavior

Should print an unspecified value, but not crash.

STL version

7f08bb3

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingfixedSomething works now, yay!

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions