If a while
or for
statement uses a loop counter, and increments or decrements it by more than one, it should use a numerical numeric comparison operator (that is, <
, <=
, >
, or >=
) to terminate the loop. This prevents the loop from executing indefinitely or until the counter wraps around and reaches the final value. (See guideline NUM00-J. Detect or prevent integer overflow.)
Noncompliant Code Example
This noncompliant code example appears to iterate five times.
...
However, the loop never terminates because the ; successive values of i
are 1, 3, 5, 7, 9 and 11, allowing the comparison with 10 to be skipped. The value reaches the maximum representable positive number (Integer.MAX_VALUE
) and on subsequent incrementing, 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 takes performs more iterations than expected.
Code Block | ||
---|---|---|
| ||
for (i = 1; i != 10; i += 5) { // ... } |
It increments i
so that it is Successive values of i
are 1, 6 and 11, skipping past 10. The value of i
then wraps from near the maximum positive value to near the lowest negative value and works its way up toward zero. It then assumes 2, 7, and 12, skipping past 10 again. After the value wraps from the high positive to the low negative side three more times, it finally reaches 0, 5, and 10, terminating the loop.
Compliant Solution
Using a numerical numeric comparison operator guarantees proper loop termination.
Code Block | ||
---|---|---|
| ||
for (i = 1; i <= 10; i += 2) { // ... } |
Noncompliant Code Example
Numerical Numeric comparison operators do not always fail to ensure loop termination when comparing with Integer.MAX_VALUE
or Integer.MIN_VALUE
.
...
This usually happens when the step size is more than one.
Compliant Solution
It is insufficient to compare with Integer.MAX_VALUE - 1
when the loop counter increment is more greater than 1. To be compliant, ensure that the comparison is carried out with (Integer.MAX_VALUE
- counter's value).
Code Block | ||
---|---|---|
| ||
for (i = 1; i <= Integer.MAX_VALUE - 2; i += 2) { // ... } |
Risk Assessment
Testing for exact values to terminate a loop may result in infinite loops and denial of service.
Guideline | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
MSC15-J | low | unlikely | low | P3 | L3 |
Automated Detection
...
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this guideline on the CERT website.
Other Languages
This guideline appears in the C Secure Coding Standard as guideline MSC21-C. Use inequality to terminate a loop whose counter changes by more than one .
This guideline appears in the C++ Secure Coding Standard as guideline MSC21-CPP. Use inequality to terminate a loop whose counter changes by more than one.
Bibliography
Wiki Markup |
---|
\[[JLS 2005|AA. Bibliography#JLS 05]\] 15.20.1 Numerical Comparison Operators <, <=, >, and >= |
...