9

PMD には、Sun Security ルールセットに ArrayIsStoredDirectly というルールがあります。

配列を受け取るコンストラクターとメソッドは、オブジェクトを複製してコピーを保存する必要があります。これにより、ユーザーによる将来の変更が内部機能に影響することを防ぎます。

これが彼らの例です:

public class Foo {
 private String [] x;
  public void foo (String [] param) {
      // Don't do this, make a copy of the array at least
      this.x=param;
  }
}

このルールの背後にある理由を完全に理解しているとは思いません。渡された配列の値を別の場所で変更できるからですか? これに関して、コレクションを渡すことと配列を渡すことの間に違いはありますか?

4

3 に答える 3

12

問題は、呼び出し元が渡した配列引数のコピーを保持し、その内容を変更できることです。オブジェクトがセキュリティ クリティカルであり、呼び出しが信頼されていないコードから行われた場合、セキュリティ ホールがあります。

このコンテキストでは、コレクションを渡してコピーせずに保存することも、潜在的なセキュリティ リスクになります。(これを伝えるPMDルールがあるかどうかはわかりません。)

どちらの場合も、リスクに対処する方法 (それが実際の場合) は、属性を引数配列またはコレクションのコピーに設定することです。一方、呼び出し元が常に信頼できるコードであることがわかっている場合、コピーは時間の無駄であり、より良い解決策は、その特定のメソッドについて沈黙するように PMD に指示することです。

于 2010-07-23T06:08:42.757 に答える
3

コレクションまたは配列を渡すことに違いはありません。どちらの場合も、送信者と受信者はデータ構造の内容を変更できます。次に例を示します。

// ... in some method
Foo myfoo = new Foo();
String[] array = {"One", "Two", "Three"};
myfoo.foo(array);     // now the Foo instance gets {"One", "Two", "Three"}

array[1] = "Changed"; // now the internal field x in myfoo is {"One", "Changed", "Three"}

この動作が望ましくない場合は、この PMD ルールに従って、配列を Foo に複製し、複製への参照を保存する必要があります。このようにして、他のクラスが内部配列への参照を保持していないことを確認します (リフレクションを少し忘れない限り、および別のメソッドでこの内部配列を返さない限り...)

于 2010-07-23T06:07:03.037 に答える
1

配列の主な問題は、配列へのアクセスを制御できないことだと思います。

ただし、オブジェクトを使用すると、メンバーをセッターの背後に隠して、何を設定するかを制御できます。add()呼び出してコピーをtoArray()返す必要があるため、コレクションにも同じことが当てはまると思います。

于 2012-01-06T13:02:20.453 に答える