[llvm-bugs] [Bug 48319] New: std::get_time does not check month range minimum

via llvm-bugs llvm-bugs at lists.llvm.org
Fri Nov 27 14:36:34 PST 2020


https://bugs.llvm.org/show_bug.cgi?id=48319

            Bug ID: 48319
           Summary: std::get_time does not check month range minimum
           Product: libc++
           Version: 3.2
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P
         Component: All Bugs
          Assignee: unassignedclangbugs at nondot.org
          Reporter: emile.cormier.jr at gmail.com
                CC: llvm-bugs at lists.llvm.org, mclow.lists at gmail.com

libc++'s std::get_time allows a day input of "00" for the %m specifier, whereas
the POSIX spec for strptime constrains it to [01,12].

When converted to a std::tm, the month becomes zero-based with a range of
[0,11], so it's understandable how this oversight in range checking could have
happened.

libc++'s std::get_time doesn't allow an input of "00" for the %d specifier, so
the range checking behavior is not consistent between the %m and %d specifiers.

For comparison, GCC's libstdc++ does not allow an input of "00" for the %m
specifier.

I've tracked the problem down to this line, where there should be an extra
condition to check that __t >= 0:
https://github.com/llvm/llvm-project/blob/527a7fdfbd7461e2aaa9eb279543c5d9dc8efa5a/libcxx/include/locale#L1956

I'm currently set-up with Clang version 11, but checking the git blame on
Github reveals that this bug probably existed since the initial import back in
2010, so I've set the Version field of this bug report to the earliest possible
value.

I don't have time to set up a build environment to check if that is indeed the
proper fix, so I leave it to the libc++ maintainers.

Here is a program that reproduces the problem:

#include <cstring>
#include <ctime>
#include <iostream>
#include <sstream>
#include <iomanip>

int main()
{
    using namespace std;
    istringstream good_month("2000-01-01");
    istringstream bad_month("2000-00-01");
    istringstream bad_day("2000-01-00");

    tm ymd;
    memset(&ymd, 0, sizeof(ymd));

    good_month >> get_time(&ymd, "%Y-%m-%d");
    cout << "!good_month=" << !good_month; // prints 0, as expected
    cout << ", ymd.tm_mon=" << ymd.tm_mon << "\n"; // prints -1

    bad_month >> get_time(&ymd, "%Y-%m-%d");
    cout << "!bad_month=" << !bad_month; // *** prints 0, should be 1 ***
    cout << ", ymd.tm_mon=" << ymd.tm_mon << "\n"; // prints 0

    bad_day >> get_time(&ymd, "%Y-%m-%d");
    cout << "!bad_day=" << !bad_day << "\n"; // prints 1, as expected

    const char c_bad_month[] = "2000-00-01";
    auto result = strptime(c_bad_month, "%Y-%m-%d", &ymd);
    cout << "(result==nullptr)=" << (result==nullptr) << "\n"; // prints 1

    return 0;
}

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20201127/750ecaa6/attachment.html>


More information about the llvm-bugs mailing list