Kingdom: Code Quality

Poor code quality leads to unpredictable behavior. From a user's perspective that often manifests itself as poor usability. For an attacker it provides an opportunity to stress the system in unexpected ways.

Code Correctness: Comparison of Boxed Primitive Types

Abstract
Comparing boxed primitives using equality operators instead of their equals() method can result in unexpected behavior.
Explanation
When dealing with boxed primitives, when comparing equality, the boxed primitive's equals() method should be called instead of the operators == and !=. The Java Specification states about boxing conversions:

"If the value p being boxed is an integer literal of type int between -128 and 127 inclusive, or the boolean literal true or false, or a character literal between '\u0000' and '\u007f' inclusive, then let a and b be the results of any two boxing conversions of p. It is always the case that a == b."

This means that if a boxed primitive is used (other than Boolean or Byte), only a range of values will be cached, or memoized. For a subset of values, using == or != will return the correct value, for all other values outside of this subset, this will return the result of comparing the object addresses.

Example 1: The following example uses equality operators on boxed primitives.


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


The code in Example 1 uses Integer boxed primitives to try to compare two int values. If mask0 and mask1 are both equal to 100, then mask0 == mask1 will return true. However, when mask0 and mask1 are both equal to 777, now mask0 == maske1 will return false as these values are not within the range of cached values for these boxed primitives.
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 - Common Weakness Enumeration CWE ID 398, CWE ID 754
[4] Standards Mapping - OWASP Application Security Verification Standard 4.0 11.1.7 Business Logic Security Requirements (L2 L3)
[5] Standards Mapping - SANS Top 25 2010 Risky Resource Management - CWE ID 754
desc.structural.java.code_correctness_comparison_of_boxed_primitive_types