CRT 中的安全性功能
許多舊的 CRT 函式都有較新且更安全的版本。 如果存在安全函式,較舊且較不安全的版本會標示為已被取代。 新版本具有 _s
(“secure”) 後綴。
在此內容中,「已被取代」表示不建議使用 函式。 這並不表示函式會從CRT中移除。
安全函式不會防止或更正安全性錯誤。 相反地,它們會在發生錯誤時攔截錯誤。 他們會對錯誤狀況進行額外的檢查。 如果發生錯誤,則會叫用錯誤處理程式(請參閱 參數驗證)。
例如,函 strcpy
式無法判斷它所複製的字串是否太大,而無法讓目的地緩衝區使用。 其安全對應 strcpy_s
專案會採用緩衝區的大小作為參數。 因此,它可以判斷是否會發生緩衝區滿溢。 如果您使用 strcpy_s
將 11 個字元複製到 10 個字元緩衝區中,這是您部分的錯誤; strcpy_s
無法更正您的錯誤。 但它可以偵測您的錯誤,並叫用無效的參數處理程式來通知您。
排除取代警告
針對較舊且較不安全的函式,有幾種方式可以排除取代警告。 最簡單的方法就是定義 _CRT_SECURE_NO_WARNINGS
或使用 warning
pragma。 兩者都會停用取代警告,但造成警告的安全性問題仍然存在。 最好讓淘汰警告保持啟用,並利用新的CRT安全性功能。
在C++中,消除淘汰警告的最簡單方式是使用 安全範本多載。 在許多情況下,多載會消除取代警告。 它們會將已取代函式的呼叫取代為安全函式版本的呼叫。 例如,以這個針對 strcpy
的已取代呼叫為例:
char szBuf[10];
strcpy(szBuf, "test"); // warning: deprecated
將 _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES
定義為 1,便可以透過將 strcpy
呼叫變更為 strcpy_s
來排除警告,並進一步防止緩衝區溢位。 如需詳細資訊,請參閱安全範本多載。
對於那些沒有安全範本多載的已取代函式,您便應該考慮手動更新您的程式碼,以使用安全的版本。
另一個與安全性無關的已取代警告來源是 POSIX 函式。 將 POSIX 函式名稱取代為其標準對等專案(例如,變更 access
為 _access
),或藉由定義 _CRT_NONSTDC_NO_WARNINGS
來停用 POSIX 相關的取代警告。 如需詳細資訊,請參閱相容性。
更多安全性功能
某些安全性功能包括:
參數驗證
保護函式及其許多不安全的對應專案,都會驗證參數。 驗證可能包括:
- 檢查
NULL
值。 - 檢查列舉值的有效性。
- 檢查整數值是否在有效範圍內。
如需詳細資訊,請參閱 參數驗證。
無效參數的處理常式也可供開發人員存取。 當函式遇到無效的參數時,CRT 可讓您透過
_set_invalid_parameter_handler
或_set_thread_local_invalid_parameter_handler
檢查這些問題,而不是判斷提示和結束應用程式。- 檢查
大小緩衝區
您必須將緩衝區大小傳遞至寫入緩衝區的任何安全函式。 安全版本會先驗證緩衝區是否夠大,再寫入該緩衝區。 驗證可協助避免可能允許惡意代碼執行的危險緩衝區溢出錯誤。 如果緩衝區的大小太小,這些函式通常會傳回
errno
錯誤碼,並叫用無效的參數處理程式。 讀取輸入緩衝區的函式 (例如gets
) 具有會要求您指定大小上限的安全版本。Null 終止
留下可能未終止字串的某些函式具有安全版本,以確保字串正確以 Null 終止。
增強的錯誤報告
安全函式會傳回錯誤碼,其錯誤資訊比預先存在的函式可用更多。 安全函式和許多既有的函式現在也已設定
errno
,而且通常會傳回errno
程式代碼類型,以提供更佳的錯誤報告。檔案系統安全性
安全的檔案 I/O API 支援預設案例中的安全檔案存取。
Windows 安全性 (機器翻譯)
安全的程序 API 會強制執行安全性原則,並允許指定 ACL。
格式化字串語法檢查
例如,當您在格式字串中使用
printf
不正確的類型欄位字元時,會偵測到無效的字串。