C#: Assume that models should apply when a method is overridable except for the implicit methods on Object and ValueType.

This commit is contained in:
Michael Nebel
2024-05-15 14:03:43 +02:00
parent ad55744877
commit d272d6a9ca
2 changed files with 18 additions and 9 deletions

View File

@@ -94,6 +94,8 @@ private import FlowSummaryImpl::Public
private import FlowSummaryImpl::Private
private import FlowSummaryImpl::Private::External
private import semmle.code.csharp.commons.QualifiedName
private import semmle.code.csharp.dispatch.OverridableCallable
private import semmle.code.csharp.frameworks.System
private import codeql.mad.ModelValidation as SharedModelVal
private predicate relevantNamespace(string namespace) {
@@ -442,20 +444,16 @@ predicate sourceNode(Node node, string kind) { sourceNode(node, kind, _) }
*/
predicate sinkNode(Node node, string kind) { sinkNode(node, kind, _) }
/** Holds if the summary should apply for all overrides of `c`. */
predicate isBaseCallableOrPrototype(UnboundCallable c) {
c.getDeclaringType() instanceof Interface
or
exists(Modifiable m | m = [c.(Modifiable), c.(Accessor).getDeclaration()] |
m.isAbstract()
or
c.getDeclaringType().(Modifiable).isAbstract() and m.(Virtualizable).isVirtual()
private predicate isOverridableCallable(OverridableCallable c) {
not exists(Type t, Callable base | c.getOverridee+() = base and t = base.getDeclaringType() |
t instanceof SystemObjectClass or
t instanceof SystemValueTypeClass
)
}
/** Gets a string representing whether the summary should apply for all overrides of `c`. */
private string getCallableOverride(UnboundCallable c) {
if isBaseCallableOrPrototype(c) then result = "true" else result = "false"
if isOverridableCallable(c) then result = "true" else result = "false"
}
private module QualifiedNameInput implements QualifiedNameInputSig {

View File

@@ -1,6 +1,17 @@
import shared.FlowSummaries
private import semmle.code.csharp.dataflow.internal.ExternalFlow
/** Holds if `c` is a base callable or prototype. */
private predicate isBaseCallableOrPrototype(UnboundCallable c) {
c.getDeclaringType() instanceof Interface
or
exists(Modifiable m | m = [c.(Modifiable), c.(Accessor).getDeclaration()] |
m.isAbstract()
or
c.getDeclaringType().(Modifiable).isAbstract() and m.(Virtualizable).isVirtual()
)
}
class IncludeFilteredSummarizedCallable extends IncludeSummarizedCallable {
/**
* Holds if flow is propagated between `input` and `output` and