天天看點

一個€引起的混亂——關于字元編碼

     上周遊戲突發一個嚴重的漏洞,玩家通過在聊天世界頻道發送€符号,會導緻接下來發言的玩家看到的内容混亂,這種搗亂的行為,我立即去查了一下,發現這是引擎在處理字元編碼時的一個錯誤導緻的,這個錯誤非常隐蔽,以至于我也是開始的時候看上去一切非常正常。

  錯誤是這樣出現的,首先程式采用多字元集,即ansi編碼,在多字元編碼下,用單位元組表示英文編碼,用兩個位元組表示非英文編碼,程式中為了顯示一段文字,先要判斷這個字元時一個單位元組的英文還是多位元組漢字的第一個字元。

  程式是這樣判斷的,假設到來的字元是 char c,如果c>0就是英文字元,否則就是漢字的第一個。因為引擎認為 0x00<c<0x80  範圍是标準asc2表示的英文字元,而漢字字元的首位采用0x80以上的。乍一看起來沒問題啊,可是問題就在這個臨界的0x80上,ansi編碼的标準上說,用0x80-0xff之間的位元組表示多位元組的字元,也就是說其實0x80和0xff這兩個字元還是單位元組的英文字元,是以使用0x00<c<0x80 顯然遺漏了0x80和0xff,引擎錯誤的把0x80和0xff當成了雙位元組的第一個。而0x80正代表的英文字元€。

  其實我覺得可能很多人會這樣寫代碼,就用char c,>0判斷英文字元,其實vc為我們提供了一個良好的接口用來判斷多字元編碼下某個位元組是否為一個多位元組字元的前驅(即不是單位元組英文字元),isdbcsleadbyte(),用它就可以很好的解決問題。

  如果想看看你的代碼裡有沒有這種問題,輸入一個€看看顯示是否正常就知道了。

上一篇: 黑色與透明
下一篇: cmd.exe

繼續閱讀