There is a Sonar Violation:
Sonar Violation: Security - Array is stored directly
public void setMyArray(String[] myArray) {
this.
It's called defensive copying. A nice article on the topic is "Whose object is it, anyway?" by Brian Goetz, which discusses difference between value and reference semantics for getters and setters.
Basically, the risk with reference semantics (without a copy) is that you erronously think you own the array, and when you modify it, you also modify other structures that have aliases to the array. You can find many information about defensive copying and problems related to object aliasing online.
It's more ease than all of this. You only need to rename the method parameter to anything else to avoid Sonar violations.
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);
}
}
There are certain cases where it is a design decision and not missed out. In these cases, you need to modify the Sonar rules to exclude it so that it doesn't show such issues in report.
To go the defensive-implementation-way can save you a lot of time. In Guava you get another nice solution to reach the goal: ImmutableCollections
http://code.google.com/p/guava-libraries/wiki/ImmutableCollectionsExplained
It's complaining that the array you're storing is the same array that is held by the caller. That is, if the caller subsequently modifies this array, the array stored in the object (and hence the object itself) will change.
The solution is to make a copy within the object when it gets passed. This is called defensive copying. A subsequent modification of the collection won't affect the array stored within the object.
It's also good practice to normally do this when returning a collection (e.g. in a corresponding getMyArray()
call). Otherwise the receiver could perform a modification and affect the stored instance.
Note that this obviously applies to all mutable collections (and in fact all mutable objects) - not just arrays. Note also that this has a performance impact which needs to be assessed alongside other concerns.
I had the same issue:
Security - Array is stored directly The user-supplied array 'palomitas' is stored directly.
my original method:
public void setCheck(boolean[] palomitas) {
this.check=palomitas;
}
fixed turned to:
public void setCheck(boolean[] palomitas) {
if(palomitas == null) {
this.check = new boolean[0];
} else {
this.check = Arrays.copyOf(palomitas, palomitas.length);
}
}
Other Example:
Security - Array is stored directly The user-supplied array
private String[] arrString;
public ListaJorgeAdapter(String[] stringArg) {
arrString = stringArg;
}
Fixed:
public ListaJorgeAdapter(String[] stringArg) {
if(stringArg == null) {
this.arrString = new String[0];
} else {
this.arrString = Arrays.copyOf(stringArg, stringArg.length);
}
}