Skip to content

Commit d272d6a

Browse files
committed
C#: Assume that models should apply when a method is overridable except for the implicit methods on Object and ValueType.
1 parent ad55744 commit d272d6a

File tree

2 files changed

+18
-9
lines changed

2 files changed

+18
-9
lines changed

csharp/ql/lib/semmle/code/csharp/dataflow/internal/ExternalFlow.qll

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ private import FlowSummaryImpl::Public
9494
private import FlowSummaryImpl::Private
9595
private import FlowSummaryImpl::Private::External
9696
private import semmle.code.csharp.commons.QualifiedName
97+
private import semmle.code.csharp.dispatch.OverridableCallable
98+
private import semmle.code.csharp.frameworks.System
9799
private import codeql.mad.ModelValidation as SharedModelVal
98100

99101
private predicate relevantNamespace(string namespace) {
@@ -442,20 +444,16 @@ predicate sourceNode(Node node, string kind) { sourceNode(node, kind, _) }
442444
*/
443445
predicate sinkNode(Node node, string kind) { sinkNode(node, kind, _) }
444446

445-
/** Holds if the summary should apply for all overrides of `c`. */
446-
predicate isBaseCallableOrPrototype(UnboundCallable c) {
447-
c.getDeclaringType() instanceof Interface
448-
or
449-
exists(Modifiable m | m = [c.(Modifiable), c.(Accessor).getDeclaration()] |
450-
m.isAbstract()
451-
or
452-
c.getDeclaringType().(Modifiable).isAbstract() and m.(Virtualizable).isVirtual()
447+
private predicate isOverridableCallable(OverridableCallable c) {
448+
not exists(Type t, Callable base | c.getOverridee+() = base and t = base.getDeclaringType() |
449+
t instanceof SystemObjectClass or
450+
t instanceof SystemValueTypeClass
453451
)
454452
}
455453

456454
/** Gets a string representing whether the summary should apply for all overrides of `c`. */
457455
private string getCallableOverride(UnboundCallable c) {
458-
if isBaseCallableOrPrototype(c) then result = "true" else result = "false"
456+
if isOverridableCallable(c) then result = "true" else result = "false"
459457
}
460458

461459
private module QualifiedNameInput implements QualifiedNameInputSig {

csharp/ql/test/library-tests/dataflow/library/FlowSummariesFiltered.ql

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
import shared.FlowSummaries
22
private import semmle.code.csharp.dataflow.internal.ExternalFlow
33

4+
/** Holds if `c` is a base callable or prototype. */
5+
private predicate isBaseCallableOrPrototype(UnboundCallable c) {
6+
c.getDeclaringType() instanceof Interface
7+
or
8+
exists(Modifiable m | m = [c.(Modifiable), c.(Accessor).getDeclaration()] |
9+
m.isAbstract()
10+
or
11+
c.getDeclaringType().(Modifiable).isAbstract() and m.(Virtualizable).isVirtual()
12+
)
13+
}
14+
415
class IncludeFilteredSummarizedCallable extends IncludeSummarizedCallable {
516
/**
617
* Holds if flow is propagated between `input` and `output` and

0 commit comments

Comments
 (0)