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

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

案件经过

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

//本来参数在终端应该是这么显示的
//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 data
123=456
abc=efg
x=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了嘛。于是问题就愉快的解决了。

看完这个故事我明白了,对待换行符要小心啊,不然会很惨的
发布了44 篇原创文章 · 获赞 7 · 访问量 24万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章