c->推荐的更安全的代码写法

数组越界类:
char str1[128] = {0};
char str2[256] = {0};
 
1:memcpy时应指定较短的变量,当str1和str2为某些结构体成员时,其大小不能很明显的看出来,需要特别注意。
不推荐:
memcpy(str1, str2, sizeof(str2));
推荐:
memset(str1, 0, sizeof(str1));
memcpy(str1, str2, sizeof(str1));
 
2:不建议使用strcpy
不推荐:
strcpy(str1, str2);
推荐:
strncpy(str1, str2, sizeof(str1));
 
int  arr[256] = {0};


3:在循环中也比较容易出现数组越界


3.1不推荐:
for(i=0; i<sizeof(arr);i++){
    if(arr[i] == 0){
        …
}
}
3.1推荐:
for(i=0; i<(sizeof(arr)/sizeof(int)); i++){
    if(arr[i] == 0){
        …  
}
}


3.2 不推荐
for(i=0; i<256; i++){
    if(arr [i-1] == '\n'){
        arr [i-1] = 0;
}
}
3.2 推荐
for(i=0; i<256; i++){
    if((i>0) && (arr[i-1] == '\n')){
        arr [i-1] = 0;
}
}


4: 调用strlen返回值作为数组下标时,容易忽略strlen为0的情况。
不推荐:
if(arr[strlen(arr)-1] == '.'){
    …
}
推荐:
if((len=strlen(arr)) && (arr[len-1]=='.')){
    …
}


5: 建议用snprintf替换sprintf
不推荐:
sprintf(str1, "test string %s", str2);
推荐:
snprintf(str1, sizeof(str1), "test string %s", str2);


6:当数组下标从其他地方传来的变量时,容易忽略对其下标范围做检查
不推荐:
unsigned int offset = struct->len;
str[offset] = 0;
推荐:
unsigned int offset = struct->len;
if(offset<sizeof(str)){
    str[offset] = 0;
}


7:将外部传入的参数作为system函数参数一部分被执行前,应先对传入的参数进行合法性检查,避免遭受sql注入类攻击.
不推荐
void sql_fun(char ifname[]){
    char buf[128] = {0};
    snprintf(buf, sizeof(buf), "ifconfig %s > file.txt", ifname);
    system(buf);
}
推荐:
void sql_fun(char ifname[]){
    char buf[128] = {0};
    if(strncmp(ifname, "ptm0")==0 || strncmp(ifname, "br0")==0){
        snprintf(buf, sizeof(buf), "ifconfig %s > file.txt", ifname);
        system(buf);
}
}


8:调用calloc、malloc、realloc函数申请内存时,申请的大小如果是传入的外部参数,应该对传入的参数范围进行检查。可以设定一个上界。
不推荐:
int alloc_fun(unsigned long size, test_struct_t *test_struct){
    ...
    test_struct->ptr = realloc(test_struct->ptr, size);
    ...
}
推荐:
#define SOAP_MAX_MALLOC_SIZE 1024*1024*5
int alloc_fun(unsigned long size, test_struct_t *test_struct){
    ...
    if(size > SOAP_MAX_MALLOC_SIZE){
        return -1;
    }else{
        test_struct->ptr = realloc(test_struct->ptr, size);
    }
    ...
}


9:调用fopen函数打开某个文件时,应对路径进行合法性检查,避免fopen函数的参数为NULL。
不推荐:
int read_file(char *filepath){
    ...
    FILE *fp = fopen(filepath, "w");
    ...
}
推荐:
int read_file(char *filepath){
    ...
    if((filepath == NULL) || (strlen(filepath)==0)){
        return -1;
    }
    FILE *fp = fopen(filepath, "w");
    ...
}


10:其他常见的错误还有如下:
10.1 打开一个文件后,没有关闭相应的文件描述符的动作。
10.2 申请了一块内存后,没有释放相应内存的动作
10.3 重复释放同一块内存。

posted on 2019-12-27 15:09  LiveWithACat  阅读(246)  评论(0编辑  收藏  举报