(1)type safetyhtml
Another characteristic of C that is worth mentioning is the lack of type safety. Type safety consists of two attributes: preservation and progress [Pfenning 04]. Preservation dictates that if a variable x has type t and x evaluates to a value v, then v also has type t. Progress tells us that evaluation of an expression does not get stuck in any unexpected way: either we have a value (and are done), or there is a way to proceed. In general, type safety implies that any operation on a particular type results in another value of that type. C was derived from two typeless languages and still shows many characteristics of a typeless or weakly typed language. For example, it is possible to use an explicit cast in C to convert from a pointer to one type to a pointer to a different type. If the resulting pointer is dereferenced, the results are undefined. Operations can legally act on signed and unsigned integers of differing lengths using implicit conversions and producing unrepresentable results. This lack of type safety leads to a wide range of security flaws and vulnerabilities.ios
因爲C語言存在(隱式/顯式)類型轉換,因此容易產生許多安全問題。express
(2)Unbounded String Copies安全
防止cin越界的方法:less
1. #include <iostream> 2. int main(void) { 3. char buf[12]; 4. cin.width(12); 5. cin >> buf; 6. cout << "echo: " << buf << endl; 7. }
The extraction operation can be limited to a specified number of characters (thereby avoiding the possibility of out-of-bounds write) if the field width inherited member (ios_base::width) is set to a value greater than 0. In this case, the extraction ends one character before the count of characters extracted reaches the value of field width leaving space for the ending null character. After a call to this extraction operation the value of the field width is reset to 0.ide
須要注意這個width是一次性的,每次調用 >> 後都會歸0。oop
代碼進行PCLint檢查時經常提示strcpy不安全,有機會要整改一下。this
(3)Off-by-One Errorslua
經典程序spa
1. int main(int argc, char* argv[]) { 2. char source[10]; 3. strcpy(source, "0123456789"); 4. char *dest = (char *)malloc(strlen(source)); 5. for (int i=1; i <= 11; i++) { 6. dest[i] = source[i]; 7. } 8. dest[i] = '\0';//據書上說VC++ 6.0能編譯經過 9. printf("dest = %s", dest); 10. }
The source character array (declared on line 2) is 10 bytes long, but strcpy() (line 3) copies 11 bytes, including a one-byte terminating null character.
The malloc() function (line 4) allocates memory on the heap of the length of the source string. However, the value returned by strlen() does not account for the null byte.
The index value i in the for loop (line 5) starts at 1, but the first position in a C array is indexed by 0.
The ending condition for the loop (line 5) is i <= 11. This means the loop will iterate one more time than the programmer likely intended.
The assignment on line 8 also causes an out-of-bounds write.
(4)Null-Termination Errors
依賴於編譯器如何分配空間,瞭解各類編譯器貌似一個大坑,仍是別跳了,老老實實注意不要忘了'\0’