Skip to content

Commit e70a283

Browse files
michaelnebelhvitved
authored andcommitted
C#: Initial refactor of SummarizedCallable and DataFlowCallable (dependencies needs to be updates).
1 parent d352253 commit e70a283

2 files changed

Lines changed: 75 additions & 3 deletions

File tree

csharp/ql/lib/semmle/code/csharp/dataflow/FlowSummary.qll

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/** Provides classes and predicates for defining flow summaries. */
22

33
import csharp
4+
private import dotnet
45
private import internal.FlowSummaryImpl as Impl
56
private import internal.DataFlowDispatch as DataFlowDispatch
67

@@ -113,7 +114,41 @@ module SummaryComponentStack {
113114
SummaryComponentStack jump(Callable c) { result = singleton(SummaryComponent::jump(c)) }
114115
}
115116

116-
class SummarizedCallable = Impl::Public::SummarizedCallable;
117+
abstract class SummarizedCallable extends DotNet::Callable {
118+
/**
119+
* Holds if data may flow from `input` to `output` through this callable.
120+
*
121+
* `preservesValue` indicates whether this is a value-preserving step
122+
* or a taint-step.
123+
*
124+
* Input specifications are restricted to stacks that end with
125+
* `SummaryComponent::argument(_)`, preceded by zero or more
126+
* `SummaryComponent::return(_)` or `SummaryComponent::content(_)` components.
127+
*
128+
* Output specifications are restricted to stacks that end with
129+
* `SummaryComponent::return(_)` or `SummaryComponent::argument(_)`.
130+
*
131+
* Output stacks ending with `SummaryComponent::return(_)` can be preceded by zero
132+
* or more `SummaryComponent::content(_)` components.
133+
*
134+
* Output stacks ending with `SummaryComponent::argument(_)` can be preceded by an
135+
* optional `SummaryComponent::parameter(_)` component, which in turn can be preceded
136+
* by zero or more `SummaryComponent::content(_)` components.
137+
*/
138+
pragma[nomagic]
139+
predicate propagatesFlow(
140+
SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue
141+
) {
142+
none()
143+
}
144+
145+
/**
146+
* Holds if values stored inside `content` are cleared on objects passed as
147+
* arguments at position `pos` to this callable.
148+
*/
149+
pragma[nomagic]
150+
predicate clearsContent(ParameterPosition pos, DataFlow::ContentSet content) { none() }
151+
}
117152

118153
private predicate recordConstructorFlow(Constructor c, int i, Property p) {
119154
c = any(RecordType r).getAMember() and
@@ -123,6 +158,22 @@ private predicate recordConstructorFlow(Constructor c, int i, Property p) {
123158
)
124159
}
125160

161+
private class SummarizedCallableAdapter extends Impl::Public::SummarizedCallable {
162+
private SummarizedCallable sc;
163+
164+
SummarizedCallableAdapter() { this = DataFlowDispatch::TSummarizedCallable(sc) }
165+
166+
final override predicate propagatesFlow(
167+
SummaryComponentStack input, SummaryComponentStack output, boolean preservesValue
168+
) {
169+
sc.propagatesFlow(input, output, preservesValue)
170+
}
171+
172+
final override predicate clearsContent(ParameterPosition pos, DataFlow::ContentSet content) {
173+
sc.clearsContent(pos, content)
174+
}
175+
}
176+
126177
private class RecordConstructorFlow extends SummarizedCallable {
127178
RecordConstructorFlow() { recordConstructorFlow(this, _, _) }
128179

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

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,8 +247,29 @@ class JumpReturnKind extends ReturnKind, TJumpReturnKind {
247247
override string toString() { result = "jump to " + target }
248248
}
249249

250-
class DataFlowCallable extends DotNet::Callable {
251-
DataFlowCallable() { this.isUnboundDeclaration() }
250+
/**
251+
* A type for modeling dataflow callables.
252+
*/
253+
newtype TDataFlowCallable =
254+
TDotNetCallable(DotNet::Callable c) { c.isUnboundDeclaration() } or
255+
TSummarizedCallable(FlowSummary::SummarizedCallable c)
256+
257+
class DataFlowCallable extends TDataFlowCallable {
258+
/** Get the underlying source code callable, if any. */
259+
Callable asCallable() { this = TDotNetCallable(result) }
260+
261+
/** Get the underlying summarized callable, if any. */
262+
FlowSummary::SummarizedCallable asSummarizedCallable() { this = TSummarizedCallable(result) }
263+
264+
/** Gets a textual representation of this dataflow callable. */
265+
string toString() {
266+
result = [this.asCallable().toString(), this.asSummarizedCallable().toString()]
267+
}
268+
269+
/** Get the location of this dataflow callable, if any. */
270+
Location getLocation() {
271+
result = this.asCallable().getLocation() or result = this.asSummarizedCallable().getLocation()
272+
}
252273
}
253274

254275
/** A call relevant for data flow. */

0 commit comments

Comments
 (0)