2012-01-21 9 views

Respuesta

31

Como dice el mensaje de error, usted está volviendo estado interno (chkBox es - muy probablemente - parte del estado interno de un objeto a pesar de que usted no está mostrando su definición)

Esto puede causar problemas si que - por ejemplo - hace

String[] box = obj.chkBox(); 
box[0] = null; 

Puesto que un objeto de matriz, ya que todos los objetos de Java, se pasa por referencia, esto va a cambiar la matriz original almacenado dentro de su objeto, así.

Lo más probable es que desea hacer para solucionar este problema es un simple

return (String[])chkBox.clone(); 

que devuelve una copia de la matriz en lugar de la matriz real.

+1

en la solución anterior terminaremos creando un nuevo objeto String [] cada vez que accedemos a él a través de clone(). Solo necesito comparar (y no crear un nuevo objeto) ¿Alguien tiene una mejor solución? –

+1

No entiendo cómo esto es útil que no sea para derrotar a Findbugs. La matriz copiada todavía tiene las referencias a las cadenas que componen el estado de obj. – David

+1

@David Las cadenas son de solo lectura, por lo que no pueden mutar. –

9

Supongamos lo siguiente:

  1. Su clase hace algo que importa desde una perspectiva de seguridad o privacidad, y que el estado de chkbox se utiliza de alguna manera en la implementación clases de sus mecanismos de privacidad/seguridad.

  2. El método chkBox() se puede invocar mediante algún código que no sea de confianza.

Consideremos ahora este código:

// ... in an untrusted method ... 

Foo foo = ... 
String[] mwahaha = foo.chkBox(); 
mwahaha[0] = "Gotcha!"; // ... this changes the effective state of `Foo` 

Al devolver una referencia a la matriz real que representa la chkbox, usted está permitiendo que el código externo a la clase Foo a meter la mano y cambiar su estado.

Esto es malo desde una perspectiva de diseño (se llama "abstracción con fugas"). Sin embargo, si esta clase se utiliza en un contexto donde también puede haber un código que no es de confianza, este (el método chkBox()) es un agujero de seguridad potencial. Eso es lo que te dice el mensaje de infracción.

(Por supuesto, el corrector de código no tiene manera de saber si esta clase en particular es realmente de seguridad crítica. Eso es para que usted pueda entender. Lo que en realidad está diciendo es "Hey! Mira! Este es sospechoso!")


La solución depende de si el código (o, de hecho toda la biblioteca o aplicación) es crítico de seguridad ... o código de seguridad crítica sea en un futuro despliegue. Si se trata de una falsa alarma que, Sólo pudo reprimir la violación; es decir, se marca de manera que serán ignorados por el comprobador de Si esto es un problema real (o podría convertirse en un problema real), entonces o bien devolver una copia de la matriz:.

return (String[]) chkBox.clone(); 

Pero claramente, hay un costo de rendimiento en la clonación de la matriz cada vez que llame al chkBox. Alternativamente, podría modificar el chkBox método para devolver un elemento seleccionado de la matriz:

public String chkBox(int i) { 
     return chkBox[i]; 
    } 

En este caso, sospecho que el enfoque alternativo será mejor ... aunque depende de cómo se utiliza actualmente el método.

+1

Todavía me pregunto por qué el sonar informa este problema solo para las matrices, y no, por ejemplo, para las listas o cualquier otro tipo de estructura de datos mutable. ¿Hay algo más, tal vez debido a la forma en que las matrices están almacenadas en la memoria? –

+0

* "¿Hay algo más, tal vez debido a la forma en que las matrices están almacenadas en la memoria?" * - Por lo que yo sé, no. –

+1

La verdadera diferencia es que con una matriz es imposible evitar que alguien con la referencia de matriz cambie los contenidos. Con los tipos de objetos, acceda a ellos a través de la API del objeto (si la API se ha elegido correctamente), lo que dificulta distinguir entre usos seguros e inseguros. (Si el verificador de errores "lloraba lobo" con demasiada frecuencia, no se usaría). –

Cuestiones relacionadas