メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

CERT C++: INT30-C

Ensure that unsigned integer operations do not wrap

説明

ルール定義

符号なし整数の演算がラップされないようにします。1

Polyspace 実装

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

  • 符号なし整数のオーバーフロー

  • 符号なし整数定数のオーバーフロー

入力値が不明であり、入力のサブセットのみがエラーの原因として考えられる場合、既定の Bug Finder 解析ではこのルールに対する違反が報告されない場合があります。特定のシステム入力値を原因とする違反の有無をチェックするには、より厳密な Bug Finder 解析を実行してください。特定のシステム入力値から欠陥を見つけるための Bug Finder チェッカーの拡張を参照してください。

チェッカーの拡張

入力値が不明であり、入力のサブセットのみがエラーの原因となっている場合、Bug Finder が "符号なし整数のオーバーフロー""符号なし整数定数のオーバーフロー" を検出しない場合があります。特定のシステム入力値を原因とする違反の有無をチェックするには、より厳密な Bug Finder 解析を実行してください。特定のシステム入力値から欠陥を見つけるための Bug Finder チェッカーの拡張を参照してください。

すべて展開する

問題

符号なし整数のオーバーフローは、符号なし整数の変数に対する演算が、結果のデータ型では表せない値になる可能性がある場合に発生します。変数のデータ型によって、変数ストレージに割り当てられるバイト数が決まり、許容される値の範囲が制限されます。

異なる浮動小数点型への正確なストレージ割り当てはプロセッサに依存します。ターゲット プロセッサ タイプ (-target)を参照してください。

リスク

C11 規格によると、符号なし整数のオーバーフローにより、ラップ アラウンド動作が発生します。ただし、ラップ アラウンド動作は常に望ましいとは限りません。たとえば、計算の結果を配列サイズとして使用し、計算がオーバーフローする場合、その配列サイズは想定よりはるかに小さい可能性があります。

修正方法

修正方法は欠陥の根本原因によって異なります。多くの場合、結果の詳細には欠陥につながる一連のイベントが表示されます。そのシーケンス内のどのイベントについても修正を実装できます。結果の詳細にイベント履歴が表示されない場合は、ソース コード内で右クリック オプションを使用して逆のトレースを行い、これまでの関連するイベントを確認できます。Polyspace デスクトップ ユーザー インターフェイスでの Bug Finder の結果の解釈も参照してください。

この欠陥は次のようにして修正できます。

  • すべての値に適応できるように、演算の結果に対してより大きいデータ型を使用。

  • オーバーフローにつながる値をチェックし、適切なエラー処理を実行。エラー処理コードでは、たとえば、オーバーフローに対する既定のラップ アラウンド動作をオーバーライドし、飽和動作を実装できます。

以下の修正例を参照してください。

問題を修正しない場合は、改めてレビューされないように結果またはコードにコメントを追加します。詳細は、以下を参照してください。

例 - 符号なし整数の最大値に 1 を加算
#include <limits.h>

unsigned int plusplus(void) {

    unsigned uvar = UINT_MAX;
    uvar++; //Noncompliant
    return uvar;
}

この関数の 3 番目のステートメントで、変数 uvar は 1 つ増加しています。しかし、uvar の値は符号なし整数の最大値であり、整数の最大値に 1 を加えた数は unsigned int では表現できません。C プログラミング言語の規格では、最大値に 1 を加えた値を法としてプログラムが結果を自動的に縮小するため、符号なしのオーバーフローはエラーとは見なされません。この例では、uvarUINT_MAX を法として縮小されます。結果は uvar = 1 です。

修正 — 異なるストレージ型

1 つの修正方法として、演算の結果をより大きいデータ型に保存することができます。この例では、unsigned int ではなく unsigned long long を返すことでオーバーフロー エラーが修正されます。

#include <limits.h>

unsigned long long plusplus(void) {

    unsigned long long ullvar = UINT_MAX;
    ullvar++;
    return ullvar;
}
問題

"符号なし整数定数のオーバーフロー" は、コンパイル時の定数を、その値を格納できないデータ型をもつ符号なし整数変数に代入すると発生します。n ビット符号なし整数は、範囲 [0, 2n-1] 内の値を保持します。

たとえば、c は 8 ビットの符号なし char 型の変数であるため、値 256 を保持できません。

unsigned char c = 256;

基本型のサイズを判別するために、Bug Finder では [ターゲット プロセッサ タイプ] (-target) の指定が使用されます。

リスク

C 標準では、オーバーフローした符号なし整数はラップされなければなりません (たとえば、C11 規格の節 6.2.5 を参照)。ただし、そのラップ アラウンド動作は意図されていないことがあり、予期しない結果を引き起こす可能性があります。

修正方法

定数値が意図したものかどうかをチェックします。値が正しい場合は、より大きいデータ型をその変数に使用します。

例 - マクロ展開での定数のオーバーフロー
#define MAX_UNSIGNED_CHAR 255 //Noncompliant
#define MAX_UNSIGNED_SHORT 65535 //Noncompliant

void main() {
    unsigned char c1 = MAX_UNSIGNED_CHAR + 1;
    unsigned short c2 = MAX_UNSIGNED_SHORT + 1;
}

この例では、1 つ以上のマクロを使用するとオーバーフローが起こるため、マクロに欠陥が表示されます。

修正 — より大きなデータ型を使用

1 つの修正方法として、オーバーフローする変数により大きいデータ型を使用します。

#define MAX_UNSIGNED_CHAR 255
#define MAX_UNSIGNED_SHORT 65535

void main() {
    unsigned short c1 = MAX_UNSIGNED_CHAR + 1;
    unsigned int c2 = MAX_UNSIGNED_SHORT + 1;
}

チェック情報

グループ: 03.整数 (INT)

バージョン履歴

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.