-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathInfiniteLoop.ql
More file actions
65 lines (61 loc) · 2.2 KB
/
InfiniteLoop.ql
File metadata and controls
65 lines (61 loc) · 2.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/**
* @name Loop with unreachable exit condition
* @description An iteration or loop with an exit condition that cannot be
* reached is an indication of faulty logic and can likely lead to infinite
* looping.
* @kind problem
* @problem.severity warning
* @security-severity 7.5
* @precision medium
* @id java/unreachable-exit-in-loop
* @tags security
* external/cwe/cwe-835
*/
import java
import Likely_Bugs.Comparison.UselessComparisonTest
/**
* The condition `cond` is a loop condition for `loop` - potentially indirectly
* by guarding a `break` or a `return` that can exit the loop.
*/
predicate loopCondition(LoopStmt loop, Expr cond, boolean polarity) {
polarity = true and cond = loop.getCondition()
or
exists(IfStmt ifstmt, Stmt exit |
ifstmt.getEnclosingStmt*() = loop.getBody() and
ifstmt.getCondition() = cond and
(
exit.(BreakStmt).getTarget() = loop or
exit.(ReturnStmt).getEnclosingStmt*() = loop.getBody()
) and
(
polarity = false and exit.getEnclosingStmt*() = ifstmt.getThen()
or
polarity = true and exit.getEnclosingStmt*() = ifstmt.getElse()
)
)
}
/**
* The expression `subcond` is a (reflexive, transitive) sub-expression of
* `cond` passing through only logical connectives. The boolean `negated`
* indicates whether an odd number of negations separates `cond` and `subcond`.
*/
predicate subCondition(Expr cond, Expr subcond, boolean negated) {
cond = subcond and negated = false
or
subCondition(cond.(AndLogicalExpr).getAnOperand(), subcond, negated)
or
subCondition(cond.(OrLogicalExpr).getAnOperand(), subcond, negated)
or
subCondition(cond.(LogNotExpr).getOperand(), subcond, negated.booleanNot())
}
from
LoopStmt loop, BinaryExpr test, boolean testIsTrue, Expr cond, boolean polarity, boolean negated
where
loopCondition(loop, cond, polarity) and
not loop instanceof EnhancedForStmt and
subCondition(cond, test, negated) and
uselessTest(_, test, testIsTrue) and
testIsTrue = polarity.booleanXor(negated)
select loop,
"Loop might not terminate, as termination depends in part on $@ being " + testIsTrue.booleanNot() +
" but it is always " + testIsTrue + ".", test, "this test"