codeql-development-mcp-server 2.24.3 → 2.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/dist/codeql-development-mcp-server.js +48111 -49526
  2. package/dist/codeql-development-mcp-server.js.map +4 -4
  3. package/package.json +9 -9
  4. package/ql/actions/tools/src/PrintCFG/PrintCFG.ql +1 -3
  5. package/ql/actions/tools/src/codeql-pack.lock.yml +14 -14
  6. package/ql/actions/tools/src/codeql-pack.yml +2 -2
  7. package/ql/cpp/tools/src/CallGraphFrom/CallGraphFrom.ql +6 -20
  8. package/ql/cpp/tools/src/CallGraphFromTo/CallGraphFromTo.md +47 -0
  9. package/ql/cpp/tools/src/CallGraphFromTo/CallGraphFromTo.ql +77 -0
  10. package/ql/cpp/tools/src/CallGraphTo/CallGraphTo.ql +6 -20
  11. package/ql/cpp/tools/src/ExternalPredicates.qll +14 -0
  12. package/ql/cpp/tools/src/PrintAST/PrintAST.ql +9 -20
  13. package/ql/cpp/tools/src/PrintCFG/PrintCFG.ql +1 -3
  14. package/ql/cpp/tools/src/codeql-pack.lock.yml +12 -12
  15. package/ql/cpp/tools/src/codeql-pack.yml +2 -2
  16. package/ql/csharp/tools/src/CallGraphFrom/CallGraphFrom.ql +4 -19
  17. package/ql/csharp/tools/src/CallGraphFromTo/CallGraphFromTo.md +49 -0
  18. package/ql/csharp/tools/src/CallGraphFromTo/CallGraphFromTo.ql +64 -0
  19. package/ql/csharp/tools/src/CallGraphTo/CallGraphTo.ql +4 -19
  20. package/ql/csharp/tools/src/ExternalPredicates.qll +14 -0
  21. package/ql/csharp/tools/src/PrintAST/PrintAST.ql +9 -17
  22. package/ql/csharp/tools/src/codeql-pack.lock.yml +10 -10
  23. package/ql/csharp/tools/src/codeql-pack.yml +2 -2
  24. package/ql/go/tools/src/CallGraphFrom/CallGraphFrom.ql +4 -19
  25. package/ql/go/tools/src/CallGraphFromTo/CallGraphFromTo.md +47 -0
  26. package/ql/go/tools/src/CallGraphFromTo/CallGraphFromTo.ql +53 -0
  27. package/ql/go/tools/src/CallGraphTo/CallGraphTo.ql +4 -20
  28. package/ql/go/tools/src/ExternalPredicates.qll +14 -0
  29. package/ql/go/tools/src/PrintAST/PrintAST.ql +132 -22
  30. package/ql/go/tools/src/codeql-pack.lock.yml +10 -10
  31. package/ql/go/tools/src/codeql-pack.yml +2 -2
  32. package/ql/java/tools/src/CallGraphFrom/CallGraphFrom.ql +4 -19
  33. package/ql/java/tools/src/CallGraphFromTo/CallGraphFromTo.md +49 -0
  34. package/ql/java/tools/src/CallGraphFromTo/CallGraphFromTo.ql +64 -0
  35. package/ql/java/tools/src/CallGraphTo/CallGraphTo.ql +4 -19
  36. package/ql/java/tools/src/ExternalPredicates.qll +14 -0
  37. package/ql/java/tools/src/PrintAST/PrintAST.ql +9 -17
  38. package/ql/java/tools/src/PrintCFG/PrintCFG.ql +11 -10
  39. package/ql/java/tools/src/codeql-pack.lock.yml +14 -14
  40. package/ql/java/tools/src/codeql-pack.yml +2 -2
  41. package/ql/javascript/tools/src/CallGraphFrom/CallGraphFrom.ql +4 -19
  42. package/ql/javascript/tools/src/CallGraphFromTo/CallGraphFromTo.md +47 -0
  43. package/ql/javascript/tools/src/CallGraphFromTo/CallGraphFromTo.ql +69 -0
  44. package/ql/javascript/tools/src/CallGraphTo/CallGraphTo.ql +4 -20
  45. package/ql/javascript/tools/src/ExternalPredicates.qll +14 -0
  46. package/ql/javascript/tools/src/PrintAST/PrintAST.ql +9 -20
  47. package/ql/javascript/tools/src/PrintCFG/PrintCFG.ql +1 -3
  48. package/ql/javascript/tools/src/codeql-pack.lock.yml +13 -13
  49. package/ql/javascript/tools/src/codeql-pack.yml +2 -2
  50. package/ql/python/tools/src/CallGraphFrom/CallGraphFrom.ql +3 -17
  51. package/ql/python/tools/src/CallGraphFromTo/CallGraphFromTo.md +46 -0
  52. package/ql/python/tools/src/CallGraphFromTo/CallGraphFromTo.ql +71 -0
  53. package/ql/python/tools/src/CallGraphTo/CallGraphTo.ql +6 -22
  54. package/ql/python/tools/src/ExternalPredicates.qll +14 -0
  55. package/ql/python/tools/src/PrintAST/PrintAST.ql +9 -20
  56. package/ql/python/tools/src/PrintCFG/PrintCFG.ql +1 -3
  57. package/ql/python/tools/src/codeql-pack.lock.yml +13 -13
  58. package/ql/python/tools/src/codeql-pack.yml +2 -2
  59. package/ql/ruby/tools/src/CallGraphFrom/CallGraphFrom.ql +4 -19
  60. package/ql/ruby/tools/src/CallGraphFromTo/CallGraphFromTo.md +48 -0
  61. package/ql/ruby/tools/src/CallGraphFromTo/CallGraphFromTo.ql +50 -0
  62. package/ql/ruby/tools/src/CallGraphTo/CallGraphTo.ql +4 -20
  63. package/ql/ruby/tools/src/ExternalPredicates.qll +14 -0
  64. package/ql/ruby/tools/src/PrintAST/PrintAST.ql +9 -17
  65. package/ql/ruby/tools/src/PrintCFG/PrintCFG.ql +1 -3
  66. package/ql/ruby/tools/src/codeql-pack.lock.yml +10 -10
  67. package/ql/ruby/tools/src/codeql-pack.yml +2 -2
  68. package/ql/swift/tools/src/CallGraphFrom/CallGraphFrom.ql +7 -16
  69. package/ql/swift/tools/src/CallGraphFromTo/CallGraphFromTo.md +47 -0
  70. package/ql/swift/tools/src/CallGraphFromTo/CallGraphFromTo.ql +80 -0
  71. package/ql/swift/tools/src/CallGraphTo/CallGraphTo.ql +8 -14
  72. package/ql/swift/tools/src/ExternalPredicates.qll +14 -0
  73. package/ql/swift/tools/src/PrintAST/PrintAST.ql +5 -15
  74. package/ql/swift/tools/src/PrintCFG/PrintCFG.ql +5 -15
  75. package/ql/swift/tools/src/codeql-pack.lock.yml +10 -10
  76. package/ql/swift/tools/src/codeql-pack.yml +2 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeql-development-mcp-server",
3
- "version": "2.24.3",
3
+ "version": "2.25.0",
4
4
  "description": "An MCP server supporting LLM requests for CodeQL development tools and resources.",
5
5
  "main": "dist/codeql-development-mcp-server.js",
6
6
  "type": "module",
@@ -55,7 +55,7 @@
55
55
  "npm": ">=11.6.2"
56
56
  },
57
57
  "dependencies": {
58
- "@modelcontextprotocol/sdk": "^1.27.1",
58
+ "@modelcontextprotocol/sdk": "^1.28.0",
59
59
  "adm-zip": "^0.5.16",
60
60
  "cors": "^2.8.6",
61
61
  "dotenv": "^17.3.1",
@@ -66,20 +66,20 @@
66
66
  },
67
67
  "devDependencies": {
68
68
  "@eslint/js": "^10.0.1",
69
- "@types/adm-zip": "^0.5.7",
69
+ "@types/adm-zip": "^0.5.8",
70
70
  "@types/cors": "^2.8.19",
71
71
  "@types/express": "^5.0.6",
72
72
  "@types/js-yaml": "^4.0.9",
73
- "@types/node": "^25.3.5",
74
- "@vitest/coverage-v8": "^4.0.18",
75
- "esbuild": "^0.27.3",
76
- "eslint": "^10.0.3",
73
+ "@types/node": "^25.5.0",
74
+ "@vitest/coverage-v8": "^4.1.2",
75
+ "esbuild": "^0.27.4",
76
+ "eslint": "^10.1.0",
77
77
  "eslint-config-prettier": "^10.1.8",
78
78
  "eslint-plugin-prettier": "^5.5.5",
79
79
  "prettier": "^3.8.1",
80
80
  "typescript": "^5.9.3",
81
- "typescript-eslint": "^8.56.1",
82
- "vitest": "^4.0.18"
81
+ "typescript-eslint": "^8.57.2",
82
+ "vitest": "^4.1.2"
83
83
  },
84
84
  "scripts": {
85
85
  "build": "npm run clean && npm run lint && npm run bundle",
@@ -18,6 +18,4 @@ query predicate nodes(Node node, string property, string value) {
18
18
  value = node.toString()
19
19
  }
20
20
 
21
- query predicate edges(Node pred, Node succ) {
22
- pred.getASuccessor() = succ
23
- }
21
+ query predicate edges(Node pred, Node succ) { pred.getASuccessor() = succ }
@@ -2,31 +2,31 @@
2
2
  lockVersion: 1.0.0
3
3
  dependencies:
4
4
  codeql/actions-all:
5
- version: 0.4.27
5
+ version: 0.4.30
6
6
  codeql/concepts:
7
- version: 0.0.15
7
+ version: 0.0.18
8
8
  codeql/controlflow:
9
- version: 2.0.25
9
+ version: 2.0.28
10
10
  codeql/dataflow:
11
- version: 2.0.25
11
+ version: 2.1.0
12
12
  codeql/javascript-all:
13
- version: 2.6.21
13
+ version: 2.6.24
14
14
  codeql/mad:
15
- version: 1.0.41
15
+ version: 1.0.44
16
16
  codeql/regex:
17
- version: 1.0.41
17
+ version: 1.0.44
18
18
  codeql/ssa:
19
- version: 2.0.17
19
+ version: 2.0.20
20
20
  codeql/threat-models:
21
- version: 1.0.41
21
+ version: 1.0.44
22
22
  codeql/tutorial:
23
- version: 1.0.41
23
+ version: 1.0.44
24
24
  codeql/typetracking:
25
- version: 2.0.25
26
- codeql/util:
27
25
  version: 2.0.28
26
+ codeql/util:
27
+ version: 2.0.31
28
28
  codeql/xml:
29
- version: 1.0.41
29
+ version: 1.0.44
30
30
  codeql/yaml:
31
- version: 1.0.41
31
+ version: 1.0.44
32
32
  compiled: false
@@ -1,6 +1,6 @@
1
1
  name: advanced-security/ql-mcp-actions-tools-src
2
- version: 2.24.3
2
+ version: 2.25.0
3
3
  description: 'Queries for codeql-development-mcp-server tools for actions language'
4
4
  library: false
5
5
  dependencies:
6
- codeql/actions-all: 0.4.27
6
+ codeql/actions-all: 0.4.30
@@ -8,18 +8,13 @@
8
8
  */
9
9
 
10
10
  import cpp
11
-
12
- /**
13
- * Gets the source function name for which to generate the call graph.
14
- * Can be a single function name or comma-separated list of function names.
15
- */
16
- external string sourceFunction();
11
+ import ExternalPredicates
17
12
 
18
13
  /**
19
14
  * Gets a single source function name from the comma-separated list.
20
15
  */
21
16
  string getSourceFunctionName() {
22
- result = sourceFunction().splitAt(",").trim()
17
+ exists(string s | sourceFunction(s) | result = s.splitAt(",").trim())
23
18
  }
24
19
 
25
20
  /**
@@ -30,7 +25,8 @@ Function getSourceFunction() {
30
25
  selectedFunc = getSourceFunctionName() and
31
26
  (
32
27
  // Match by exact function name
33
- result.getName() = selectedFunc or
28
+ result.getName() = selectedFunc
29
+ or
34
30
  // Match by qualified name
35
31
  result.getQualifiedName() = selectedFunc
36
32
  )
@@ -41,15 +37,5 @@ from FunctionCall call, Function source, Function callee
41
37
  where
42
38
  call.getTarget() = callee and
43
39
  call.getEnclosingFunction() = source and
44
- (
45
- // Use external predicate if available
46
- source = getSourceFunction()
47
- or
48
- // Fallback for unit tests: include test files
49
- (
50
- not exists(getSourceFunction()) and
51
- source.getFile().getParentContainer().getParentContainer().getBaseName() = "test"
52
- )
53
- )
54
- select call,
55
- "Call from `" + source.getQualifiedName() + "` to `" + callee.getQualifiedName() + "`"
40
+ source = getSourceFunction()
41
+ select call, "Call from `" + source.getQualifiedName() + "` to `" + callee.getQualifiedName() + "`"
@@ -0,0 +1,47 @@
1
+ # CallGraphFromTo for C++
2
+
3
+ Displays calls on reachable paths from a source function to a target function, showing transitive call graph connectivity.
4
+
5
+ ## Overview
6
+
7
+ This query identifies all function calls that lie on any transitive call path from a specified source function to a specified target function. Given both a source and target function name, it reports each call site along the connecting paths, which is useful for understanding indirect call chains, security-relevant data flow paths, and function reachability.
8
+
9
+ The query uses transitive closure (`calls*`) to determine reachability, then reports only the direct call sites that contribute to paths between the source and target. It accepts function names via extensible predicates (`sourceFunction` and `targetFunction`) populated via CodeQL data extensions or model packs (see `ExternalPredicates.qll`) and supports both simple and qualified name matching.
10
+
11
+ ## Use Cases
12
+
13
+ This query is primarily used for:
14
+
15
+ - Determining if a call path exists between two functions
16
+ - Mapping indirect call chains from a source to a target function
17
+ - Analyzing security-relevant paths (e.g., from user input handlers to sensitive operations)
18
+ - Understanding transitive dependencies between functions
19
+
20
+ ## Example
21
+
22
+ The following C++ code demonstrates a transitive call chain from `source` through `intermediate` to `target`:
23
+
24
+ ```cpp
25
+ void target() {}
26
+
27
+ void intermediate() {
28
+ target();
29
+ }
30
+
31
+ void source() {
32
+ intermediate();
33
+ }
34
+ ```
35
+
36
+ Running with `sourceFunction = "source"` and `targetFunction = "target"` produces results showing each call site on the path with a message like: "Reachable call from `source` to `intermediate`".
37
+
38
+ ## Output Format
39
+
40
+ The query is a `@kind problem` query producing rows of:
41
+
42
+ - ``select call, "Reachable call from `caller` to `callee`"``
43
+
44
+ ## References
45
+
46
+ - [C++ Functions](https://en.cppreference.com/w/cpp/language/functions)
47
+ - [CodeQL Call Graph Analysis](https://codeql.github.com/docs/writing-codeql-queries/about-data-flow-analysis/)
@@ -0,0 +1,77 @@
1
+ /**
2
+ * @name Call Graph From To for cpp
3
+ * @description Displays calls on reachable paths from a source function to a target function, showing transitive call graph connectivity.
4
+ * @id cpp/tools/call-graph-from-to
5
+ * @kind problem
6
+ * @problem.severity recommendation
7
+ * @tags call-graph
8
+ */
9
+
10
+ import cpp
11
+ import ExternalPredicates
12
+
13
+ /**
14
+ * Gets a single source function name from the comma-separated list.
15
+ */
16
+ string getSourceFunctionName() {
17
+ exists(string s | sourceFunction(s) | result = s.splitAt(",").trim())
18
+ }
19
+
20
+ /**
21
+ * Gets a single target function name from the comma-separated list.
22
+ */
23
+ string getTargetFunctionName() {
24
+ exists(string s | targetFunction(s) | result = s.splitAt(",").trim())
25
+ }
26
+
27
+ /**
28
+ * Gets a function by matching against the selected source function names.
29
+ */
30
+ Function getSourceFunction() {
31
+ exists(string selectedFunc |
32
+ selectedFunc = getSourceFunctionName() and
33
+ (
34
+ // Match by exact function name
35
+ result.getName() = selectedFunc
36
+ or
37
+ // Match by qualified name
38
+ result.getQualifiedName() = selectedFunc
39
+ )
40
+ )
41
+ }
42
+
43
+ /**
44
+ * Gets a function by matching against the selected target function names.
45
+ */
46
+ Function getTargetFunction() {
47
+ exists(string selectedFunc |
48
+ selectedFunc = getTargetFunctionName() and
49
+ (
50
+ // Match by exact function name
51
+ result.getName() = selectedFunc
52
+ or
53
+ // Match by qualified name
54
+ result.getQualifiedName() = selectedFunc
55
+ )
56
+ )
57
+ }
58
+
59
+ /**
60
+ * Holds if function `caller` directly calls function `callee`.
61
+ */
62
+ predicate calls(Function caller_, Function callee_) {
63
+ exists(FunctionCall c | c.getEnclosingFunction() = caller_ and c.getTarget() = callee_)
64
+ }
65
+
66
+ from FunctionCall call, Function caller, Function callee
67
+ where
68
+ call.getTarget() = callee and
69
+ call.getEnclosingFunction() = caller and
70
+ exists(Function source, Function target |
71
+ source = getSourceFunction() and
72
+ target = getTargetFunction() and
73
+ calls*(source, caller) and
74
+ calls*(callee, target)
75
+ )
76
+ select call,
77
+ "Reachable call from `" + caller.getQualifiedName() + "` to `" + callee.getQualifiedName() + "`"
@@ -8,18 +8,13 @@
8
8
  */
9
9
 
10
10
  import cpp
11
-
12
- /**
13
- * Gets the target function name for which to generate the call graph.
14
- * Can be a single function name or comma-separated list of function names.
15
- */
16
- external string targetFunction();
11
+ import ExternalPredicates
17
12
 
18
13
  /**
19
14
  * Gets a single target function name from the comma-separated list.
20
15
  */
21
16
  string getTargetFunctionName() {
22
- result = targetFunction().splitAt(",").trim()
17
+ exists(string s | targetFunction(s) | result = s.splitAt(",").trim())
23
18
  }
24
19
 
25
20
  /**
@@ -30,7 +25,8 @@ Function getTargetFunction() {
30
25
  selectedFunc = getTargetFunctionName() and
31
26
  (
32
27
  // Match by exact function name
33
- result.getName() = selectedFunc or
28
+ result.getName() = selectedFunc
29
+ or
34
30
  // Match by qualified name
35
31
  result.getQualifiedName() = selectedFunc
36
32
  )
@@ -41,15 +37,5 @@ from FunctionCall call, Function target, Function caller
41
37
  where
42
38
  call.getTarget() = target and
43
39
  call.getEnclosingFunction() = caller and
44
- (
45
- // Use external predicate if available
46
- target = getTargetFunction()
47
- or
48
- // Fallback for unit tests: include test files
49
- (
50
- not exists(getTargetFunction()) and
51
- target.getFile().getParentContainer().getParentContainer().getBaseName() = "test"
52
- )
53
- )
54
- select call,
55
- "Call to `" + target.getQualifiedName() + "` from `" + caller.getQualifiedName() + "`"
40
+ target = getTargetFunction()
41
+ select call, "Call to `" + target.getQualifiedName() + "` from `" + caller.getQualifiedName() + "`"
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Shared extensible predicate declarations for MCP server tools queries.
3
+ * Values are provided via dataExtensions YAML files during testing,
4
+ * or via a temporary data extension pack at runtime from the MCP server.
5
+ */
6
+
7
+ /** Holds for each source function name for call graph analysis. */
8
+ extensible predicate sourceFunction(string name);
9
+
10
+ /** Holds for each target function name for call graph analysis. */
11
+ extensible predicate targetFunction(string name);
12
+
13
+ /** Holds for each selected source file path for AST/CFG printing. */
14
+ extensible predicate selectedSourceFiles(string path);
@@ -8,18 +8,13 @@
8
8
 
9
9
  import cpp
10
10
  import semmle.code.cpp.PrintAST
11
-
12
- /**
13
- * Gets the source files to generate AST from.
14
- * Can be a single file path or comma-separated list of file paths.
15
- */
16
- external string selectedSourceFiles();
11
+ import ExternalPredicates
17
12
 
18
13
  /**
19
14
  * Gets a single source file from the comma-separated list.
20
15
  */
21
16
  string getSelectedSourceFile() {
22
- result = selectedSourceFiles().splitAt(",").trim()
17
+ exists(string s | selectedSourceFiles(s) | result = s.splitAt(",").trim())
23
18
  }
24
19
 
25
20
  /**
@@ -30,11 +25,14 @@ File getSelectedFile() {
30
25
  selectedFile = getSelectedSourceFile() and
31
26
  (
32
27
  // Match by exact relative path from source root
33
- result.getRelativePath() = selectedFile or
28
+ result.getRelativePath() = selectedFile
29
+ or
34
30
  // Match by file name if no path separators
35
- (not selectedFile.matches("%/%") and result.getBaseName() = selectedFile) or
31
+ not selectedFile.matches("%/%") and result.getBaseName() = selectedFile
32
+ or
36
33
  // Match by ending path component
37
- result.getAbsolutePath().suffix(result.getAbsolutePath().length() - selectedFile.length()) = selectedFile
34
+ result.getAbsolutePath().suffix(result.getAbsolutePath().length() - selectedFile.length()) =
35
+ selectedFile
38
36
  )
39
37
  )
40
38
  }
@@ -44,14 +42,5 @@ File getSelectedFile() {
44
42
  * Falls back to test directory structure when external predicates are not available.
45
43
  */
46
44
  class Cfg extends PrintAstConfiguration {
47
- override predicate shouldPrintDeclaration(Declaration decl) {
48
- // Use external predicate if available
49
- decl.getFile() = getSelectedFile()
50
- or
51
- // Fallback for unit tests: include test files
52
- (
53
- not exists(getSelectedFile()) and
54
- decl.getFile().getParentContainer().getParentContainer().getBaseName() = "test"
55
- )
56
- }
45
+ override predicate shouldPrintDeclaration(Declaration decl) { decl.getFile() = getSelectedFile() }
57
46
  }
@@ -17,6 +17,4 @@ query predicate nodes(ControlFlowNode node, string property, string value) {
17
17
  value = node.toString()
18
18
  }
19
19
 
20
- query predicate edges(ControlFlowNode pred, ControlFlowNode succ) {
21
- pred.getASuccessor() = succ
22
- }
20
+ query predicate edges(ControlFlowNode pred, ControlFlowNode succ) { pred.getASuccessor() = succ }
@@ -2,27 +2,27 @@
2
2
  lockVersion: 1.0.0
3
3
  dependencies:
4
4
  codeql/controlflow:
5
- version: 2.0.25
5
+ version: 2.0.28
6
6
  codeql/cpp-all:
7
- version: 7.1.0
7
+ version: 8.0.1
8
8
  codeql/dataflow:
9
- version: 2.0.25
9
+ version: 2.1.0
10
10
  codeql/mad:
11
- version: 1.0.41
11
+ version: 1.0.44
12
12
  codeql/quantum:
13
- version: 0.0.19
13
+ version: 0.0.22
14
14
  codeql/rangeanalysis:
15
- version: 1.0.41
15
+ version: 1.0.44
16
16
  codeql/ssa:
17
- version: 2.0.17
17
+ version: 2.0.20
18
18
  codeql/tutorial:
19
- version: 1.0.41
19
+ version: 1.0.44
20
20
  codeql/typeflow:
21
- version: 1.0.41
21
+ version: 1.0.44
22
22
  codeql/typetracking:
23
- version: 2.0.25
24
- codeql/util:
25
23
  version: 2.0.28
24
+ codeql/util:
25
+ version: 2.0.31
26
26
  codeql/xml:
27
- version: 1.0.41
27
+ version: 1.0.44
28
28
  compiled: false
@@ -1,6 +1,6 @@
1
1
  name: advanced-security/ql-mcp-cpp-tools-src
2
- version: 2.24.3
2
+ version: 2.25.0
3
3
  description: 'Queries for codeql-development-mcp-server tools for cpp language'
4
4
  library: false
5
5
  dependencies:
6
- codeql/cpp-all: 7.1.0
6
+ codeql/cpp-all: 8.0.1
@@ -8,18 +8,13 @@
8
8
  */
9
9
 
10
10
  import csharp
11
-
12
- /**
13
- * Gets the source method name for which to generate the call graph.
14
- * Can be a single method name or comma-separated list of method names.
15
- */
16
- external string sourceFunction();
11
+ import ExternalPredicates
17
12
 
18
13
  /**
19
14
  * Gets a single source method name from the comma-separated list.
20
15
  */
21
16
  string getSourceFunctionName() {
22
- result = sourceFunction().splitAt(",").trim()
17
+ exists(string s | sourceFunction(s) | result = s.splitAt(",").trim())
23
18
  }
24
19
 
25
20
  /**
@@ -36,15 +31,5 @@ from Call call, Callable source, Callable callee
36
31
  where
37
32
  call.getEnclosingCallable() = source and
38
33
  call.getTarget() = callee and
39
- (
40
- // Use external predicate if available
41
- source = getSourceFunction()
42
- or
43
- // Fallback for unit tests: include test files
44
- (
45
- not exists(getSourceFunction()) and
46
- source.getFile().getParentContainer().getParentContainer().getBaseName() = "test"
47
- )
48
- )
49
- select call,
50
- "Call from `" + source.getName() + "` to `" + callee.getName() + "`"
34
+ source = getSourceFunction()
35
+ select call, "Call from `" + source.getName() + "` to `" + callee.getName() + "`"
@@ -0,0 +1,49 @@
1
+ # CallGraphFromTo for C# Source Files
2
+
3
+ Displays calls on reachable paths from a source method to a target method, showing transitive call graph connectivity.
4
+
5
+ ## Overview
6
+
7
+ This query identifies all method calls that lie on any transitive call path from a specified source method to a specified target method. Given both a source and target method name, it reports each call site along the connecting paths, which is useful for understanding indirect call chains, security-relevant data flow paths, and method reachability.
8
+
9
+ The query uses transitive closure (`calls*`) to determine reachability, then reports only the direct call sites that contribute to paths between the source and target. It accepts method names via extensible predicates (`sourceFunction` and `targetFunction`) populated via CodeQL data extensions / model packs (see `ExternalPredicates.qll`).
10
+
11
+ ## Use Cases
12
+
13
+ This query is primarily used for:
14
+
15
+ - Determining if a call path exists between two methods
16
+ - Mapping indirect call chains from a source to a target method
17
+ - Analyzing security-relevant paths (e.g., from user input handlers to sensitive operations)
18
+ - Understanding transitive dependencies between methods
19
+
20
+ ## Example
21
+
22
+ The following C# code demonstrates a transitive call chain from `Source` through `Intermediate` to `Target`:
23
+
24
+ ```csharp
25
+ class Example {
26
+ void Target() {}
27
+
28
+ void Intermediate() {
29
+ Target();
30
+ }
31
+
32
+ void Source() {
33
+ Intermediate();
34
+ }
35
+ }
36
+ ```
37
+
38
+ Running with `sourceFunction = "Source"` and `targetFunction = "Target"` produces results showing each call site on the path with a message like: "Reachable call from `Source` to `Intermediate`".
39
+
40
+ ## Output Format
41
+
42
+ The query is a `@kind problem` query producing rows of:
43
+
44
+ - ``select call, "Reachable call from `caller` to `callee`"``
45
+
46
+ ## References
47
+
48
+ - [C# Methods](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/methods)
49
+ - [CodeQL Call Graph Analysis](https://codeql.github.com/docs/writing-codeql-queries/about-data-flow-analysis/)
@@ -0,0 +1,64 @@
1
+ /**
2
+ * @name Call Graph From To for csharp
3
+ * @description Displays calls on reachable paths from a source method to a target method, showing transitive call graph connectivity.
4
+ * @id csharp/tools/call-graph-from-to
5
+ * @kind problem
6
+ * @problem.severity recommendation
7
+ * @tags call-graph
8
+ */
9
+
10
+ import csharp
11
+ import ExternalPredicates
12
+
13
+ /**
14
+ * Gets a single source method name from the comma-separated list.
15
+ */
16
+ string getSourceFunctionName() {
17
+ exists(string s | sourceFunction(s) | result = s.splitAt(",").trim())
18
+ }
19
+
20
+ /**
21
+ * Gets a single target method name from the comma-separated list.
22
+ */
23
+ string getTargetFunctionName() {
24
+ exists(string s | targetFunction(s) | result = s.splitAt(",").trim())
25
+ }
26
+
27
+ /**
28
+ * Gets a method by matching against the selected source method names.
29
+ */
30
+ Callable getSourceFunction() {
31
+ exists(string selectedFunc |
32
+ selectedFunc = getSourceFunctionName() and
33
+ result.getName() = selectedFunc
34
+ )
35
+ }
36
+
37
+ /**
38
+ * Gets a method by matching against the selected target method names.
39
+ */
40
+ Callable getTargetFunction() {
41
+ exists(string selectedFunc |
42
+ selectedFunc = getTargetFunctionName() and
43
+ result.getName() = selectedFunc
44
+ )
45
+ }
46
+
47
+ /**
48
+ * Holds if callable `caller` directly calls callable `callee`.
49
+ */
50
+ predicate calls(Callable caller_, Callable callee_) {
51
+ exists(Call c | c.getEnclosingCallable() = caller_ and c.getTarget() = callee_)
52
+ }
53
+
54
+ from Call call, Callable caller, Callable callee
55
+ where
56
+ call.getEnclosingCallable() = caller and
57
+ call.getTarget() = callee and
58
+ exists(Callable source, Callable target |
59
+ source = getSourceFunction() and
60
+ target = getTargetFunction() and
61
+ calls*(source, caller) and
62
+ calls*(callee, target)
63
+ )
64
+ select call, "Reachable call from `" + caller.getName() + "` to `" + callee.getName() + "`"
@@ -8,18 +8,13 @@
8
8
  */
9
9
 
10
10
  import csharp
11
-
12
- /**
13
- * Gets the target method name for which to generate the call graph.
14
- * Can be a single method name or comma-separated list of method names.
15
- */
16
- external string targetFunction();
11
+ import ExternalPredicates
17
12
 
18
13
  /**
19
14
  * Gets a single target method name from the comma-separated list.
20
15
  */
21
16
  string getTargetFunctionName() {
22
- result = targetFunction().splitAt(",").trim()
17
+ exists(string s | targetFunction(s) | result = s.splitAt(",").trim())
23
18
  }
24
19
 
25
20
  /**
@@ -36,15 +31,5 @@ from Call call, Callable target, Callable caller
36
31
  where
37
32
  call.getTarget() = target and
38
33
  call.getEnclosingCallable() = caller and
39
- (
40
- // Use external predicate if available
41
- target = getTargetFunction()
42
- or
43
- // Fallback for unit tests: include test files
44
- (
45
- not exists(getTargetFunction()) and
46
- target.getFile().getParentContainer().getParentContainer().getBaseName() = "test"
47
- )
48
- )
49
- select call,
50
- "Call to `" + target.getName() + "` from `" + caller.getName() + "`"
34
+ target = getTargetFunction()
35
+ select call, "Call to `" + target.getName() + "` from `" + caller.getName() + "`"
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Shared extensible predicate declarations for MCP server tools queries.
3
+ * Values are provided via dataExtensions YAML files during testing,
4
+ * or via a temporary data extension pack at runtime from the MCP server.
5
+ */
6
+
7
+ /** Holds for each source function name for call graph analysis. */
8
+ extensible predicate sourceFunction(string name);
9
+
10
+ /** Holds for each target function name for call graph analysis. */
11
+ extensible predicate targetFunction(string name);
12
+
13
+ /** Holds for each selected source file path for AST/CFG printing. */
14
+ extensible predicate selectedSourceFiles(string path);