メインコンテンツ

CERT C: Rec.DCL06-C

Use meaningful symbolic constants to represent literal values

説明

ルール定義

リテラル値を表現するために、意味のあるシンボリック定数を使用します。1

Polyspace 実装

ルール チェッカーは以下の問題をチェックします。

  • バッファー サイズがハードコードされています

  • ループ境界がハード コードされています

すべて展開する

問題

バッファー サイズがハード コードされていますは、配列などのメモリ バッファーを宣言する際に、シンボリック定数ではなく数値を使用する場合に発生します。

リスク

バッファー サイズがハード コードされていると、次の問題の原因となります。

  • バッファー サイズがハード コードされていると、誤りが生じる可能性が大きくなり、そのため保守コストも高くなる。ポリシーの変更によりバッファー サイズの変更が必要になった場合、開発者はコードにバッファー サイズが出現するたびに変更しなければならない。

  • ハード コードされている定数は、コードが開示された場合に攻撃にさらされることがある。

修正方法

バッファー サイズには、ハード コードされている定数ではなくシンボリック名を使用します。シンボリック名には、const 修飾子付き変数、enum 定数またはマクロを含めます。

enum 定数の使用を推奨します。

  • マクロは前処理後に、その定数値によって置き換えられます。したがって、ループ境界が外部にさらされる場合があります。

  • enum 定数はコンパイルの時点で既知となっています。したがって、コンパイラではループをより効率的に最適化できます。

    const 修飾子付き変数は、多くの場合、実行時に既知となります。

例 - ハードコードされたバッファー サイズ
int table[100]; //Noncompliant

void read(int);

void func(void) {
    for (int i=0; i<100; i++) //Noncompliant
        read(table[i]);
}

この例では、配列 table のサイズと for ループのループ境界がハード コードされています。

修正 — シンボリック名を使用

考えられる 1 つの修正方法として、ハード コードされているサイズをシンボリック名に置き換えます。

const int MAX_1 = 100;        
#define MAX_2 100
enum { MAX_3 = 100 };

int table_2[MAX_2];
int table_3[MAX_3];

void read(int);

void func(void) {
    int table_1[MAX_1];
    for (int i=0; i < MAX_1; i++)
        read(table_1[i]);
    for (int i=0; i < MAX_2; i++)
        read(table_2[i]);
    for (int i=0; i < MAX_3; i++)
        read(table_3[i]);
}
問題

ループ境界がハード コードされていますは、forwhile または do-while ループの境界にシンボリック定数でなく数値を使用した場合に発生します。

リスク

ループ境界がハード コードされていると、次の問題の原因となります。

  • ループ境界がハード コードされていると、時間のかかる計算やリソース割り当てがループに含まれている場合に、サービス拒否攻撃に対する脆弱性が生じる。

  • ループ境界がハード コードされていると、誤りが生じる可能性が大きくなり、保守コストが高くなる。ポリシーの変更によりループ境界の変更が必要になった場合、開発者はコードに境界が出現するたびに変更しなければならない。

    たとえば、ループ境界が 10000 であり、ネットワーク サーバー アプリケーションでサポートされているクライアント接続数の最大値を表現しているとします。サーバーでサポートしているクライアント数がこれより多い場合、コード内のループ境界のインスタンスをすべて変更しなければなりません。ループ境界が 1 回しか発生しない場合でも、コード内の 10000 の数値に対して検索しなければなりません。この数値は、ループ境界以外の場所にも現れる可能性があります。こうした場所は、ループ境界を検索する前に参照しておかなければなりません。

修正方法

ループ境界に、ハード コードされている定数ではなくシンボリック名を使用します。シンボリック名には、const 修飾子付き変数、enum 定数またはマクロが含まれます。以下の理由により、enum 定数の使用が推奨されます。

  • マクロは前処理後に、その定数値によって置き換えられます。したがって、バッファー サイズが外部にさらされる場合があります。

  • enum 定数はコンパイルの時点で既知となっています。したがって、コンパイラではストレージをより効率的に割り当てられます。

    const 修飾子付き変数は、多くの場合、実行時に既知となります。

例 - ハード コードされたループ境界
void performOperation(int);

void func(void) {
    for (int i=0; i<100; i++) //Noncompliant
        performOperation(i);
}

この例では、for ループの境界がハード コードされています。

修正 — シンボリック名を使用

考えられる 1 つの修正方法として、ハード コードされているループ境界をシンボリック名に置き換えます。

const int MAX_1 = 100;
#define MAX_2 100
enum { MAX_3 = 100 };

void performOperation_1(int);
void performOperation_2(int);
void performOperation_3(int);

void func(void) {
    for (int i=0; i<MAX_1; i++)
        performOperation_1(i);
    for (int i=0; i<MAX_2; i++)
        performOperation_2(i);
    for (int i=0; i<MAX_3; i++)
        performOperation_3(i);
}

チェック情報

グループ: Rec.02.宣言と初期化 (DCL)

バージョン履歴

R2019a で導入


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.