codeql-development-mcp-server 2.25.0-rc1 → 2.25.1

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 +10562 -12415
  2. package/dist/codeql-development-mcp-server.js.map +4 -4
  3. package/package.json +5 -5
  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
@@ -0,0 +1,71 @@
1
+ /**
2
+ * @name Call Graph From To for python
3
+ * @description Displays calls on reachable paths from a source function to a target function, showing transitive call graph connectivity.
4
+ * @id python/tools/call-graph-from-to
5
+ * @kind problem
6
+ * @problem.severity recommendation
7
+ * @tags call-graph
8
+ */
9
+
10
+ import python
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
+ result.getName() = selectedFunc
34
+ )
35
+ }
36
+
37
+ /**
38
+ * Gets a function by matching against the selected target function names.
39
+ */
40
+ Function getTargetFunction() {
41
+ exists(string selectedFunc |
42
+ selectedFunc = getTargetFunctionName() and
43
+ result.getName() = selectedFunc
44
+ )
45
+ }
46
+
47
+ /**
48
+ * Holds if function `caller` directly calls function `callee` by name.
49
+ */
50
+ predicate calls(Function caller_, Function callee_) {
51
+ exists(CallNode c |
52
+ c.getScope() = caller_ and
53
+ c.getNode().(Call).getFunc().(Name).getId() = callee_.getName()
54
+ )
55
+ }
56
+
57
+ from CallNode call, Function caller
58
+ where
59
+ call.getScope() = caller and
60
+ exists(Function source, Function target |
61
+ source = getSourceFunction() and
62
+ target = getTargetFunction() and
63
+ calls*(source, caller) and
64
+ exists(Function callee |
65
+ call.getNode().(Call).getFunc().(Name).getId() = callee.getName() and
66
+ calls*(callee, target)
67
+ )
68
+ )
69
+ select call.getNode(),
70
+ "Reachable call from `" + caller.getName() + "` to `" +
71
+ call.getNode().(Call).getFunc().(Name).getId() + "`"
@@ -8,40 +8,24 @@
8
8
  */
9
9
 
10
10
  import python
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
  /**
26
21
  * Gets the caller name for a call expression.
27
22
  */
28
23
  string getCallerName(CallNode call) {
29
- if exists(call.getScope())
30
- then result = call.getScope().getName()
31
- else result = "Module"
24
+ if exists(call.getScope()) then result = call.getScope().getName() else result = "Module"
32
25
  }
33
26
 
34
27
  from CallNode call
35
- where
36
- (
37
- // Use external predicate if available
38
- call.getNode().(Call).getFunc().(Name).getId() = getTargetFunctionName()
39
- or
40
- // Fallback for unit tests: include test files
41
- (
42
- not exists(getTargetFunctionName()) and
43
- call.getLocation().getFile().getParentContainer().getParentContainer().getBaseName() = "test"
44
- )
45
- )
28
+ where call.getNode().(Call).getFunc().(Name).getId() = getTargetFunctionName()
46
29
  select call.getNode(),
47
- "Call to `" + call.getNode().(Call).getFunc().(Name).getId() + "` from `" + getCallerName(call) + "`"
30
+ "Call to `" + call.getNode().(Call).getFunc().(Name).getId() + "` from `" + getCallerName(call) +
31
+ "`"
@@ -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);
@@ -7,18 +7,13 @@
7
7
  */
8
8
 
9
9
  import semmle.python.PrintAst
10
-
11
- /**
12
- * Gets the source files to generate AST from.
13
- * Can be a single file path or comma-separated list of file paths.
14
- */
15
- external string selectedSourceFiles();
10
+ import ExternalPredicates
16
11
 
17
12
  /**
18
13
  * Gets a single source file from the comma-separated list.
19
14
  */
20
15
  string getSelectedSourceFile() {
21
- result = selectedSourceFiles().splitAt(",").trim()
16
+ exists(string s | selectedSourceFiles(s) | result = s.splitAt(",").trim())
22
17
  }
23
18
 
24
19
  /**
@@ -29,11 +24,14 @@ File getSelectedFile() {
29
24
  selectedFile = getSelectedSourceFile() and
30
25
  (
31
26
  // Match by exact relative path from source root
32
- result.getRelativePath() = selectedFile or
27
+ result.getRelativePath() = selectedFile
28
+ or
33
29
  // Match by file name if no path separators
34
- (not selectedFile.matches("%/%") and result.getBaseName() = selectedFile) or
30
+ not selectedFile.matches("%/%") and result.getBaseName() = selectedFile
31
+ or
35
32
  // Match by ending path component
36
- result.getAbsolutePath().suffix(result.getAbsolutePath().length() - selectedFile.length()) = selectedFile
33
+ result.getAbsolutePath().suffix(result.getAbsolutePath().length() - selectedFile.length()) =
34
+ selectedFile
37
35
  )
38
36
  )
39
37
  }
@@ -45,16 +43,7 @@ File getSelectedFile() {
45
43
  class Cfg extends PrintAstConfiguration {
46
44
  override predicate shouldPrint(AstNode e, Location l) {
47
45
  super.shouldPrint(e, l) and
48
- (
49
- // Use external predicate if available
50
- l.getFile() = getSelectedFile()
51
- or
52
- // Fallback for unit tests: include test files
53
- (
54
- not exists(getSelectedFile()) and
55
- l.getFile().getParent().getParent().getBaseName() = "test"
56
- )
57
- ) and
46
+ l.getFile() = getSelectedFile() and
58
47
  // Exclude the "Name" class so that results are deterministic
59
48
  // for a given source file, which is required for reproducible results
60
49
  not e.getAQlClass() = "Name"
@@ -16,6 +16,4 @@ query predicate nodes(ControlFlowNode node, string property, string value) {
16
16
  value = node.toString()
17
17
  }
18
18
 
19
- query predicate edges(ControlFlowNode pred, ControlFlowNode succ) {
20
- pred.getASuccessor() = succ
21
- }
19
+ query predicate edges(ControlFlowNode pred, ControlFlowNode succ) { pred.getASuccessor() = succ }
@@ -2,29 +2,29 @@
2
2
  lockVersion: 1.0.0
3
3
  dependencies:
4
4
  codeql/concepts:
5
- version: 0.0.15
5
+ version: 0.0.20
6
6
  codeql/controlflow:
7
- version: 2.0.25
7
+ version: 2.0.30
8
8
  codeql/dataflow:
9
- version: 2.0.25
9
+ version: 2.1.2
10
10
  codeql/mad:
11
- version: 1.0.41
11
+ version: 1.0.46
12
12
  codeql/python-all:
13
- version: 6.1.0
13
+ version: 7.0.3
14
14
  codeql/regex:
15
- version: 1.0.41
15
+ version: 1.0.46
16
16
  codeql/ssa:
17
- version: 2.0.17
17
+ version: 2.0.22
18
18
  codeql/threat-models:
19
- version: 1.0.41
19
+ version: 1.0.46
20
20
  codeql/tutorial:
21
- version: 1.0.41
21
+ version: 1.0.46
22
22
  codeql/typetracking:
23
- version: 2.0.25
23
+ version: 2.0.30
24
24
  codeql/util:
25
- version: 2.0.28
25
+ version: 2.0.33
26
26
  codeql/xml:
27
- version: 1.0.41
27
+ version: 1.0.46
28
28
  codeql/yaml:
29
- version: 1.0.41
29
+ version: 1.0.46
30
30
  compiled: false
@@ -1,6 +1,6 @@
1
1
  name: advanced-security/ql-mcp-python-tools-src
2
- version: 2.25.0-rc1
2
+ version: 2.25.1
3
3
  description: 'Queries for codeql-development-mcp-server tools for python language'
4
4
  library: false
5
5
  dependencies:
6
- codeql/python-all: 6.1.0
6
+ codeql/python-all: 7.0.3
@@ -9,32 +9,17 @@
9
9
 
10
10
  private import codeql.ruby.AST
11
11
  private import codeql.ruby.DataFlow
12
-
13
- /**
14
- * Gets the source method name for which to generate the call graph.
15
- * Can be a single method name or comma-separated list of method names.
16
- */
17
- external string sourceFunction();
12
+ import ExternalPredicates
18
13
 
19
14
  /**
20
15
  * Gets a single source method name from the comma-separated list.
21
16
  */
22
17
  string getSourceFunctionName() {
23
- result = sourceFunction().splitAt(",").trim()
18
+ exists(string s | sourceFunction(s) | result = s.splitAt(",").trim())
24
19
  }
25
20
 
26
21
  from MethodCall call, MethodBase source
27
22
  where
28
23
  call.getEnclosingMethod() = source and
29
- (
30
- // Use external predicate if available
31
- source.getName() = getSourceFunctionName()
32
- or
33
- // Fallback for unit tests: include test files
34
- (
35
- not exists(getSourceFunctionName()) and
36
- source.getLocation().getFile().getParentContainer().getParentContainer().getBaseName() = "test"
37
- )
38
- )
39
- select call,
40
- "Call from `" + source.getName() + "` to `" + call.getMethodName() + "`"
24
+ source.getName() = getSourceFunctionName()
25
+ select call, "Call from `" + source.getName() + "` to `" + call.getMethodName() + "`"
@@ -0,0 +1,48 @@
1
+ # CallGraphFromTo for Ruby
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 Ruby code demonstrates a transitive call chain from `source` through `intermediate` to `target`:
23
+
24
+ ```ruby
25
+ def target
26
+ end
27
+
28
+ def intermediate
29
+ target
30
+ end
31
+
32
+ def source
33
+ intermediate
34
+ end
35
+ ```
36
+
37
+ 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`".
38
+
39
+ ## Output Format
40
+
41
+ The query is a `@kind problem` query producing rows of:
42
+
43
+ - ``select call, "Reachable call from `caller` to `callee`"``
44
+
45
+ ## References
46
+
47
+ - [Ruby Methods](https://ruby-doc.org/3.2.0/syntax/methods_rdoc.html)
48
+ - [CodeQL Call Graph Analysis](https://codeql.github.com/docs/writing-codeql-queries/about-data-flow-analysis/)
@@ -0,0 +1,50 @@
1
+ /**
2
+ * @name Call Graph From To for ruby
3
+ * @description Displays calls on reachable paths from a source method to a target method, showing transitive call graph connectivity.
4
+ * @id ruby/tools/call-graph-from-to
5
+ * @kind problem
6
+ * @problem.severity recommendation
7
+ * @tags call-graph
8
+ */
9
+
10
+ private import codeql.ruby.AST
11
+ private import codeql.ruby.DataFlow
12
+ import ExternalPredicates
13
+
14
+ /**
15
+ * Gets a single source method name from the comma-separated list.
16
+ */
17
+ string getSourceFunctionName() {
18
+ exists(string s | sourceFunction(s) | result = s.splitAt(",").trim())
19
+ }
20
+
21
+ /**
22
+ * Gets a single target method name from the comma-separated list.
23
+ */
24
+ string getTargetFunctionName() {
25
+ exists(string s | targetFunction(s) | result = s.splitAt(",").trim())
26
+ }
27
+
28
+ /**
29
+ * Holds if method `caller` directly calls method `callee` by name.
30
+ */
31
+ predicate calls(MethodBase caller_, MethodBase callee_) {
32
+ exists(MethodCall c |
33
+ c.getEnclosingMethod() = caller_ and
34
+ c.getMethodName() = callee_.getName()
35
+ )
36
+ }
37
+
38
+ from MethodCall call, MethodBase caller
39
+ where
40
+ call.getEnclosingMethod() = caller and
41
+ exists(MethodBase source, MethodBase target |
42
+ source.getName() = getSourceFunctionName() and
43
+ target.getName() = getTargetFunctionName() and
44
+ calls*(source, caller) and
45
+ exists(MethodBase callee |
46
+ call.getMethodName() = callee.getName() and
47
+ calls*(callee, target)
48
+ )
49
+ )
50
+ select call, "Reachable call from `" + caller.getName() + "` to `" + call.getMethodName() + "`"
@@ -9,18 +9,13 @@
9
9
 
10
10
  private import codeql.ruby.AST
11
11
  private import codeql.ruby.DataFlow
12
-
13
- /**
14
- * Gets the target method name for which to generate the call graph.
15
- * Can be a single method name or comma-separated list of method names.
16
- */
17
- external string targetFunction();
12
+ import ExternalPredicates
18
13
 
19
14
  /**
20
15
  * Gets a single target method name from the comma-separated list.
21
16
  */
22
17
  string getTargetFunctionName() {
23
- result = targetFunction().splitAt(",").trim()
18
+ exists(string s | targetFunction(s) | result = s.splitAt(",").trim())
24
19
  }
25
20
 
26
21
  /**
@@ -33,16 +28,5 @@ string getCallerName(MethodCall call) {
33
28
  }
34
29
 
35
30
  from MethodCall call
36
- where
37
- (
38
- // Use external predicate if available
39
- call.getMethodName() = getTargetFunctionName()
40
- or
41
- // Fallback for unit tests: include test files
42
- (
43
- not exists(getTargetFunctionName()) and
44
- call.getLocation().getFile().getParentContainer().getParentContainer().getBaseName() = "test"
45
- )
46
- )
47
- select call,
48
- "Call to `" + call.getMethodName() + "` from `" + getCallerName(call) + "`"
31
+ where call.getMethodName() = getTargetFunctionName()
32
+ select call, "Call to `" + call.getMethodName() + "` from `" + getCallerName(call) + "`"
@@ -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
  private import codeql.ruby.AST
10
10
  private import codeql.ruby.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
  }
@@ -46,12 +44,6 @@ File getSelectedFile() {
46
44
  class Cfg extends PrintAstConfiguration {
47
45
  override predicate shouldPrintNode(AstNode n) {
48
46
  super.shouldPrintNode(n) and
49
- (
50
- // Use external predicate if available
51
- n.getLocation().getFile() = getSelectedFile()
52
- or
53
- // Fallback for unit tests: include all files
54
- not exists(getSelectedFile())
55
- )
47
+ n.getLocation().getFile() = getSelectedFile()
56
48
  }
57
49
  }
@@ -17,6 +17,4 @@ query predicate nodes(CfgNode node, string property, string value) {
17
17
  value = node.toString()
18
18
  }
19
19
 
20
- query predicate edges(CfgNode pred, CfgNode succ) {
21
- pred.getASuccessor() = succ
22
- }
20
+ query predicate edges(CfgNode pred, CfgNode succ) { pred.getASuccessor() = succ }
@@ -2,23 +2,23 @@
2
2
  lockVersion: 1.0.0
3
3
  dependencies:
4
4
  codeql/concepts:
5
- version: 0.0.15
5
+ version: 0.0.20
6
6
  codeql/controlflow:
7
- version: 2.0.25
7
+ version: 2.0.30
8
8
  codeql/dataflow:
9
- version: 2.0.25
9
+ version: 2.1.2
10
10
  codeql/mad:
11
- version: 1.0.41
11
+ version: 1.0.46
12
12
  codeql/regex:
13
- version: 1.0.41
13
+ version: 1.0.46
14
14
  codeql/ruby-all:
15
- version: 5.1.9
15
+ version: 5.1.14
16
16
  codeql/ssa:
17
- version: 2.0.17
17
+ version: 2.0.22
18
18
  codeql/tutorial:
19
- version: 1.0.41
19
+ version: 1.0.46
20
20
  codeql/typetracking:
21
- version: 2.0.25
21
+ version: 2.0.30
22
22
  codeql/util:
23
- version: 2.0.28
23
+ version: 2.0.33
24
24
  compiled: false
@@ -1,6 +1,6 @@
1
1
  name: advanced-security/ql-mcp-ruby-tools-src
2
- version: 2.25.0-rc1
2
+ version: 2.25.1
3
3
  description: 'Queries for codeql-development-mcp-server tools for ruby language'
4
4
  library: false
5
5
  dependencies:
6
- codeql/ruby-all: 5.1.9
6
+ codeql/ruby-all: 5.1.14
@@ -8,25 +8,23 @@
8
8
  */
9
9
 
10
10
  import swift
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
- string getSourceFunctionName() { result = sourceFunction().splitAt(",").trim() }
16
+ string getSourceFunctionName() {
17
+ exists(string s | sourceFunction(s) | result = s.splitAt(",").trim())
18
+ }
22
19
 
23
20
  /**
24
21
  * Gets a function by matching against the selected source function names.
22
+ * Supports both base names (e.g. "sourceFunc") and full Swift signatures (e.g. "sourceFunc()").
25
23
  */
26
24
  Function getSourceFunction() {
27
25
  exists(string selectedFunc |
28
26
  selectedFunc = getSourceFunctionName() and
29
- result.getName() = selectedFunc
27
+ (result.getName() = selectedFunc or result.getName().matches(selectedFunc + "(%"))
30
28
  )
31
29
  }
32
30
 
@@ -42,12 +40,5 @@ string getCalleeName(CallExpr call) {
42
40
  from CallExpr call, Function source
43
41
  where
44
42
  call.getEnclosingFunction() = source and
45
- (
46
- // Use external predicate if available
47
- source = getSourceFunction()
48
- or
49
- // Fallback for unit tests: include specific test files
50
- not exists(getSourceFunction()) and
51
- source.getFile().getBaseName() = "Example1.swift"
52
- )
43
+ source = getSourceFunction()
53
44
  select call, "Call from `" + source.getName() + "` to `" + getCalleeName(call) + "`"
@@ -0,0 +1,47 @@
1
+ # CallGraphFromTo for Swift
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 / 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 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 Swift code demonstrates a transitive call chain from `source` through `intermediate` to `target`:
23
+
24
+ ```swift
25
+ func target() {}
26
+
27
+ func intermediate() {
28
+ target()
29
+ }
30
+
31
+ func 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
+ - [Swift Functions](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/functions)
47
+ - [CodeQL Call Graph Analysis](https://codeql.github.com/docs/writing-codeql-queries/about-data-flow-analysis/)