Una mala calidad del código lleva a un comportamiento no predecible. Desde la perspectiva de un usuario, muchas veces también supone una usabilidad limitada. Pero para un atacante es una oportunidad para atacar al sistema de formas insospechadas.
void clean_up()
{
char tmp[256];
...
free(tmp);
return;
}
System.Object.Equals()
:
public boolean Equals(string obj) {
...
}
System.Object.Equals()
utiliza un argumento de tipo object
, nunca se llama al método.Object.equals()
:
public boolean equals(Object obj1, Object obj2) {
...
}
Object.equals()
toma solo un argumento, el método en el Example 1
no se llama nunca.ISerializable
, pero que no declaran el atributo [Serializable]
no se serializarán.[Serializable]
. Si la clase se puede serializar mediante los métodos de serialización predeterminados definidos por .NET Framework, esto es necesario y suficiente para que el objeto se serialice correctamente. Si la clase requiere métodos de serialización personalizados, debe implementar también la interfaz ISerializable
. Sin embargo, la clase debe declarar aún el atributo [Serializable]
.CustomStorage
implementa la interfaz ISerializable
. Sin embargo, debido a que no puede declarar el atributo [Serializable]
, no se serializará.
public class CustomStorage: ISerializable {
...
}
java.io.Serializable
pueden ocasionar problemas y filtrar información de la clase externa.
...
class User implements Serializable {
private int accessLevel;
class Registrator implements Serializable {
...
}
}
Example 1
, cuando se serializa la clase interna Registrator
, también se serializa el campo accessLevel
de la clase externa User
.synchronized
, garantizando un comportamiento correcto cuando varios subprocesos acceden a la misma instancia. Todos los métodos de reemplazo también deben ser declarados como synchronized
porque, de no ser así, podría producirse un comportamiento inesperado.Foo
reemplaza a la clase Bar
, pero no declara el método synchronizedMethod
para que sea synchronized
:
public class Bar {
public synchronized void synchronizedMethod() {
for (int i=0; i<10; i++) System.out.print(i);
System.out.println();
}
}
public class Foo extends Bar {
public void synchronizedMethod() {
for (int i=0; i<10; i++) System.out.print(i);
System.out.println();
}
}
Foo
en el tipo Bar
. Si se da la misma instancia a dos subprocesos distintos y synchronizedMethod
se ejecuta repetidamente, el comportamiento se impredecible.obj.Equals(null)
debe ser siempre false.Equals()
para comparar un objeto con null
. El contrato del método Equals()
requiere que esta comparación devuelva siempre un valor "false".obj.equals(null)
siempre será "false".equals()
para comparar un objeto con null
. Esta comparación siempre devolverá false, porque el objeto no es null
. (Si el objeto es null
, el programa lanzará una NullPointerException
).pthread_create()
desde la función main()
del proceso primario finalizarán antes de tiempo si el proceso primario termina la ejecución antes que cualquier subproceso que haya generado sin llamar pthread_exit()
. Llamar pthread_exit()
garantiza que el proceso primario se mantendrá activo hasta que todos sus subprocesos hayan finalizado la ejecución. Otra opción es que el proceso primario puede llamar pthread_join
en todos los subprocesos secundarios y garantizar su compleción antes de que el proceso concluya.pthread_create()
para crear un subproceso y, a continuación, sale normalmente. Si el subproceso secundario no ha completado su ejecución hasta que la función main()
vuelve, entonces finalizará antes de tiempo.
void *Simple(void *threadid)
{
...
pthread_exit(NULL);
}
int main(int argc, char *argv[]) {
int rc;
pthread_t pt;
rc = pthread_create(&pt, NULL, Simple, (void *)t);
if (rc){
exit(-1);
}
}