C++ C+中的堆栈溢出校正+;
我在一本书中读到了下面的代码,书中说这很容易受到堆栈溢出的影响。虽然使用了fgets(),但我无法理解,为什么它容易受到攻击 我的理解是,使用fgets()而不是get()通常通过在末尾放置null来帮助我们消除缓冲区溢出。我错过什么了吗?应该使用什么代替fgets()来纠正堆栈溢出C++ C+中的堆栈溢出校正+;,c++,stack-overflow,C++,Stack Overflow,我在一本书中读到了下面的代码,书中说这很容易受到堆栈溢出的影响。虽然使用了fgets(),但我无法理解,为什么它容易受到攻击 我的理解是,使用fgets()而不是get()通常通过在末尾放置null来帮助我们消除缓冲区溢出。我错过什么了吗?应该使用什么代替fgets()来纠正堆栈溢出 void getinp(char *inp, int siz) { puts("Input value: "); fgets(inp, siz, stdin); printf("buffer3 g
void getinp(char *inp, int siz)
{
puts("Input value: ");
fgets(inp, siz, stdin);
printf("buffer3 getinp read %s\n", inp);
}
void display(char * val)
{
char tmp[16];
sprintf(tmp, "read val: %s\n", val);
puts(tmp);
}
int main(int argc, char *argv[])
{
char buf[16];
getinp(buf, sizeof(buf));
display(buf);
printf("buffer3 done\n");
}
在display中,无法确定val+12字节是否适合16个字符的缓冲区。在
display中tmp
声明为16char
s长,但您正在编写(使用sprintf
)不仅val
(保证为16个字符或更少),而且“读取val:”
和最后的\n
)
这意味着,如果用户插入的字符超过16-11=5个,则显示中的缓冲区溢出
一种解决方案是在display
中声明buf
足够大,以存储val
和附加文本,尽管在现实世界中,您只需使用printf
写入stdout
(无中间缓冲区)
另外,通常当您有一个sprintf
并且存在缓冲区溢出的潜在风险时,您会使用snprintf
(实际上,我总是使用它);snprintf
,而不是溢出缓冲区,如果输出太长,则截断输出,并返回如果输出缓冲区足够大,将写入的字符数。查看代码以及这两个答案如何解释它,我认为这实际上不是关于堆栈溢出,而是关于溢出用于读取文本的16字节缓冲区的流。该缓冲区实际上是在堆栈上分配的,但即使该缓冲区中存在溢出,我也不会将其称为堆栈溢出。不要混淆堆栈溢出(通常通过无限递归发生)缓冲区溢出是指将太多数据写入缓冲区;特别是堆栈缓冲区溢出是指存储在堆栈上的缓冲区溢出。感谢您的快速回复。因此,函数getinp不对溢出负责,是内置的sprintf函数在执行此操作。将此行添加到上述程序中在函数void display中,更正缓冲区溢出??snprintf(tmp,sizeof(tmp),“read val:%s\n”,val);这将防止缓冲区溢出,但不允许打印长度超过5个字符的输入字符串。您还应放大buf(或仅使用printf而不是sprintf+put)。