istream::gcount()
can overflowSection: 31.7.5.4 [istream.unformatted] Status: C++23 Submitter: Jonathan Wakely Opened: 2020-07-10 Last modified: 2023-11-22
Priority: 0
View all other issues in [istream.unformatted].
View all issues with C++23 status.
Discussion:
The standard doesn't say what gcount()
should return if the last unformatted input
operation extracted more than numeric_limits<streamsize>::max()
characters.
This is possible when using istream::ignore(numeric_limits<streamsize>::max(), delim)
,
which will keep extracting characters until the delimiter is found. On a 32-bit platform files
larger than 2GB can overflow the counter, so can a streambuf reading from a network socket,
or producing random characters.
istream::ignore
, so that gcount()
returns
numeric_limits<streamsize>::max()
. Libc++ results in an integer overflow.
As far as I'm aware, only istream::ignore
can extract more than
numeric_limits<streamsize>::max()
characters at once. We could either fix it
in the specification of ignore
, or in gcount
.
Previous resolution [SUPERSEDED]:
This wording is relative to N4861.
Option A:Option B:
Modify 31.7.5.4 [istream.unformatted] as indicated:
streamsize gcount() const;-2- Effects: None. This member function does not behave as an unformatted input function (as described above).
-3- Returns: The number of characters extracted by the last unformatted input member function called for the object. If the number cannot be represented, returnsnumeric_limits<streamsize>::max()
.
Modify 31.7.5.4 [istream.unformatted] as indicated:
basic_istream<charT, traits>& ignore(streamsize n = 1, int_type delim = traits::eof());-25- Effects: Behaves as an unformatted input function (as described above). After constructing a sentry object, extracts characters and discards them. Characters are extracted until any of the following occurs:
(25.1) —
n != numeric_limits<streamsize>::max()
(17.3.5 [numeric.limits]) andn
characters have been extracted so far(25.2) — end-of-file occurs on the input sequence (in which case the function calls
setstate(eofbit)
, which may throwios_base::failure
(31.5.4.4 [iostate.flags]));(25.3) —
traits::eq_int_type(traits::to_int_type(c), delim)
for the next available input characterc
(in which casec
is extracted).-?- If the number of characters extracted is greater than
-26- Remarks: The last condition will never occur ifnumeric_limits<streamsize>::max()
then for the purposes ofgcount()
the number is treated asnumeric_limits<streamsize>::max()
.traits::eq_int_type(delim, traits::eof())
. -27- Returns:*this
.
[2020-07-17; Moved to Ready in telecon]
On the reflector Davis pointed out that there are other
members which can cause gcount()
to overflow.
There was unanimous agreement on the reflector and the telecon
that Option A is better.
[2020-11-09 Approved In November virtual meeting. Status changed: Ready → WP.]
Proposed resolution:
This wording is relative to N4861.
Modify 31.7.5.4 [istream.unformatted] as indicated:
streamsize gcount() const;-2- Effects: None. This member function does not behave as an unformatted input function (as described above).
-3- Returns: The number of characters extracted by the last unformatted input member function called for the object. If the number cannot be represented, returnsnumeric_limits<streamsize>::max()
.