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.
- package/dist/codeql-development-mcp-server.js +48111 -49526
- package/dist/codeql-development-mcp-server.js.map +4 -4
- package/package.json +9 -9
- package/ql/actions/tools/src/PrintCFG/PrintCFG.ql +1 -3
- package/ql/actions/tools/src/codeql-pack.lock.yml +14 -14
- package/ql/actions/tools/src/codeql-pack.yml +2 -2
- package/ql/cpp/tools/src/CallGraphFrom/CallGraphFrom.ql +6 -20
- package/ql/cpp/tools/src/CallGraphFromTo/CallGraphFromTo.md +47 -0
- package/ql/cpp/tools/src/CallGraphFromTo/CallGraphFromTo.ql +77 -0
- package/ql/cpp/tools/src/CallGraphTo/CallGraphTo.ql +6 -20
- package/ql/cpp/tools/src/ExternalPredicates.qll +14 -0
- package/ql/cpp/tools/src/PrintAST/PrintAST.ql +9 -20
- package/ql/cpp/tools/src/PrintCFG/PrintCFG.ql +1 -3
- package/ql/cpp/tools/src/codeql-pack.lock.yml +12 -12
- package/ql/cpp/tools/src/codeql-pack.yml +2 -2
- package/ql/csharp/tools/src/CallGraphFrom/CallGraphFrom.ql +4 -19
- package/ql/csharp/tools/src/CallGraphFromTo/CallGraphFromTo.md +49 -0
- package/ql/csharp/tools/src/CallGraphFromTo/CallGraphFromTo.ql +64 -0
- package/ql/csharp/tools/src/CallGraphTo/CallGraphTo.ql +4 -19
- package/ql/csharp/tools/src/ExternalPredicates.qll +14 -0
- package/ql/csharp/tools/src/PrintAST/PrintAST.ql +9 -17
- package/ql/csharp/tools/src/codeql-pack.lock.yml +10 -10
- package/ql/csharp/tools/src/codeql-pack.yml +2 -2
- package/ql/go/tools/src/CallGraphFrom/CallGraphFrom.ql +4 -19
- package/ql/go/tools/src/CallGraphFromTo/CallGraphFromTo.md +47 -0
- package/ql/go/tools/src/CallGraphFromTo/CallGraphFromTo.ql +53 -0
- package/ql/go/tools/src/CallGraphTo/CallGraphTo.ql +4 -20
- package/ql/go/tools/src/ExternalPredicates.qll +14 -0
- package/ql/go/tools/src/PrintAST/PrintAST.ql +132 -22
- package/ql/go/tools/src/codeql-pack.lock.yml +10 -10
- package/ql/go/tools/src/codeql-pack.yml +2 -2
- package/ql/java/tools/src/CallGraphFrom/CallGraphFrom.ql +4 -19
- package/ql/java/tools/src/CallGraphFromTo/CallGraphFromTo.md +49 -0
- package/ql/java/tools/src/CallGraphFromTo/CallGraphFromTo.ql +64 -0
- package/ql/java/tools/src/CallGraphTo/CallGraphTo.ql +4 -19
- package/ql/java/tools/src/ExternalPredicates.qll +14 -0
- package/ql/java/tools/src/PrintAST/PrintAST.ql +9 -17
- package/ql/java/tools/src/PrintCFG/PrintCFG.ql +11 -10
- package/ql/java/tools/src/codeql-pack.lock.yml +14 -14
- package/ql/java/tools/src/codeql-pack.yml +2 -2
- package/ql/javascript/tools/src/CallGraphFrom/CallGraphFrom.ql +4 -19
- package/ql/javascript/tools/src/CallGraphFromTo/CallGraphFromTo.md +47 -0
- package/ql/javascript/tools/src/CallGraphFromTo/CallGraphFromTo.ql +69 -0
- package/ql/javascript/tools/src/CallGraphTo/CallGraphTo.ql +4 -20
- package/ql/javascript/tools/src/ExternalPredicates.qll +14 -0
- package/ql/javascript/tools/src/PrintAST/PrintAST.ql +9 -20
- package/ql/javascript/tools/src/PrintCFG/PrintCFG.ql +1 -3
- package/ql/javascript/tools/src/codeql-pack.lock.yml +13 -13
- package/ql/javascript/tools/src/codeql-pack.yml +2 -2
- package/ql/python/tools/src/CallGraphFrom/CallGraphFrom.ql +3 -17
- package/ql/python/tools/src/CallGraphFromTo/CallGraphFromTo.md +46 -0
- package/ql/python/tools/src/CallGraphFromTo/CallGraphFromTo.ql +71 -0
- package/ql/python/tools/src/CallGraphTo/CallGraphTo.ql +6 -22
- package/ql/python/tools/src/ExternalPredicates.qll +14 -0
- package/ql/python/tools/src/PrintAST/PrintAST.ql +9 -20
- package/ql/python/tools/src/PrintCFG/PrintCFG.ql +1 -3
- package/ql/python/tools/src/codeql-pack.lock.yml +13 -13
- package/ql/python/tools/src/codeql-pack.yml +2 -2
- package/ql/ruby/tools/src/CallGraphFrom/CallGraphFrom.ql +4 -19
- package/ql/ruby/tools/src/CallGraphFromTo/CallGraphFromTo.md +48 -0
- package/ql/ruby/tools/src/CallGraphFromTo/CallGraphFromTo.ql +50 -0
- package/ql/ruby/tools/src/CallGraphTo/CallGraphTo.ql +4 -20
- package/ql/ruby/tools/src/ExternalPredicates.qll +14 -0
- package/ql/ruby/tools/src/PrintAST/PrintAST.ql +9 -17
- package/ql/ruby/tools/src/PrintCFG/PrintCFG.ql +1 -3
- package/ql/ruby/tools/src/codeql-pack.lock.yml +10 -10
- package/ql/ruby/tools/src/codeql-pack.yml +2 -2
- package/ql/swift/tools/src/CallGraphFrom/CallGraphFrom.ql +7 -16
- package/ql/swift/tools/src/CallGraphFromTo/CallGraphFromTo.md +47 -0
- package/ql/swift/tools/src/CallGraphFromTo/CallGraphFromTo.ql +80 -0
- package/ql/swift/tools/src/CallGraphTo/CallGraphTo.ql +8 -14
- package/ql/swift/tools/src/ExternalPredicates.qll +14 -0
- package/ql/swift/tools/src/PrintAST/PrintAST.ql +5 -15
- package/ql/swift/tools/src/PrintCFG/PrintCFG.ql +5 -15
- package/ql/swift/tools/src/codeql-pack.lock.yml +10 -10
- 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.
|
|
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.
|
|
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.
|
|
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.
|
|
74
|
-
"@vitest/coverage-v8": "^4.
|
|
75
|
-
"esbuild": "^0.27.
|
|
76
|
-
"eslint": "^10.0
|
|
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.
|
|
82
|
-
"vitest": "^4.
|
|
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",
|
|
@@ -2,31 +2,31 @@
|
|
|
2
2
|
lockVersion: 1.0.0
|
|
3
3
|
dependencies:
|
|
4
4
|
codeql/actions-all:
|
|
5
|
-
version: 0.4.
|
|
5
|
+
version: 0.4.30
|
|
6
6
|
codeql/concepts:
|
|
7
|
-
version: 0.0.
|
|
7
|
+
version: 0.0.18
|
|
8
8
|
codeql/controlflow:
|
|
9
|
-
version: 2.0.
|
|
9
|
+
version: 2.0.28
|
|
10
10
|
codeql/dataflow:
|
|
11
|
-
version: 2.0
|
|
11
|
+
version: 2.1.0
|
|
12
12
|
codeql/javascript-all:
|
|
13
|
-
version: 2.6.
|
|
13
|
+
version: 2.6.24
|
|
14
14
|
codeql/mad:
|
|
15
|
-
version: 1.0.
|
|
15
|
+
version: 1.0.44
|
|
16
16
|
codeql/regex:
|
|
17
|
-
version: 1.0.
|
|
17
|
+
version: 1.0.44
|
|
18
18
|
codeql/ssa:
|
|
19
|
-
version: 2.0.
|
|
19
|
+
version: 2.0.20
|
|
20
20
|
codeql/threat-models:
|
|
21
|
-
version: 1.0.
|
|
21
|
+
version: 1.0.44
|
|
22
22
|
codeql/tutorial:
|
|
23
|
-
version: 1.0.
|
|
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.
|
|
29
|
+
version: 1.0.44
|
|
30
30
|
codeql/yaml:
|
|
31
|
-
version: 1.0.
|
|
31
|
+
version: 1.0.44
|
|
32
32
|
compiled: false
|
|
@@ -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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
28
|
+
result.getRelativePath() = selectedFile
|
|
29
|
+
or
|
|
34
30
|
// Match by file name if no path separators
|
|
35
|
-
|
|
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()) =
|
|
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.
|
|
5
|
+
version: 2.0.28
|
|
6
6
|
codeql/cpp-all:
|
|
7
|
-
version:
|
|
7
|
+
version: 8.0.1
|
|
8
8
|
codeql/dataflow:
|
|
9
|
-
version: 2.0
|
|
9
|
+
version: 2.1.0
|
|
10
10
|
codeql/mad:
|
|
11
|
-
version: 1.0.
|
|
11
|
+
version: 1.0.44
|
|
12
12
|
codeql/quantum:
|
|
13
|
-
version: 0.0.
|
|
13
|
+
version: 0.0.22
|
|
14
14
|
codeql/rangeanalysis:
|
|
15
|
-
version: 1.0.
|
|
15
|
+
version: 1.0.44
|
|
16
16
|
codeql/ssa:
|
|
17
|
-
version: 2.0.
|
|
17
|
+
version: 2.0.20
|
|
18
18
|
codeql/tutorial:
|
|
19
|
-
version: 1.0.
|
|
19
|
+
version: 1.0.44
|
|
20
20
|
codeql/typeflow:
|
|
21
|
-
version: 1.0.
|
|
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.
|
|
27
|
+
version: 1.0.44
|
|
28
28
|
compiled: false
|
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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);
|