...
While this statement is true, arithmetic operations in the Java platform require as much caution as in C and C++ . Integer as integer operations can result in overflow because . Java does not provide any indication of overflow conditions and silently wraps. While integer overflows in vulnerable C and C++ programs may result in execution of arbitrary code, in Java, wrapped values typically result in incorrect computations and unanticipated outcomes.
...
Wiki Markup |
---|
Failure to account for integer overflow has resulted in failures of real systems, for instanceexample, when implementing the {{compareTo()}} method. The meaning of the return value of the {{compareTo()}} method is defined only in terms of its sign and whether it is zero; the magnitude of the return value is irrelevant. Consequently, an apparent --- but incorrect --- optimization would be to subtract the operands and return the result. For operands of opposite sign, this can result in integer overflow; consequently violating the {{compareTo()}} contract \[[Bloch 2008, item 12|AA. Bibliography#Bloch 08]\]. |
...
Code Block | ||
---|---|---|
| ||
private static final BigInteger bigMaxIntbigMaxLong = BigInteger.valueOf(IntegerLong.MAX_VALUE); private static final BigInteger bigMinIntbigMinLong = BigInteger.valueOf(IntegerLong.MIN_VALUE); public BigInteger intRangeChecklongRangeCheck(BigInteger val) throws ArithmeticException { if (val.compareTo(bigMaxIntbigMaxLong) == 1 || val.compareTo(bigMinIntbigMinLong) == -1) { throw new ArithmeticException("Integer overflow"); } return val; } public intlong multAccum(intlong oldAcc, intlong newVal, intlong scale) throws ArithmeticException { BigInteger product = BigInteger.valueOf(newVal).multiply(BigInteger.valueOf(scale)); BigInteger res = intRangeChecklongRangeCheck(BigInteger.valueOf(oldAcc).add(product)); return res.intValuelongValue(); // safe conversion } |
Noncompliant Code Example AtomicInteger
Operations on objects of type AtomicInteger
suffer from the same overflow issues as do the other integer types. The solutions are generally similar to those shown above; however, concurrency issues add additional complications. First, avoid possible issues with time-of-check-time-of-use (see VNA02-J. Ensure that compound operations on shared variables are atomic for more information). Secondly, use of an AtomicInteger
creates happens-before relationships between the various threads that access it. Consequently, changes to the number or order of accesses may alter the execution of the overall program. In such cases you must either choose to accept the altered execution or carefully craft the implementation of your compliant technique to preserve the exact number and order of accesses to the AtomicInteger
.
Noncompliant Code Example
This noncompliant code example uses an AtomicInteger
which is part of the concurrency utilities. The concurrency utilities lack integer overflow checks.
Code Block | ||
---|---|---|
| ||
class InventoryManager { private final AtomicInteger itemsInInventory = new AtomicInteger(100); //... public final void returnItem() { itemsInInventory++; } } |
Consequently, itemsInInventory
may wrap around to Integer.MIN_VALUE
after the increment operation.
Compliant Solution (AtomicInteger
)
This compliant solution uses the get()
and compareAndSet()
methods provided by AtomicInteger
to guarantee successful manipulation of the shared value of itemsInInventory
. Note that:
...
Wiki Markup |
---|
The arguments to the {{compareAndSet()}} method are the expected value of the variable when the method is invoked and the intended new value. The variable's value will beis updated if and only if the current value and the expected value are equal \[[API 2006|AA. Bibliography#API 06]\] class [{{AtomicInteger}}|http://download.oracle.com/javase/6/docs/api/java/util/concurrent/atomic/AtomicInteger.html]. Refer to guideline [VNA02-J. Ensure that compound operations on shared variables are atomic] for more details. |
...
INT00-EX2: The added complexity and cost of programmer-written overflow checks may exceed their value for all but the most-critical code. In such cases, consider the alternative of treating integral values as though they are tainted data, using appropriate range checks as the notional "sanitizing" code. These range checks should ensure that incoming values cannot cause integer overflow. Note that sound determination of allowable ranges may require deep understanding of the details of the code protected by the range checks; correct determination of the allowable ranges may be extremely difficult.
...