diff --git a/stl/inc/xloctime b/stl/inc/xloctime index 1dbf298843e..55cb9f0df2d 100644 --- a/stl/inc/xloctime +++ b/stl/inc/xloctime @@ -539,6 +539,8 @@ protected: private: ios_base::iostate __CLRCALL_OR_CDECL _Getint(_InIt& _First, _InIt& _Last, int _Lo, int _Hi, int& _Val, const _Ctype& _Ctype_fac) const { // get integer in range [_Lo, _Hi] from [_First, _Last) + _STL_INTERNAL_CHECK(0 <= _Hi && _Hi <= 9999); + const int _Hi_digits = (_Hi <= 9 ? 1 : _Hi <= 99 ? 2 : _Hi <= 999 ? 3 : 4); char _Ac[_MAX_INT_DIG]; char* _Ep; char* _Ptr = _Ac; @@ -554,26 +556,26 @@ private: } } - bool _Seendigit = false; + int _Digits_seen = 0; for (; _First != _Last && _Ctype_fac.narrow(*_First) == '0'; ++_First) { // strip leading zeros - _Seendigit = true; + ++_Digits_seen; } - if (_Seendigit) { + if (_Digits_seen > 0) { *_Ptr++ = '0'; // replace one or more with single zero } for (char* const _Pe = &_Ac[_MAX_INT_DIG - 1]; - _First != _Last && '0' <= (_Ch = _Ctype_fac.narrow(*_First)) && _Ch <= '9'; - _Seendigit = true, (void) ++_First) { // copy digits + _First != _Last && '0' <= (_Ch = _Ctype_fac.narrow(*_First)) && _Ch <= '9' && _Digits_seen < _Hi_digits; + ++_Digits_seen, (void) ++_First) { // copy digits *_Ptr = _Ch; if (_Ptr < _Pe) { ++_Ptr; // drop trailing digits if already too large } } - if (!_Seendigit) { + if (_Digits_seen == 0) { _Ptr = _Ac; } diff --git a/tests/std/tests/Dev11_0836436_get_time/test.cpp b/tests/std/tests/Dev11_0836436_get_time/test.cpp index d6279cde33d..2d704e204dd 100644 --- a/tests/std/tests/Dev11_0836436_get_time/test.cpp +++ b/tests/std/tests/Dev11_0836436_get_time/test.cpp @@ -242,6 +242,78 @@ void test_990695() { assert(t.tm_year == 114); } + { + istringstream iss("20200609"); + ios_base::iostate err = Bit; + tm t{}; + const string fmt("%Y%m%d"); + use_facet>(iss.getloc()) + .get(Iter(iss.rdbuf()), Iter(), iss, err, &t, fmt.c_str(), fmt.c_str() + fmt.size()); + assert(t.tm_mon == 5); + assert(t.tm_mday == 9); + assert(t.tm_year == 120); + } + + { + istringstream iss("20201213"); + ios_base::iostate err = Bit; + tm t{}; + const string fmt("%Y%m%d"); + use_facet>(iss.getloc()) + .get(Iter(iss.rdbuf()), Iter(), iss, err, &t, fmt.c_str(), fmt.c_str() + fmt.size()); + assert(t.tm_mon == 11); + assert(t.tm_mday == 13); + assert(t.tm_year == 120); + } + + { + istringstream iss("2020112"); + ios_base::iostate err = Bit; + tm t{}; + const string fmt("%Y%m%d"); + use_facet>(iss.getloc()) + .get(Iter(iss.rdbuf()), Iter(), iss, err, &t, fmt.c_str(), fmt.c_str() + fmt.size()); + assert(t.tm_mon == 10); + assert(t.tm_mday == 2); + assert(t.tm_year == 120); + } + + { + istringstream iss("2020061125"); + ios_base::iostate err = Bit; + tm t{}; + const string fmt("%Y%m%d"); + use_facet>(iss.getloc()) + .get(Iter(iss.rdbuf()), Iter(), iss, err, &t, fmt.c_str(), fmt.c_str() + fmt.size()); + assert(t.tm_mon == 5); + assert(t.tm_mday == 11); + assert(t.tm_year == 120); + } + + { + istringstream iss("2020120625119"); + ios_base::iostate err = Bit; + tm t{}; + const string fmt("%Y12%m25%d"); + use_facet>(iss.getloc()) + .get(Iter(iss.rdbuf()), Iter(), iss, err, &t, fmt.c_str(), fmt.c_str() + fmt.size()); + assert(t.tm_mon == 5); + assert(t.tm_mday == 11); + assert(t.tm_year == 120); + } + + { + istringstream iss("2020092Text"); + ios_base::iostate err = Bit; + tm t{}; + const string fmt("%Y%m%d"); + use_facet>(iss.getloc()) + .get(Iter(iss.rdbuf()), Iter(), iss, err, &t, fmt.c_str(), fmt.c_str() + fmt.size()); + assert(t.tm_mon == 8); + assert(t.tm_mday == 2); + assert(t.tm_year == 120); + } + { istringstream iss("sep 31 2014"); ios_base::iostate err = Bit; @@ -290,6 +362,79 @@ void test_990695() { assert(t.tm_year == 105); } + { + istringstream iss("20200609"); + tm t = {}; + const string fmt("%Y%m%d"); + iss >> get_time(&t, fmt.c_str()); + assert(!iss.fail()); + assert(t.tm_mon == 5); + assert(t.tm_mday == 9); + assert(t.tm_year == 120); + } + + { + istringstream iss("2020112"); + tm t = {}; + const string fmt("%Y%m%d"); + iss >> get_time(&t, fmt.c_str()); + assert(!iss.fail()); + assert(t.tm_mon == 10); + assert(t.tm_mday == 2); + assert(t.tm_year == 120); + } + + { + istringstream iss("2020061125"); + tm t = {}; + const string fmt("%Y%m%d"); + iss >> get_time(&t, fmt.c_str()); + assert(!iss.fail()); + assert(t.tm_mon == 5); + assert(t.tm_mday == 11); + assert(t.tm_year == 120); + } + + { + istringstream iss("2020124"); + tm t = {}; + const string fmt("%Y%d%m"); + iss >> get_time(&t, fmt.c_str()); + assert(!iss.fail()); + assert(t.tm_mon == 3); + assert(t.tm_mday == 12); + assert(t.tm_year == 120); + } + + { + istringstream iss("2020104Text"); + tm t = {}; + const string fmt("%Y%d%m"); + iss >> get_time(&t, fmt.c_str()); + assert(!iss.fail()); + assert(t.tm_mon == 3); + assert(t.tm_mday == 10); + assert(t.tm_year == 120); + } + + { + istringstream iss("202000000000000923"); + tm t = {}; + const string fmt("%Y%m%d"); + iss >> get_time(&t, fmt.c_str()); + assert(iss.fail()); + } + + { + istringstream iss("202000000000000923"); + ios_base::iostate err = Bit; + tm t{}; + const string fmt("%Y%m%d"); + use_facet>(iss.getloc()) + .get(Iter(iss.rdbuf()), Iter(), iss, err, &t, fmt.c_str(), fmt.c_str() + fmt.size()); + assert(err == ios_base::failbit); + } + { // This case should fail istringstream iss("2011-D-18");