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
"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
Example 1: The following example uses equality operators on boxed primitives.
The code in
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