如何防止scanf导致C中的缓冲区溢出? [英] How to prevent scanf causing a buffer overflow in C?

查看:30
本文介绍了如何防止scanf导致C中的缓冲区溢出?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用此代码:

while ( scanf("%s", buf) == 1 ){

防止可能的缓冲区溢出以便它可以传递随机长度的字符串的最佳方法是什么?

What would be the best way to prevent possible buffer overflow so that it can be passed strings of random lengths?

我知道我可以通过调用来限制输入字符串,例如:

I know I can limit the input string by calling for example:

while ( scanf("%20s", buf) == 1 ){

但我更希望能够处理用户输入的任何内容.或者这不能使用 scanf 安全地完成,我应该使用 fgets?

But I'd prefer to be able to process whatever the user inputs. Or can't this be done safely using scanf and I should use fgets?

推荐答案

在他们的书中 The Practice of Programming(非常值得一读),Kernighan 和 Pike 讨论了这个问题,他们通过使用 snprintf() 创建带有传递给 scanf() 函数系列的正确缓冲区大小.实际上:

In their book The Practice of Programming (which is well worth reading), Kernighan and Pike discuss this problem, and they solve it by using snprintf() to create the string with the correct buffer size for passing to the scanf() family of functions. In effect:

int scanner(const char *data, char *buffer, size_t buflen)
{
    char format[32];
    if (buflen == 0)
        return 0;
    snprintf(format, sizeof(format), "%%%ds", (int)(buflen-1));
    return sscanf(data, format, buffer);
}

注意,这仍然将输入限制为缓冲区"提供的大小.如果您需要更多空间,那么您必须进行内存分配,或者使用非标准库函数为您进行内存分配.

Note, this still limits the input to the size provided as 'buffer'. If you need more space, then you have to do memory allocation, or use a non-standard library function that does the memory allocation for you.

注意 POSIX 2008 (2013) 版本的 scanf() 函数族支持字符串输入的格式修饰符 m(赋值分配字符)(%s, %c, %[).它没有采用 char * 参数,而是采用 char ** 参数,并为它读取的值分配必要的空间:

Note that the POSIX 2008 (2013) version of the scanf() family of functions supports a format modifier m (an assignment-allocation character) for string inputs (%s, %c, %[). Instead of taking a char * argument, it takes a char ** argument, and it allocates the necessary space for the value it reads:

char *buffer = 0;
if (sscanf(data, "%ms", &buffer) == 1)
{
    printf("String is: <<%s>>
", buffer);
    free(buffer);
}

如果 sscanf() 函数不能满足所有的转换规范,那么在函数返回之前它为类似 %ms 的转换分配的所有内存都会被释放.

If the sscanf() function fails to satisfy all the conversion specifications, then all the memory it allocated for %ms-like conversions is freed before the function returns.

这篇关于如何防止scanf导致C中的缓冲区溢出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆