怎樣才能避免C語言的)目標緩衝區溢出

當用於sprintf() 的格式串已知且相對簡單時, 你有時可以預測出緩衝區的大 小。如果格式串中包含一個或兩個%s, 你可以數出固定字符的個數再加上對插入 的字符串的strlen() 調用的返回值。對於整形, %d 輸出的字符數不會超過((sizeof(int) * CHAR_BIT + 2) / 3 + 1) /* +1 for ’-’ */ CHAR BIT 在 中定義, 但是這個計算可能有些過於保守了。它計 算的是數字以八進制存儲需要的字節數; 十進制的存儲可以保證使用同樣或更少 的字節數。

當格式串更復雜或者在運行前未知的時候, 預測緩衝區大小會變得跟重新實現sprintf 一樣困難, 而且會很容易出錯。有一種最後防線的技術, 就是fprintf() 向一塊內存區或臨時文件輸出同樣的內容, 然後檢查fprintf 的返回值或臨時文件的大小, 但請參見問題19.14, 並提防寫文件錯誤。

如果不能確保緩衝區足夠大, 你就不能調用sprintf(), 以防緩衝區溢出後改寫其它的內存區。如果格式串已知, 你可以用%.Ns 控制%s 擴展的長度, 或者使用%.*s, 參見問題12.9。要避免溢出問題, 你可以使用限制長度的sprintf() 版本, 即snprintf()。這樣使用:
snprintf(buf, bufsize, "You typed \"%s\"", answer);
snprintf() 在幾個stdio 庫中已經提供好幾年了, 包括GNU 和4.4bsd。在C99中已經被標準化了。作爲一個額外的好處, C99 的snprintf() 提供了預測任意sprintf() 調用所需的緩衝區大小的方法。C99 的snprintf() 返回它可能放到緩衝區的字符數, 而它又可以用0 作爲緩衝區大小進行調用。因此nch = snprintf(NULL, 0, fmtstring, /* 其它參數*/ );
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章