Skip to content

Commit 2acde22

Browse files
committed
C#: Add QL and tests for handles.
1 parent 0ee209e commit 2acde22

File tree

4 files changed

+74
-0
lines changed

4 files changed

+74
-0
lines changed

csharp/ql/src/semmle/code/dotnet/Element.qll

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,14 @@ class NamedElement extends Element, @dotnet_named_element {
8282
/** Gets a unique string label for this element. */
8383
string getLabel() { none() }
8484

85+
/** Holds if `other` has the same metadata handle in the same assembly. */
86+
predicate matchesHandle(NamedElement other) {
87+
exists(Assembly asm, int handle |
88+
metadata_handle(this, asm, handle) and
89+
metadata_handle(other, asm, handle)
90+
)
91+
}
92+
8593
/**
8694
* Holds if this element was compiled from source code that is also present in the
8795
* database. That is, this element corresponds to another element from source.

csharp/ql/src/semmlecode.csharp.dbscheme

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1703,4 +1703,5 @@ cil_attribute_positional_argument(
17031703
@metadata_entity = @cil_method | @cil_type | @cil_field | @cil_property | @field | @property |
17041704
@callable | @value_or_ref_type | @void_type;
17051705

1706+
#keyset[entity, location]
17061707
metadata_handle(int entity : @metadata_entity ref, int location: @assembly ref, int handle: int ref)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
tooManyMatchingHandles
2+
missingCil
3+
cilLocationViolation
4+
csharpLocationViolation
5+
matchingObjectMethods
6+
| Equals(object) | System.Boolean System.Object.Equals(System.Object) |
7+
| Equals(object, object) | System.Boolean System.Object.Equals(System.Object,System.Object) |
8+
| GetHashCode() | System.Int32 System.Object.GetHashCode() |
9+
| GetType() | System.Type System.Object.GetType() |
10+
| MemberwiseClone() | System.Object System.Object.MemberwiseClone() |
11+
| Object() | System.Void System.Object..ctor() |
12+
| ReferenceEquals(object, object) | System.Boolean System.Object.ReferenceEquals(System.Object,System.Object) |
13+
| ToString() | System.String System.Object.ToString() |
14+
| ~Object() | System.Void System.Object.Finalize() |
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import csharp
2+
import cil
3+
import dotnet
4+
5+
class MetadataEntity extends DotNet::NamedElement, @metadata_entity {
6+
int getHandle() { metadata_handle(this, _, result) }
7+
8+
predicate hasHandle() { exists(getHandle()) }
9+
10+
Assembly getAssembly() { metadata_handle(this, result, _) }
11+
}
12+
13+
query predicate tooManyMatchingHandles(MetadataEntity e) {
14+
count(MetadataEntity e2 | e.matchesHandle(e2))>2
15+
}
16+
17+
query predicate missingCil(Element e) {
18+
(
19+
e instanceof Callable
20+
or
21+
e instanceof Type
22+
or
23+
e instanceof Field
24+
) and
25+
e.fromLibrary() and
26+
e.(MetadataEntity).hasHandle() and
27+
not exists(CIL::Element ce | ce.(MetadataEntity).matchesHandle(e))
28+
}
29+
30+
query predicate cilLocationViolation(CIL::Element e) {
31+
e instanceof MetadataEntity
32+
and
33+
exists(e.getALocation())
34+
and
35+
not e.getALocation() = e.(MetadataEntity).getAssembly()
36+
}
37+
38+
query predicate csharpLocationViolation(Element e) {
39+
e.fromLibrary() and
40+
e.(MetadataEntity).hasHandle() and
41+
not e.getALocation() = e.(MetadataEntity).getAssembly()
42+
}
43+
44+
query predicate matchingObjectMethods(string s1, string s2) {
45+
exists(Callable m1, CIL::Method m2 |
46+
m1.getDeclaringType().getQualifiedName() = "System.Object"
47+
and m1.matchesHandle(m2) and
48+
s1 = m1.toStringWithTypes() and
49+
s2 = m2.toStringWithTypes()
50+
)
51+
}

0 commit comments

Comments
 (0)