Clonare una lista

di il
5 risposte

Clonare una lista

Ciao,
ho problemi con Sonar, mi chiede di clonare una lista poiché la segnala come vulnerabilità. Di preciso mi segnala l'errore sul metodo getter del mio oggetto. Questo l'errore:
Instead use an unmodifiable Collection (via Collections.unmodifiableCollection, Collections.unmodifiableList, ...) or make a copy of the mutable object, and store or return the copy instead.
This rule checks that arrays, collections and Dates are not stored or returned directly.
Detto che si tratta di una lista di stringhe che mi arriva da FE, che prendo le varie stringhe e vado ad eseguire delle query, qual'è la soluzione corretta? Non posso testare, non posso rilasciare, ho provato (cercando in rete):
public void setMiaLista(List<String> miaLista) {
       this.miaLista = miaLista.stream().collect(Collectors.toList()); 
}

public List<String> getMiaLista() {
		return miaLista;
	}
Soluzione adeguata al problema? Controindicazioni? O devo fare diversamente? Da notare che l'errore me lo segnala sul return del getter.
Grazie

5 Risposte

  • Re: Clonare una lista

    Test90 ha scritto:


    ho problemi con Sonar, mi chiede di clonare una lista poiché la segnala come vulnerabilità.
    Premetto intanto che gli avvertimenti di SonarQube li ritengo in certa parte da prendere molto con "le pinze". Lo usano anche sui progetti su cui lavoro. Avevo scritto una enum che ha degli attributi (final) quindi avevo dovuto scrivere un costruttore (che è private per default) per inizializzare i campi. E Sonar mi dice "Remove this unused private "xxx" constructor". NOO non posso toglierlo!!

    Test90 ha scritto:


    Di preciso mi segnala l'errore sul metodo getter del mio oggetto. Questo l'errore:
    Instead use an unmodifiable Collection (via Collections.unmodifiableCollection, Collections.unmodifiableList, ...) or make a copy of the mutable object, and store or return the copy instead.
    This rule checks that arrays, collections and Dates are not stored or returned directly.
    Beh, è solo una questione di stile, insomma per "buona" programmazione non esporre dati "mutabili". Ma il problema non è tanto questo: dove vengono usati quei dati? A CHI/DOVE potrebbe fare danni? Se danni non ne fa o non ne può fare perché TU conosci i punti in cui viene usato quel dato e SAI che non c'è nulla che causa problemi .... allora è un non-problema.

    Test90 ha scritto:


    public void setMiaLista(List<String> miaLista) {
           this.miaLista = miaLista.stream().collect(Collectors.toList()); 
    }
    In generale le collezioni fornite dai Collector predefiniti sono comunque "mutabili".

    Da Java 10 c'è un nuovo Collectors.toUnmodifiableList() (avrebbero potuto aggiungerlo già da Java 8 ...)

    Test90 ha scritto:


    Soluzione adeguata al problema? Controindicazioni? O devo fare diversamente? Da notare che l'errore me lo segnala sul return del getter.
    Banalmente: clonare la lista (le stringhe sono immutabili quindi NON è un problema se vengono condivise) ... oppure restituire la lista incapsulata in un "unmodifiable" list (il wrapper tramite Collections)
  • Re: Clonare una lista

    andbin ha scritto:



    Premetto intanto che gli avvertimenti di SonarQube li ritengo in certa parte da prendere molto con "le pinze". Lo usano anche sui progetti su cui lavoro. Avevo scritto una enum che ha degli attributi (final) quindi avevo dovuto scrivere un costruttore (che è private per default) per inizializzare i campi. E Sonar mi dice "Remove this unused private "xxx" constructor". NOO non posso toglierlo!!

    Beh, è solo una questione di stile, insomma per "buona" programmazione non esporre dati "mutabili". Ma il problema non è tanto questo: dove vengono usati quei dati? A CHI/DOVE potrebbe fare danni? Se danni non ne fa o non ne può fare perché TU conosci i punti in cui viene usato quel dato e SAI che non c'è nulla che causa problemi .... allora è un non-problema.

    In generale le collezioni fornite dai Collector predefiniti sono comunque "mutabili".

    Da Java 10 c'è un nuovo Collectors.toUnmodifiableList() (avrebbero potuto aggiungerlo già da Java 8 ...)

    Banalmente: clonare la lista (le stringhe sono immutabili quindi NON è un problema se vengono condivise) ... oppure restituire la lista incapsulata in un "unmodifiable" list (il wrapper tramite Collections)
    Eh sempre per esigenze lavorative siamo costretti e stare sotto una certa soglia di segnalazioni di vulnerabilità (e considera anche i blocchi di commenti come vulnerabilità).
    Comunque in questo caso si tratta di una lista di stringhe che mi arriva da FE e che uso come parametri per la mia query, ma devo per forza fare una copia come richiesto da sonar. Quindi per risolvere quel problema sul getter e non avere problemi nell'applicativo basta questo?
    	public List<String> getLista() {
    		return lista;
    	}
    
    	public void setLista(List<String> lista) {
    		this.lista = Collections.unmodifiableList(lista);
    	}
  • Re: Clonare una lista

    Test90 ha scritto:


    Quindi per risolvere quel problema sul getter e non avere problemi nell'applicativo basta questo?
    	public List<String> getLista() {
    		return lista;
    	}
    
    	public void setLista(List<String> lista) {
    		this.lista = Collections.unmodifiableList(lista);
    	}
    . C'è una questione: in quell'oggetto la lista è immutabile e chi chiama getLista() non la può modificare. Ma chi chiama setLista ha "in mano" la lista che è mutabile e può tenersela, modificarla in seguito o passarla altrove dove può essere ulteriormente modificata.
    Insomma, anche se è una questione molto "fine", resta comunque un potenziale "pericolo" per la lista.

    Quindi magari sarebbe meglio nel setLista

    this.lista = Collections.unmodifiableList(new ArrayList<>(lista));
  • Re: Clonare una lista

    andbin ha scritto:



    . C'è una questione: in quell'oggetto la lista è immutabile e chi chiama getLista() non la può modificare. Ma chi chiama setLista ha "in mano" la lista che è mutabile e può tenersela, modificarla in seguito o passarla altrove dove può essere ulteriormente modificata.
    Insomma, anche se è una questione molto "fine", resta comunque un potenziale "pericolo" per la lista.

    Quindi magari sarebbe meglio nel setLista

    this.lista = Collections.unmodifiableList(new ArrayList<>(lista));
    Perfetto, grazie.
    E se invece dovesse capitarmi una situazione tipo: FE mi invia lista, io su questa lista vado a lavorarci, effettuare modifiche per poi rimandarla al FE, non va utilizzato questo approccio, e quindi come si clona una lista "modificabile" o non ha senso farlo anche se sonar dovesse segnalarlo?
  • Re: Clonare una lista

    Test90 ha scritto:


    E se invece dovesse capitarmi una situazione tipo: FE mi invia lista, io su questa lista vado a lavorarci, effettuare modifiche per poi rimandarla al FE, non va utilizzato questo approccio
    E perché no? L'unica cosa che l'approccio detto prima porta è che la lista nel bean non può essere alterata (benevolmente o malevolmente che sia).
    Ma tu puoi prendere la lista con getLista() e farci "altre" operazioni. Ovviamente NON puoi modificare esattamente quell'oggetto lista ma puoi trasformarla in mille altri modi.
Devi accedere o registrarti per scrivere nel forum
5 risposte