Skip to content

Commit

Permalink
<xloctime>: time_get::get can still assert 'istreambuf_iterator is no…
Browse files Browse the repository at this point in the history
…t dereferenceable' when the format is longer than the stream (#2851)
  • Loading branch information
Alikhalesi authored Jul 14, 2022
1 parent 18451dc commit 16207c8
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 1 deletion.
5 changes: 4 additions & 1 deletion stl/inc/xloctime
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,10 @@ protected:
const _Ctype& _Ctype_fac = _STD use_facet<_Ctype>(_Iosbase.getloc());

for (; *_Fmtfirst != '\0'; ++_Fmtfirst) {
if (*_Fmtfirst == '%') {
if (_First == _Last) {
_State |= ios_base::failbit;
break;
} else if (*_Fmtfirst == '%') {
_First = do_get(_First, _Last, _Iosbase, _State, _Pt,
*++_Fmtfirst); // convert a single field
} else if (*_Fmtfirst == ' ') {
Expand Down
32 changes: 32 additions & 0 deletions tests/std/tests/Dev11_0836436_get_time/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ void test_locale_chinese();
void test_invalid_argument();
void test_buffer_resizing();
void test_gh_2618();
void test_gh_2848();

int main() {
assert(read_hour("12 AM") == 0);
Expand Down Expand Up @@ -155,6 +156,7 @@ int main() {
test_invalid_argument();
test_buffer_resizing();
test_gh_2618();
test_gh_2848();
}

typedef istreambuf_iterator<char> Iter;
Expand Down Expand Up @@ -873,3 +875,33 @@ void test_gh_2618() {
// 1-digit strings: same as 2-digit
TestTimeGetYear("1", 2001, 1, 2001);
}

void test_gh_2848() {
// GH-2848 <xloctime>: time_get::get can still assert 'istreambuf_iterator is not dereferenceable' when
// the format is longer than the stream
{
const locale loc{locale::classic()};
const auto& tmget{use_facet<time_get<char>>(loc)};
ios_base::iostate err{ios_base::goodbit};
tm when{};
const string fmt{"%X"};
istringstream iss{"3:04"};
istreambuf_iterator<char> first{iss};
const istreambuf_iterator<char> last{};
tmget.get(first, last, iss, err, &when, fmt.data(), fmt.data() + fmt.size());
assert(err == (ios_base::eofbit | ios_base::failbit));
}

{
const locale loc{locale::classic()};
const auto& tmget{use_facet<time_get<wchar_t>>(loc)};
ios_base::iostate err{ios_base::goodbit};
tm when{};
const wstring fmt{L"%X"};
wistringstream iss{L"3:04"};
istreambuf_iterator<wchar_t> first{iss};
const istreambuf_iterator<wchar_t> last{};
tmget.get(first, last, iss, err, &when, fmt.data(), fmt.data() + fmt.size());
assert(err == (ios_base::eofbit | ios_base::failbit));
}
}

0 comments on commit 16207c8

Please sign in to comment.