Are C++ strings and streams buffer overflow safe?

跟風遠走 提交于 2019-12-21 09:08:02

问题


If I use std::cin, std::cout and std::string, is there any possibility that someone will exploit the buffer overflow?

I ask this because I still see a lot of people that still use null-terminated strings instead of standard containers in C++.


回答1:


It depends. Of course, when you use C-style code/API's, there is no difference.

But using STL or C++ idioms doesn't guarantee that you're safe.

C++ gives you the choice, always. Contrast these two near-identical twins:

int n;
std::cin >> n;
std::string s(n, '*'); // create a data store of given size

std::vector<char> v(1000);
std::copy(s.begin(), s.end(), v.begin()); // NOT safe if n > 1000

safe variant:

int n;
std::cin >> n;
if (n > MAX_LIMIT) 
    throw std::runtime_error("input too large");
std::string s(std::min(0, n), '*'); // note input sanitation

std::vector<char> v;
v.reserve(1000);
std::copy(s.begin(), s.end(), std::back_inserter(v)); // safe



回答2:


One of the big reasons you still see people using C-strings in C++ (besides not knowing about strings, or being stuck in a C mindset), is that std::istream::getline works with char pointers and not strings. As do a huge number of other parts of the library. Part of the reason for that was so that "you don't pay for what you don't use". IE: people that just want to get a line of text shouldn't have to instantiate a string (thereby also having to pull in another template class) to do so. You can use std::getline to get lines as strings if you want them, but that's not obvious. So some people think they still need to use char buffers to get a line of text.

(Seems a lot of that is changed in C++11, and you can use strings in a lot of places where you had to pass a char* before. Maybe that'll help a bit with the C-in-C++ problem.)

Standard strings and streams are designed to be overflow-resistant, and are all-around safer than a char pointer (at least when they're not used like a plain old array/pointer; blindly using str's iterator without regard for str.end() is usually a bad idea, but str.push_back(), str += "text", str.at(x), and stream insertion/extraction operators are perfectly safe). If you can use them, i highly recommend you do so.




回答3:


Still lot of people use null-terminated strings because they do not realize the convenience of using std::string and they are really writing procedural c++ not c++.

Most programmers migrating/migrated from c to c++ are the ones who still use null-terminated strings.

It is perfectly safe and you should use std::string in c++ wherever you can.

std:string actually protects you against buffer overflow(unlike c strings) by dynamically growing in size as the data added to it is increased.

An code sample:

#include <iostream>
using namespace std;

int main()
{
    string str("std::String");
    for (int i=0; i<20; ++i)
    {
        cout << "capacity is " << str.capacity() << endl;
        str += " ,is Overrun safe string";
    }
    return 0;
}

Output:

capacity is 11
capacity is 35
capacity is 70
capacity is 140
capacity is 140
capacity is 140
capacity is 280
capacity is 280
capacity is 280
capacity is 280
capacity is 280
capacity is 280
capacity is 560
capacity is 560
capacity is 560
capacity is 560
capacity is 560
capacity is 560
capacity is 560
capacity is 560




回答4:


C-strings may be faster, because std containers have to support some functionality that they support. So, nobody can point the best choice for all times.



来源:https://stackoverflow.com/questions/8015355/are-c-strings-and-streams-buffer-overflow-safe

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!