Skip to content

Commit 31a374a

Browse files
committed
C#: Add copy of the shared CaptureSummaryModels logic.
1 parent e5cce6c commit 31a374a

File tree

1 file changed

+87
-0
lines changed

1 file changed

+87
-0
lines changed
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import CaptureSummaryModelsSpecific
2+
3+
/**
4+
* Capture fluent APIs that return `this`.
5+
* Example of a fluent API:
6+
* ```
7+
* public class Foo {
8+
* public Foo someAPI() {
9+
* // some side-effect
10+
* return this;
11+
* }
12+
* }
13+
* ```
14+
*/
15+
string captureQualifierFlow(TargetAPI api) {
16+
exists(ReturnStmt rtn |
17+
rtn.getEnclosingCallable() = api and
18+
isOwnInstanceAccess(rtn)
19+
) and
20+
result = asValueModel(api, qualifierString(), "ReturnValue")
21+
}
22+
23+
class TaintRead extends DataFlow::FlowState {
24+
TaintRead() { this = "TaintRead" }
25+
}
26+
27+
class TaintStore extends DataFlow::FlowState {
28+
TaintStore() { this = "TaintStore" }
29+
}
30+
31+
class ThroughFlowConfig extends TaintTracking::Configuration {
32+
ThroughFlowConfig() { this = "ThroughFlowConfig" }
33+
34+
override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) {
35+
source instanceof DataFlow::ParameterNode and
36+
source.getEnclosingCallable() instanceof TargetAPI and
37+
state instanceof TaintRead
38+
}
39+
40+
override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) {
41+
sink instanceof ReturnNodeExt and
42+
not isOwnInstanceAccessNode(sink) and
43+
not exists(captureQualifierFlow(sink.asExpr().getEnclosingCallable())) and
44+
(state instanceof TaintRead or state instanceof TaintStore)
45+
}
46+
47+
override predicate isAdditionalFlowStep(
48+
DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2,
49+
DataFlow::FlowState state2
50+
) {
51+
exists(TypedContent tc |
52+
store(node1, tc, node2, _) and
53+
isRelevantContent(tc.getContent()) and
54+
(state1 instanceof TaintRead or state1 instanceof TaintStore) and
55+
state2 instanceof TaintStore
56+
)
57+
or
58+
exists(DataFlow::Content c |
59+
readStep(node1, c, node2) and
60+
isRelevantContent(c) and
61+
state1 instanceof TaintRead and
62+
state2 instanceof TaintRead
63+
)
64+
}
65+
66+
override predicate isSanitizer(DataFlow::Node n) {
67+
exists(Type t | t = n.getType() and not isRelevantType(t))
68+
}
69+
70+
override DataFlow::FlowFeature getAFeature() {
71+
result instanceof DataFlow::FeatureEqualSourceSinkCallContext
72+
}
73+
}
74+
75+
string captureThroughFlow(TargetAPI api) {
76+
exists(
77+
ThroughFlowConfig config, DataFlow::ParameterNode p, ReturnNodeExt returnNodeExt, string input,
78+
string output
79+
|
80+
config.hasFlow(p, returnNodeExt) and
81+
returnNodeExt.getEnclosingCallable() = api and
82+
input = parameterNodeAsInput(p) and
83+
output = returnNodeAsOutput(returnNodeExt) and
84+
input != output and
85+
result = asTaintModel(api, input, output)
86+
)
87+
}

0 commit comments

Comments
 (0)