【问题标题】:Reading char* from stream - another buffer overflow fiasco?从流中读取 char* - 另一个缓冲区溢出惨败?
【发布时间】:2018-01-18 03:51:36
【问题描述】:

今天我发现下面编译并打印 42:

#include <iostream>
#include <sstream>

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

但这是一个潜在的缓冲区溢出攻击,对吧?如果我们从用户提供的流中读取数据,我们无法轻易知道数据的大小,因此无法分配足够的存储空间。 std::gets 已被删除,也许这也应该被删除?

【问题讨论】:

  • 这显示了正确的方法,我的问题更多是关于为什么 c++ 允许如此轻松地射击自己。
  • @M.M fgets 有一个尺寸参数,这个没有。
  • @M.M 哦,我不知道,我想你可以回答一下。

标签: c++ io iostream buffer-overflow


【解决方案1】:

好吧,在这种情况下,您可以通过编写来防止缓冲区溢出:

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

所以我认为它更类似于fgets 的情况,可以用来射击自己的脚,但也可以正确使用,这是一个非常可行的选择正确使用。

我预计仍有足够多的实时代码使用 operator&gt;&gt; 的这种重载,因此弃用它并不可行,例如:

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

但对于编写新代码,我的建议是完全避免使用数组(即 C 样式数组)。而是使用std::string,或std::array,或其他更难导致缓冲区溢出的容器。

【讨论】:

  • 我看不出使用 std::array 会如何改变这里
  • @MooingDuck 我希望operator&gt;&gt;std::istreamstd::array 会出现过载...如果没有,那么应该有:)
  • 很遗憾,除了std::stringstd::wstring 之外,没有任何C++ 容器有这样的重载
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-30
  • 1970-01-01
  • 2018-12-31
  • 1970-01-01
  • 2015-12-16
  • 1970-01-01
相关资源
最近更新 更多