[skill] strncpy里边有两个坑
以前的笔记,今日翻出了复看了一下,转过来。
------------------------------------
今天发现xxxdump中使用xxx_strncpy 替换 strncpy导致的bug。
原因是strncpy:
Warning: If there is no null byte among the first n bytes of src, the string placed in dest will not be null terminated.
但是xxx_strncpy会保证dest是0结尾。
典型的就是xxxdumpd中的xxx_info.c中的使用,原来使用strncpy没问题,但是替换了之后会导致str截断。
我们需要了解这个差异,避免以后的问题。
原则上,不再推荐使用原生的strncpy。
***security name***
2014-10-11
r = xxx_strncpy(dst, src, n) 与 r = strncpy(dst, src, n) 比较:
一: n>len(src)时,拷贝len(src)个字符后,strncpy 会将 len(src) 到 n 部分全部置零,xxx_strncpy只给 len(scr)+ 1 置零。
二: n<=len(src)时,strncpy 只拷贝 n 个字符, xxx_strncpy拷贝n-1个,把第n个置零。
三: 返回值不同,见下边的例子。
char dst[10] = "123456789";
0x7fffffffe3e0: 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38
0x7fffffffe3e8: 0x39 0x00
char* src = "abcde";
1. n = 8;
strncpy:
0x7fffffffe3e0: 0x61 0x62 0x63 0x64 0x65 0x00 0x00 0x00
0x7fffffffe3e8: 0x39 0x00
r = 0x7fffffffe3e0 "abcde"
xxx_strncpy:
0x7fffffffe3e0: 0x61 0x62 0x63 0x64 0x65 0x00 0x37 0x38
0x7fffffffe3e8: 0x39 0x00
r =0x7fffffffe3e5 ""
2. n = 2;
strncpy:
0x7fffffffe3e0: 0x61 0x62 0x33 0x34 0x35 0x36 0x37 0x38
0x7fffffffe3e8: 0x39 0x00
r = 0x7fffffffe3e0 "ab3456789"
xxx_strncpy:
0x7fffffffe3e0: 0x61 0x00 0x33 0x34 0x35 0x36 0x37 0x38
0x7fffffffe3e8: 0x39 0x00
r = = 0x7fffffffe3e1 ""
Date: 2014/3/11 12:57
strncpy:
0x7fffffffe3e0: 0x61 0x62 0x33 0x34 0x35 0x36 0x37 0x38
0x7fffffffe3e8: 0x39 0x00
r = 0x7fffffffe3e0 "ab3456789"
xxx_strncpy:
0x7fffffffe3e0: 0x61 0x00 0x33 0x34 0x35 0x36 0x37 0x38
0x7fffffffe3e8: 0x39 0x00
r = = 0x7fffffffe3e1 ""
------------------- Cao Tong-------- Original Message --------
Date: 2014/3/11 12:57
推荐使用xxx_strncpy 替代 strncpy说明:/*
* Apache's "replacement" for the strncpy() function. We roll our
* own to implement these specific changes:
* (1) strncpy() doesn't always null terminate and we want it to.
* (2) strncpy() null fills, which is bogus, esp. when copy 8byte
* strings into 8k blocks.
* (3) Instead of returning the pointer to the beginning of
* the destination string, we return a pointer to the
* terminating '\0' to allow us to "check" for truncation
*
* apr_cpystrn() follows the same call structure as strncpy().
*/char* xxx_strncpy(char *dst, const char *src, size_t dst_size)
{***security name***2014-3-11