strcat、strncat安全性讨论

strcat

  • 函数声明:
char *strcat(char *dest, const char *src);
  • 问题:
    看下面这串代码:(结果在注释)
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"_public.h"
void main(){
        char str1[11];
        int i;
        memset(str1,0,sizeof(str1));

        M_strcpy(str1,11,"abc");
        for(i=0;i<11;i++) printf("%c,",str1[i]);	//a,b,c,,,,,,,,,
        puts("");
        printf("%s\n",str1);	//abc
        printf("%d\n",strlen(str1));	//3
        
        strcat(str1,"defghijklmnopqrst");
        for(i=0;i<11;i++) printf("%c,",str1[i]);	//a,b,c,d,e,f,g,h,i,j,k,	这里溢出了,理应存10位留1位"/0"
        puts("");
        printf("%s\n",str1);	//abcdefghijkl	溢出
        printf("%d\n",strlen(str1));	//13	长度较定义长

M_strcpy是改写过的strcpy(见strcpy、strncpy安全性讨论
通过上述测试发现<string.h>库提供的strcat函数有如下问题:
1.对于拼接后字符串溢出问题未做处理;
2.对于拼接结束后是否将字符串后续清空不方便测试,但是有改写的M_strcpy支撑,所以对此不做讨论;

  • 改写:
/*安全的strcat*/
char *M_strcat(char *dest,size_t destsize, const char *src){
        if(strlen(src)>(destsize-strlen(dest)-1)) strncat(dest,src,(destsize-strlen(dest)-1));
        else strcat(dest,src);
        return dest;
}

这里对dest字符串占用长度是无法判断的,所以增加了一个dstsize参数;
需要注意:不能用sizeof函数对字符串求长度,因为传入的是指针,所以求得的长度一定是8!

strncat

  • 函数声明:
char *strncat(char *dest, const char *src, size_t n);

strncat与strcat一样,就不赘述了,附上改写的代码:

/*安全的strncat*/
char *M_strncat(char *dest,size_t destsize, const char *src,size_t n){
        if(n>(destsize-strlen(dest)-1)) strncat(dest,src,(destsize-strlen(dest)-1));
        else if(strlen(src)<n) strncat(dest,src,strlen(src));
        else strncat(dest,src,n);
        return dest;
}

版权声明:本文为qq_42622746原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。