一个换行符引发的“血案”

来源:互联网 发布:sql触发器类型 编辑:程序博客网 时间:2024/05/21 08:49

今天项目发生了一件很有意思的事情,案件很离奇。案件的经过是这样的:

案件经过

我们在写一个库对接硬件平台和第三方模块,库封装了一些平台有关的接口给第三方使用,但是当我们把对接第三方模块的时候对方服务器报错了,服务器方反馈上报的某个参数有误。然后我们发现参数的确有误:

//本来参数在终端应该是这么显示的//printf("abc=[%s]", efg)abc=[efg]//但是结果是这样的]bc=[efg

但是我的接口只有两行代码不可能有错吧:

int xuean_get_abc(char* efg) {    const char* value = my_database_get_safe("abc", "");    if(isNull(value))        return -1;    strcpy(efg, value);    return 0;}

这种业务代码除了可能缓冲区溢出之外,应该没什么什么太大的问题吧。为什么那个”]”莫名其妙跑到了最前面去了呢,我一开始怀疑字符串太长缓冲区溢出,但是想想,不可能啊,覆盖的结果也不应该是这样的呀。于是觉得肯定是数据库返回的东西有问题了。

//show all data123=456abc=efgx=z

没问题呀看上去很完美啊,那就奇怪了,为什么那个”]”跑去前面去了呢,它长腿了吗?但是我坚信肯定是它有问题了,那干脆把整个数据的内存16进制打出来,于是看到这样的结果:

65 66 67 D 0

果然在NULL和efg之间还有一个“D”,对应“\r“,单独的”\r”可是回到最左边的意思,怪不得那个”]”跑回去,但是这一切是怎么发生的呢,从群众中来还得回群众中去啊,干脆看看那个kv数据库的代码:

fgets(buf, MAX_BUF_LEN, file);//xxxx进行一些长度判断buf[strlen(buf) - 1] = '\0';//是要去掉换行符的重要//于是buf高高兴兴的塞入到数据库中去了

这段代码看上去很完美啊,一个字符都没有多余。但是突然发现那个精辟的地方有点奇怪,于是用二进制编辑器一看,果然这个文件是在windows下编辑的,呵呵,呵呵,呵呵,windows和linux的换行符好像有点不太一样吧,对的,你不能假定换行符就是”\n”,因为它有可能还是”\r\n”,哦哦哦,\n去掉了不久只剩下\r了嘛。于是问题就愉快的解决了。

看完这个故事我明白了,对待换行符要小心啊,不然会很惨的