Title
operator>>(basic_istream&, CharT*) makes it hard to avoid buffer overflows
Status
resolved
Section
[istream.extractors]
Submitter
Richard Smith

Created on 2015-05-08.00:00:00 last changed 65 months ago

Messages

Date: 2018-11-12.04:30:58

Proposed resolution:

This wording is relative to N4606.

  1. Modify [istream.extractors] as indicated:

    template<class charT, class traits, size_t N>
      basic_istream<charT, traits>& operator>>(basic_istream<charT, traits>& in,
                                               charT* scharT (&s)[N]);
    template<class traits, size_t N>
      basic_istream<char, traits>& operator>>(basic_istream<char, traits>& in,
                                              unsigned char* sunsigned char (&s)[N]);
    template<class traits, size_t N>
      basic_istream<char, traits>& operator>>(basic_istream<char, traits>& in,
                                              signed char* ssigned char (&s)[N]);
    

    -7- Effects: Behaves like a formatted input member (as described in [istream.formatted.reqmts]) of in. After a sentry object is constructed, operator>> extracts characters and stores them into successive locations of an array whose first element is designated by s. If width() is greater than zero, n is width()min(size_t(width()), N). Otherwise n is the number of elements of the largest array of char_type that can store a terminating charT()N. n is the maximum number of characters stored.

Date: 2018-11-11.00:00:00

[ 2018-11-11 Resolved by P0487R1, adopted in San Diego. ]

Date: 2018-08-23.00:00:00

[ 2018-08-23 Batavia Issues processing ]

Will be resolved by the adoption of P0487.

Date: 2016-08-03.12:32:27

[ 2016-08, Chicago ]

Tues PM: General agreement on deprecating the unsafe call, but no consensus for the P/R.

General feeling that implementation experience would be useful.

Date: 2016-08-02.18:53:14

[ 2016-08, Chicago: Zhihao Yuan comments and provides wording ]

Rationale:

  1. I would like to keep some reasonable code working;

  2. Reasonable code includes two cases:

    1. width() > 0, any pointer argument

    2. width() >= 0, array argument

  3. For a), banning bad code will become a silent behavior change at runtime; for b), it breaks at compile time.

I propose to replace these signatures with references to arrays. An implementation may want to ship the old instantiatations in the binary without exposing the old signatures.

Date: 2015-11-04.16:49:21

[ 2015-10, Kona Saturday afternoon ]

STL: This overload is evil and should probably die.

VV: I agree with that, even though I don't care.

STL: Say that we either remove it outright following the gets() rationale, or at least deprecate it.

Move to Open; needs a paper.

Date: 2017-02-02.00:41:18

[ 2015-06, Telecon ]

VV: Request a paper to deprecate / remove anything

Date: 2015-05-21.17:37:03

We removed gets() (due to an NB comment and C11 — bastion of backwards compatibility — doing the same). Should we remove this too?

Unlike gets(), there are legitimate uses:

char buffer[32];
char text[32] = // ...
ostream_for_buffer(text) >> buffer; // ok, can't overrun buffer

… but the risk from constructs like "std::cin >> buffer" seems to outweigh the benefit.

The issue had been discussed on the library reflector starting around c++std-lib-35541.

History
Date User Action Args
2018-11-12 04:30:58adminsetmessages: + msg10172
2018-11-12 04:30:58adminsetstatus: open -> resolved
2018-08-24 13:31:33adminsetmessages: + msg10113
2016-08-03 12:32:27adminsetmessages: + msg8359
2016-08-02 18:53:14adminsetmessages: + msg8341
2016-08-02 18:53:14adminsetmessages: + msg8340
2015-11-04 16:49:21adminsetmessages: + msg7608
2015-11-04 16:49:21adminsetstatus: new -> open
2015-09-27 20:30:23adminsetmessages: + msg7550
2015-05-08 00:00:00admincreate