Skip to content

Commit 68ea3e7

Browse files
committed
Data flow: Add debugging predicates for rendering data flow graphs for summarized callables
1 parent d5955f1 commit 68ea3e7

File tree

4 files changed

+210
-0
lines changed

4 files changed

+210
-0
lines changed

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,19 @@ abstract class DataFlowCall extends TDataFlowCall {
262262

263263
/** Gets the location of this call. */
264264
abstract Location getLocation();
265+
266+
/**
267+
* Holds if this element is at the specified location.
268+
* The location spans column `startcolumn` of line `startline` to
269+
* column `endcolumn` of line `endline` in file `filepath`.
270+
* For more information, see
271+
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
272+
*/
273+
final predicate hasLocationInfo(
274+
string filepath, int startline, int startcolumn, int endline, int endcolumn
275+
) {
276+
this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
277+
}
265278
}
266279

267280
/** A non-delegate C# call relevant for data flow. */

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

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -870,4 +870,96 @@ module Private {
870870
)
871871
}
872872
}
873+
874+
/**
875+
* Provides query predicates for rendering the generated data flow graph for
876+
* a summarized callable.
877+
*
878+
* Import this module into a `.ql` file of `@kind graph` to render the graph.
879+
* The graph is restricted to callables from `RelevantSummarizedCallable`.
880+
*/
881+
module RenderSummarizedCallable {
882+
/** A summarized callable to include in the graph. */
883+
abstract class RelevantSummarizedCallable extends SummarizedCallable { }
884+
885+
private newtype TNodeOrCall =
886+
MkNode(Node n) {
887+
exists(RelevantSummarizedCallable c |
888+
n = summaryNode(c, _)
889+
or
890+
n.(ParamNode).isParameterOf(c, _)
891+
)
892+
} or
893+
MkCall(DataFlowCall call) {
894+
call = summaryDataFlowCall(_) and
895+
call.getEnclosingCallable() instanceof RelevantSummarizedCallable
896+
}
897+
898+
private class NodeOrCall extends TNodeOrCall {
899+
Node asNode() { this = MkNode(result) }
900+
901+
DataFlowCall asCall() { this = MkCall(result) }
902+
903+
string toString() {
904+
result = this.asNode().toString()
905+
or
906+
result = this.asCall().toString()
907+
}
908+
909+
/**
910+
* Holds if this element is at the specified location.
911+
* The location spans column `startcolumn` of line `startline` to
912+
* column `endcolumn` of line `endline` in file `filepath`.
913+
* For more information, see
914+
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
915+
*/
916+
predicate hasLocationInfo(
917+
string filepath, int startline, int startcolumn, int endline, int endcolumn
918+
) {
919+
this.asNode().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
920+
or
921+
this.asCall().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
922+
}
923+
}
924+
925+
query predicate nodes(NodeOrCall n, string key, string val) {
926+
key = "semmle.label" and val = n.toString()
927+
}
928+
929+
private predicate edgesComponent(NodeOrCall a, NodeOrCall b, string value) {
930+
exists(boolean preservesValue |
931+
Private::Steps::summaryLocalStep(a.asNode(), b.asNode(), preservesValue) and
932+
if preservesValue = true then value = "value" else value = "taint"
933+
)
934+
or
935+
exists(Content c |
936+
Private::Steps::summaryReadStep(a.asNode(), c, b.asNode()) and
937+
value = "read (" + c + ")"
938+
or
939+
Private::Steps::summaryStoreStep(a.asNode(), c, b.asNode()) and
940+
value = "store (" + c + ")"
941+
or
942+
Private::Steps::summaryClearsContent(a.asNode(), c) and
943+
b = a and
944+
value = "clear (" + c + ")"
945+
)
946+
or
947+
summaryPostUpdateNode(b.asNode(), a.asNode()) and
948+
value = "post-update"
949+
or
950+
b.asCall() = summaryDataFlowCall(a.asNode()) and
951+
value = "receiver"
952+
or
953+
exists(int i |
954+
summaryArgumentNode(b.asCall(), a.asNode(), i) and
955+
value = "argument (" + i + ")"
956+
)
957+
}
958+
959+
query predicate edges(NodeOrCall a, NodeOrCall b, string key, string value) {
960+
key = "semmle.label" and
961+
edgesComponent(a, b, _) and
962+
value = strictconcat(string s | edgesComponent(a, b, s) | s, " / ")
963+
}
964+
}
873965
}

java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,19 @@ class DataFlowCall extends TDataFlowCall {
234234

235235
/** Gets the location of this call. */
236236
abstract Location getLocation();
237+
238+
/**
239+
* Holds if this element is at the specified location.
240+
* The location spans column `startcolumn` of line `startline` to
241+
* column `endcolumn` of line `endline` in file `filepath`.
242+
* For more information, see
243+
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
244+
*/
245+
final predicate hasLocationInfo(
246+
string filepath, int startline, int startcolumn, int endline, int endcolumn
247+
) {
248+
this.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
249+
}
237250
}
238251

239252
/** A source call, that is, a `Call`. */

java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -870,4 +870,96 @@ module Private {
870870
)
871871
}
872872
}
873+
874+
/**
875+
* Provides query predicates for rendering the generated data flow graph for
876+
* a summarized callable.
877+
*
878+
* Import this module into a `.ql` file of `@kind graph` to render the graph.
879+
* The graph is restricted to callables from `RelevantSummarizedCallable`.
880+
*/
881+
module RenderSummarizedCallable {
882+
/** A summarized callable to include in the graph. */
883+
abstract class RelevantSummarizedCallable extends SummarizedCallable { }
884+
885+
private newtype TNodeOrCall =
886+
MkNode(Node n) {
887+
exists(RelevantSummarizedCallable c |
888+
n = summaryNode(c, _)
889+
or
890+
n.(ParamNode).isParameterOf(c, _)
891+
)
892+
} or
893+
MkCall(DataFlowCall call) {
894+
call = summaryDataFlowCall(_) and
895+
call.getEnclosingCallable() instanceof RelevantSummarizedCallable
896+
}
897+
898+
private class NodeOrCall extends TNodeOrCall {
899+
Node asNode() { this = MkNode(result) }
900+
901+
DataFlowCall asCall() { this = MkCall(result) }
902+
903+
string toString() {
904+
result = this.asNode().toString()
905+
or
906+
result = this.asCall().toString()
907+
}
908+
909+
/**
910+
* Holds if this element is at the specified location.
911+
* The location spans column `startcolumn` of line `startline` to
912+
* column `endcolumn` of line `endline` in file `filepath`.
913+
* For more information, see
914+
* [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/).
915+
*/
916+
predicate hasLocationInfo(
917+
string filepath, int startline, int startcolumn, int endline, int endcolumn
918+
) {
919+
this.asNode().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
920+
or
921+
this.asCall().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn)
922+
}
923+
}
924+
925+
query predicate nodes(NodeOrCall n, string key, string val) {
926+
key = "semmle.label" and val = n.toString()
927+
}
928+
929+
private predicate edgesComponent(NodeOrCall a, NodeOrCall b, string value) {
930+
exists(boolean preservesValue |
931+
Private::Steps::summaryLocalStep(a.asNode(), b.asNode(), preservesValue) and
932+
if preservesValue = true then value = "value" else value = "taint"
933+
)
934+
or
935+
exists(Content c |
936+
Private::Steps::summaryReadStep(a.asNode(), c, b.asNode()) and
937+
value = "read (" + c + ")"
938+
or
939+
Private::Steps::summaryStoreStep(a.asNode(), c, b.asNode()) and
940+
value = "store (" + c + ")"
941+
or
942+
Private::Steps::summaryClearsContent(a.asNode(), c) and
943+
b = a and
944+
value = "clear (" + c + ")"
945+
)
946+
or
947+
summaryPostUpdateNode(b.asNode(), a.asNode()) and
948+
value = "post-update"
949+
or
950+
b.asCall() = summaryDataFlowCall(a.asNode()) and
951+
value = "receiver"
952+
or
953+
exists(int i |
954+
summaryArgumentNode(b.asCall(), a.asNode(), i) and
955+
value = "argument (" + i + ")"
956+
)
957+
}
958+
959+
query predicate edges(NodeOrCall a, NodeOrCall b, string key, string value) {
960+
key = "semmle.label" and
961+
edgesComponent(a, b, _) and
962+
value = strictconcat(string s | edgesComponent(a, b, s) | s, " / ")
963+
}
964+
}
873965
}

0 commit comments

Comments
 (0)