1

Today I've discovered that the following compiles and prints 42:

#include <iostream>
#include <sstream>

int main()
{
    std::stringstream s;
    s << 42;
    char c[8];
    s >> c;
    std::cout << c;
}

But this is a potential buffer overflow attack, right? If we are reading from the user-supplied stream, we can't easily know the size of the data and therefore can't allocate enough storage. std::gets was removed, maybe this should be too?

  • Maybe related to https://stackoverflow.com/questions/3203452/how-to-read-entire-stream-into-a-stdstring ? – lz96 Aug 10 '17 at 04:45
  • This shows the correct way to do this, my question is more about why c++ allows to shoot myself in the foot so easily. –  Aug 10 '17 at 04:48
  • @M.M `fgets` has a size parameter, this one doesn't. –  Aug 10 '17 at 04:51
  • @M.M Oh, I didn't know that, I guess you can make it an answer. –  Aug 10 '17 at 05:00

1 Answers1

0

Well, you can prevent buffer overflow in this case by writing:

s >> setw(sizeof c) >> c;

So I think it is more akin to the case of fgets, which can be used to shoot yourself in the foot, but can also be used correctly and it is a perfectly viable option when used correctly.

I expect there is still enough live code that uses this overload of operator>> that it's not really viable to deprecate it, e.g.:

void func(char *buf, size_t buf_len)
{
    std::cin >> setw(buf_len) >> buf;
}

But for writing new code my advice would be to avoid using arrays entirely (C-style arrays, that is). Instead use std::string, or std::array, or other such containers which are harder to cause buffer overflows on.

M.M
  • 138,810
  • 21
  • 208
  • 365