forked from github/codeql
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathIteratorRemoveMayFail.ql
More file actions
75 lines (70 loc) · 2.34 KB
/
IteratorRemoveMayFail.ql
File metadata and controls
75 lines (70 loc) · 2.34 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
66
67
68
69
70
71
72
73
74
75
/**
* @name Call to Iterator.remove may fail
* @description Attempting to invoke 'Iterator.remove' on an iterator over a collection that does not
* support element removal causes a runtime exception.
* @kind problem
* @problem.severity warning
* @precision medium
* @id java/iterator-remove-failure
* @suites security-and-quality
* @tags reliability
* correctness
* logic
*/
import java
class SpecialCollectionCreation extends MethodCall {
SpecialCollectionCreation() {
exists(Method m, RefType rt | m = this.(MethodCall).getCallee() and rt = m.getDeclaringType() |
rt.hasQualifiedName("java.util", "Arrays") and m.hasName("asList")
or
rt.hasQualifiedName("java.util", "Collections") and
m.getName().regexpMatch("singleton.*|unmodifiable.*")
)
}
}
predicate containsSpecialCollection(Expr e, SpecialCollectionCreation origin) {
e = origin
or
exists(Variable v |
containsSpecialCollection(pragma[only_bind_into](v.getAnAssignedValue()), origin) and
e = v.getAnAccess()
)
or
exists(Call c, int i |
containsSpecialCollection(c.getArgument(i), origin) and
e = c.getCallee().getSourceDeclaration().getParameter(i).getAnAccess()
)
or
exists(Call c, ReturnStmt r | e = c |
r.getEnclosingCallable() = c.getCallee().getSourceDeclaration() and
containsSpecialCollection(r.getResult(), origin)
)
}
predicate iterOfSpecialCollection(Expr e, SpecialCollectionCreation origin) {
exists(MethodCall ma | ma = e |
containsSpecialCollection(ma.getQualifier(), origin) and
ma.getCallee().hasName("iterator")
)
or
exists(Variable v |
iterOfSpecialCollection(pragma[only_bind_into](v.getAnAssignedValue()), origin) and
e = v.getAnAccess()
)
or
exists(Call c, int i |
iterOfSpecialCollection(c.getArgument(i), origin) and
e = c.getCallee().getSourceDeclaration().getParameter(i).getAnAccess()
)
or
exists(Call c, ReturnStmt r | e = c |
r.getEnclosingCallable() = c.getCallee().getSourceDeclaration() and
iterOfSpecialCollection(r.getResult(), origin)
)
}
from MethodCall remove, SpecialCollectionCreation scc
where
remove.getCallee().hasName("remove") and
iterOfSpecialCollection(remove.getQualifier(), scc)
select remove,
"This call may fail when iterating over $@, since it does not support element removal.", scc,
"the collection"