-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathHashedButNoHash.ql
More file actions
63 lines (58 loc) · 1.78 KB
/
HashedButNoHash.ql
File metadata and controls
63 lines (58 loc) · 1.78 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
/**
* @name Hashed value without hashCode definition
* @description Classes that define an 'equals' method but no 'hashCode' method, and whose instances
* are stored in a hashing data structure, can lead to unexpected results.
* @kind problem
* @problem.severity error
* @precision very-high
* @id java/hashing-without-hashcode
* @tags quality
* reliability
* correctness
*/
import java
import Equality
/** Holds if `c` defines an `equals` method but no `hashCode` method. */
predicate eqNoHash(Class c) {
exists(Method m | m = c.getAMethod() |
m instanceof EqualsMethod and
// If the inherited `equals` is a refining `equals`
// then the superclass hash code is still valid.
not m instanceof RefiningEquals
) and
not c.getAMethod() instanceof HashCodeMethod and
c.fromSource()
}
predicate hashingMethod(Method m) {
exists(string name, string names |
names = "add,contains,containsKey,get,put,remove" and
name = names.splitAt(",") and
m.getName() = name
)
}
/** Holds if `e` is an expression in which `t` is used in a hashing data structure. */
predicate usedInHash(RefType t, Expr e) {
exists(RefType s |
s.getName().matches("%Hash%") and not s.getSourceDeclaration().getName() = "IdentityHashMap"
|
exists(MethodCall ma |
ma.getQualifier().getType() = s and
ma.getArgument(0).getType() = t and
e = ma and
hashingMethod(ma.getMethod())
)
or
exists(ConstructorCall cc |
cc.getConstructedType() = s and
s.(ParameterizedType).getTypeArgument(0) = t and
cc = e
)
)
}
from RefType t, Expr e
where
usedInHash(t, e) and
eqNoHash(t.getSourceDeclaration())
select e,
"Type '" + t.getName() + "' does not define hashCode(), " +
"but is used in a hashing data-structure."