C++中的堆栈溢出校正

Stack overflow correction in C++

本文关键字:栈溢出 堆栈 C++      更新时间:2023-10-16

我在一本书中读到了下面的代码,其中说这很容易受到堆栈溢出的影响。虽然已经使用了fgets(),但我无法理解,为什么它容易受到攻击?

我的理解是,使用 fgets() 而不是 gets() 通常通过在末尾放置一个 null 来帮助我们摆脱缓冲区溢出。我错过了什么吗?应该用什么代替 fgets() 来纠正堆栈溢出?

void getinp(char *inp, int siz)
{
puts("Input value: ");
fgets(inp, siz, stdin);
printf("buffer3 getinp read %sn", inp);
}
void display(char * val)
{
char tmp[16];
sprintf(tmp, "read val: %sn", val);
puts(tmp);
}
int main(int argc, char *argv[])
{
char buf[16];
getinp(buf, sizeof(buf));
display(buf);
printf("buffer3 donen");
}

Indisplaytmp声明为 16chars 长,但您正在编写(带有sprintf)不仅有val(保证为 16 个字符或更少),而且还"read val: "和最后的n)。

这意味着,如果用户插入超过 16-11=5 个字符,则display中会出现缓冲区溢出。

一种解决方案是将buf声明为足够大display以存储val和附加文本,尽管在现实世界中,您只需使用printf(没有中间缓冲区)写入stdout

此外,通常当您有sprintf并且存在缓冲区溢出的潜在风险时,您可以使用snprintf代替(实际上,我总是使用它);snprintf,而不是溢出缓冲区,如果输出太长,则会截断输出,并返回输出缓冲区足够大时将写入的字符数。

在显示中,无法确保 val + 12 字节适合 16 个字符的缓冲区。