-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathIteratorRemoveMayFail.ql
More file actions
66 lines (61 loc) · 2.17 KB
/
IteratorRemoveMayFail.ql
File metadata and controls
66 lines (61 loc) · 2.17 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
/**
* @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
* @tags reliability
* correctness
* logic
*/
import java
class SpecialCollectionCreation extends MethodAccess {
SpecialCollectionCreation() {
exists(Method m, RefType rt | m = this.(MethodAccess).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(v.getAnAssignedValue(), origin) and
e = v.getAnAccess()
) or
exists(Call c, int i |
containsSpecialCollection(c.getArgument(i), origin) and
e = c.getCallee().getParameter(i).getAnAccess()
) or
exists(Call c, ReturnStmt r | e = c |
r.getEnclosingCallable() = c.getCallee() and
containsSpecialCollection(r.getResult(), origin)
)
}
predicate iterOfSpecialCollection(Expr e, SpecialCollectionCreation origin) {
exists(MethodAccess ma | ma = e |
containsSpecialCollection(ma.getQualifier(), origin) and
ma.getCallee().hasName("iterator")
) or
exists(Variable v |
iterOfSpecialCollection(v.getAnAssignedValue(), origin) and
e = v.getAnAccess()
) or
exists(Call c, int i |
iterOfSpecialCollection(c.getArgument(i), origin) and
e = c.getCallee().getParameter(i).getAnAccess()
) or
exists(Call c, ReturnStmt r | e = c |
r.getEnclosingCallable() = c.getCallee() and
iterOfSpecialCollection(r.getResult(), origin)
)
}
from MethodAccess remove, SpecialCollectionCreation scc
where
remove.getCallee().hasName("remove") and
iterOfSpecialCollection(remove.getQualifier(), scc)
select remove,
"This call may fail when iterating over the collection created $@, since it does not support element removal.",
scc, "here"