Skip to content

Commit 3986274

Browse files
committed
Java: Convert support for fluent interfaces.
1 parent 579c955 commit 3986274

File tree

2 files changed

+8
-26
lines changed

2 files changed

+8
-26
lines changed

java/ql/src/semmle/code/java/dataflow/internal/DataFlowUtil.qll

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,14 @@ predicate simpleLocalFlowStep(Node node1, Node node2) {
150150
)
151151
or
152152
FlowSummaryImpl::Private::Steps::summaryLocalStep(node1, node2, true)
153+
or
154+
// If flow through a method updates a parameter from some input A, and that
155+
// parameter also is returned through B, then we'd like a combined flow from A
156+
// to B as well. As an example, this simplifies modeling of fluent methods:
157+
// for `StringBuilder.append(x)` with a specified value flow from qualifier to
158+
// return value and taint flow from argument 0 to the qualifier, then this
159+
// allows the inferral of taint flow from argument 0 to the return value.
160+
node1.(SummaryNode).(PostUpdateNode).getPreUpdateNode().(ParameterNode) = node2
153161
}
154162

155163
/**

java/ql/src/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,6 @@ predicate localTaintStep(DataFlow::Node src, DataFlow::Node sink) {
4646
* different objects.
4747
*/
4848
predicate localAdditionalTaintStep(DataFlow::Node src, DataFlow::Node sink) {
49-
localAdditionalBasicTaintStep(src, sink)
50-
or
51-
composedValueAndTaintModelStep(src, sink)
52-
}
53-
54-
private predicate localAdditionalBasicTaintStep(DataFlow::Node src, DataFlow::Node sink) {
5549
localAdditionalTaintExprStep(src.asExpr(), sink.asExpr())
5650
or
5751
localAdditionalTaintUpdateStep(src.asExpr(),
@@ -67,26 +61,6 @@ private predicate localAdditionalBasicTaintStep(DataFlow::Node src, DataFlow::No
6761
not FlowSummaryImpl::Private::Steps::summaryLocalStep(src, sink, true)
6862
}
6963

70-
/**
71-
* Holds if an additional step from `src` to `sink` through a call can be inferred from the
72-
* combination of a value-preserving step providing an alias between an input and the output
73-
* and a taint step from `src` to one the aliased nodes. For example, if we know that `f(a, b)` returns
74-
* the exact value of `a` and also propagates taint from `b` to `a`, then we also know that
75-
* the return value is tainted after `f` completes.
76-
*/
77-
private predicate composedValueAndTaintModelStep(ArgumentNode src, DataFlow::Node sink) {
78-
exists(Call call, ArgumentNode valueSource, DataFlow::PostUpdateNode valueSourcePost |
79-
src.argumentOf(call, _) and
80-
valueSource.argumentOf(call, _) and
81-
src != valueSource and
82-
valueSourcePost.getPreUpdateNode() = valueSource and
83-
// in-x -value-> out-y and in-z -taint-> in-x ==> in-z -taint-> out-y
84-
localAdditionalBasicTaintStep(src, valueSourcePost) and
85-
DataFlow::localFlowStep(valueSource, DataFlow::exprNode(call)) and
86-
sink = DataFlow::exprNode(call)
87-
)
88-
}
89-
9064
/**
9165
* Holds if the additional step from `src` to `sink` should be included in all
9266
* global taint flow configurations.

0 commit comments

Comments
 (0)