Skip to content

Commit 7a475eb

Browse files
committed
C#: Fix CSV overrides logic
1 parent df29538 commit 7a475eb

File tree

2 files changed

+47
-21
lines changed

2 files changed

+47
-21
lines changed

csharp/ql/src/semmle/code/csharp/dataflow/ExternalFlow.qll

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -325,33 +325,49 @@ private predicate elementSpec(
325325
summaryModel(namespace, type, subtypes, name, signature, ext, _, _, _)
326326
}
327327

328+
private predicate elementSpec(
329+
string namespace, string type, boolean subtypes, string name, string signature, string ext,
330+
UnboundValueOrRefType t
331+
) {
332+
elementSpec(namespace, type, subtypes, name, signature, ext) and
333+
t.hasQualifiedName(namespace, type)
334+
}
335+
328336
private class UnboundValueOrRefType extends ValueOrRefType {
329337
UnboundValueOrRefType() { this.isUnboundDeclaration() }
330338

331-
UnboundValueOrRefType getASubTypeUnbound() { result = this.getASubType().getUnboundDeclaration() }
339+
UnboundValueOrRefType getASubTypeUnbound() {
340+
exists(Type t |
341+
result.getABaseType() = t and
342+
this = t.getUnboundDeclaration()
343+
)
344+
}
332345
}
333346

334-
bindingset[namespace, type, subtypes]
335-
private UnboundValueOrRefType interpretType(string namespace, string type, boolean subtypes) {
336-
exists(UnboundValueOrRefType t |
337-
t.hasQualifiedName(namespace, type) and
338-
if subtypes = true then result = t.getASubTypeUnbound*() else result = t
339-
)
340-
}
347+
private class UnboundCallable extends Callable, Virtualizable {
348+
UnboundCallable() { this.isUnboundDeclaration() }
341349

342-
private Member interpretMember(
343-
string namespace, string type, boolean subtypes, string name, string signature
344-
) {
345-
elementSpec(namespace, type, subtypes, name, signature, _) and
346-
exists(UnboundValueOrRefType t |
347-
t = interpretType(namespace, type, subtypes) and
348-
result.getDeclaringType() = t and
349-
result.hasName(name)
350-
)
350+
predicate overridesOrImplementsUnbound(UnboundCallable that) {
351+
exists(Callable c |
352+
this.overridesOrImplementsOrEquals(c) and
353+
this != c and
354+
that = c.getUnboundDeclaration()
355+
)
356+
}
351357
}
352358

353359
private class InterpretedCallable extends Callable {
354-
InterpretedCallable() { this = interpretMember(_, _, _, _, _) }
360+
InterpretedCallable() {
361+
exists(UnboundValueOrRefType t, boolean subtypes, string name |
362+
elementSpec(_, _, subtypes, name, _, _, t) and
363+
this.hasName(name)
364+
|
365+
this.getDeclaringType() = t
366+
or
367+
subtypes = true and
368+
this.getDeclaringType() = t.getASubTypeUnbound+()
369+
)
370+
}
355371
}
356372

357373
private string paramsStringPartA(InterpretedCallable c, int i) {
@@ -388,10 +404,13 @@ private string paramsString(InterpretedCallable c) {
388404
private Element interpretElement0(
389405
string namespace, string type, boolean subtypes, string name, string signature
390406
) {
391-
elementSpec(namespace, type, subtypes, name, signature, _) and
392-
exists(UnboundValueOrRefType t | t = interpretType(namespace, type, subtypes) |
407+
exists(UnboundValueOrRefType t | elementSpec(namespace, type, subtypes, name, signature, _, t) |
393408
exists(Member m |
394-
result = m and
409+
(
410+
result = m
411+
or
412+
subtypes = true and result.(UnboundCallable).overridesOrImplementsUnbound(m)
413+
) and
395414
m.getDeclaringType() = t and
396415
m.hasName(name)
397416
|
@@ -400,6 +419,12 @@ private Element interpretElement0(
400419
paramsString(m) = signature
401420
)
402421
or
422+
(
423+
result = t
424+
or
425+
subtypes = true and
426+
result = t.(UnboundValueOrRefType).getASubTypeUnbound+()
427+
) and
403428
result = t and
404429
name = "" and
405430
signature = ""

csharp/ql/test/library-tests/dataflow/external-models/steps.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ summaryThroughStep
1010
| Steps.cs:26:13:26:31 | this access | Steps.cs:26:25:26:30 | [post] access to local variable argOut | false |
1111
| Steps.cs:41:29:41:29 | 0 | Steps.cs:41:13:41:30 | call to method StepGeneric | true |
1212
| Steps.cs:42:30:42:34 | false | Steps.cs:42:13:42:35 | call to method StepGeneric2 | true |
13+
| Steps.cs:44:36:44:43 | "string" | Steps.cs:44:13:44:44 | call to method StepOverride | true |
1314
summaryGetterStep
1415
| Steps.cs:28:13:28:16 | this access | Steps.cs:28:13:28:34 | call to method StepFieldGetter | Steps.cs:57:13:57:17 | field Field |
1516
| Steps.cs:32:13:32:16 | this access | Steps.cs:32:13:32:37 | call to method StepPropertyGetter | Steps.cs:63:13:63:20 | property Property |

0 commit comments

Comments
 (0)