下面通过该事例来说明字符串使用是要注意的几点:
[该程序测试环境: redhat linux 9.0, gcc]
1>. strcpy与sprintf在对字符串上功能没什么分别, 当然在将多个不同类型的数据保存到一个字符串中用sprintf函数还是比较方便的.
2>. 注意strcpy, sprintf都是比较危险的函数, 如果字符超过目标字符的长度时会出现益处, 益处的字符可能会将你原来有用的数据给覆盖了. 在网上提到的很多漏洞都是由于使用这两种函数引起的.
3>. 安全函数strncpy, snprintf还是有一定差别的. 从结果中可以看到snprintf函数会自动在字符后加上'\0'. strncpy函数只是复制最大的长度不超过指定的长度, 但不会自己再在后面添加'\0'. 也就是说, 在同时超出字符保存的个数时, snprintf要比strncpy少复制一个字符. 个人认为还是snprintf函数比较好.
具体测试程序如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
static void str_init(char *str, int row, int col)
{
int i;
for (i = 0; i < row * col; i)
str[i] = '?';
}
static void str_print(const char *str, int len)
{
int i;
for (i = 0; i < len; i)
printf("[%d]:%c:x ", i, str[i], str[i]);
printf("\n");
}
int main(int argc, char **argv)
{
int i;
char str[3][10], *p;
p = &str[0][0];
/* ------------------ test strcpy function ---------------- */
str_init(p, 3, 10);
for (i = 0; i < 3; i)
strcpy(str[i], "abc");
printf("\ntest strcpy str value: \n");
str_print(str[0], 30);
/* ------------------- test sprintf function ------------------- */
str_init(p, 3, 10);
for (i = 0; i < 3; i)
sprintf(str[i], "abc");
printf("\ntest sprintf str value: \n");
str_print(str[0], 30);
/* ---------------- test strcpy function overflow ---------------- */
str_init(p, 3, 10);
strcpy(str[0], "01234567890123456789");
printf("\ntest strcpy overflow str value: \n");
str_print(str[0], 30);
/* ---------------- test sprintf function overflow ---------------- */
str_init(p, 3, 10);
sprintf(str[0], "01234567890123456789");
printf("\ntest sprintf overflow str value: \n");
str_print(str[0], 30);
/* ---------------- test snprintf function ---------------- */
str_init(p, 3, 10);
snprintf(str[0], 10, "01234567890123456789");
printf("\ntest snprintf str value: \n");
str_print(str[0], 30);
/* ---------------- test strncpy function ---------------- */
str_init(p, 3, 10);
strncpy(str[0], "01234567890123456789", 10);
printf("\ntest strncpy str value: \n");
str_print(str[0], 30);
return (0);
}
|
result:
test strcpy str value:
[0]:a:61 [1]:b:62 [2]:c:63 [3]::00 [4]:?:3f [5]:?:3f [6]:?:3f [7]:?:3f [8]:?:3f [9]:?:3f [10]:a:61 [11]:b:62 [12]:c:63 [13]::00 [14]:?:3f [15]:?:3f [16]:?:3f [17]:?:3f [18]:?:3f [19]:?:3f [20]:a:61 [21]:b:62 [22]:c:63 [23]::00 [24]:?:3f [25]:?:3f [26]:?:3f [27]:?:3f [28]:?:3f [29]:?:3f
test sprintf str value:
[0]:a:61 [1]:b:62 [2]:c:63 [3]::00 [4]:?:3f [5]:?:3f [6]:?:3f [7]:?:3f [8]:?:3f [9]:?:3f [10]:a:61 [11]:b:62 [12]:c:63 [13]::00 [14]:?:3f [15]:?:3f [16]:?:3f [17]:?:3f [18]:?:3f [19]:?:3f [20]:a:61 [21]:b:62 [22]:c:63 [23]::00 [24]:?:3f [25]:?:3f [26]:?:3f [27]:?:3f [28]:?:3f [29]:?:3f
test strcpy overflow str value:
[0]:0:30 [1]:1:31 [2]:2:32 [3]:3:33 [4]:4:34 [5]:5:35 [6]:6:36 [7]:7:37 [8]:8:38 [9]:9:39 [10]:0:30 [11]:1:31 [12]:2:32 [13]:3:33 [14]:4:34 [15]:5:35 [16]:6:36 [17]:7:37 [18]:8:38 [19]:9:39 [20]::00 [21]:?:3f [22]:?:3f [23]:?:3f [24]:?:3f [25]:?:3f [26]:?:3f [27]:?:3f [28]:?:3f [29]:?:3f
test sprintf overflow str value:
[0]:0:30 [1]:1:31 [2]:2:32 [3]:3:33 [4]:4:34 [5]:5:35 [6]:6:36 [7]:7:37 [8]:8:38 [9]:9:39 [10]:0:30 [11]:1:31 [12]:2:32 [13]:3:33 [14]:4:34 [15]:5:35 [16]:6:36 [17]:7:37 [18]:8:38 [19]:9:39 [20]::00 [21]:?:3f [22]:?:3f [23]:?:3f [24]:?:3f [25]:?:3f [26]:?:3f [27]:?:3f [28]:?:3f [29]:?:3f
test snprintf str value:
[0]:0:30 [1]:1:31 [2]:2:32 [3]:3:33 [4]:4:34 [5]:5:35 [6]:6:36 [7]:7:37 [8]:8:38 [9]::00 [10]:?:3f [11]:?:3f [12]:?:3f [13]:?:3f [14]:?:3f [15]:?:3f [16]:?:3f [17]:?:3f [18]:?:3f [19]:?:3f [20]:?:3f [21]:?:3f [22]:?:3f [23]:?:3f [24]:?:3f [25]:?:3f [26]:?:3f [27]:?:3f [28]:?:3f [29]:?:3f
test strncpy str value:
[0]:0:30 [1]:1:31 [2]:2:32 [3]:3:33 [4]:4:34 [5]:5:35 [6]:6:36 [7]:7:37 [8]:8:38 [9]:9:39 [10]:?:3f [11]:?:3f [12]:?:3f [13]:?:3f [14]:?:3f [15]:?:3f [16]:?:3f [17]:?:3f [18]:?:3f [19]:?:3f [20]:?:3f [21]:?:3f [22]:?:3f [23]:?:3f [24]:?:3f [25]:?:3f [26]:?:3f [27]:?:3f [28]:?:3f [29]:?:3f
阅读(3523) | 评论(1) | 转发(0) |