[英]Why C doesn't have a function which is used like strcpy() and check buffer size automatically to prevent buffer overflow bug?
我真的很想知道為什么C中沒有像strcpy()
, memcpy()
等函數會自動檢查緩沖區的大小。 表現如下:
#define strcpy2(X, Y) strncpy(X, Y, sizeof(X))
有人告訴我:“因為這是古老的語言。” 但是,C並非一成不變的語言。 IOS可以修復該標准,並添加了諸如strncpy
類的新功能。
其他人告訴我:“這會導致性能問題。” 但是,我認為“如果存在類似的功能,那么在性能很重要的情況下,您仍然可以使用舊功能。在所有情況下,您都可以使用該功能,並且可以期望提高安全性。”
還有一些人告訴我:“所以,有一個類似strncpy()
的函數,或者“ C是為考慮此問題的專業開發人員設計的”,但是strncpy()
不會自動進行檢查-開發人員必須確定緩沖區的大小,以及由專業開發人員制作的大型程序(如Chrome)仍然具有緩沖區溢出漏洞。
我想知道為什么無法執行此功能的技術原因。
*英語不是我的母語。 所以我想可能有一些錯誤...對此感到抱歉。 (編輯(cmaster):現在應該修復。希望您喜歡新的措辭。)
如果X通常是一個指針,則sizeof X不會告訴您X指向的數組的大小。 大小必須作為參數傳遞。
要真正理解C函數無法執行所需功能的原因,您需要了解數組與指針之間的區別,以及數組衰減為指針的含義。 只是讓您了解我在說什么:
int array[7]; //define an array
int* pointer = array; //define a pointer that points to the same memory, array decays into a pointer to the first int
//Now the following two expressions are precisely equivalent, since array decays to a pointer again:
pointer[3];
array[3];
//However, the sizeof of the two is not the same:
assert(sizeof(array) == 7*sizeof(int)); //this is what you used in your define
assert(*pointer == sizeof(int)); //probably not what you expected
//Now the thing gets nasty: Array declarations in function arguments truly decay into pointers!
void foo(int bar[9]) {
assert(sizeof(bar) == sizeof(int)); //I bet, you didn't expect this!
}
//This is, because the definition of foo() is truly equivalent to this definition:
void foo(int* bar) {
assert(sizeof(bar) == sizeof(int));
}
//Transfering this to your #define, this will definitely not do what you want:
void baz(char aBuffer[BUFFER_SIZE], const char* source) {
strcpy2(aBuffer, source); //This will copy only the first four or eight bytes (depending on the size of a pointer on your system), no matter how big you make BUFFER_SIZE!
}
希望我現在已經誘使您使用Google進行數組指針衰減...
事實是,C語言在很大程度上依賴於以下事實:不需要數組大小即可正確訪問數組元素,只有周圍的循環才需要知道大小。 這樣,數組在許多地方都會衰減為純指針,一旦它們衰減,就無法恢復數組的大小。 這給語言帶來了極大的靈活性和簡單性(非常容易處理子數組!),但同時也使行為像#define
的函數成為不可能。
技術原因是:在C語言中,緩沖區大小無法自動檢查,因為它不受語言管理。 諸如strcpy
函數對指針進行操作,盡管指針指向緩沖區,但strcpy
實現無法知道緩沖區的長度。 您使用sizeof
建議不起作用,因為sizeof
返回對象的大小,而不是指針指向的緩沖區的大小。 (在您的示例中,它將始終返回相同的數字,最有可能是4或8)。
C語言使程序員負責管理緩沖區大小,因此可以使用諸如strncpy
函數並顯式傳遞緩沖區大小。 但是永遠不可能在C中實現strcpy
安全版本,因為它將要求語言處理指針的方式發生根本變化。
所有這些都同樣適用於Objective C的C ++之類的C后代。
#include <stdlib.h>
char* x;
if (!asprintf(&x, "%s", y)) {
perror("asprintf");
exit(1);
}
// from here, x will contain the content of y
在假設y為Null終止的情況下,這可以安全地工作。
(在平板電腦上寫了一個,所以請原諒任何愚蠢的錯誤。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.