ABV.NON_ARRAY

非配列オブジェクトが配列として使用される

ABV.NON_ARRAY チェッカーは、非配列オブジェクトが配列として使用された場合に欠陥を検出します。

脆弱性とリスク

非配列オブジェクトが配列として使用されると、隣接するメモリ位置が破損したり、誤って解釈されたりする可能性があります。

軽減と防止

適合のためのソリューションは、配列要素にアクセスするためにさらに使用できる配列オブジェクトのみを使用することです。

脆弱コード例

コピー
extern int anything();

void foo(int *arr, int *num_pwr)
{
    *num_pwr = anything();
    arr[*num_pwr] = 5;
}

void bar(int *arr)
{
    int num_pwr;
    foo(arr, &num_pwr);
}
void blah()
{
    int singleton = 0;
    int *p = &singleton;
    bar(p);   // ABV.NON_ARRAY defect
}

Klocwork で 18 行目についてABV.NON_ARRAY が報告されます。これは、非配列オブジェクトのアドレスを保持するポインター p が関数 'bar' に渡されるためです。'bar' (6 行目) 内では、このポインターが配列として扱われ、その結果、隣接するメモリ位置が破損したり、誤って解釈されたりする可能性があります。

修正コード例

コピー
extern int anything();

void foo(int *arr, int *num_pwr)
{
    *num_pwr = anything();
    arr[*num_pwr] = 5;
}

void bar(int *arr)
{
    int num_pwr;
    foo(arr, &num_pwr);
}
void blah()
{
    int arr[2]= {0};
    int *p = arr;
    bar(p);
}

この場合、p が保持するのは非配列オブジェクトではなく配列 arr のベースアドレスであるため、ABV.NON_ARRAY には該当しません。したがって、このシナリオでは 18 行目で ABV.NON_ARRAY の指摘は発生しません。