<xloctime>: time_get::get can still assert 'istreambuf_iterator is not dereferenceable' when the format is longer than the stream (#2851)

This commit is contained in:
Alikhalesi 2022-07-15 06:12:21 +08:00 коммит произвёл GitHub
Родитель 18451dc254
Коммит 16207c85e5
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 36 добавлений и 1 удалений

Просмотреть файл

@ -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 == ' ') {

Просмотреть файл

@ -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);
@ -155,6 +156,7 @@ int main() {
test_invalid_argument();
test_buffer_resizing();
test_gh_2618();
test_gh_2848();
}
typedef istreambuf_iterator<char> Iter;
@ -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));
}
}