2010-07-23 11 views
9

PMD ha una regola chiamata ArrayIsStoredDirectly nel set di regole Sun Security:ragionamento dietro ArrayIsStoredDirectly regola della PMD

Costruttori e metodi che ricevono gli array dovrebbero clonare oggetti e memorizzare la copia. Ciò impedisce che le future modifiche da parte dell'utente influiscano sulla funzionalità interna.

Ecco il loro esempio:

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; 
    } 
} 

Non credo di capire completamente il ragionamento dietro questa regola. È perché i valori nella matrice passata possono essere alterati da qualche altra parte? C'è una differenza tra il passaggio di una raccolta e il passaggio di un array rispetto a questo?

+0

Nessuna differenza in relazione al passaggio dell'array alla raccolta. Una leggera differenza nel trattamento sicuro degli array e delle raccolte è che con gli array è corretto chiamare .clone(), ma non ci si deve fidare del metodo .clone() di una raccolta. –

risposta

12

Il problema è che il chiamante può conservare una copia dell'argomento dell'array passato e può quindi modificarne il contenuto. Se l'oggetto è critico per la sicurezza e la chiamata è fatta da codice non affidabile, hai un buco di sicurezza.

In questo contesto, passare una raccolta e salvarla senza copiarla sarebbe anche un potenziale rischio per la sicurezza. (Non so se c'è una regola PMD per dirti questo.)

In entrambi i casi, il modo per affrontare il rischio (se è reale) è impostare l'attributo su una copia dell'array argomento o collezione. D'altra parte, se si sa che il chiamante sarà sempre un codice attendibile, la copia è una perdita di tempo e una soluzione migliore sarebbe dire a PMD di essere tranquillo riguardo a quel particolare metodo.

+0

Grazie. Mi sono confuso dal fatto che PMD si stesse lamentando di aver impostato direttamente un array ma non delle collezioni e ho pensato che potevo mancare qualche comprensione in merito alla gestione degli array rispetto alle collezioni. –

+1

Non penso che passare una collezione sarebbe un rischio per la sicurezza. Perché se sei preoccupato per il codice non fidato puoi usare una collezione immutabile. Ma un array raw non può essere immutabile. – n3utrino

+0

@gabe - Ci sono due casi da considerare. 1) Passi un codice errato a una raccolta e la modifica. 2) Il codice errato ti passa la raccolta e la modifica dietro la schiena. Passando una guardia della collezione ** non modificabile contro 1) ma non 2. (Non esiste una classe di raccolta immutabile in Java ... solo non modificabile ... e la differenza è significativa). –

3

Non c'è differenza tra il passaggio di una raccolta o di un array: in entrambi i casi, mittente e destinatario possono modificare il contenuto della struttura dati. Ecco un esempio:

// ... 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"} 

Se non si desidera questo comportamento, è necessario, seguendo questa regola PMD, clonare la matrice di Foo e memorizzare un riferimento al clone. In questo modo ci si assicura che nessun'altra classe abbia un riferimento al proprio array interno (a meno che non si dimentichi la riflessione per un momento e a meno che non si restituisca questo array interno in un altro metodo ...)

1

Penso che il problema principale con gli array è che non è possibile controllare accesso ad esso.

Ma con un oggetto si nascondono i membri dietro setter in cui è possibile controllare ciò che verrà impostato. Penso che lo stesso valga per le raccolte perché è necessario chiamare add() e toArray() restituisce una copia.

Problemi correlati