From 9a048c9e23719cefb29652cdd6147d570c732100 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 23 Feb 2026 11:45:30 +0100 Subject: [PATCH 1/7] Prepare to share PrintGraph.qll with DFG viewer --- shared/controlflow/codeql/controlflow/Cfg.qll | 11 ++-- .../codeql/controlflow/PrintGraph.qll | 51 +++++++++---------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/shared/controlflow/codeql/controlflow/Cfg.qll b/shared/controlflow/codeql/controlflow/Cfg.qll index 157bf0ffd4f3..74b52629f8fc 100644 --- a/shared/controlflow/codeql/controlflow/Cfg.qll +++ b/shared/controlflow/codeql/controlflow/Cfg.qll @@ -1315,13 +1315,18 @@ module MakeWithSplitting< private import PrintGraph as Pp + final private class FinalNode = Node; + private module PrintGraphInput implements Pp::InputSig { class Callable = CfgScope; - class ControlFlowNode = Node; + class Node = FinalNode; - ControlFlowNode getASuccessor(ControlFlowNode n, SuccessorType t) { - result = n.getASuccessor(t) + Node getASuccessor(Node n, string s) { + exists(SuccessorType t | + result = n.getASuccessor(t) and + if t instanceof DirectSuccessor then s = "" else s = t.toString() + ) } } diff --git a/shared/controlflow/codeql/controlflow/PrintGraph.qll b/shared/controlflow/codeql/controlflow/PrintGraph.qll index c4a942feab23..85b474ffbaa4 100644 --- a/shared/controlflow/codeql/controlflow/PrintGraph.qll +++ b/shared/controlflow/codeql/controlflow/PrintGraph.qll @@ -1,6 +1,6 @@ /** - * Provides modules for printing control flow graphs in VSCode via the "View - * CFG" query. Also provides modules for printing control flow graphs in tests + * Provides modules for printing control flow and data flow graphs in VSCode via the + * "View CFG/DFG" queries. Also provides modules for printing such graphs in tests * and as Mermaid diagrams. */ overlay[local?] @@ -8,12 +8,11 @@ module; private import codeql.util.FileSystem private import codeql.util.Location -private import SuccessorType signature module InputSig { class Callable; - class ControlFlowNode { + class Node { Callable getEnclosingCallable(); Location getLocation(); @@ -21,34 +20,28 @@ signature module InputSig { string toString(); } - ControlFlowNode getASuccessor(ControlFlowNode n, SuccessorType t); + Node getASuccessor(Node n, string label); } -/** Provides modules for printing control flow graphs. */ +/** Provides modules for printing flow graphs. */ module PrintGraph Input> { private import Input /** A node to be included in the output of `TestOutput`. */ - signature class RelevantNodeSig extends ControlFlowNode; + signature class RelevantNodeSig extends Node; /** - * Import this module into a `.ql` file to output a CFG. The + * Import this module into a `.ql` file to output a graph. The * graph is restricted to nodes from `RelevantNode`. */ module TestOutput { - /** Holds if `pred -> succ` is an edge in the CFG. */ + /** Holds if `pred -> succ` is an edge in the graph. */ query predicate edges(RelevantNode pred, RelevantNode succ, string label) { - label = - strictconcat(SuccessorType t, string s | - succ = getASuccessor(pred, t) and - if t instanceof DirectSuccessor then s = "" else s = t.toString() - | - s, ", " order by s - ) + label = strictconcat(string s | succ = getASuccessor(pred, s) | s, ", " order by s) } /** - * Provides logic for representing a CFG as a [Mermaid diagram](https://mermaid.js.org/). + * Provides logic for representing a graph as a [Mermaid diagram](https://mermaid.js.org/). */ module Mermaid { private string nodeId(RelevantNode n) { @@ -103,8 +96,8 @@ module PrintGraph Input> { } } - /** Provides the input to `ViewCfgQuery`. */ - signature module ViewCfgQueryInputSig { + /** Provides the input to `ViewGraphQuery`. */ + signature module ViewGraphQueryInputSig { /** Gets the source file selected in the IDE. Should be an `external` predicate. */ string selectedSourceFile(); @@ -118,15 +111,15 @@ module PrintGraph Input> { * Holds if `callable` spans column `startColumn` of line `startLine` to * column `endColumn` of line `endLine` in `file`. */ - predicate cfgScopeSpan( + predicate callableSpan( Callable callable, File file, int startLine, int startColumn, int endLine, int endColumn ); } /** - * Provides an implementation for a `View CFG` query. + * Provides an implementation for a `View CFG` or `View DFG` query. * - * Import this module into a `.ql` that looks like + * Import this module into a `.ql` that looks like (for the `View CFG` query): * * ```ql * @name Print CFG @@ -136,15 +129,17 @@ module PrintGraph Input> { * @kind graph * @tags ide-contextual-queries/print-cfg * ``` + * + * For the `View DFG` query replace "cfg" with "dfg" above and "control flow" with "data flow". */ - module ViewCfgQuery ViewCfgQueryInput> { - private import ViewCfgQueryInput + module ViewGraphQuery ViewGraphQueryInput> { + private import ViewGraphQueryInput bindingset[file, line, column] private Callable smallestEnclosingScope(File file, int line, int column) { result = min(Callable callable, int startLine, int startColumn, int endLine, int endColumn | - cfgScopeSpan(callable, file, startLine, startColumn, endLine, endColumn) and + callableSpan(callable, file, startLine, startColumn, endLine, endColumn) and ( startLine < line or @@ -162,9 +157,9 @@ module PrintGraph Input> { private import IdeContextual - final private class FinalControlFlowNode = ControlFlowNode; + final private class FinalNode = Node; - private class RelevantNode extends FinalControlFlowNode { + private class RelevantNode extends FinalNode { RelevantNode() { this.getEnclosingCallable() = smallestEnclosingScope(getFileBySourceArchiveName(selectedSourceFile()), @@ -178,7 +173,7 @@ module PrintGraph Input> { import Output::Mermaid - /** Holds if `pred` -> `succ` is an edge in the CFG. */ + /** Holds if `pred` -> `succ` is an edge in the graph. */ query predicate edges(RelevantNode pred, RelevantNode succ, string attr, string val) { attr = "semmle.label" and Output::edges(pred, succ, val) From dc2c8f3a9cd72fd0fe9ffdc5b0ac9968610586d3 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 23 Feb 2026 13:10:55 +0100 Subject: [PATCH 2/7] Update PrintCfg queries to use new interface --- java/ql/lib/printCfg.ql | 7 ++++--- .../lib/semmle/code/java/ControlFlowGraph.qll | 20 +++++++++++++++---- .../ql/lib/ide-contextual-queries/printCfg.ql | 7 ++++--- .../ql/lib/ide-contextual-queries/PrintCfg.ql | 7 ++++--- shared/controlflow/codeql/controlflow/Cfg.qll | 5 ++++- .../swift/controlflow/internal/PrintCFG.ql | 6 +++--- 6 files changed, 35 insertions(+), 17 deletions(-) diff --git a/java/ql/lib/printCfg.ql b/java/ql/lib/printCfg.ql index 5e3cc22644ef..b176918ffa33 100644 --- a/java/ql/lib/printCfg.ql +++ b/java/ql/lib/printCfg.ql @@ -8,6 +8,7 @@ */ import java +import PrintCfg external string selectedSourceFile(); @@ -21,14 +22,14 @@ external int selectedSourceColumn(); private predicate selectedSourceColumnAlias = selectedSourceColumn/0; -module ViewCfgQueryInput implements ViewCfgQueryInputSig { +module ViewCfgQueryInput implements ViewGraphQueryInputSig { predicate selectedSourceFile = selectedSourceFileAlias/0; predicate selectedSourceLine = selectedSourceLineAlias/0; predicate selectedSourceColumn = selectedSourceColumnAlias/0; - predicate cfgScopeSpan( + predicate callableSpan( Callable callable, File file, int startLine, int startColumn, int endLine, int endColumn ) { file = callable.getFile() and @@ -42,4 +43,4 @@ module ViewCfgQueryInput implements ViewCfgQueryInputSig { } } -import ViewCfgQuery +import ViewGraphQuery diff --git a/java/ql/lib/semmle/code/java/ControlFlowGraph.qll b/java/ql/lib/semmle/code/java/ControlFlowGraph.qll index 64449b6f93d7..f477651b15db 100644 --- a/java/ql/lib/semmle/code/java/ControlFlowGraph.qll +++ b/java/ql/lib/semmle/code/java/ControlFlowGraph.qll @@ -1776,16 +1776,28 @@ class ConditionNode extends ControlFlow::Node { ExprParent getCondition() { result = this.asExpr() or result = this.asStmt() } } -private import codeql.controlflow.PrintGraph as PrintGraph +private import codeql.util.PrintGraph as PrintGraph private module PrintGraphInput implements PrintGraph::InputSig { private import java as J class Callable = J::Callable; - class ControlFlowNode = J::ControlFlowNode; + final private class FinalControlFlowNode = J::ControlFlowNode; - ControlFlowNode getASuccessor(ControlFlowNode n, SuccessorType t) { result = n.getASuccessor(t) } + class Node extends FinalControlFlowNode { + string getOrderDisambiguation() { result = "" } + } + + predicate edge(Node node1, string s, Node node2) { + exists(SuccessorType t | + node2 = node1.getASuccessor(t) and + if t instanceof DirectSuccessor then s = "" else s = t.toString() + ) + } } -import PrintGraph::PrintGraph +/** Provides utilities for visualising the CFG. */ +module PrintCfg { + import PrintGraph::PrintGraph +} diff --git a/ruby/ql/lib/ide-contextual-queries/printCfg.ql b/ruby/ql/lib/ide-contextual-queries/printCfg.ql index 1c4cec61a3ef..d6f5dbbcd35f 100644 --- a/ruby/ql/lib/ide-contextual-queries/printCfg.ql +++ b/ruby/ql/lib/ide-contextual-queries/printCfg.ql @@ -10,6 +10,7 @@ private import codeql.Locations private import codeql.ruby.controlflow.internal.ControlFlowGraphImpl private import codeql.ruby.controlflow.ControlFlowGraph +private import PrintCfg external string selectedSourceFile(); @@ -23,14 +24,14 @@ external int selectedSourceColumn(); private predicate selectedSourceColumnAlias = selectedSourceColumn/0; -module ViewCfgQueryInput implements ViewCfgQueryInputSig { +module ViewCfgQueryInput implements ViewGraphQueryInputSig { predicate selectedSourceFile = selectedSourceFileAlias/0; predicate selectedSourceLine = selectedSourceLineAlias/0; predicate selectedSourceColumn = selectedSourceColumnAlias/0; - predicate cfgScopeSpan( + predicate callableSpan( CfgScope scope, File file, int startLine, int startColumn, int endLine, int endColumn ) { file = scope.getFile() and @@ -38,4 +39,4 @@ module ViewCfgQueryInput implements ViewCfgQueryInputSig { } } -import ViewCfgQuery +import ViewGraphQuery diff --git a/rust/ql/lib/ide-contextual-queries/PrintCfg.ql b/rust/ql/lib/ide-contextual-queries/PrintCfg.ql index e7b25ea8df8e..8159daa22808 100644 --- a/rust/ql/lib/ide-contextual-queries/PrintCfg.ql +++ b/rust/ql/lib/ide-contextual-queries/PrintCfg.ql @@ -10,6 +10,7 @@ private import codeql.files.FileSystem private import codeql.rust.controlflow.internal.ControlFlowGraphImpl private import codeql.rust.controlflow.ControlFlowGraph +private import PrintCfg /** * Gets the source file to generate a CFG from. @@ -32,14 +33,14 @@ external int selectedSourceColumn(); private predicate selectedSourceColumnAlias = selectedSourceColumn/0; -private module ViewCfgQueryInput implements ViewCfgQueryInputSig { +private module ViewCfgQueryInput implements ViewGraphQueryInputSig { predicate selectedSourceFile = selectedSourceFileAlias/0; predicate selectedSourceLine = selectedSourceLineAlias/0; predicate selectedSourceColumn = selectedSourceColumnAlias/0; - predicate cfgScopeSpan( + predicate callableSpan( CfgScope scope, File file, int startLine, int startColumn, int endLine, int endColumn ) { file = scope.getFile() and @@ -47,4 +48,4 @@ private module ViewCfgQueryInput implements ViewCfgQueryInputSig { } } -import ViewCfgQuery +import ViewGraphQuery diff --git a/shared/controlflow/codeql/controlflow/Cfg.qll b/shared/controlflow/codeql/controlflow/Cfg.qll index 74b52629f8fc..b87785cda0fd 100644 --- a/shared/controlflow/codeql/controlflow/Cfg.qll +++ b/shared/controlflow/codeql/controlflow/Cfg.qll @@ -1330,7 +1330,10 @@ module MakeWithSplitting< } } - import Pp::PrintGraph + /** Provides utilities for visualising the CFG. */ + module PrintCfg { + import Pp::PrintGraph + } /** Provides a set of consistency queries. */ module Consistency { diff --git a/swift/ql/lib/codeql/swift/controlflow/internal/PrintCFG.ql b/swift/ql/lib/codeql/swift/controlflow/internal/PrintCFG.ql index 2f9a0572111c..58c742a71e53 100644 --- a/swift/ql/lib/codeql/swift/controlflow/internal/PrintCFG.ql +++ b/swift/ql/lib/codeql/swift/controlflow/internal/PrintCFG.ql @@ -33,14 +33,14 @@ external int selectedSourceColumn(); private predicate selectedSourceColumnAlias = selectedSourceColumn/0; -module ViewCfgQueryInput implements Impl::ViewCfgQueryInputSig { +module ViewCfgQueryInput implements Impl::PrintCfg::ViewGraphQueryInputSig { predicate selectedSourceFile = selectedSourceFileAlias/0; predicate selectedSourceLine = selectedSourceLineAlias/0; predicate selectedSourceColumn = selectedSourceColumnAlias/0; - predicate cfgScopeSpan( + predicate callableSpan( CfgInput::CfgScope scope, File file, int startLine, int startColumn, int endLine, int endColumn ) { file = scope.getFile() and @@ -48,4 +48,4 @@ module ViewCfgQueryInput implements Impl::ViewCfgQueryInputSig { } } -import Impl::ViewCfgQuery +import Impl::PrintCfg::ViewGraphQuery From 2017f84b79eb804f5f55566821b1bc9d5c0f4323 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 23 Feb 2026 11:47:41 +0100 Subject: [PATCH 3/7] Add getOrderDisambiguation to signature and use it --- shared/controlflow/codeql/controlflow/Cfg.qll | 4 +++- .../controlflow/codeql/controlflow/PrintGraph.qll | 13 +++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/shared/controlflow/codeql/controlflow/Cfg.qll b/shared/controlflow/codeql/controlflow/Cfg.qll index b87785cda0fd..f3eb535fce4c 100644 --- a/shared/controlflow/codeql/controlflow/Cfg.qll +++ b/shared/controlflow/codeql/controlflow/Cfg.qll @@ -1320,7 +1320,9 @@ module MakeWithSplitting< private module PrintGraphInput implements Pp::InputSig { class Callable = CfgScope; - class Node = FinalNode; + class Node extends FinalNode { + string getOrderDisambiguation() { result = "" } + } Node getASuccessor(Node n, string s) { exists(SuccessorType t | diff --git a/shared/controlflow/codeql/controlflow/PrintGraph.qll b/shared/controlflow/codeql/controlflow/PrintGraph.qll index 85b474ffbaa4..5b34818c9c2e 100644 --- a/shared/controlflow/codeql/controlflow/PrintGraph.qll +++ b/shared/controlflow/codeql/controlflow/PrintGraph.qll @@ -18,6 +18,9 @@ signature module InputSig { Location getLocation(); string toString(); + + /** Gets a string to distinguish nodes that have the same location and toString value. */ + string getOrderDisambiguation(); } Node getASuccessor(Node n, string label); @@ -53,7 +56,10 @@ module PrintGraph Input> { p.getLocation() .hasLocationInfo(filePath, startLine, startColumn, endLine, endColumn) | - p order by filePath, startLine, startColumn, endLine, endColumn, p.toString() + p + order by + filePath, startLine, startColumn, endLine, endColumn, p.toString(), + p.getOrderDisambiguation() ) ).toString() } @@ -87,7 +93,8 @@ module PrintGraph Input> { | edge, "\n" order by - filePath, startLine, startColumn, endLine, endColumn, pred.toString() + filePath, startLine, startColumn, endLine, endColumn, pred.toString(), + pred.getOrderDisambiguation() ) } @@ -165,8 +172,6 @@ module PrintGraph Input> { smallestEnclosingScope(getFileBySourceArchiveName(selectedSourceFile()), selectedSourceLine(), selectedSourceColumn()) } - - string getOrderDisambiguation() { result = "" } } private module Output = TestOutput; From 71f4436350091a5159ac8b2780b2413b4ca76007 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 23 Feb 2026 11:49:11 +0100 Subject: [PATCH 4/7] Move PrintGraph to codeql.util --- shared/controlflow/codeql/controlflow/Cfg.qll | 2 +- .../codeql/controlflow => util/codeql/util}/PrintGraph.qll | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename shared/{controlflow/codeql/controlflow => util/codeql/util}/PrintGraph.qll (100%) diff --git a/shared/controlflow/codeql/controlflow/Cfg.qll b/shared/controlflow/codeql/controlflow/Cfg.qll index f3eb535fce4c..7f7007d54a2a 100644 --- a/shared/controlflow/codeql/controlflow/Cfg.qll +++ b/shared/controlflow/codeql/controlflow/Cfg.qll @@ -1313,7 +1313,7 @@ module MakeWithSplitting< } } - private import PrintGraph as Pp + private import codeql.util.PrintGraph as Pp final private class FinalNode = Node; diff --git a/shared/controlflow/codeql/controlflow/PrintGraph.qll b/shared/util/codeql/util/PrintGraph.qll similarity index 100% rename from shared/controlflow/codeql/controlflow/PrintGraph.qll rename to shared/util/codeql/util/PrintGraph.qll From aa587c0ef6810fcd7a611e52019b15bea41ed32f Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 23 Feb 2026 11:56:36 +0100 Subject: [PATCH 5/7] Refactor 'getASuccessor' to edges/3 This interface works better when defining the DFG edges in the next commit --- shared/controlflow/codeql/controlflow/Cfg.qll | 6 +++--- shared/util/codeql/util/PrintGraph.qll | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/shared/controlflow/codeql/controlflow/Cfg.qll b/shared/controlflow/codeql/controlflow/Cfg.qll index 7f7007d54a2a..0cff98ef4be9 100644 --- a/shared/controlflow/codeql/controlflow/Cfg.qll +++ b/shared/controlflow/codeql/controlflow/Cfg.qll @@ -1324,10 +1324,10 @@ module MakeWithSplitting< string getOrderDisambiguation() { result = "" } } - Node getASuccessor(Node n, string s) { + predicate edge(Node node1, string label, Node node2) { exists(SuccessorType t | - result = n.getASuccessor(t) and - if t instanceof DirectSuccessor then s = "" else s = t.toString() + node2 = node1.getASuccessor(t) and + if t instanceof DirectSuccessor then label = "" else label = t.toString() ) } } diff --git a/shared/util/codeql/util/PrintGraph.qll b/shared/util/codeql/util/PrintGraph.qll index 5b34818c9c2e..bbeb9332ed8c 100644 --- a/shared/util/codeql/util/PrintGraph.qll +++ b/shared/util/codeql/util/PrintGraph.qll @@ -23,7 +23,7 @@ signature module InputSig { string getOrderDisambiguation(); } - Node getASuccessor(Node n, string label); + predicate edge(Node node1, string label, Node node2); } /** Provides modules for printing flow graphs. */ @@ -40,7 +40,7 @@ module PrintGraph Input> { module TestOutput { /** Holds if `pred -> succ` is an edge in the graph. */ query predicate edges(RelevantNode pred, RelevantNode succ, string label) { - label = strictconcat(string s | succ = getASuccessor(pred, s) | s, ", " order by s) + label = strictconcat(string s | edge(pred, s, succ) | s, ", " order by s) } /** From 61ae276a5337d98e93712fcadcaff6c96c84b11d Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 23 Feb 2026 13:05:13 +0100 Subject: [PATCH 6/7] Add PrintDfg.qll Adding this directly in the DataFlow module would expose it publicly via the `DataFlow::` prefix which does not seem desirable. We just want to be able to access it ourselves, so I've put it in its own file. --- shared/dataflow/codeql/dataflow/DataFlow.qll | 6 +++ shared/dataflow/codeql/dataflow/PrintDfg.qll | 45 ++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 shared/dataflow/codeql/dataflow/PrintDfg.qll diff --git a/shared/dataflow/codeql/dataflow/DataFlow.qll b/shared/dataflow/codeql/dataflow/DataFlow.qll index 7f9c0194374b..3a7afd7e873e 100644 --- a/shared/dataflow/codeql/dataflow/DataFlow.qll +++ b/shared/dataflow/codeql/dataflow/DataFlow.qll @@ -361,6 +361,12 @@ signature module InputSig { * visible. */ default predicate isEvaluatingInOverlay() { none() } + + /** + * Gets a string to distinguish nodes that have the same location and toString value, + * for use when generating graphs with `PrintDfg.qll`. + */ + default string nodeGetOrderDisambiguation(Node node) { result = "" } } module Configs Lang> { diff --git a/shared/dataflow/codeql/dataflow/PrintDfg.qll b/shared/dataflow/codeql/dataflow/PrintDfg.qll new file mode 100644 index 000000000000..5b3a836d7050 --- /dev/null +++ b/shared/dataflow/codeql/dataflow/PrintDfg.qll @@ -0,0 +1,45 @@ +/** + * Provides a module for implementing the `View DFG` query based on inputs to the data flow library. + */ + +private import codeql.util.Location +private import codeql.dataflow.DataFlow as DF +private import codeql.dataflow.TaintTracking as TT + +module MakePrintDfg< + LocationSig Location, DF::InputSig DataFlowLang, + TT::InputSig TaintTrackingLang> +{ + private import DataFlowLang + private import codeql.util.PrintGraph as Pp + + final private class FinalNode = Node; + + private module PrintGraphInput implements Pp::InputSig { + class Callable = DataFlowLang::DataFlowCallable; + + class Node extends FinalNode { + string getOrderDisambiguation() { result = DataFlowLang::nodeGetOrderDisambiguation(this) } + + Callable getEnclosingCallable() { result = DataFlowLang::nodeGetEnclosingCallable(this) } + } + + predicate edge(Node node1, string label, Node node2) { + simpleLocalFlowStep(node1, node2, _) and label = "value" + or + jumpStep(node1, node2) and label = "jump" + or + TaintTrackingLang::defaultAdditionalTaintStep(node1, node2, _) and label = "taint" + or + exists(ContentSet c | + readStep(node1, c, node2) and label = "read[" + c.toString() + "]" + or + storeStep(node1, c, node2) and label = "store[" + c.toString() + "]" + ) + or + node1 = node2.(PostUpdateNode).getPreUpdateNode() and label = "post-update" + } + } + + import Pp::PrintGraph +} From c236ace5e83b935ee781df6d979c7e12f7248972 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 23 Feb 2026 13:05:26 +0100 Subject: [PATCH 7/7] Add 'View DFG' queries for JS, Java, Ruby, C#, Rust --- csharp/ql/lib/printDfg.ql | 53 +++++++++++++++++++ java/ql/lib/printDfg.ql | 50 +++++++++++++++++ javascript/ql/lib/printDfg.ql | 48 +++++++++++++++++ .../ql/lib/ide-contextual-queries/printDfg.ql | 44 +++++++++++++++ .../ql/lib/ide-contextual-queries/PrintDfg.ql | 44 +++++++++++++++ 5 files changed, 239 insertions(+) create mode 100644 csharp/ql/lib/printDfg.ql create mode 100644 java/ql/lib/printDfg.ql create mode 100644 javascript/ql/lib/printDfg.ql create mode 100644 ruby/ql/lib/ide-contextual-queries/printDfg.ql create mode 100644 rust/ql/lib/ide-contextual-queries/PrintDfg.ql diff --git a/csharp/ql/lib/printDfg.ql b/csharp/ql/lib/printDfg.ql new file mode 100644 index 000000000000..8d8b6f9a4fa7 --- /dev/null +++ b/csharp/ql/lib/printDfg.ql @@ -0,0 +1,53 @@ +/** + * @name Print DFG + * @description Produces a representation of a file's Data Flow Graph. + * This query is used by the VS Code extension. + * @id cs/print-dfg + * @kind graph + * @tags ide-contextual-queries/print-dfg + */ + +import csharp +private import semmle.code.csharp.dataflow.internal.DataFlowImplSpecific as DF +private import semmle.code.csharp.dataflow.internal.TaintTrackingImplSpecific as TT +private import codeql.dataflow.PrintDfg +private import MakePrintDfg + +external string selectedSourceFile(); + +private predicate selectedSourceFileAlias = selectedSourceFile/0; + +external int selectedSourceLine(); + +private predicate selectedSourceLineAlias = selectedSourceLine/0; + +external int selectedSourceColumn(); + +private predicate selectedSourceColumnAlias = selectedSourceColumn/0; + +module ViewDfgQueryInput implements ViewGraphQueryInputSig { + predicate selectedSourceFile = selectedSourceFileAlias/0; + + predicate selectedSourceLine = selectedSourceLineAlias/0; + + predicate selectedSourceColumn = selectedSourceColumnAlias/0; + + predicate callableSpan( + DF::CsharpDataFlow::DataFlowCallable callable, File file, int startLine, int startColumn, + int endLine, int endColumn + ) { + exists(Callable c | + c = callable.asCallable(_) and + file = c.getFile() and + callable.getLocation().getStartLine() = startLine and + callable.getLocation().getStartColumn() = startColumn and + exists(Location loc | + loc.getEndLine() = endLine and + loc.getEndColumn() = endColumn and + loc = c.getBody().getLocation() + ) + ) + } +} + +import ViewGraphQuery diff --git a/java/ql/lib/printDfg.ql b/java/ql/lib/printDfg.ql new file mode 100644 index 000000000000..6913c9407d7d --- /dev/null +++ b/java/ql/lib/printDfg.ql @@ -0,0 +1,50 @@ +/** + * @name Print DFG + * @description Produces a representation of a file's Data Flow Graph. + * This query is used by the VS Code extension. + * @id java/print-cfg + * @kind graph + * @tags ide-contextual-queries/print-dfg + */ + +import java +private import semmle.code.java.dataflow.internal.DataFlowImplSpecific as DF +private import semmle.code.java.dataflow.internal.TaintTrackingImplSpecific as TT +private import codeql.dataflow.PrintDfg +private import MakePrintDfg + +external string selectedSourceFile(); + +private predicate selectedSourceFileAlias = selectedSourceFile/0; + +external int selectedSourceLine(); + +private predicate selectedSourceLineAlias = selectedSourceLine/0; + +external int selectedSourceColumn(); + +private predicate selectedSourceColumnAlias = selectedSourceColumn/0; + +module ViewDfgQueryInput implements ViewGraphQueryInputSig { + predicate selectedSourceFile = selectedSourceFileAlias/0; + + predicate selectedSourceLine = selectedSourceLineAlias/0; + + predicate selectedSourceColumn = selectedSourceColumnAlias/0; + + predicate callableSpan( + DF::JavaDataFlow::DataFlowCallable callable, File file, int startLine, int startColumn, + int endLine, int endColumn + ) { + file = callable.asCallable().getFile() and + callable.getLocation().getStartLine() = startLine and + callable.getLocation().getStartColumn() = startColumn and + exists(Location loc | + loc.getEndLine() = endLine and + loc.getEndColumn() = endColumn and + loc = callable.asCallable().getBody().getLocation() + ) + } +} + +import ViewGraphQuery diff --git a/javascript/ql/lib/printDfg.ql b/javascript/ql/lib/printDfg.ql new file mode 100644 index 000000000000..94f1e4bdf0f4 --- /dev/null +++ b/javascript/ql/lib/printDfg.ql @@ -0,0 +1,48 @@ +/** + * @name Print DFG + * @description Produces a representation of a file's Data Flow Graph. + * This query is used by the VS Code extension. + * @id js/print-dfg + * @kind graph + * @tags ide-contextual-queries/print-dfg + */ + +private import javascript +private import semmle.javascript.dataflow.internal.sharedlib.DataFlowArg +private import codeql.dataflow.PrintDfg +import MakePrintDfg + +external string selectedSourceFile(); + +private predicate selectedSourceFileAlias = selectedSourceFile/0; + +external int selectedSourceLine(); + +private predicate selectedSourceLineAlias = selectedSourceLine/0; + +external int selectedSourceColumn(); + +private predicate selectedSourceColumnAlias = selectedSourceColumn/0; + +module ViewCfgQueryInput implements ViewGraphQueryInputSig { + predicate selectedSourceFile = selectedSourceFileAlias/0; + + predicate selectedSourceLine = selectedSourceLineAlias/0; + + predicate selectedSourceColumn = selectedSourceColumnAlias/0; + + /** + * Holds if `callable` spans column `startColumn` of line `startLine` to + * column `endColumn` of line `endLine` in `file`. + */ + predicate callableSpan( + JSDataFlow::DataFlowCallable callable, File file, int startLine, int startColumn, int endLine, + int endColumn + ) { + callable + .getLocation() + .hasLocationInfo(file.getAbsolutePath(), startLine, startColumn, endLine, endColumn) + } +} + +import ViewGraphQuery diff --git a/ruby/ql/lib/ide-contextual-queries/printDfg.ql b/ruby/ql/lib/ide-contextual-queries/printDfg.ql new file mode 100644 index 000000000000..731925fe7d7c --- /dev/null +++ b/ruby/ql/lib/ide-contextual-queries/printDfg.ql @@ -0,0 +1,44 @@ +/** + * @name Print DFG + * @description Produces a representation of a file's Data Flow Graph. + * This query is used by the VS Code extension. + * @id rb/print-dfg + * @kind graph + * @tags ide-contextual-queries/print-dfg + */ + +private import codeql.Locations +private import codeql.ruby.dataflow.internal.DataFlowImplSpecific as DF +private import codeql.ruby.dataflow.internal.TaintTrackingImplSpecific as TT +private import codeql.dataflow.PrintDfg +private import MakePrintDfg + +external string selectedSourceFile(); + +private predicate selectedSourceFileAlias = selectedSourceFile/0; + +external int selectedSourceLine(); + +private predicate selectedSourceLineAlias = selectedSourceLine/0; + +external int selectedSourceColumn(); + +private predicate selectedSourceColumnAlias = selectedSourceColumn/0; + +module ViewDfgQueryInput implements ViewGraphQueryInputSig { + predicate selectedSourceFile = selectedSourceFileAlias/0; + + predicate selectedSourceLine = selectedSourceLineAlias/0; + + predicate selectedSourceColumn = selectedSourceColumnAlias/0; + + predicate callableSpan( + DF::RubyDataFlow::DataFlowCallable callable, File file, int startLine, int startColumn, + int endLine, int endColumn + ) { + file = callable.asCfgScope().getFile() and + callable.getLocation().hasLocationInfo(_, startLine, startColumn, endLine, endColumn) + } +} + +import ViewGraphQuery diff --git a/rust/ql/lib/ide-contextual-queries/PrintDfg.ql b/rust/ql/lib/ide-contextual-queries/PrintDfg.ql new file mode 100644 index 000000000000..8121bfbbbab2 --- /dev/null +++ b/rust/ql/lib/ide-contextual-queries/PrintDfg.ql @@ -0,0 +1,44 @@ +/** + * @name Print DFG + * @description Produces a representation of a file's Data Flow Graph. + * This query is used by the VS Code extension. + * @id rust/print-dfg + * @kind graph + * @tags ide-contextual-queries/print-dfg + */ + +private import rust +private import codeql.rust.dataflow.internal.DataFlowImpl as DF +private import codeql.rust.dataflow.internal.TaintTrackingImpl as TT +private import codeql.dataflow.PrintDfg +private import MakePrintDfg + +external string selectedSourceFile(); + +private predicate selectedSourceFileAlias = selectedSourceFile/0; + +external int selectedSourceLine(); + +private predicate selectedSourceLineAlias = selectedSourceLine/0; + +external int selectedSourceColumn(); + +private predicate selectedSourceColumnAlias = selectedSourceColumn/0; + +private module ViewDfgQueryInput implements ViewGraphQueryInputSig { + predicate selectedSourceFile = selectedSourceFileAlias/0; + + predicate selectedSourceLine = selectedSourceLineAlias/0; + + predicate selectedSourceColumn = selectedSourceColumnAlias/0; + + predicate callableSpan( + DF::RustDataFlow::DataFlowCallable callable, File file, int startLine, int startColumn, + int endLine, int endColumn + ) { + file = callable.asCfgScope().getFile() and + callable.getLocation().hasLocationInfo(_, startLine, startColumn, endLine, endColumn) + } +} + +import ViewGraphQuery