那些不安全的庫函式
C 和 C++ 不能夠自動地做邊界檢查,邊界檢查的代價是效率,一般來講,C 在大多數情況下注重效率,然而,獲得效率的代價是,C 程式員必須十分警覺以避免緩沖區溢位問題,

C語言標準庫中的許多字串處理和IO流讀取函式是導致緩沖區溢位的罪魁禍首,我們有必要了解這些函式,在編程中多加小心,
一、字串處理函式
strcpy()
strcpy() 函式將源字串復制到緩沖區,沒有指定要復制字符的具體數目!如果源字串碰巧來自用戶輸入,且沒有專門限制其大小,則有可能會造成緩沖區溢位!
我們也可以使用strncpy來完成同樣的目的:
strncpy (dst, src, dst_size-1);
如果 src 比 dst 大,則該函式不會拋出一個錯誤;當達到最大尺寸時,它只是停止復制字符,注意上面呼叫 strncpy() 中的 -1,如果 src 比 dst 長,則那給我們留有空間,將一個空字符放在 dst 陣列的末尾,
但是! strncpy()也不完全安全,也有可能把事情搞糟,即使“安全”的呼叫有時會留下未終止的字串,或者會發生微妙的相差一位錯誤,
確保 strcpy() 不會溢位的另一種方式是,在需要它時就分配空間,確保通過在源字串上呼叫 strlen() 來分配足夠的空間,
dst = (char*)malloc(strlen(src));strcpy(dst, src);
strcat()
strcat() 函式非常類似于 strcpy(),除了它可以將一個字串合并到緩沖區末尾,它也有一個類似的、更安全的替代方法 strncat(),如果可能,使用 strncat() 而不要使用 strcat(),
sprintf()、vsprintf

函式 sprintf() 和 vsprintf() 是用來格式化文本和將其存入緩沖區的通用函式,它們可以用直接的方式模仿 strcpy()
行為,換句話說,使用 sprintf() 和 vsprintf() 與使用 strcpy() 一樣,都很容易對程式造成緩沖區溢位,
sprintf() 的許多版本帶有使用這種函式的更安全的方法,可以指定格式字串本身每個自變數的精度,sprintf 采用” * ”來占用一個本來需要一個指定寬度或精度的常數數字的位置,而實際的寬度或精度就可以和其它被列印的變數一樣被提供出來,
例如:sprintf(usage,"USAGE: %*s\n", BUF_SIZE, argv[0]);
二、字符讀取函式
gets()
永遠不要使用 gets(),
該函式從標準輸入讀入用戶輸入的一行文本,它在遇到 EOF 字符或換行字符之前,不會停止讀入文本,也就是:gets() 根本不執行邊界檢查,因此,使用 gets() 總是有可能使任何緩沖區溢位,
作為一個替代方法,可以使用方法 fgets(),它可以做與 gets() 所做的同樣的事情,但它接受用來限制讀入字符數目的大小引數,因此,提供了一種防止緩沖區溢位的方法,
getchar()、fgetc()、getc()、read()

如果在回圈中使用這些函式,確保檢查緩沖區邊界
scanf()系列 : sscanf()、fscanf()、vfscanf()、vscanf()、vsscanf()
scanf系列的函式也設計得很差,目的地緩沖區也可能會發生溢位,
同樣地,我們用設定寬度也可以解決這個問題,
getenv()
使用系統呼叫 getenv() 的最大問題是您從來不能假定特殊環境變數是任何特定長度的,
三、使用安全版本的代碼庫
微軟對于有緩沖溢位危險的API使用其開發的安全版本的庫來替代,
SafeCRT自Visual Studio 2005起開始支持,當代碼中使用了禁用的危險的CRT函式,Visual Studio 2005編譯時會報告相應警告資訊,以提醒開發人員考慮將其替代為Safe CRT中更為安全,
有關字串拷貝的API
例如:strcpy, wcscpy等
替代的Safe CRT函式:strcpy_s
有關字串合并的API

例如:strcat, wcscat等
替代的Safe CRT函式:strcat_s
有關sprintf的API
例如:sprintf, swprintf等
替代的Safe CRT函式:
_snprintf_s
_snwprintf_s
其它被禁用的API還有scanf, strtok, gets, itoa等等, ”n”系列的字串處理函式,例如strncpy等,也在被禁用之列,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/195903.html
標籤:C
