Potential Infinite Loop

ID

java.potential_infinite_loop

Severity

high

Resource

Resource Management

Language

Java

Tags

CWE:835, NIST.SP.800-53, PCI-DSS:6.5.6

Description

Potential loop with unreachable exit condition ('Infinite Loop').

Rationale

An infinite loop occurs when a condition within a loop construct is never met, causing the loop to execute indefinitely. This can lead to resource exhaustion and decreased application performance, potentially resulting in application hangs or crashes.

The risk of an infinite loop arises when loop control logic fails to converge to a termination condition. Such failure might stem from incorrect increment/decrement operations, faulty exit conditions, or logic errors that prevent the loop from breaking.

Consider the following Java code example:

public void processItems(List<String> items) {
    int index = 0;
    while (index >= 0) { // Faulty condition
        System.out.println("Processing item: " + items.get(index));
        index++; // This will eventually lead to IndexOutOfBoundsException
    }
}

In this example, the condition index >= 0 is always true, making the loop run indefinitely. Furthermore, since the condition does not accurately check the bounds of the items list, it can also generate a run-time exception when the index surpasses the list size. Proper loop control logic should ensure that loop conditions are precise and logically sound to prevent infinite execution.

Remediation

To fix the previous example, use a loop that correctly checks for exit condition:

public void processItems(List<String> items) {
    // Alternative: while loop with fixed condition
    int index = 0, size = items.size();
    while (index < size) {
        System.out.println("Processing item: " + items.get(index));
        index++;
    }
    // Alternative: for loop over the collection items
    for (int i = 0; i < items.size(); i++) {
        System.out.println("Processing item: " + items.get(i));
    }
    // Alternative: for-each loop without explicit index
    for (String item : items) {
        System.out.println("Processing item: " + item);
    }
    // Alternative: stream API and lambdas
    items.forEach(item -> System.out.println("Processing item: " + item));
}

To remediate potential infinite loops, apply these practical tips:

  1. Use Correct Loop Conditions: Ensure that the loop condition logically corresponds to the desired number of iterations and checks inside a sensible constraint, such as the length of an array or list.

  2. Include Termination Logic: If using a non-standard loop, such as while or do-while, confirm that termination conditions are precise and can be met.

  3. Implement Defensive Programming Techniques: Add checks within the loop body to ensure termination logic is being correctly applied. This may involve using safe exit strategies with break statements when certain conditions are met.

  4. Perform Regular Code Reviews: Engage code review processes to catch logical errors in loop constructs. Pair with Static Application Security Testing (SAST) tools to automatically identify potential infinite loop constructs.

  5. Testing and Simulation: Conduct thorough testing with diverse datasets to ensure loops behave as expected across various scenarios. Automated tests can effectively identify infinite loop risks.

Configuration

The rule has the following configurable parameters:

  • allowExplicitInfiniteLoops: true|false (default: false) - Set to true if intentional non-empty infinite loops, coded as while(true) or for(;;), are allowed

References

  • CWE-835 : Loop with Unreachable Exit Condition ('Infinite Loop').