ba8fe4b483
My previous fix for PR 94749 did fix the reported case, so that the next character is not discarded if it happens to equal the delimiter when __n characters have already been read. But it introduced a new bug, which is that the delimiter character would *not* be discarded if the number of characters discarded is numeric_limits<streamsize>::max() or more before reaching the delimiter. The new bug happens because I changed the code to check _M_gcount < __n. But when __n == numeric_limits<streamsize>::max() that is false, and so we don't discard the delimiter. It's not sufficient to check for the delimiter when the __large_ignore condition is true, because there's an edge case where the delimiter is reached when _M_gcount == __n and so we break out of the loop without setting __large_ignore. PR 96161 is a similar bug to the original PR 94749 report, where eofbit is set after discarding __n characters if there happen to be no more characters in the stream. This patch fixes both cases (and the regression) by checking different conditions for the __n == max case and the __n < max case. For the former case, we know that we must have either reached the delimiter or EOF, and the value of _M_gcount doesn't matter (except to avoid integer overflow). For the latter case we need to check _M_gcount first and only set eofbit or discard the delimiter if it didn't reach __n. For the latter case overflow can't happen because _M_gcount <= __n < max. libstdc++-v3/ChangeLog: PR libstdc++/94749 PR libstdc++/96161 * include/bits/istream.tcc (basic_istream::ignore(streamsize)) [n == max]: Check overflow conditions on _M_gcount. Rely on the fact that either EOF or the delimiter was reached. [n < max]: Check _M_gcount < n before checking for EOF or delimiter. (basic_istream::ignore(streamsize, char_type): Likewise. * src/c++98/compatibility.cc (istream::ignore(streamsize)) (wistream::ignore(streamsize)): Likewise. * src/c++98/istream.cc (istream::ignore(streamsize, char_type)) (wistream::ignore(streamsize, char_type)): Likewise. * testsuite/27_io/basic_istream/ignore/char/94749.cc: Check that delimiter is discarded if the number of characters ignored doesn't fit in streamsize. * testsuite/27_io/basic_istream/ignore/wchar_t/94749.cc: Likewise. * testsuite/27_io/basic_istream/ignore/char/96161.cc: New test. * testsuite/27_io/basic_istream/ignore/wchar_t/96161.cc: New test. |
||
---|---|---|
.. | ||
allocator-inst.cc | ||
bitmap_allocator.cc | ||
codecvt.cc | ||
compatibility-debug_list-2.cc | ||
compatibility-debug_list.cc | ||
compatibility-ldbl.cc | ||
compatibility.cc | ||
complex_io.cc | ||
concept-inst.cc | ||
cow-istream-string.cc | ||
ext-inst.cc | ||
globals_io.cc | ||
hash_tr1.cc | ||
hash-long-double-tr1-aux.cc | ||
hashtable_tr1.cc | ||
ios_failure.cc | ||
ios_init.cc | ||
ios_locale.cc | ||
istream-string.cc | ||
istream.cc | ||
list_associated-2.cc | ||
list_associated.cc | ||
list-aux-2.cc | ||
list-aux.cc | ||
list.cc | ||
locale_facets.cc | ||
locale_init.cc | ||
locale.cc | ||
localename.cc | ||
Makefile.am | ||
Makefile.in | ||
math_stubs_float.cc | ||
math_stubs_long_double.cc | ||
misc-inst.cc | ||
mt_allocator.cc | ||
parallel_settings.cc | ||
pool_allocator.cc | ||
stdexcept.cc | ||
streambuf.cc | ||
strstream.cc | ||
tree.cc | ||
valarray.cc |