Reino: Code Quality

Códigos de baixa qualidade levam a comportamentos imprevisíveis. Da perspectiva do usuário, isso normalmente se manifesta como usabilidade ruim. Para um invasor, trata-se de uma oportunidade para atacar o sistema de formas imprevistas.

Code Correctness: Comparison of Boxed Primitive Types

Abstract
Comparar primitivas encaixotadas com o uso de operadores de igualdade em vez de seus métodos equals() pode resultar em um comportamento inesperado.
Explanation
Ao lidar com primitivas encaixotadas, ao comparar a igualdade, o método equals() da primitiva encaixotada deve ser chamado em vez dos operadores == e !=. A Especificação Java declara o seguinte sobre conversões de encaixotamento:

"Se o valor de p que está sendo encaixotado for um número inteiro literal do tipo int entre -128 e 127, inclusive, ou um booliano literal true ou false, ou um caractere literal entre '\u0000' e '\u007f', inclusive, deixe que a e b sejam os resultados de quaisquer duas conversões de encaixotamento de p. Em todos os casos, a == b."

Isso significa que, se uma primitiva encaixotada for usada (diferente de Boolean ou Byte), apenas uma faixa de valores será armazenada em cache ou memorizada. Para um subconjunto de valores, o uso de == ou != retornará o valor correto. Para todos os outros valores fora desse subconjunto, isso retornará o resultado da comparação dos endereços de objetos.

Exemplo 1: O exemplo a seguir usa operadores de igualdade em primitivas encaixotadas.


...
Integer mask0 = 100;
Integer mask1 = 100;
...
if (file0.readWriteAllPerms){
mask0 = 777;
}
if (file1.readWriteAllPerms){
mask1 = 777;
}
...
if (mask0 == mask1){
//assume file0 and file1 have same permissions
...
}
...


O código no Example 1 usa primitivas encaixotadas Integer para tentar comparar dois valores int. Se mask0 e mask1 forem ambos iguais a 100, mask0 == mask1 retornará true. No entanto, quando mask0 e mask1 forem ambos iguais a 777, mask0 == maske1 agora retornará false, pois esses valores não estão dentro do intervalo de valores armazenados em cache para essas primitivas encaixotadas.
References
[1] EXP03-J. Do not use the equality operators when comparing values of boxed primitives CERT
[2] Java Language Specification Chapter 5. Conversions and Contexts Oracle
[3] Standards Mapping - CIS Azure Kubernetes Service Benchmark 1.0
[4] Standards Mapping - CIS Amazon Elastic Kubernetes Service Benchmark 5.0
[5] Standards Mapping - CIS Amazon Web Services Foundations Benchmark 1
[6] Standards Mapping - CIS Google Kubernetes Engine Benchmark normal
[7] Standards Mapping - Common Weakness Enumeration CWE ID 398, CWE ID 754
[8] Standards Mapping - OWASP Application Security Verification Standard 4.0 11.1.7 Business Logic Security Requirements (L2 L3)
[9] Standards Mapping - SANS Top 25 2010 Risky Resource Management - CWE ID 754
desc.structural.java.code_correctness_comparison_of_boxed_primitive_types