-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathHashedButNoHash.ql
More file actions
58 lines (51 loc) · 1.43 KB
/
HashedButNoHash.ql
File metadata and controls
58 lines (51 loc) · 1.43 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
/**
* @name Hashed value without GetHashCode definition
* @description Finds uses of hashing on types that define 'Equals(...)' but not 'GetHashCode()'.
* @kind problem
* @problem.severity warning
* @precision high
* @id cs/gethashcode-is-not-defined
* @tags reliability
* maintainability
*/
import csharp
import semmle.code.csharp.frameworks.System
predicate dictionary(ConstructedType constructed)
{
exists(UnboundGenericType dict |
dict.hasQualifiedName("System.Collections.Generic", "Dictionary<,>") and
constructed = dict.getAConstructedGeneric())
}
predicate hashtable(Class c)
{
c.hasQualifiedName("System.Collections", "Hashtable")
}
predicate hashstructure(Type t)
{
hashtable(t) or dictionary(t)
}
predicate hashAdd(Expr e)
{
exists(MethodCall mc, string name |
(name = "Add" or name = "ContainsKey") and
mc.getArgument(0) = e and
mc.getTarget().hasName(name) and
hashstructure(mc.getTarget().getDeclaringType()))
}
predicate eqWithoutHash(RefType t)
{
t.getAMethod() instanceof EqualsMethod
and not t.getAMethod() instanceof GetHashCodeMethod
}
predicate hashCall(Expr e)
{
exists(MethodCall mc |
mc.getQualifier() = e and
mc.getTarget() instanceof GetHashCodeMethod)
}
from Expr e, Type t
where (hashAdd(e) or hashCall(e))
and e.getType() = t
and eqWithoutHash(t)
select e, "This expression is hashed, but type '" + t.getName()
+ "' only defines Equals(...) not GetHashCode()."