[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