配列は Object.equals() メソッドをオーバーライドしない。つまり、equals() メソッドの実装は、配列の中身ではなく参照を比較する。2つの配列の中身を比較する場合は、2引数の Arrays.equals() メソッドを使わなくてはならない。あえて参照の等価性をチェックしたい場合は、等値演算子 == や != を使わなくてはならない。配列の equals() メソッドは予期せぬ結果を招くことがあるので、使うべきではない。
違反コード
以下の違反コード例は、2つの配列の比較に、間違って Object.equals() メソッドを使っている。
public void arrayEqualsExample(){ int[] arr1 = new int[20]; // 0 で初期化 int[] arr2 = new int[20]; // 0 で初期化 arr1.equals(arr2); // false }
適合コード
以下の適合コードでは、2つの配列の比較に2引数の Arrays.equals() メソッドを使っている。
public void arrayEqualsExample(){ int[] arr1 = new int[20]; // 0 で初期化 int[] arr2 = new int[20]; // 0 で初期化 Arrays.equals(arr1, arr2); // true }
リスク評価
配列の中身の比較に equals() メソッドや関係演算子を使うと、間違った結果が得られ、脆弱性につながる可能性がある。
ルール | 深刻度 | 可能性 | 修正コスト | 優先度 | レベル |
---|---|---|---|---|---|
EXP02-J | 低 | 高 | 低 | P9 | L2 |
自動検出
静的解析で Array.equals(...) の使用を検出するのは容易である。
関連ガイドライン
MITRE CWE | CWE-595. Comparison of Object References Instead of Object Contents |
参考文献
[API 2006] | Class Arrays |
翻訳元
これは以下のページを翻訳したものです。
EXP02-J. Use the two-argument Arrays.equals() method to compare the contents of arrays (revision 48)