一個換行符引發的“血案”

今天項目發生了一件很有意思的事情,案件很離奇。案件的經過是這樣的:

案件經過

我們在寫一個庫對接硬件平臺和第三方模塊,庫封裝了一些平臺有關的接口給第三方使用,但是當我們把對接第三方模塊的時候對方服務器報錯了,服務器方反饋上報的某個參數有誤。然後我們發現參數的確有誤:

//本來參數在終端應該是這麼顯示的
//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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章