webentwicklung-frage-antwort-db.com.de

Sonarverletzung: Sicherheit - Array wird direkt gespeichert

Es gibt eine Sonarverletzung:

Sonarverletzung: Sicherheit - Array wird direkt gespeichert

public void setMyArray(String[] myArray) { 
  this.myArray = myArray; 
} 

Lösung:

public void setMyArray(String[] newMyArray) { 
  if(newMyArray == null) { 
    this.myArray = new String[0]; 
  } else { 
   this.myArray = Arrays.copyOf(newMyArray, newMyArray.length); 
  } 
}

Aber ich frage mich warum?

60
Junchen Liu

Es beschwert sich, dass das Array, das Sie speichern, das gleiche Array ist, das der Anrufer hält. Das heißt, wenn der Aufrufer dieses Array anschließend ändert, ändert sich das im Objekt gespeicherte Array (und damit auch das Objekt selbst).

Die Lösung besteht darin, eine Kopie innerhalb des Objekts zu erstellen, wenn es übergeben wird. Dies wird als defensives Kopieren bezeichnet. Eine nachträgliche Änderung der Sammlung hat keinen Einfluss auf das im Objekt gespeicherte Array. 

Es ist auch empfehlenswert, dies normalerweise zu tun, wenn eine Sammlung zurückgegeben wird (z. B. in einem entsprechenden Aufruf von getMyArray()). Andernfalls könnte der Empfänger eine Änderung vornehmen und die gespeicherte Instanz beeinflussen.

Beachten Sie, dass dies natürlich für alle veränderbaren Sammlungen (und tatsächlich für alle veränderlichen Objekte) gilt - nicht nur für Arrays. Beachten Sie auch, dass dies Auswirkungen auf die Leistung hat, die neben anderen Bedenken bewertet werden muss.

51
Brian Agnew

Es heißt defensives Kopieren. Ein schöner Artikel zum Thema ist "Wessen Objekt ist es überhaupt?" von Brian Goetz, der den Unterschied zwischen Wert- und Referenzsemantik für Getter und Setter behandelt. 

Grundsätzlich besteht das Risiko bei Referenzsemantiken (ohne Kopie) darin, dass Sie irrtümlicherweise der Meinung sind, dass Sie das Array besitzen, und wenn Sie es modifizieren, ändern Sie auch andere Strukturen, die ein Array mit Aliasnamen haben. Sie finden viele Informationen zum defensiven Kopieren und zu Problemen beim Online-Aliasing von Objekten.

21
ewernli

Ich hatte das gleiche Problem:

Sicherheit - Array wird direkt gespeichert Das vom Benutzer bereitgestellte Array 'palomitas' wird direkt gespeichert.

meine ursprüngliche Methode:

public void setCheck(boolean[] palomitas) {
        this.check=palomitas;
    }

fix gedreht zu:

public void setCheck(boolean[] palomitas) { 
      if(palomitas == null) { 
        this.check = new boolean[0]; 
      } else { 
       this.check = Arrays.copyOf(palomitas, palomitas.length); 
      } 
}

Anderes Beispiel:

Sicherheit - Array wird direkt gespeichert Das vom Benutzer bereitgestellte Array

private String[] arrString;

    public ListaJorgeAdapter(String[] stringArg) {      
        arrString = stringArg;
    }

Fest:

public ListaJorgeAdapter(String[] stringArg) {  
    if(stringArg == null) { 
      this.arrString = new String[0]; 
    } else { 
      this.arrString = Arrays.copyOf(stringArg, stringArg.length); 
    } 
}
12
Elenasys

Um diese zu eliminieren, müssen Sie das Array klonen, bevor Sie es speichern oder zurückgeben, wie in der folgenden Klassenimplementierung gezeigt. Auf diese Weise kann niemand die ursprünglichen Daten Ihrer Klasse ändern oder abrufen, sondern nur eine Kopie.

public byte[] getarrString() {
    return arrString.clone();
}
/**
 * @param arrStringthe arrString to set
 */
public void arrString(byte[] arrString) {
    this.arrString= arrString.clone();
}

Ich habe es so benutzt und jetzt bekomme ich keine SONAR-Verletzung ...

3
Wolverine789

Es ist leichter als alles. Sie müssen den Methodenparameter nur in einen anderen Namen umbenennen, um Sonarverletzungen zu vermeiden.

http://osdir.com/ml/Java-sonar-general/2012-01/msg00223.html

public void setInventoryClassId(String[] newInventoryClassId)
    {                
            if(newInventoryClassId == null)
            {
                    this.inventoryClassId = new String[0];
            }
            else
            {
                    this.inventoryClassId = Arrays.copyOf(newInventoryClassId, newInventoryClassId.length);
            }

    } 
2
Sky Games Inc

Es gibt bestimmte Fälle, in denen es eine Designentscheidung ist und nicht übersehen wird. In diesen Fällen müssen Sie die Sonar-Regeln so ändern, dass sie nicht im Bericht angezeigt werden.

0
Tushar Patel

Die Implementierung der defensiven Implementierung kann Ihnen viel Zeit sparen. In Guava erhalten Sie eine weitere Lösung von Nizza, um das Ziel zu erreichen: ImmutableCollections

http://code.google.com/p/guava-libraries/wiki/ImmutableCollectionsExplained

0
Jordi Laforge