False Negative: ConstantLoopCondition.ql misses loops whose exit condition stays constant after being wrapped in helpers.
- Langage dominant
- CodeQL
- Étoiles
- 10.1k
- Forks
- 2.1k
- Merge moyen
- 2 j 15 h
- PR mergées (30 j)
- 141
Description
Version
codeql 2.24.3
## Checker
- Checker id: `Likely Bugs/Termination/ConstantLoopCondition.ql`
- Checker description: This checker detects loop conditions that are constant within the loop body, potentially leading to non-terminating loops.
## Description of the false negative
These loops are still non-terminating for the same reason as the direct patterns: the value that controls exit never changes inside the loop. The code only wraps that check in a helper or rewrites the exit test into an equivalent form.
That should not move the sample outside the scope of `Likely Bugs/Termination/ConstantLoopCondition.ql`.
## Affected test cases
### `PosCase1_Var5.java`
`x` is never updated, so `check(x)` never changes. The helper only obscures an otherwise obvious infinite loop.
```java
// while loop with condition variable defined outside and no updates in body should be flagged as infinite loop
package scensct.var.pos;
public class PosCase1_Var5 {
private static boolean check(int val) {
return val > 0;
}
public static void main(String[] args) {
int x = 5;
// condition via helper method, x not updated
while (check(x)) {
System.out.println("stuck via method");
}
}
}
```
### `PosCase2_Var4.java`
`conditionHolds(y)` is stable because `y` is never modified in the loop body. This is still a constant loop condition.
```java
// while loop with condition using final field and variable defined outside should be flagged as infinite loop
package scensct.var.pos;
public class PosCase2_Var4 {
private static final int LIMIT = 10;
public static void main(String[] args) {
int y = 3;
// Extract condition evaluation to a helper method
while (conditionHolds(y)) {
System.out.println("stuck");
}
}
private static boolean conditionHolds(int val) {
return val < LIMIT;
}
}
```
### `PosCase5_Var5.java`
The loop exit is written as a guarded `return`, but `counter` never changes, so `shouldExit(counter)` remains false forever and the loop still does not terminate.
```java
// while true loop with if condition using variable defined outside controlling all exits should be flagged as infinite loop
package scensct.var.pos;
public class PosCase5_Var5 {
// Helper method to compute constant condition
private static boolean shouldExit(int c) {
return c == 1;
}
public static void main(String[] args) {
int counter = 0;
while (true) {
// Exit condition hidden in method call
if (shouldExit(counter)) {
return;
}
System.out.println("stuck");
}
}
}
```
## Cause analysis
The misses point to a query that is matching specific loop syntax rather than the underlying stability of the condition. Once the condition is computed in a helper or turned into an equivalent exit guard, the analysis seems to stop following it.
That leaves a real blind spot. Developers often factor loop predicates into helpers, and those helpers do not make a non-terminating loop any safer.
## References
None known.
Guide de contribution
Ouvrir le guide de contribution
Piste de recherche
Commencez par Likely Bugs/Termination/ConstantLoopCondition.ql et examinez comment ses tests existants couvrent les conditions de boucle constantes. Reproduisez les cas non détectés dans PosCase1_Var5.java, PosCase2_Var4.java et PosCase5_Var5.java, puis exécutez les tests de requête concernés. C’est terminé lorsque les trois boucles non terminantes encapsulées dans des helpers ou protégées par des gardes sont détectées, sans perdre la couverture existante.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Évaluation
- Stack technique
- java
- Domaine
- devtools, security
- Type d'issue
- Bug
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Activité
- Calme
- Clarté
- Plutôt claire
- Accessibilité débutants
- 45/100