石器时代LA官方

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 6350|回复: 0

[基础教材] strcpy与strncpy的安全版本

[复制链接]

1万

主题

491

回帖

3万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
35504
石币
24669
发表于 2013-10-3 00:33:47 | 显示全部楼层 |阅读模式

char* src = new char[10];
memset(src, 1, 10);
char* dest = new char[20];
strcpy(dest, src);
在这个例子中,我们不容易发现strcpy这个语句中有Bug。因为src没有休止符。
目前公司的做法是采用codescan工具找出strcpy,并使用strncpy代替。但实际上,这种方法也不是安全的做法。strcpy之所以不安全是由于接口本身的bug,strncpy可以再某种程度上避免strcpy所带来的缺陷。但strncpy任然不是安全的。因为有可能出现目标指针的字节数不足存放源指针所指向的内容。
如:
char* src = "hello world!";
char* dest = new char[10];
strncpy(dest, src, strlen(src)); // 这里有bug
目前对于strcpy,strncpy,从VS2005开始已经推出相应的安全版本:
接口的定义改变如下:
char* strcpy(char* dest, const char* src) --> errno_t strcpy_s(char* dest, size_t numElems, const char* src)
char* strcpy(char* dest, const char* src, size_t count) --> errno_t strcpy_s(char* dest, size_t numElems, const char* src, size_t count)
后者之所以比前者安全,是因为他们在接口增加了一个参数numElems来表明dest中的字节数,防止目标指针dest中的空间不够而导致出现Bug,同时返回值改成返回错误代码,而不是为了一些所谓的方便而返回char*。这样接口的定义就比原来安全很多。
所以我们应该把strcpy改成strncpy_s。这样会更为安全。
最后总结下:
接口的定义往往很重要。但同时也有一些相应的规范。如:
1)在接口中,如果出现需要修改的目标指针,需要增加相应的可存放字节数。
2)接口一般返回int(errno_t实际上就是int),这样可以标志返回错误类型。(注:在使用异常的环境下则不同,一般不返回。还有在一些比较特殊的情况下直接返回我们想要的类型。)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|石器时代LA官方

GMT+8, 2024-4-28 19:03 , Processed in 0.103338 second(s), 21 queries .

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表