This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of WP status.

### 3464. `istream::gcount()` can overflow

Section: 29.7.4.4 [istream.unformatted] Status: WP Submitter: Jonathan Wakely Opened: 2020-07-10 Last modified: 2020-11-09

Priority: 0

View all other issues in [istream.unformatted].

View all issues with WP 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.

Libstdc++ saturates the counter in `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:

> 1. Modify 29.7.4.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, returns `numeric_limits<streamsize>::max()`.

> Option B:

> 1. Modify 29.7.4.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:

>    > > 1. (25.1) — `n != numeric_limits<streamsize>::max()` (17.3.5 [numeric.limits]) and `n` characters have been extracted so far

>    > > 2. (25.2) — end-of-file occurs on the input sequence (in which case the function calls `setstate(eofbit)`, which may throw `ios_base::failure` (29.5.4.4 [iostate.flags]));

>    > > 3. (25.3) — `traits::eq_int_type(traits::to_int_type(c), delim)` for the next available input character `c` (in which case `c` is extracted).

>    > > -?- If the number of characters extracted is greater than `numeric_limits<streamsize>::max()` then for the purposes of `gcount()` the number is treated as `numeric_limits<streamsize>::max()`.

>    > > -26- Remarks: The last condition will never occur if `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.

1. Modify 29.7.4.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, returns `numeric_limits<streamsize>::max()`.