strcpy(非安全性) ,strncpy ,strlcpy(转载) .
来源:互联网 发布:网络推广外包迅捷 编辑:程序博客网 时间:2024/05/16 08:49
一下是使用strcpy_s与strcpy的安全性比较
char szBuf[2] = {0};
strcpy_s(szBuf, 2, "12131"); //新的CRT函数
strcpy(szBuf, "12131"); //老的CRT函数
上述代码,明显有缓冲区溢出的问题。 使用strcpy_s函数则会抛出一个异常。而使用strcpy函数的结果则未定,因为它错误地改变了程序中其他部分的内存的数据,可能不会抛出异常但导致程序数据错误,也可能由于非法内存访问抛出异常。
使用新的增强安全的CRT函数有什么好处呢?简单地说,新的函数加强了对参数合法性的检查以及缓冲区边界的检查,如果发现错误,会返回errno或抛出异常。老版本的这些CRT函数则没有那么严格的检查与校验,如果错误地传输了参数或者缓冲区溢出,那么错误并不能被立刻发现,对于定位程序错误也带来更大困难。
以下是MSDN关于CRT安全增强的说明。
好多人已经知道利用strncpy替代strcpy来防止缓冲区越界。
但是如果还要考虑运行效率的话,也许strlcpy是一个更好的方式。
1. strcpy
我们知道,strcpy 是依据\0作为结束判断的,如果 to 的空间不够,则会引起 buffer overflow。strcpy 常规的实现代码如下(来自 OpenBSD 3.9):
char *
strcpy(char *to, const char *from)
{
char *save = to;
for (; (*to = *from) != ''; ++from, ++to);
return(save);
}
但通常,我们的 from 都来源于用户的输入,很可能是非常大的一个字符串,因此 strcpy 不够安全。
2. strncpy
在 ANSI C 中,strcpy 的安全版本是 strncpy。
char *strncpy(char *s1, const char *s2, size_t n);
但 strncpy 其行为是很诡异的(不符合我们的通常习惯)。标准规定 n 并不是 sizeof(s1),而是要复制的 char 的个数。一个最常见的问题,就是 strncpy 并不帮你保证 结束。
char buf[8];
strncpy( buf, "abcdefgh", 8 );
看这个程序,buf 将会被 "abcdefgh" 填满,但却没有 结束符了。
另外,如果 s2 的内容比较少,而 n 又比较大的话,strncpy 将会把之间的空间都用 填充。这又出现了一个效率上的问题,如下:
char buf[80];
strncpy( buf, "abcdefgh", 79 );
上面的 strncpy 会填写 79 个 char,而不仅仅是 "abcdefgh" 本身。
strncpy 的标准用法为:(手工写上 )
strncpy(path, src, sizeof(path) - 1);
path[sizeof(path) - 1] = '';
len = strlen(path);
3. strlcpy
// Copy src to string dst of size siz. At most siz-1 characters
// will be copied. Always NUL terminates (unless siz == 0).
// Returns strlen(src); if retval >= siz, truncation occurred.
size_t
strlcpy(char *dst, const char *src, size_t siz);
而使用 strlcpy,就不需要我们去手动负责\0了,仅需要把 sizeof(dst) 告之 strlcpy 即可:
strlcpy(path, src, sizeof(path));
len = strlen(path);
if ( len >= sizeof(path) )
printf("src is truncated.");
并且 strlcpy 传回的是 strlen(str),因此我们也很方便的可以判断数据是否被截断。
[* 一点点历史 *]
strlcpy 并不属于 ANSI C,至今也还不是标准。
strlcpy 来源于 OpenBSD 2.4,之后很多 unix-like 系统的 libc 中都加入了 strlcpy 函数,在 FreeBSD、Linux 里面都找到了 strlcpy。(Linux使用的是 glibc,glibc里面有 strlcpy,则所有的 Linux 版本也都应该有 strlcpy)
但 Windows 下是没有 strlcpy 的,对应的是strcpy_s函数
- strcpy(非安全性) ,strncpy ,strlcpy(转载)
- strcpy(非安全性) ,strncpy ,strlcpy(转载) .
- strcpy,strncpy,strlcpy,memcpy
- strcpy, strncpy and strlcpy
- strcpy,strncpy,strlcpy,memcpy
- strcpy,strncpy,strlcpy,memcpy
- strcpy strncpy strlcpy
- strcpy strncpy和strlcpy
- strcpy ,strncpy ,strlcpy
- strcpy ,strncpy ,strlcpy
- strcpy strncpy strlcpy
- strcpy,strncpy,strlcpy,memcpy
- strcpy ,strncpy ,strlcpy地用法
- strcpy ,strncpy ,strlcpy地用法
- strcpy ,strncpy ,strlcpy地用法
- strcpy ,strncpy ,strlcpy地用法
- strcpy ,strncpy ,strlcpy地用法
- strcpy,strncpy,strlcpy,memcpy 用法
- 【HDOJ】 <Problem - 1000> : A+B Problem
- android-4.4源码 在ubuntu上编译和 模拟运行
- 使用UFT进行接口测试
- 内存管理
- Android下通过pocketsphinx实现离线语音识别的环境搭建和demo运行
- strcpy(非安全性) ,strncpy ,strlcpy(转载) .
- 关于Debug和Release之本质区别 .
- 内存泄漏测试小工具
- 《ASP.NET MVC 入门系列教程》索引贴(转)
- 10条找工作箴言!让你年末跳槽不再盲目!
- DLL动态链接库和LIB静态链接库之程序员经验分析
- POJ 2255(二叉树问题)
- c++中RTTI的观念和使用
- 书