If Unless coded properly, a while
or for
statement uses a loop counter, and increments or decrements it by more than one, it should use a numerical comparison operator to terminate the loop. loop may execute forever or until the counter wraps around and reaches its final value. (See NUM00-J. Detect or prevent integer overflow.) This problem may result from incrementing or decrementing a loop counter by more than one and then testing for equality to a specified value to terminate the loop. In this case, it is possible that the loop counter will leapfrog the specified value and execute either forever or until the counter wraps around and reaches its final value. This problem may also be caused by naïve testing against limits—for example, looping while a counter is less than or equal to Integer.MAX_VALUE
or greater than or equal to Integer.MIN_VALUE
.
Noncompliant Code Example
This noncompliant code example may appear to have 5 iterations, but in fact, the loop never terminates because the value of i will increment from 1 to 3 to 5 to 7 to 9 to 11, skipping right over 10. Using 32-bit integers on a two's-complement machine, the value will reach the maximum representable positive number and then wrap to the second lowest negative number (an odd number). It will work its way up to -1, then 1, and proceed as at the beginning.appears to iterate five times:
Code Block | ||
---|---|---|
| ||
for (i = 1; i != 10; i += 2) {
// ...
}
|
However, the loop never terminates. Successive values of i
are 1, 3, 5, 7, 9, 11, and so on; the comparison with 10 never evaluates to true
. The value reaches the maximum representable positive number (Integer.MAX_VALUE
), then wraps to the second-lowest negative number (Integer.MIN_VALUE + 1
). It then works its way up to –1, then 1, and proceeds as described earlier.
Noncompliant Code Example
This noncompliant code example terminates but performs more iterations than expected:
Code Block | ||
---|---|---|
| ||
for ( | ||
Code Block | ||
| ||
for ( i = 1; i != 10; i += 2 5) { // ... } |
Noncompliant Code Example
This noncompliant code example will terminate (using 32-bit integers on a two's-complement machine), but only after many more iterations than expected. It will increment i from 1 to 6 to 11, skipping past 10. It will then wrap Successive values of i
are 1, 6, and 11, skipping 10. The value of i
then wraps from near the maximum positive value to near the lowest negative value and work works its way up toward zero0. It will reach then assumes 2, 7, and 12, skipping 10 again. After the value wraps from the high-positive to the low-negative side three more times, it will finally reach reaches 0, 5, and 10, where the loop will terminateterminating the loop.
Compliant Solution
One solution is to simply ensure the loop termination condition is reached before the counter inadvertently wraps.
Code Block | ||
---|---|---|
| ||
for ( i = 1; i !== 1011; i += 5 2) { // ... } |
Compliant Solution
Using This solution can be fragile when one or more of the conditions affecting the iteration must be changed. A better solution is to use a numerical comparison operator guarantees proper loop termination(that is, <
, <=
, >
, or >=
) to terminate the loop.
Code Block | ||
---|---|---|
| ||
for ( i = 1; i <= 10; i += 2 ) { // ... } |
Risk Assessment
Testing for exact values runs the risk of a loop terminating after much longer than expected, or never terminating at all.
Recommendation | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
MSC36-J | low | unlikely | low | P1 | L3 |
Automated Detection
None.
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Other Languages
This rule appears in the C Secure Coding Standard as MSC21-C. Use inequality to terminate a loop whose counter changes by more than one .
This rule appears in the C++ Secure Coding Standard as MSC21-CPP. Use inequality to terminate a loop whose counter changes by more than one.
References
This latter solution can be more robust in the event of changes to the iteration conditions. However, this approach should never replace careful consideration regarding the intended and actual number of iterations.
Noncompliant Code Example
A loop expression that tests whether a counter is less than or equal to Integer.MAX_VALUE
or greater than or equal to Integer.MIN_VALUE
will never terminate because the expression will always evaluate to true
. For example, the following loop will never terminate because i
can never be greater than Integer.MAX_VALUE
:
Code Block | ||
---|---|---|
| ||
for (i = 1; i <= Integer.MAX_VALUE; i++) {
// ...
}
|
Compliant Solution
The loop in this compliant solution terminates when i is equal to Integer.MAX_VALUE
:
Code Block | ||
---|---|---|
| ||
for (i = 1; i != Integer.MAX_VALUE; i++) {
// ...
}
|
If the loop is meant to iterate for every value of i
greater than 0, including Integer.MAX_VALUE
, it can be implemented as follows:
Code Block | ||
---|---|---|
| ||
i = 0;
do {
i++
// ...
} while (i != Integer.MAX_VALUE);
|
Noncompliant Code Example
This noncompliant code example initializes the loop counter i
to 0 and then increments it by 2 on each iteration, basically enumerating all the even, positive values. The loop is expected to terminate when i
is greater than Integer.MAX_VALUE - 1
, an even value. In this case, the loop fails to terminate because the counter wraps around before becoming greater than Integer.MAX_VALUE - 1
.
Code Block | ||
---|---|---|
| ||
for (i = 0; i <= Integer.MAX_VALUE - 1; i += 2) {
// ...
} |
Compliant Solution
The loop in this compliant solution terminates when the counter i is greater than Integer.MAX_VALUE minus the step value as the loop-terminating condition.
Code Block | ||
---|---|---|
| ||
for (i = 0; i <= Integer.MAX_VALUE - 2; i += 2) {
// ...
}
|
Applicability
Incorrect termination of loops may result in infinite loops, poor performance, incorrect results, and other problems. In any of the conditions used to terminate a loop can be influenced by an attacker, these errors can be exploited to cause a denial of service or other attack.
Automated Detection
Bibliography
...
\[[INT34-J. Perform explicit range checking to ensure integer operations do not overflow]\]
\[[JLS 05|AA. Java References#JLS 05]\] 15.20.1 Numerical Comparison Operators <, <=, >, and >= Wiki Markup