Suggestions and rules
Suggestion:
Understanding how arrays work
When getting the length of an array, do not apply the sizeof operator to the pointer.
Display to specify the boundary of the array, even if it has been implicitly specified by the initialization value list
Rules:
Ensure that the array index is within the valid range
Use consistent array notation in all source files
Ensure that the length parameter of the variable-length array is within the valid range
Ensure that the replication target has sufficient storage space.
Ensure that the array type in the expression is compatible
Loop iteration to the end of the array is not allowed
Do not subtract or compare two pointers that do not point to the same array.
Do not add or subtract an integer to a pointer pointing to a non-array object.
If the result value does not reference a valid array element, do not add or subtract an integer from the pointer.
URL: http://www.cnblogs.com/archimedes/p/c-security-array.html.
When getting the length of an array, do not apply the sizeof operator to the pointer.
Code:
void clear(int array[]) { for(size_t i = 0; i < sizeof(array) / sizeof(array[0]); i++) { array[i] = 0; }}void dowork(void) { int dis[12]; clear(dis); /*...*/}
Clear () uses sizeof (array)/sizeof (array [0]) to determine the number of elements in this array. However, since array is a form parameter, It is a pointer type, sizeof (array) = sizeof (int *) = 4 (32-bit OS)
When the sizeof operator is applied to a form parameter declared as an array or function type, it produces an adjusted (pointer) type length.
Solution:
void clear(int array[], size_t len) { for(size_t i = 0; i < len; i++) { array[i] = 0; }}void dowork(void) { int dis[12]; clear(dis, sizeof(dis) / sizeof(dis[0])); /*...*/}
Make sure that the array index is within the valid range:
Code:
enum {TABLESIZE = 100};int *table = NULL;int insert_in_table(int pos, int value) { if(!table) { table = (int *)malloc(sizeof(int) *TABLESIZE); } if(pos >= TABLESIZE) { return -1; } table[pos] = value; return 0;}
POS is int type and may be negative, resulting in writing outside the memory boundary referenced by the Array
Solution:
enum {TABLESIZE = 100};int *table = NULL;int insert_in_table(size_t pos, int value) { if(!table) { table = (int *)malloc(sizeof(int) *TABLESIZE); } if(pos >= TABLESIZE) { return -1; } table[pos] = value; return 0;}
Use consistent array notation in all source files
Void func (char * A); and void func (char a []); are equivalent
In addition to the function prototype, if an array is declared as a pointer in a file and declared as an array in another different file, they are not equivalent.
Code:
// Main. C # include <stdlib. h> Enum {arraysize = 100}; char * A; void insert_a (void); int main (void) {A = (char *) malloc (arraysize ); if (A = NULL) {// handle Allocation Error} insert_a (); Return 0 ;}// insert_a.cchar A []; void insert_a (void) {A [0] = 'a ';}
Solution:
// Insert_a.henum {arraysize = 100}; extern char * A; void insert_a (void); // insert_a.c # include "insert_a.h" char * A; void insert_a (void) {A [0] = 'a';} // main. C # include <stdlib. h> # include "insert_a.h" int main (void) {A = (char *) malloc (arraysize); if (a = NULL) {// handle Allocation Error} insert_a (); Return 0 ;}
Ensure that the length parameter of the variable-length array is within the valid range
Code:
void func(size_t s) { int vla[s]; /*...*/}/*...*/func(size);/*...*/
Solution:
Enum {max_array = 1024}; void func (size_t s) {If (S <max_array & S! = 0) {int VLA [s];/*... */} else {// error handling }}/*... */func (size );/*... */
Ensure that the replication target has sufficient storage space.
Code:
Enum {workspace_size = 256}; void func (const int SRC [], size_t Len) {int Dest [workspace_size]; If (LEN> workspace_size) {// error handling} memcpy (DEST, SRC, sizeof (INT) * Len );/*... */}
Ensure that the array type in the expression is compatible
Code:
Enum {A = 10, B = 15, c = 20}; int arr1 [C] [B]; int (* arr2) [a]; arr2 = arr1; // does not match! = B
Solution:
Enum {A = 10, B = 10, c = 20}; int arr1 [C] [B]; int (* arr2) [a]; arr2 = arr1; // match a = B
Do not add or subtract an integer to a pointer pointing to a non-array object.
Code:
struct numbers { short num1; short num2; /*...*/ short num9;};int sum_numbers(const struct numbers *numb) { int total = 0; const int *numb_ptr; for(numb_ptr = &numb->num1; numb_ptr <= &numb->num9; numb_ptr++) { total += *(numb_ptr); } return total;}int main(void) { struct numbers my_numbers = {1,2,3,4,5,6,7,8,9}; sum_numbers(&my_numbers); return 0;}
The above code tries to use pointers to access elements in the structure, which is dangerous because the fields in the structure are not necessarily continuous in the memory.
Solution (using arrays ):
struct numbers { short num1; short num2; /*...*/ short num9;};int sum_numbers(const short *numb, size_t dim) { int total = 0; const int *numb_ptr; for(numb_ptr = numb; numb_ptr < numb + dim; numb_ptr++) { total += *(numb_ptr); } return total;}int main(void) { short my_numbers[9] = {1,2,3,4,5,6,7,8,9}; sum_numbers(my_numbers, sizeof(my_numbers) / sizeof(my_numbers[0])); return 0;}
References
C security coding standard