2017-08-10 112 views
1

今天,我發現下面的編譯和打印42:從流中讀取char * - 另一個緩衝區溢出失敗?

#include <iostream> 
#include <sstream> 

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

但是,這是一個潛在的緩衝區溢出攻擊,對不對?如果我們從用戶提供的數據流中讀取數據,我們無法輕易知道數據的大小,因此無法分配足夠的存儲空間。 std::gets被刪除,也許這應該也是?

+0

也許與https://stackoverflow.com/questions/3203452/how-to-read-entire-stream-into-a-stdstring相關? – lz96

+0

這顯示了正確的方法來做到這一點,我的問題是更多關於爲什麼c + +可以輕鬆地拍攝自己的腳。 – Lyberta

+0

@ M.M'fgets'有一個size參數,這個不是。 – Lyberta

回答

1

那麼,你可以通過書面防止緩衝區溢出在這種情況下:

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

所以我覺得它更像是的fgets的情況下,可以用來拍攝自己的腳,但也可以正確使用,正確使用它是一個完美可行的選擇。

我希望仍然存在使用這種超負荷的operator>>,它是不是真的可行棄用它,夠活代碼如:

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

但對於編寫新的代碼我的建議是避免使用陣列完全(C風格的數組,就是這樣)。而應使用std::stringstd::array或其他此類容器,這些容器很難導致緩衝區溢出。

+0

我不明白如何使用'std :: array'在這裏更改任何東西 –

+0

@MooingDuck我希望''std :: istream'和'std :: array'會導致'operator >>'重載。 ..如果不是那麼應該有:) –

+0

不幸的是,沒有C++容器有這樣的重載,除了'std :: string'和'std :: wstring' –