2010-07-23 10 views
9

PMD tiene una regla llamada ArrayIsStoredDirectly en el conjunto de reglas de seguridad Sun:razonamiento detrás de la regla ArrayIsStoredDirectly del PMD

de constructores y métodos que reciben las matrices debe clonar objetos y almacenar la copia. Esto evita que los cambios futuros del usuario afecten la funcionalidad interna.

Aquí es su ejemplo:

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

No creo que entiendo por completo el razonamiento detrás de esta regla. ¿Es porque los valores en el conjunto pasado pueden ser alterados en otro lugar? ¿Hay alguna diferencia entre pasar una colección o pasar una matriz con respecto a esto?

+0

No hay diferencia en lo que respecta a pasar matriz vs Colección. Una pequeña diferencia en el tratamiento seguro de matrices y colecciones es que con matrices está bien llamar a .clone(), pero no debe confiar en el método .clone() de una colección. –

Respuesta

12

El problema es que la persona que llama puede guardar una copia del argumento de la matriz que pasó, y luego puede cambiar su contenido. Si el objeto es crítico para la seguridad y la llamada se realiza a partir de un código que no es de confianza, tiene un agujero de seguridad.

En este contexto, pasar una colección y guardarla sin copiarla también sería un posible riesgo de seguridad. (No sé si existe una regla de PMD que le diga esto.)

En ambos casos, la forma de abordar el riesgo (si es real) es establecer el atributo en una copia del argumento matriz o colección. Por otro lado, si usted sabe que la persona que llama siempre será un código de confianza, la copia es una pérdida de tiempo, y una mejor solución sería decirle a PMD que no haga ningún comentario sobre ese método en particular.

+0

Gracias. Me confundí porque PMD se quejaba de establecer directamente una matriz pero no de colecciones y pensaba que podría faltar algo de comprensión con respecto al manejo de las matrices frente a las colecciones. –

+1

No creo que pasar una colección sería un riesgo para la seguridad. Porque si te preocupa el código que no es de confianza, puedes usar una colección inmutable. Pero una matriz en bruto no puede ser inmutable. – n3utrino

+0

@gabe - Hay dos casos que debe tener en cuenta. 1) Pasa el código incorrecto a una colección y lo modifica. 2) El código incorrecto pasa tu colección y la modifica detrás de tu espalda. Pasar una colección ** no modificable protege contra 1) pero no 2. (No hay clase de colección inmutable en Java ... solo no modificable ... y la diferencia es significativa). –

3

No hay diferencia entre pasar una colección o una matriz: en ambos casos, el remitente y el receptor pueden modificar el contenido de la estructura de datos. He aquí un ejemplo:

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

Si no desea este comportamiento, tiene que, siguiendo esta regla PMD, clonar la matriz en Foo y almacenar una referencia al clon. De esta manera, asegúrese de que ninguna otra clase haga referencia a su matriz interna (a menos que olvidemos la reflexión por un momento y salvo que no devolvamos esta matriz interna en otro método ...)

1

Creo que el principal problema con las matrices es que no puede controlar el acceso a ella.

Pero con un Objeto ocultas miembros detrás de Setters donde puedes controlar lo que se establecerá. Creo que lo mismo se aplica a las colecciones porque necesita llamar al add() y toArray() devuelve una copia.

Cuestiones relacionadas