DBZ.ITERATOR.FLOAT

ループ反復子がゼロ浮動小数点数除算で使用される可能性があります

ゼロを除数として除算やモジュロ演算に使用しようとすると、ランタイムエラーが発生します。ゼロによる除算の欠陥は、効果的でないエラー処理または競合状態のためにしばしば起こります。通常、プログラム終了の異常が発生します。値が C/C++ コードにおいて除算またはモジュロ演算の除数として使用される前に、ゼロに等しくないことを確認するためにチェックする必要があります。

DBZ チェッカーは、除算やモジュロ演算の除数としてゼロが使用されているインスタンスを検索します。

DBZ.ITERATOR.FLOAT チェッカーは、ループの実行でゼロ定数値を割り当てられたループ反復子が、後で、除算やモジュロ演算の除数として、先にゼロ値がチェックされずに使用される可能性がある状況にフラグを立てます。

脆弱性とリスク

通常、整数をゼロで除算すると、プロセスの失敗または例外を引き起こします。また、演算は成功するかもしれませんが、誤った答えになる可能性もあります。浮動小数のゼロでの除算は、より分かりにくくなります。これは、コンパイラの実装に依存しています。コンパイラが IEEE 浮動小数点標準規格 (IEEE 754) に従う場合、浮動小数をゼロで除算した結果は明確なものとなります。しかし、C および C++ 標準規格は IEEE 754 規格への準拠を強制しません。従って、浮動小数点数のゼロ除算は、C および C++ では未定義の動作であり、プロセスの失敗や例外を発生させる可能性があります。

軽減と防止

ゼロによる除算の指摘は通常、効果的でない例外処理が原因で発生します。この脆弱性を回避するために、これを除算やモジュロ演算の除数として使用する前に、ゼロ値がないかを確認してください。

脆弱コード例

コピー
double count_sum_of_custom_arithmetic_series_defect() {
    for (float i = -1.0f; i <= 2.0f; i += 0.5f) {
        float result = 10.0f / i; //DBZ.ITERATOR.FLOAT
    }
   return 10.0f;
}

浮動小数点数のゼロ除算で「i」が使用される可能性があることを示す DBZ.ITERATOR.FLOAT (行 3) がKlocwork で報告されます。

修正コード例

コピー
double count_sum_of_custom_arithmetic_series_fixed() {
    for (float i = -1.0f; i <= 2.0f; i += 0.5f) {
        if(i != 0.0f)
            float result = 10.0f / i; //no DBZ.ITERATOR.FLOAT
    }
   return 10.0f;
}

チェックによってゼロ除算が防止されるため、DBZ.ITERATOR.FLOAT が報告される可能性はありません。

外部参考資料