C中不安全函数

本文探讨了C语言中可能导致缓冲区溢出的不安全函数,如gets(), strcpy(), strcat()等,并建议使用安全的替代函数,如fgets(), strncpy(), strncat()等。同时提到了sprintf()系列和scanf()系列函数的潜在风险,推荐使用snprintf()和限制输入长度的方法来避免缓冲区溢出。文章强调了进行边界检查的重要性,并提醒开发者注意第三方库中可能存在的问题。" 125351082,11411855,Java基础教程:File、Properties与网络编程入门,"['java', '网络编程', '开发语言']
摘要由CSDN通过智能技术生成
 C 中大多数缓冲区溢出问题可以直接追溯到标准 C 库。最有害的罪魁祸首是不进行自变量检查的、有问题的字符串操作(strcpy、strcat、sprintf 和 gets)。一般来讲,象“避免使用 strcpy()”和“永远不使用 gets()”这样严格的规则接近于这个要求。

       今天,编写的程序仍然利用这些调用,因为从来没有人教开发人员避免使用它们。某些人从各处获得某个提示,但即使是优秀的开发人员也会被这弄糟。他们也许在危险函数的自变量上使用自己总结编写的检查,或者错误地推论出使用潜在危险的函数在某些特殊情况下是“安全”的。

       第 一位公共敌人是 gets()。永远不要使用 gets()。该函数从标准输入读入用户输入的一行文本,它在遇到 EOF 字符或换行字符之前,不会停止读入文本。也就是:gets() 根本不执行边界检查。因此,使用 gets() 总是有可能使任何缓冲区溢出。作为一个替代方法,可以使用方法 fgets()。它可以做与 gets() 所做的同样的事情,但它接受用来限制读入字符数目的大小参数,因此,提供了一种防止缓冲区溢出的方法。例如,不要使用以下代码:

void main()
  {
  char buf[1024];
  gets(buf);
  }

 

而使用以下代码:

#define BUFSIZE 1024

void main()
  {
  char buf[BUFSIZE];
  fgets(buf, BUFSIZE, stdin);
  }

 

C 编程中的主要陷阱

C 语言中一些标准函数很有可能使您陷入困境。但不是所有函数使用都不好。通常,利用这些函数之一需要任意输入传递给该函数。这个列表包括:

  • strcpy()
  • strcat()
  • sprintf()
  • scanf()
  • sscanf()
  • fscanf()
  • vfscanf()
  • vsprintf
  • vscanf()
  • vsscanf()
  • streadd()
  • strecpy()
  • strtrns()

坏消息是我们推荐,如果有任何可能,避免使用这些函数。好消息是,在大多数情况下,都有合理的替代方法。我们将仔细检查它们中的每一个,所以可以看到什么构成了它们的误用,以及如何避免它。

strcpy()函数将源字符串复制到缓冲区。没有指定要复制字符的具体数目。复制字符的数目直接取决于源字符串中的数目。如果源字符串碰巧来自用户输入,且没有专门限制其大小,则有可能会陷入大的麻烦中!

如果知道目的地缓冲区的大小,则可以添加明确的检查:

if(strlen(src) >= dst_size) {
  /* Do something appropriate, such as throw an error. */
  }
       else {
  strcpy(dst, src);

 

完成同样目的的更容易方式是使用 strncpy() 库例程:

strncpy(dst, src, dst_size-1);
  dst[dst_size-1] = '\0'; /* Always do this to be safe! */

 

如果 src 比 dst 大,则该函数不会抛出一个错误;当达到最大尺寸时,它只是停止复制字符。注意上面调用 strncpy() 中的 -1。如果 src 比 dst 长,则那给我们留有空间,将一个空字符放在 dst 数组的末尾。

当然,可能使用 strcpy() 不会带来任何潜在的安全性问题,正如在以下示例中所见:

strcpy(buf, "Hello!");

 

即使这个操作造成 buf 的溢出,但它只是对几个字符这样而已。由于我们静态地知道那些字符是什么,并且很明显,由于没有危害,所以这里无须担心 ― 当然,除非可以用其它方式覆盖字符串“Hello”所在的静态存储器。

确保 strcpy() 不会溢出的另一种方式是,在需要它时就分配空间,确保通过在源字符串上调用 strlen() 来分配足够的空间。例如:

dst = (char *)malloc(strlen(src));
  strcpy(dst, src);

 

strcat()函数非常类似于 strcpy(),除了它可以将一个字符串合并到缓冲区末尾。它也有一个类似的、更安全的替代方法 strncat()。如果可能,使用 strncat() 而不要使用 strcat()。

函数 sprintf()和 vsprintf()是用来格式化文本和将其存入缓冲区的通用函数。它们可以用直接的方式模仿 s

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值