C安全編碼--數組

來源:互聯網
上載者:User

標籤:des   style   blog   http   color   使用   

建議和規則

建議:

  • 理解數組的工作方式

  • 擷取數組的長度時不要對指標應用sizeof操作符

  • 顯示地指定數組的邊界,即使它已經由初始化值列表隱式地指定

規則:

  • 保證數組索引位於合法的範圍內

  • 在所有源檔案中使用一致的數組記法

  • 保證變長數組的長度參數位於合法範圍之內

  • 保證複製的目標具有足夠的儲存空間

  • 保證運算式中的數群組類型是相容的

  • 不允許迴圈迭代到數組尾部之後

  • 不要對兩個並不指向同一個數組的指標進行相減或比較

  • 不要把一個指向非數組對象的指標加上或減去一個整數

  • 如果結果值並不引用合法的數組元素,不要把指標加上或減去一個整數

本文地址:http://www.cnblogs.com/archimedes/p/c-security-array.html,轉載請註明源地址。

擷取數組的長度時不要對指標應用sizeof操作符

代碼:

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()使用sizeof(array) / sizeof(array[0])這種用法確定這個數組的元素數量,但由於array是一個形參,因此它是指標類型,sizeof(array) = sizeof(int *) = 4  (32位OS)

當sizeof操作符應用於聲明為數組或函數類型的形參時,它產生經過調整的(指標)類型的長度

解決方案:

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]));    /*...*/}
保證數組索引位於合法的範圍內:

代碼:

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為int類型,可能為負數,導致在數組所引用的記憶體邊界之外進行寫入

解決方案:

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;}
在所有源檔案中使用一致的數組記法

當在同一檔案中時,void func(char *a);  和  void func(char a[]); 完全等價

但在函數原型之外,如果一個數組在一個檔案中聲明為指標,在另一個不同的檔案中聲明為數組,它們是不等價的

代碼:

//main.c#include<stdlib.h>enum {ARRAYSIZE = 100};char *a;void insert_a(void);int main(void) {    a = (char*)malloc(ARRAYSIZE);    if(a == NULL) {        //處理分配錯誤    }    insert_a();    return 0;}//insert_a.cchar a[];void insert_a(void) {    a[0] = ‘a‘;}

解決方案:

//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) {        //處理分配錯誤    }    insert_a();    return 0;}
保證變長數組的長度參數位於合法範圍之內

代碼:

void func(size_t s) {    int vla[s];    /*...*/}/*...*/func(size);/*...*/

解決方案:

enum {MAX_ARRAY = 1024};void func(size_t s) {    if(s < MAX_ARRAY && s != 0) {        int vla[s];        /*...*/    } else {        //錯誤處理    }}/*...*/func(size);/*...*/
保證複製的目標具有足夠的儲存空間

代碼:

enum {WORKSPACE_SIZE = 256};void func(const int src[], size_t len) {    int dest[WORKSPACE_SIZE];    if(len > WORKSPACE_SIZE) {        //錯誤處理    }    memcpy(dest, src, sizeof(int) * len);    /*...*/}
保證運算式中的數群組類型是相容的

代碼:

enum {a = 10, b = 15, c = 20};int arr1[c][b];int (*arr2)[a];arr2 = arr1;  //不匹配 a != b

解決方案:

enum {a = 10, b = 10, c = 20};int arr1[c][b];int (*arr2)[a];arr2 = arr1;  //匹配 a == b
不要把一個指向非數組對象的指標加上或減去一個整數

代碼:

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;}

上面的代碼試圖用指標運算訪問結構的元素,這是危險的,因為結構中的欄位並不保證在記憶體中是連續的

解決方案(使用數組):

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;}
參考資料

《C安全編碼通訊協定》

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.